安装 Node.js 从官网下载安装包)

网络 阅读: 2026-01-13 05:19:27

从零开始:以太坊ERC20代币开发详解**


以太坊作为全球领先的智能合约平台,其上发行的代币数量庞大,其中ERC20标准是最具影响力和广泛应用的代币标准之一,ERC20定义了一套统一的接口和规则,使得不同的代币可以在以太坊生态中无缝交互,例如在交易所交易、钱包存储、DeFi协议中使用等,本文将详细讲解ERC20代币的开发流程,包括核心概念、标准接口、智能合约编写、测试、部署以及注意事项。

什么是ERC20?

ERC20是“Ethereum Request for Comments 20”的缩写,即以太坊改进建议第20号,它不是一个具体的代币,而是一个技术标准,规定了以太坊上同质化代币(Fungible Token,即每个代币完全相同,可以互换)应遵循的规范,遵循ERC20标准的代币,其行为具有一致性,可以被各种以太坊钱包、交易所和应用识别和支持。

ERC20核心接口与事件

ERC20标准定义了必须实现的接口(函数)和推荐实现的事件,这些是开发ERC20代币合约的基础。

核心接口函数:

  • function name() public view returns (string): 返回代币的名称,"MyToken"。
  • function symbol() public view returns (string): 返回代币的符号,"MTK",通常2-3个字符。
  • function decimals() public view returns (uint8): 返回代币的小数位数,用于计算精度,18位小数意味着1个代币等于 10^18 个最小单位(wei类似)。
  • function totalSupply() public view returns (uint256): 返回代币的总供应量。
  • function balanceOf(address _owner) public view returns (uint256): 返回指定地址 _owner 拥有的代币数量。
  • function transfer(address _to, uint256 _value) public returns (bool): 将调用者(msg.sender)的 _value 数量代币转移到地址 _to,成功返回 true
  • function transferFrom(address _from, address _to, uint256 _value) public returns (bool): 从地址 _from 转移 _value 数量代币到地址 _to,调用者需要有来自 _from 的足够授权(通过 approve)。
  • function approve(address _spender, uint256 _value) public returns (bool): 授权地址 _spender 可以调用 transferFrom 从调用者(msg.sender)处转移最多 _value 数量的代币。
  • function allowance(address _owner, address _spender) public view returns (uint256): 返回地址 _spender 被授权从地址 _owner 处转移的代币数量。

推荐事件:

  • event Transfer(address indexed from, address indexed to, uint256 value): 当代币发生转移时触发(包括铸造和销毁)。from 为零地址表示铸造,to 为零地址表示销毁。
  • event Approval(address indexed owner, address indexed spender, uint256 value): 当 approve 函数被调用时触发,授权额度发生变化。

开发环境准备

在开始编写ERC20代币合约之前,需要准备以下开发环境:

  1. Node.js and npm/yarn: JavaScript运行时环境和包管理器。
  2. Truffle: 一个流行的以太坊开发框架,用于编译、测试和部署智能合约。
  3. Ganache: 一本本地的以太坊区块链,用于快速开发和测试,可以立即生成测试账户和提供以太坊。
  4. MetaMask: 一个浏览器钱包插件,用于与以太坊区块链交互,管理账户,以及在测试网上部署和测试合约。
  5. Solidity: 以太坊智能合约的编程语言,需要安装Solidity编译器(solc)。

安装步骤(简述):

npm install -g truffle
# 安装 Ganache (从官网下载桌面应用或命令行版本)
# 安装 MetaMask (浏览器扩展商店)

编写ERC20代币智能合约

我们可以使用Truffle提供的ERC20合约模板,或者从OpenZeppelin库导入经过审计的ERC20实现,后者更安全可靠。

使用OpenZeppelin库(推荐)

OpenZeppelin提供了一套安全的、标准化的智能合约组件,包括ERC20代币。

  • 初始化项目:

    mkdir my-erc20-token
    cd my-erc20-token
    npm init -y
    npm install @openzeppelin/contracts
  • 编写合约: 在 contracts/ 目录下创建 MyToken.sol 文件。

    // 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个代币,18位小数
            _mint(msg.sender, 1000000 * 10**decimals());
        }
    }
    • SPDX-License-Identifier: 指定许可证。
    • pragma solidity ^0.8.20; 指定Solidity编译器版本。
    • import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 导入OpenZeppelin的ERC20合约。
    • contract MyToken is ERC20; 声明我们的合约继承自ERC20。
    • constructor: 构造函数,在合约部署时调用,我们在这里设置了代币的名称和符号,并通过 _mint 函数向部署者铸造初始代币。_mint 是ERC20合约内部提供的铸造函数。

编译合约

在项目根目录下运行:

truffle compile

如果成功,会在 build/contracts/ 目录下生成编译后的JSON文件(ABI和字节码)。

测试合约

测试是确保智能合约正确性和安全性的重要环节。

  • 编写测试脚本: 在 test/ 目录下创建 myToken.test.js 文件(使用JavaScript或TypeScript)。

    const MyToken = artifacts.require("MyToken");
    contract("MyToken", (accounts) => {
        it("should put 1000000 MyToken in the first account", async () => {
            const myTokenInstance = await MyToken.deployed();
            const balance = await myTokenInstance.balanceOf(accounts[0]);
            assert.equal(balance.toString(), "1000000000000000000000000", "1000000 tokens weren't in the first account");
        });
        it("should transfer tokens correctly", async () => {
            const myTokenInstance = await MyToken.deployed();
            const sender = accounts[0];
            const receiver = accounts[1];
            const amount = web3.utils.toWei("100", "ether"); // 假设decimals是18
            // 检查初始余额
            let senderBalance = await myTokenInstance.balanceOf(sender);
            let receiverBalance = await myTokenInstance.balanceOf(receiver);
            assert.equal(senderBalance.toString(), "1000000000000000000000000");
            assert.equal(receiverBalance.toString(), "0");
            // 转移
            await myTokenInstance.transfer(receiver, amount);
            // 检查转移后余额
            senderBalance = await myTokenInstance.balanceOf(sender);
            receiverBalance = await myTokenInstance.balanceOf(receiver);
            assert.equal(senderBalance.toString(), "999900000000000000000000");
            assert.equal(receiverBalance.toString(), "100000000000000000000");
        });
    });
  • 运行测试:

    truffle test

部署合约

部署合约到以太坊网络(可以是本地Ganache、测试网如Goerli或Sepolia,或主网)。

  • 配置Truffle: 在 truffle-config.js (或 truffle.js) 中配置网络。

    require('dotenv').config(); // 使用.env文件管理私钥等敏感信息
    const { MNEMONIC, INFURA_API_KEY } = process.env;
    module.exports = {
      networks: {
        development: {
          host: "127.0.0.1",     // Localhost (default: none)
          port: 7545,            // Standard Ethereum port (default: none)
          network_id: "*",       // Any network (default: none)
        },
        goerli: {
          provider: () => new HDWalletProvider(MNEMONIC, `https://goerli.infura.io/v

本文 原创,转载保留链接!网址:https://licai.bangqike.com/bixun/1326069.html

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

扫一扫关注我们,了解最新精彩内容

搜索