ERC20 - OpenZeppelin 文档

本文档介绍了 OpenZeppelin Contracts 库中与 ERC20 代币标准相关的接口、合约和实用程序。

你当前阅读的不是此文档的最新版本。5.x 是当前版本。

ERC 20

https://docs.openzeppelin.com/contracts/api/token/erc20 查看本文档效果更佳

这组接口、合约和实用程序都与 ERC20 Token Standard 相关。

有关 ERC20 token 的概述以及如何创建 token 合约的演练,请阅读我们的 ERC20 指南

有一些核心合约实现了 EIP 中指定的行为:

  • IERC20: 所有 ERC20 实现都应符合的接口。

  • ERC20: ERC20 接口的实现,包括 name, symboldecimals 对基础接口的可选标准扩展。

此外,还有多个自定义扩展,包括:

最后,有一些实用程序可以以各种方式与 ERC20 合约交互。

  • SafeERC20: 接口的包装器,无需处理布尔返回值。

  • TokenTimelock: 为受益人持有 token ,直到指定时间。

以下相关 EIP 处于草案状态,可以在草案目录中找到。

这组核心合约旨在保持公正,允许开发人员访问 ERC20 中的内部函数(例如 _mint),并以他们喜欢的方式将它们公开为外部函数。另一方面,ERC20 Presets(例如 ERC20PresetMinterPauser)使用固定的模式进行设计,以便为开发人员提供现成的、可部署的合约。

Core

IERC20

EIP 中定义的 ERC20 标准接口。

函数

事件

totalSupply() → uint256 external

返回现有 token 的数量。

balanceOf(address account) → uint256 external

返回 account 拥有的 token 数量。

transfer(address recipient, uint256 amount) → bool external

amount 个 token 从调用者的帐户转移到 recipient

返回一个布尔值,指示操作是否成功。

发出一个 Transfer 事件。

allowance(address owner, address spender) → uint256 external

返回 spender 将被允许代表 owner 通过 transferFrom 支配的剩余 token 数量。 默认为零。

当调用 approvetransferFrom 时,此值会发生变化。

approve(address spender, uint256 amount) → bool external

设置 amount 作为 spender 对调用者 token 的津贴。

返回一个布尔值,指示操作是否成功。

请注意,使用此方法更改津贴会带来风险,即有人可能会通过不幸的交易排序来同时使用旧津贴和新津贴。一种可能的解决方案是首先将消费者的津贴减少到 0,然后设置所需的值:https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729

发出一个 Approval 事件。

transferFrom(address sender, address recipient, uint256 amount) → bool external

使用授权机制将 amount 个 token 从 sender 转移到 recipient。 然后从调用者的授信额度中扣除 amount

返回一个布尔值,指示操作是否成功。

发出一个 Transfer 事件。

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

value 个 token 从一个帐户(from)转移到另一个帐户(to)时发出。

请注意,value 可能为零。

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

当通过调用 approve 设置 spenderowner 的授权时发出。 value 是新的授权。

ERC20

IERC20 接口的实现。

此实现与 token 的创建方式无关。 这意味着必须在使用 _mint 的派生合约中添加供应机制。 有关通用机制,请参见 ERC20PresetMinterPauser

有关详细的撰写,请参见我们的指南如何实现供应机制

我们遵循了通用的 OpenZeppelin 指南:函数在失败时恢复,而不是返回 false。 尽管如此,此行为是常规的,并且不与 ERC20 应用程序的期望相冲突。

此外,在调用 transferFrom 时会发出 Approval 事件。 这允许应用程序仅通过侦听所述事件来重建所有帐户的授权。 EIP 的其他实现可能不会发出这些事件,因为规范中没有要求。

最后,添加了非标准的 decreaseAllowanceincreaseAllowance 函数,以缓解围绕设置授权的众所周知的问题。 请参见 IERC20.approve

函数

事件

IERC20

constructor(string name_, string symbol_) public

namesymbol 设置值,使用默认值 18 初始化 decimals

要为 decimals 选择其他值,请使用 _setupDecimals

所有这三个值都是不可变的:它们只能在构造期间设置一次。

name() → string public

返回 token 的名称。

symbol() → string public

返回 token 的符号,通常是名称的简短版本。

decimals() → uint8 public

返回用于获取其用户表示形式的小数位数。 例如,如果 decimals 等于 2,则应向用户将 505 个 token 的余额显示为 5,05505 / 10 ** 2)。

token 通常选择值 18,以模仿以太币和 Wei 之间的关系。 这是 ERC20 使用的值,除非调用 _setupDecimals

此信息仅用于 显示 目的:它绝不影响合约的任何算术,包括 IERC20.balanceOfIERC20.Transfer
totalSupply() → uint256 public

请参见 IERC20.totalSupply

balanceOf(address account) → uint256 public

请参见 IERC20.balanceOf

transfer(address recipient, uint256 amount) → bool public

请参见 IERC20.Transfer

要求:

  • recipient 不能是零地址。

  • 调用者必须至少具有 amount 的余额。

allowance(address owner, address spender) → uint256 public

请参见 IERC20.allowance

approve(address spender, uint256 amount) → bool public

请参见 IERC20.approve

要求:

  • spender 不能是零地址。
transferFrom(address sender, address recipient, uint256 amount) → bool public

请参见 IERC20.transferFrom

发出 Approval 事件,指示已更新的津贴。 EIP 中没有对此要求。 请参见 ERC20 开头的注释。

要求:

  • senderrecipient 不能为零地址。

  • sender 必须至少具有 amount 的余额。

  • 调用者必须至少具有 senderamount token 的津贴。

increaseAllowance(address spender, uint256 addedValue) → bool public

以原子方式将授予 spender 的津贴增加调用者。

这是 approve 的替代方法,可以用作 IERC20.approve 中描述的问题的缓解措施。

发出 Approval 事件,指示已更新的津贴。

要求:

  • spender 不能是零地址。
decreaseAllowance(address spender, uint256 subtractedValue) → bool public

以原子方式将授予 spender 的津贴减少调用者。

这是 approve 的替代方法,可以用作 IERC20.approve 中描述的问题的缓解措施。

发出 Approval 事件,指示已更新的津贴。

要求:

  • spender 不能是零地址。

  • spender 必须至少具有 subtractedValue 的调用者的津贴。

_transfer(address sender, address recipient, uint256 amount) internal

amount 个 token 从 sender 转移到 recipient

此内部函数等效于 transfer,可用于例如实施自动 token 费用、削减机制等。

发出一个 transfer 事件。

要求:

  • sender 不能是零地址。

  • recipient 不能是零地址。

  • sender 必须至少具有 amount 的余额。

_mint(address account, uint256 amount) internal

创建 amount 个 token 并将它们分配给 account,从而增加总供应量。

发出一个 transfer 事件,其中将 from 设置为零地址。

要求:

  • to 不能是零地址。
_burn(address account, uint256 amount) internal

account 销毁 amount 个 token,从而减少总供应量。

发出一个 transfer 事件,其中将 to 设置为零地址。

要求:

  • account 不能是零地址。

  • account 必须至少具有 amount 个 token。

_approve(address owner, address spender, uint256 amount) internal

设置 amount 作为 spenderowner 的 token 的津贴。

此内部函数等效于 approve,可用于例如为某些子系统设置自动津贴等。

发出一个 Approval 事件。

要求:

  • owner 不能是零地址。

  • spender 不能是零地址。

_setupDecimals(uint8 decimals_) internal

decimals 设置为默认值 18 以外的值。

此函数应仅从构造函数中调用。 与 token 合约交互的大多数应用程序都不会期望 decimals 发生更改,如果更改可能会导致错误。
_beforeTokenTransfer(address from, address to, uint256 amount) internal

在任何 token 转移之前调用的Hook。 这包括铸造和销毁。

调用条件:

  • fromto 均为非零值时,fromamount 个 token 将被转移到 to

  • from 为零时,将为 to 铸造 amount 个 token。

  • to 为零时,将销毁 fromamount 个 token。

  • fromto 永远不会都为零。

要了解有关Hook的更多信息,请转到 Using Hooks

Extensions

ERC20Snapshot

此合约使用快照机制扩展了 ERC20 token。 创建快照后,将记录当时的点余额和总供应量,以供以后访问。

这可用于安全地创建基于 token 余额的机制,例如免信任股息或加权投票。 在简单的实现中,可以通过重用来自不同帐户的相同余额来执行“双重支出”攻击。 通过使用快照来计算股息或投票权,这些攻击不再适用。 它也可以用于创建有效的 ERC20 分叉机制。

快照由内部 _snapshot 函数创建,该函数将发出 Snapshot 事件并返回快照 id。 要获取创建快照时的总供应量,请使用快照 id 调用函数 totalSupplyAt。 要获取创建快照时的帐户余额,请使用快照 id 和帐户地址调用 balanceOfAt 函数。

Gas Costs

快照是高效的。 快照创建是 O(1)。 从快照中检索余额或总供应量在已创建的快照数量中为 O(log_n),尽管特定帐户的 n 通常会小得多,因为后续快照中的相同余额存储为单个条目。

由于额外的快照记帐,普通 ERC20 转移存在恒定的开销。 对于特定帐户紧随快照之后的第一次传输,此开销仅是显着的。 后续传输将具有正常成本,直到下一个快照,依此类推。

函数

ERC20

事件

IERC20

_snapshot() → uint256 internal

创建一个新快照并返回其快照 ID。

发出一个 Snapshot 事件,其中包含相同的 ID。

_snapshotinternal,你必须决定如何将其外部公开。 它的使用可能仅限于一组帐户,例如使用 AccessControl,或者可能对公众开放。

虽然某些信任最小化机制(例如分叉)需要一种开放的调用 _snapshot 的方法,但你必须考虑到攻击者可能会以两种方式使用它。首先,它可以用于增加从快照中检索值的成本,尽管它会以对数方式增长,从而使此攻击长期无效。 其次,它可以用于定位特定帐户并增加 ERC20 转移的成本,如上面的“Gas Costs”部分中所述。我们尚未衡量实际数字; 如果你对此感兴趣,请与我们联系。
balanceOfAt(address account, uint256 snapshotId) → uint256 public

检索创建 snapshotId 时的 account 余额。

totalSupplyAt(uint256 snapshotId) → uint256 public

检索创建 snapshotId 时的总供应量。

_beforeTokenTransfer(address from, address to, uint256 amount) internal
Snapshot(uint256 id) event

当创建由 id 标识的快照时,由 _snapshot 发出。

ERC20Pausable

具有可暂停的 token 转移、铸造和销毁的 ERC20 token。

适用于诸如在评估期结束之前阻止交易,或具有紧急开关以在出现重大错误时冻结所有 token 转移的情况。

函数

Pausable

事件

Pausable

IERC20

_beforeTokenTransfer(address from, address to, uint256 amount) internal

查看 ERC20._beforeTokenTransfer.

要求:

  • 合约必须未暂停。

ERC20Burnable

ERC20 的扩展,允许 token 持有者销毁他们自己的 token 以及他们拥有授权的 token,这种方式可以通过链下方式识别(通过事件分析)。

函数

ERC20

事件

IERC20

burn(uint256 amount) public

从调用者处销毁 amount 数量的 token。

查看 ERC20._burn

burnFrom(address account, uint256 amount) public

account 处销毁 amount 数量的 token,从调用者的授权中扣除。

查看 ERC20._burnERC20.allowance

要求:

  • 调用者必须至少拥有 amount 数量的 accounts 的 token 授权。

ERC20Capped

ERC20 的扩展,增加了 token 供应量的上限。

函数

ERC20

事件

IERC20

constructor(uint256 cap_) internal

设置 cap 的值。这个值是不可变的,只能在构造期间设置一次。

cap() → uint256 public

返回 token 总供应量的上限。

_beforeTokenTransfer(address from, address to, uint256 amount) internal

查看 ERC20._beforeTokenTransfer

要求:

  • 新铸造的 token 不能使总供应量超过上限。

实用工具

SafeERC20

ERC20 操作的包装器,在失败时抛出异常(当 token 合约返回 false 时)。也支持不返回值(而是在失败时恢复或抛出异常)的 Token,假定非恢复调用是成功的。 要使用此库,你可以将 using SafeERC20 for IERC20; 语句添加到你的合约中, 这允许你将安全操作称为 token.safeTransfer(…​) 等。

函数

safeTransfer(contract IERC20 token, address to, uint256 value) internal
safeTransferFrom(contract IERC20 token, address from, address to, uint256 value) internal
safeApprove(contract IERC20 token, address spender, uint256 value) internal

已弃用。此函数存在与 IERC20.approve 中发现的问题类似的问题,不鼓励使用。

如果可能,请改用 safeIncreaseAllowancesafeDecreaseAllowance

safeIncreaseAllowance(contract IERC20 token, address spender, uint256 value) internal
safeDecreaseAllowance(contract IERC20 token, address spender, uint256 value) internal

TokenTimelock

一个 token 持有者合约,它将允许受益人在给定的释放时间后提取 token。

适用于简单的归属计划,例如“顾问在 1 年后获得他们所有的 token”。

函数

constructor(contract IERC20 token_, address beneficiary_, uint256 releaseTime_) public
token() → contract IERC20 public
beneficiary() → address public
releaseTime() → uint256 public
release() public

← 草案

ERC 721 →

  • 原文链接: docs.openzeppelin.com/co...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
OpenZeppelin
OpenZeppelin
江湖只有他的大名,没有他的介绍。