在区块链的世界里,以太坊无疑是最具影响力的平台之一,而其上的ERC20标准更是奠定了代币经济的基石,ERC20是一种技术标准,定义了以太坊上同质化代币(即每个代币都是

随机配图
完全相同的,可互换)的接口和行为规范,遵循ERC20标准开发的代币可以轻松与钱包、交易所、去中心化应用(DApp)等生态系统集成,本文将带你一步步了解如何编写一个基本的以太坊ERC20智能合约。

什么是ERC20标准

ERC20标准规定了代币合约必须实现的一组方法和事件,主要包括:

必须实现的方法(函数):

  • name():返回代币的名称,"MyToken"。
  • symbol():返回代币的符号,"MTK"。
  • decimals():返回代币的小数位数,用于计算精度,通常为18。
  • totalSupply():返回代币的总供应量。
  • balanceOf(address _owner):返回指定地址的代币余额。
  • transfer(address _to, uint256 _value):向指定地址转移指定数量的代币。
  • transferFrom(address _from, address _to, uint256 _value):从指定地址转移指定数量的代币(通常需要先调用approve授权)。
  • allowance(address _owner, address _spender):返回_owner授权给_spender的代币数量。
  • approve(address _spender, uint256 _value):授权_spender可以从调用者账户中转移最多_value数量的代币。

必须实现的事件:

  • Transfer(address indexed from, address indexed to, uint256 value):当代币被转移时触发(从fromto,数量为value),创建代币时,from地址为0x000...000
  • Approval(address indexed owner, address indexed spender, uint256 value):当approve方法被调用时触发,表示owner授权给spender的额度为value

开发环境准备

在开始编写合约之前,你需要准备以下工具:

  1. Solidity 编译器:Solidity是以太坊智能合约的主要编程语言。
  2. 以太坊客户端或开发框架:如Truffle、Hardhat,或者直接使用在线的Remix IDE(Remix非常适合初学者,无需本地配置)。
  3. MetaMask钱包:用于与以太坊网络交互,测试和部署合约。
  4. 测试网ETH:用于支付部署合约时的gas费用,你可以从以太坊测试网水龙头获取测试ETH。

编写一个简单的ERC20合约

我们将使用Solidity语言,并借助OpenZeppelin库来编写一个安全且标准的ERC20合约,OpenZeppelin是一个提供安全、可测试的智能合约库的框架,强烈建议在实际项目中使用。

步骤1:创建项目文件 在你的项目目录下,创建一个名为MyToken.sol的文件。

步骤2:编写合约代码 以下是一个基于OpenZeppelin的ERC20合约示例:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {
    constructor(string memory name, string memory symbol) ERC20(name, symbol) {
        // 在部署时,向合约创建者(msg.sender)发行1000000个代币
        // 假设decimals为18,所以实际发行数量为 1000000 * 10^18
        _mint(msg.sender, 1000000 * 10**decimals());
    }
}

代码解释:

  • SPDX-License-Identifier: MIT:指定许可证类型,这是良好的实践。
  • pragma solidity ^0.8.20;:指定Solidity编译器版本,^0.8.20表示使用0.8.20或更高但不包括0.9.0的版本。
  • import "@openzeppelin/contracts/token/ERC20/ERC20.sol";:导入OpenZeppelin的ERC20标准合约。
  • contract MyToken is ERC20 { ... }:定义名为MyToken的合约,继承自OpenZeppelin的ERC20合约。
  • constructor(string memory name, string memory symbol) ERC20(name, symbol) { ... }:构造函数,在合约部署时调用,它接收代币名称和符号作为参数,并传递给父合约ERC20的构造函数。
  • _mint(msg.sender, 1000000 * 10**decimals());_mint是ERC20合约内部的一个函数,用于创建新的代币并分配到指定地址,这里我们向合约的创建者(msg.sender)发行1000000个代币,乘以10**decimals()是为了考虑小数位数,因为decimals()默认为18,所以实际发行的是1000000 * 10^18个最小单位(wei级别的代币)。

编译和部署合约

使用Remix IDE(推荐初学者):

  1. 打开浏览器,访问 Remix IDE
  2. 在"File Explorers"标签页中,创建一个新的文件MyToken.sol,并将上述代码粘贴进去。
  3. 在"Solidity Compiler"标签页,选择合适的编译器版本(如0.8.20),然后点击"Compile MyToken.sol"按钮。
  4. 在"Deploy & Run Transactions"标签页:
    • 选择"ENVIRONMENT"为"Remix VM (Shanghai)" - 这是一个模拟的以太坊环境,无需真实ETH。
    • "ACCOUNT"会自动选择一个测试账户,并显示其余额。
    • 在"CONTRACT"下拉菜单中选择"MyToken - MyToken`。
    • 在"Deploy"按钮上方,输入构造函数所需的参数,例如"My Awesome Token"和"MAT"
    • 点击"Deploy"按钮。
  5. 部署成功后,你可以在"Deployed Contracts"列表中看到你的MyToken合约,并可以调用其函数进行测试,如查看name(), symbol(), totalSupply(), balanceOf()等。

使用Truffle/Hardhat(本地开发):

  1. 初始化项目:truffle inithardhat
  2. 安装OpenZeppelin:npm install @openzeppelin/contracts
  3. 将合约代码放在contracts目录下(如contracts/MyToken.sol)。
  4. 配置truffle-config.jshardhat.config.js
  5. 编译合约:truffle compilenpx hardhat compile
  6. 编写迁移脚本(如migrations/2_deploy_contracts.js)。
  7. 部署到测试网:truffle develop(本地测试网)或配置Infura等后端部署到公共测试网。

测试和验证

部署成功后,你需要测试合约的各项功能是否符合预期:

  • 查询代币信息:调用name(), symbol(), decimals(), totalSupply()
  • 查询余额:调用balanceOf()查询部署账户或其他账户的余额。
  • 代币转账
    • 调用transfer()将代币从部署账户转移到另一个账户。
    • 验证双方余额是否正确变化。
    • 测试transferFrom()
      1. 部署账户调用approve()授权另一个账户(如账户B)花费一定数量的代币。
      2. 账户B调用transferFrom()从部署账户转移代币到账户B或其他账户。
      3. 验证授权额度、双方余额。

重要注意事项

  1. 安全性:不要轻易使用自己编写的ERC20合约模板,尤其是涉及资金安全的部分,强烈建议使用像OpenZeppelin这样经过审计和广泛使用的库。
  2. Gas成本:代币操作会消耗gas,复杂的合约或大量的转账会消耗更多gas,在设计和部署时需考虑。
  3. 代币经济学:发行量、增发机制、销毁机制等需要在合约中仔细设计,或在后续通过升级(使用代理模式)来实现。
  4. 网络选择:开发和测试阶段建议使用测试网(如Sepolia, Goerli),确认无误后再考虑部署到主网。
  5. 合约地址和ABI:部署成功后,务必记录下合约地址和应用程序二进制接口(ABI),这些是与你的代币交互所必需的。

通过本文,你应该已经了解了ERC20标准的基本概念,并学会了如何使用Solid