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发行量

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的ERC20智能合约示例: ```solidity pragma solidity ^0.8.0; contract ERC20Token { string public name; string public symbol; uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; constructor(string memory _name, string memory _symbol, uint256 _totalSupply) { name = _name; symbol = _symbol; totalSupply = _totalSupply; balanceOf[msg.sender] = _totalSupply; } function transfer(address _to, uint256 _value) public returns (bool success) { require(balanceOf[msg.sender] >= _value, "Insufficient balance"); balanceOf[msg.sender] -= _value; balanceOf[_to] += _value; emit Transfer(msg.sender, _to, _value); return true; } function approve(address _spender, uint256 _value) public returns (bool success) { allowance[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); return true; } function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) { require(balanceOf[_from] >= _value, "Insufficient balance"); require(allowance[_from][msg.sender] >= _value, "Insufficient allowance"); balanceOf[_from] -= _value; balanceOf[_to] += _value; allowance[_from][msg.sender] -= _value; emit Transfer(_from, _to, _value); return true; } event Transfer(address indexed _from, address indexed _to, uint256 _value); event Approval(address indexed _owner, address indexed _spender, uint256 _value); } ``` 该合约包括以下功能: - `name`:代币名称 - `symbol`:代币符号 - `totalSupply`:代币总量 - `balanceOf`:每个地址的代币余额 - `allowance`:允许其他地址花费的代币数量 该合约实现了ERC20标准中的以下函数: - `transfer`:从调用者的地址向另一个地址发送代币 - `approve`:允许另一个地址花费指定数量的代币 - `transferFrom`:从一个地址向另一个地址发送代币,前提是已经获得了允许 该合约还定义了两个事件: - `Transfer`:代币发送时触发 - `Approval`:允许花费代币时触发 要部署这个合约,你需要使用Solidity编译器将其编译为字节码,然后将字节码发送到以太坊网络上。你可以使用Remix或Truffle等工具来编译和部署智能合约

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值