文章前言
在经典的ERC-20场景中,如果用户想要授权给第三方账户或者智能合约进行转账操作,那么需要通过两个事务来完成整个转账的操作,在这里需要注意的是在授权是需要指定对应的amount数量,那么当每次进行授权转账时都需要进行一次查询或者让A用户再次授权给B用户:
-
A用户授权B用户可以操作A用户amount数量的token
-
B用户获得A用户的授权之后调用转账函数进行转账
ERC-777标准引入了运营商的概念来解决授权给第三方账户或智能合约进行转账操作的问题,在ERC-777中运营商有两种类型:
-
常规运营商:一个地址,允许代表另一个地址发送和记录代币
-
默认运营商:一个地址,允许所有代币持有者发送和记录代币
优势对比
ERC-777与ERC-20对比具有以下优势:
-
采用接口send(dest,value,data)发送代币,先前兼容
-
任何合约都可以定义收到代币时触发的tokensReceived事件,避免ERC20代币中的双重调用问题
-
合约和常规地址可以通过注册一个tokensToSend或tokensReceivedFunction函数来控制或拒绝发送或接收的代币,避免ERC20代币中存在的代币卡死问题
-
代币持有者可以授权或回收管理其代币的操作员权限,这些操作员通常是交易所合约或自动收费系统中的支付处理器
-
每个代币交易都包含userData数据字段,在操作员操作时也有类似的operatorData字段,从而可以自由地将数据传递给接收方
-
向后兼容不支持tokensReceived函数的钱包
接口列表
这里我们以OpenZeppelin官方提供的ERC-777标准为例进行分析,首先我们看以下IERC-777中指明的一个ERC-777需要实现的接口:
#FUNCTIONS
name()
symbol()
granularity()
totalSupply()
balanceOf(owner)
send(recipient, amount, data)
burn(amount, data)
isOperatorFor(operator, tokenHolder)
authorizeOperator(operator)
revokeOperator(operator)
defaultOperators()
operatorSend(sender, recipient, amount, data, operatorData)
operatorBurn(account, amount, data, operatorData)
#EVENTS
Sent(operator, from, to, amount, data, operatorData)
Minted(operator, to, amount, data, operatorData)
Burned(operator, from, amount, data, operatorData)
AuthorizedOperator(operator, tokenHolder)
RevokedOperator(operator, tokenHolder)
源码分析
OpenZeppelin官方提供了ERC-777标准示例代码如下:
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC777/ERC777.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import \\\"./IERC777.sol\\\";
import \\\"./IERC777Recipient.sol\\\";
import \\\"./IERC777Sender.sol\\\";
import \\\"../ERC20/IERC20.sol\\\";
import \\\"../../utils/Address.sol\\\";
import \\\"../../utils/Context.sol\\\";
import \\\"../../utils/introspection/IERC1820Registry.sol\\\";
/**
* @dev Implementation of the {IERC777} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
*
* Support for ERC20 is included in this contract, as specified by the EIP: both
* the ERC777 and ERC20 interfaces can be safely used when interacting with it.
* Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token
* movements.
*
* Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there
* are no special restrictions in the amount of tokens that created, moved, or
* destroyed. This makes integration with ERC20 applications seamless.
*/
contract ERC777 is Context, IERC777, IERC20 {
using Address for address;
IERC1820Registry constant internal _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
mapping(address => uint256) private _balances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
bytes32 private constant _TOKENS_S
原创文章,作者:七芒星实验室,如若转载,请注明出处:https://www.sudun.com/ask/34362.html