Skip to content

ERC777

ERC20一样,ERC777也是可替换代币的标准,它的关注点在交易代币时允许更复杂的交互。更通俗地说,对于代币,它通过提供等效于msg.value字段的方式是代币和以太币更紧密的联系在一起。
该标准还带来了多项生活质量改进,例如摆脱对decimals的混淆,使用适当的事件进行铸造和燃烧等等,但它的杀手级功能是接收hook。hook只是合约中一个简单的函数,当代币发送给它时会调用它,这意味着账户和合约可以对接收到的代币做出反应。
这实现了许多有趣的用例,包括使用token的原子购买(无需在两个单独的交易中进行approvetransferFrom),拒绝接受token(通过在hook调用上进行rerevert操作),将接收到的token直接重定向给另外的地址(类似于PaymentSplitter的做法),等等。
此外,由于合约需要实现这些hook才能接收代币,因此任何代币都不会卡在不了解 ERC777 协议的合约中,而这种情况使用 ERC20 时发生过无数次。

如果已经在使用ERC20了呢

该标准已涵盖。ERC777标准向后兼容ERC20,这意味着您可以像 ERC20 一样与这些代币进行交互,使用标准中的函数,同时仍然获得所有细节,包括发送hook。请参考EIP向后兼容章节获取更多咨询。

构建ERC777 token合约

我们还会用 ERC20中的GLD例子,这次我们使用ERC777。和往常一样,查看API Reference来获取更多的功能细节说明。

solidity
// contracts/GLDToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC777/ERC777.sol";

contract GLDToken is ERC777 {
    constructor(uint256 initialSupply, address[] memory defaultOperators)
        ERC777("Gold", "GLD", defaultOperators)
    {
        _mint(msg.sender, initialSupply, "", "");
    }
}

在这个例子中,我们继承了ERC777合约,它提供了对ERC20的兼容支持。ERC777的API和ERC20很相似,我们也是需要调用_mint方法将initialSupply的代币分配给合约部署者。和ERC20_mint方法不同,它包含了一些额外的参数,不过现在可以先忽略。
你可能注意到了,我们指定了namesymbol,但没有设置decimals。ERC777 规范强制包含对这些功能的支持(与 ERC20 不同,它是可选的,除非我们引入了 ERC20Detailed),并且指定了decimals会返回一个固定值18,因此我们没有必要自己手工设置。如果想复习一下decimals的相关内容,可以参考ERC20向导
最后,我们需要设置defaultOperators,能够代表其持有人转移代币的特殊账户(通常是其他智能合约)。如果你不打算在你的token中设置特殊账户,可以设置一个空数组就可以了。请继续关注即将发布的有关 ERC777 操作员的深入指南!
这就是一个基本的代币合约!我们现在可以部署它,并使用相同的 balanceOf 方法来查询部署者的余额:

sh
> GLDToken.balanceOf(deployerAddress)
1000

要将代币从一个帐户转移到另一个帐户,我们可以使用 ERC20 的transfer方法,也可以使用新的 ERC777 的send方法,它们的作用非常相似,但添加了一个可选的data字段:

sh
> GLDToken.transfer(otherAddress, 300)
> GLDToken.send(otherAddress, 300, "")
> GLDToken.balanceOf(otherAddress)
600
> GLDToken.balanceOf(deployerAddress)
400

向合约发送代币

使用 send 时的一个关键区别是token转移到其他合约可能会返回以下消息:

ada
ERC777: token recipient contract has no implementer for ERC777TokensRecipient

这是个好事!这表示接受合约不支持ERC777协议,所以转账操作是不允许的,避免token被永久锁住。作为例子,Golem 合约目前持有超过 35 万个 GNT 代币价值数万美元,但却没有方法可以提取出来。几乎每个 ERC20 支持的项目都会发生这种情况,通常是由于用户错误。
即将发布的指南将介绍合约如何将自己注册为接收者、发送和接收挂钩以及 ERC777 的其他高级功能!

Released under the MIT License.