ERC-20协议是什么意思?
ERC代表“Etuereum Request for Comment”,以太坊社区为了创建一个以太坊平台的标准,开发人员提交了一个以太坊改进方案(EIP),改进方案中包括协议规范和合约标准。最终确定的EIP为以太坊开发者提供了一套可实施的标准。这使得智能合约可以遵循这些通用的接口标准来构建。可以在这里检索到所有EIP提案。
而ERC-20是以太坊上最重要的智能合约标准之一。它已经成为基于以太坊公链上用于发行可替换通证,所使用智能合约的技术标准。ERC-20 定义了所有可替换的以太坊通证都应该遵守的通用规则列表。 这简化了开发者的任务,开发者知道只要通证遵循标准中的规则,每次发布新的通证时就不需要重新实现每个新项目。
知识点:什么是可替换的以太坊通证,还有不可替换的以太坊通证吗?
可替换的以太坊通证是表示通证与通证之间是完全一样的,可以被替换的,通常遵循ERC-20标准。比如A钱包中的一个ERC-20通证和B钱包中的一个相同合约地址的ERC-20通证,在区块链上看来完全一致没有什么不同,可以被相互替换。
不可替换的以太坊通证又叫非同质化通证(Non-Fungible Token)缩写为NFT,就算AB两个钱包中存在合约地址相同的两个通证,它们也存在着不一致的属性值,它们是不一样的。所以在区块链上看来是不可被相互替换的。这样的通证通常遵循ERC-721标准。
这里有段 ERC-20 接口代码,它定义了遵循 ERC-20 标准通证所必须实现的函数:
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
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 to, uint256 amount) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
下面说明一下这些函数的用途
取值函数 totalSupply
这个函数返回存在的通证数量,展示了目前该通证的流通总量,可以被所有函数调取。该函数是一个取值函数,不会修改合约的状态。重点:Solidity 中没有浮点数。 因此,大多数通证都会采用 18 位小数,并且会返回总供应量和其他结果,如下所示:1 个通证 = 100000000000000000。 这需要在处理通证数量时格外注意,不过并不是每个通证都有 18 位小数。
function totalSupply() external view returns (uint256);
balanceOf
这个函数返回某地址拥有的通证数量(account)。 该函数同样是一个取值函数,不会修改合约的状态。
function balanceOf(address account) external view returns (uint256);
allowance
此函数被用来查看owner给spender的通证额度。此函数是一个取值函数,不会修改合约的状态,并且默认应返回 0。
function allowance(address owner, address spender)
external
view
returns (uint256);
*** 作函数 transfer
将一定数量(amount)的通证从函数调用者地址(msg.sender)移动到接收者(to)地址。此函数发出稍后定义的Transfer事件。 如果可进行转账,它将返回 true,转账 *** 作需要消耗gas。
function transfer(address to, uint256 amount) external returns (bool);
approve
函数调用方(msg.sender)可以调用这个函数授权spender代表它使用amount数量的通证,即设置允许spender从函数调用方(msg.sender)余额转账的allowance的数额。 此函数发出 Approval 事件。 此函数返回是否成功设置了余量。
function approve(address spender, uint256 amount) external returns (bool);
transferFrom
使用余量机制将通证的amount从from移动到to。 然后从调用者的余量中扣除该数额。 此函数发出Transfer事件。
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
事件 Transfer
将通证的数量value从from地址发送到to地址时会发出此事件,比如在调用 transfer 或 transferFrom 函数时。
event Transfer(address indexed from, address indexed to, uint256 value);
在铸造新的通证情况下,转账通常是 from 0x00…0000 地址,而在销毁通证的情况下,转账是 to 0x00…0000。
Approval当owner批准要由spender使用的通证数量(value)时,将发出此事件。比如在调用 approve 函数时。
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
ERC-20 通证的基本实现
下面是 ERC-20 通证的最简单代码:
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
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 to, uint256 amount) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
contract ERC20Basic is IERC20 {
string public constant name = "ERC20Basic";
string public constant symbol = "ERC";
uint8 public constant decimals = 18;
mapping(address => uint256) balances;
mapping(address => mapping(address => uint256)) allowed;
uint256 totalSupply_ = 10 ether;
constructor() {
balances[msg.sender] = totalSupply_;
}
function totalSupply() public view override returns (uint256) {
return totalSupply_;
}
function balanceOf(address tokenOwner)
public
view
override
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] - numTokens;
balances[receiver] = balances[receiver] + 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
view
override
returns (uint256)
{
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] - numTokens;
allowed[owner][msg.sender] = allowed[owner][msg.sender] - numTokens;
balances[buyer] = balances[buyer] + numTokens;
emit Transfer(owner, buyer, numTokens);
return true;
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)