在去中心化金融(DeFi)、NFT、游戏和各类社区治理蓬勃发展的今天,以太坊上的代币(Token)扮演着至关重要的角色,无论是稳定币usdt、治理币UNI,还是你最喜欢的NFT项目,其背后都离不开一个核心组件——代币合约,理解代币合约的源码,是深入探索区块链世界的基石,本文将带您从零开始,全面解析以太坊代币合约的源码,揭示其工作原理与核心逻辑。

以太坊本身是一个去中心化的世界计算机,它内置的加密货币是ETH,我们如何在以太坊上创建新的数字资产呢?答案就是通过智能合约。
代币合约本质上是一段部署在以太坊区块链上的代码,它定义了资产的规则:
通过遵循一套标准化的接口,不同的代币合约可以实现互操作性,从而被钱包、交易所、DeFi协议等广泛支持。
当我们谈论以太坊上的代币合约源码时,绝大多数情况下指的是遵循 ERC-20 标准的合约,ERC-20是以太坊社区提出的一个技术标准,它规定了一套所有 fungible token(同质化代币)都必须实现的接口和事件,就像USB接口标准一样,任何符合ERC-20标准的代币都可以插入任何支持ERC-20的“设备”(如钱包或交易所)。

ERC-20标准定义了以下核心接口:
// ERC-20 接口示例
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
totalSupply(): 查询代币的总供应量。balanceOf(account): 查询指定地址的代币余额。transfer(recipient, amount): 从调用者地址向recipient地址转移amount数量的代币。approve(spender, amount): 授权spender地址可以从调用者地址最多转移amount数量的代币。transferFrom(sender, recipient, amount): 从sender地址向recipient地址转移amount数量的代币,此操作需要sender已经授权调用者。Transfer: 在代币转移时触发,方便区块链浏览器和钱包追踪交易。Approval: 在授权时触发。下面是一个最基础、最经典的ERC-20代币合约源码实现,我们将逐行解析其逻辑。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
// "MyToken" 是代币名称, "MTK" 是代币符号
// 初始供应量为 1,000,000 个代币,并有 18 位小数
contract MyToken is ERC20 {
constructor(string memory name, string memory symbol) ERC20(name, symbol) {
_mint(msg.sender, 1000000 * 10**18);
}
}
代码逐行解析:
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;
pragma 是 Solidity 编译器指令,这行代码告诉编译器:“这段代码需要使用 Solidity 0.8.20 或更高版本(但不包括 0.9.0)来编译”,使用特定版本的 pragma 可以确保代码的行为在不同编译器版本中保持一致,避免因编译器升级导致的意外错误。import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
ERC20.sol 文件包含了符合 ERC-20 标准的所有核心实现,包括 balanceOf, transfer, approve 等函数,以及所有权管理、安全检查(如防止整数溢出/下溢)等,这样做既安全又高效。contract MyToken is ERC20 { ... }
contract MyToken:定义了一个名为 MyToken 的新智能合约。is ERC20:表示 MyToken 合约 继承 自 OpenZeppelin 的 ERC20 合约,这意味着 MyToken 自动获得了所有 ERC-20 的标准功能。constructor(string memory name, string memory symbol) ERC20(name, symbol) { ... }
constructor:这是一个特殊的函数,只在合约首次部署时执行一次,之后便无法再被调用,通常用于进行初始化操作。string memory name, string memory symbol:构造函数接收两个参数,分别是代币的全称(如 "My Token")和符号(如 "MTK")。ERC20(name, symbol):这是构造函数调用,在 MyToken 继承 ERC20 的情况下,我们必须显式调用父合约(ERC20)的构造函数,并将 name 和 symbol 传递给它,以便父合约能正确设置代币的元数据。*`_mint(msg.sender, 1000000 1018);`
_mint:这是 OpenZeppelin ERC20 合约提供的一个内部函数,用于在指定地址上创建新的代币并增加总供应量,注意,它不是公开的 mint 函数,通常只有合约所有者才能控制铸币逻辑。msg.sender:这是一个全局变量,始终指向当前调用该函数的地址,在构造函数中,msg.sender 就是部署这个合约的钱包地址。1000000 * 10**18:这是要铸造的代币数量。
1000000:我们想要的总供应量,即 100 万。10**18:这是以太坊和大多数 ERC-20 代币使用的精度单位,代表 18 位小数,这样做是为了统一处理,无论代币的小数位数是多少,合约内部都以最小的单位(wei级别)进行计算,我们实际铸造的是 1,000,000 * 1,000,000,000,000,000,000 = 1,000,000,000,000,000,000,000,000 个最小单位,显示给用户时就是 100 万 MTK。.sol 文件,将上面的代码粘贴进去。免责声明:本文为转载,非本网原创内容,不代表本网观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
如有疑问请发送邮件至:bangqikeconnect@gmail.com