以太坊上最重要的智能合约标准之一就是ERC-20,它已经成为以太坊区块链上所有可替代令牌实现的智能合约的技术标准。

ERC-20定义了所有可替代以太坊令牌都应遵守的通用规则列表。因此,该令牌标准使所有类型的开发人员都能够准确预测新令牌在更大的以太坊系统中的功能。这简化了开发人员的任务,因为他们可以继续进行工作,并且知道只要发行令牌遵循规则,就不需要在每次发布新令牌时都重做每个新项目。

这里以接口的形式呈现了ERC-20必须实现的功能。如果不确定什么是接口,请查看有关Solidity中OOP编程的文章。

pragma solidity ^0.6.0; interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); 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); }

这是每个功能的逐行解释。之后我们将介绍ERC-20令牌的简单实现。

Getters

function totalSupply() external view returns (uint256);

返回存在的令牌数量。此函数是一个获取器,不会修改合同的状态。请记住,Solidity中没有浮点数。因此,大多数令牌采用18位小数,并会返回总供给量和其他结果,如下所示1个令牌的1000000000000000000。并非每个令牌都有18位小数,这是您在处理令牌时真正需要注意的事项。

function balanceOf(address account) external view returns (uint256);

返回地址(account)拥有的令牌数量。此函数是一个获取器,不会修改合同的状态。

function allowance(address owner, address spender) external view returns (uint256);

ERC-20标准允许一个地址给另一个地址一个余量,以便能够从中检索令牌。此getter返回spender将允许用来代表花费的令牌剩余数量owner。此函数是一个getter,不会修改合同的状态,默认情况下应返回0。

Functions

function transfer(address recipient, uint256 amount) external returns (bool);

amount令牌的从功能调用者地址(msg.sender)移动到接收者地址。此函数发出Transfer稍后定义的事件。如果可以传输,则返回true。

function approve(address spender, uint256 amount) external returns (bool);

设定的量allowancespender被允许从函数调用方(转移msg.sender)的平衡。此函数发出Approval事件。该函数返回是否成功设置了allowance。

function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

移动amount从令牌senderrecipient使用 allowance机制。然后从呼叫者的 allowance中扣除该金额。此函数发出Transfer事件。

Events

event Transfer(address indexed from, address indexed to, uint256 value);

当令牌数量(值)从from地址发送到该地址时,将发出此事件to

在铸造新令牌的情况下,传输通常from为0x00..0000地址,而在刻录令牌的情况下,传输为to0x00..0000。。

event Approval(address indexed owner, address indexed spender, uint256 value);

当令牌的数量(value)被批准并由所owner使用时,会发出此事件spender。

ERC-20令牌的基本实现

这是一种ERC-20令牌的最简单的代码:

pragma solidity ^0.6.0; interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); 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); } contract ERC20Basic is IERC20 { string public constant name = "ERC20Basic"; string public constant symbol = "ERC"; uint8 public constant decimals = 18; event Approval(address indexed tokenOwner, address indexed spender, uint tokens); event Transfer(address indexed from, address indexed to, uint tokens); mapping(address => uint256) balances; mapping(address => mapping (address => uint256)) allowed; uint256 totalSupply_; using SafeMath for uint256; constructor(uint256 total) public { totalSupply_ = total; balances[msg.sender] = totalSupply_; } function totalSupply() public override view returns (uint256) { return totalSupply_; } function balanceOf(address tokenOwner) public override view returns (uint256) { return balances[tokenOwner]; } function transfer(address receiver, uint256 numTokens) public override returns (bool) { require(numTokens <= balances[msg.sender]); balances[msg.sender] = balances[msg.sender].sub(numTokens); balances[receiver] = balances[receiver].add(numTokens); emit Transfer(msg.sender, receiver, numTokens); return true; } function approve(address delegate, uint256 numTokens) public override returns (bool) { allowed[msg.sender][delegate] = numTokens; emit Approval(msg.sender, delegate, numTokens); return true; } function allowance(address owner, address delegate) public override view returns (uint) { return allowed[owner][delegate]; } function transferFrom(address owner, address buyer, uint256 numTokens) public override returns (bool) { require(numTokens <= balances[owner]); require(numTokens <= allowed[owner][msg.sender]); balances[owner] = balances[owner].sub(numTokens); allowed[owner][msg.sender] = allowed[owner][msg.sender].sub(numTokens); balances[buyer] = balances[buyer].add(numTokens); emit Transfer(owner, buyer, numTokens); return true; } } library SafeMath { function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c >= a); return c; } }
订阅我们的新闻
获取最新的文章
更多内容
您想提升区块链认知吗?
让我们保持联系