ERC20 Token

ERC20是一个token合约标准,具体的概念和友好的合约库,可参考openzeppelin.接下来的代码创建一个erc20 token

// SPDX-License-Identifier: GPL-3.0pragma solidity ^0.8.0;import "@openzeppelin/contracts/token/ERC20/ERC20.sol";contract IcoToken is ERC20{constructor(uint256 initialSupply) ERC20("xoToken","XO"){_mint(msg.sender,initialSupply);}}

注:solidity 0.6.8版本以后增加的SPDX申明,许可证标识符是必须要有的

合约与合约间的调用

关于合约与合约的调用我们以ICO作为示例来展示

什么是ICO,大致意思是,你有一个很好的项目需要融资,对方给你ETH,你发行代币(ERC20 Token)给投资人

所以ICO会是一个独立的合约,ERC20 Token又是另外一个合约,代码在上一个代码片段已体现,接下来通过ICO合约 展示合约间的调用

// SPDX-License-Identifier: GPL-3.0pragma solidity ^0.8.0;import "@openzeppelin/contracts/token/ERC20/IERC20.sol";import "@openzeppelin/contracts/utils/math/SafeMath.sol";import "./a_IcoToken.sol";contract IcoExchange{using SafeMath for uint256;// ico的状态定义enum IcoState {Before,Start,End}IcoState public icoState = IcoState.Before;address private owner;// ico的token地址IcoToken public icoToken ;uint256 public totalSupply= 1000000 * (10**18);uint256 public exchangeTokenTotal = 0;uint256 public rate =2;constructor(){// 申明ico属主// 创建ico tokenowner = msg.sender;icoToken=new IcoToken(totalSupply);}event ReceiveICO(address from,uint256 ethValue,uint256 icoTokenValue);event StartICO(address who);event EndICO(address who,uint256 allEth,uint256 exchangeTokenTotal);// 判断ico属主modifier isOwner(){require(owner== msg.sender,"must the owner");_;}// 判断当前状态modifier inBefore(){require(icoState==IcoState.Before,"icoState is not Before");_;}modifier inStart(){require(icoState==IcoState.Start,"icoState is not Start");_;}// ico的状态控制function startICO() public isOwner inBefore {icoState = IcoState.Start;emit StartICO(msg.sender);}function endICO() public isOwner inStart{emit EndICO(msg.sender,address(this).balance,exchangeTokenTotal);// eth提取payable(owner).transfer(address(this).balance);// 剩余代币返还给ico的发起人icoToken.transfer(owner,totalSupply.sub(exchangeTokenTotal));icoState = IcoState.End;}function inICO() public inStart payable{require(msg.value>0,"inICO can't bossTokenValue,"icoTOken balance not enough");icoToken.transfer(msg.sender,bossTokenValue);exchangeTokenTotal = exchangeTokenTotal.add(bossTokenValue);emit ReceiveICO(msg.sender,msg.value,bossTokenValue);}receive() external payable{inICO();}}

测试方式:你可以再remix完成编译部署和测试

前置: 运行环境(ENVIRONMENT)选择= Remix VM(London)

1.编译和部署 假设A地址部署合约

2.测试开启ICO:A地址触发合约方法:startICO

3.测试投资:其它地址直接向合约地址转ETH,或调用合约方法inICO

4.测试结束投资: A地址触发合约方法:endICO

结束时 测试结果示例

上个例子展示的是创建合约+合约间的调用,那么传入合约地址,怎么调用合约方法呢

很简单 示例如下:

1. 引入合约的接口或直接就合约引入

import “@openzeppelin/contracts/token/ERC20/IERC20.sol”;

2. 如下方式得到合约实例并调用合约方法,erc20实例代码

IERC20(合约地址).totalSupply() // 查询某一个erc20合约的token发行量