ERC20的创建及合约之间的调用(合约调用合约)

ERC20 Token

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

// SPDX-License-Identifier: GPL-3.0
pragma 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.0
pragma 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 token
        owner = 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 <=0");
        // 发送代币给对方
        uint256 bossTokenValue = rate.mul(msg.value);
        require(totalSupply.sub(exchangeTokenTotal)>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发行量

猜你喜欢

转载自blog.csdn.net/m0_37298500/article/details/127785235