问题描述
我的理解是,您可以在实例化自定义 ERC-777 时定义一个操作符,该操作符可以使用 operatorSend
函数进行传输,而无需获得发件人的批准。但是,似乎无法获取将令牌部署到继承的构造函数中的合同的地址。我尝试将地址推送到构造函数体中的数组中,但似乎没有。
contract MainToken is ERC777 {
address[] ops=;
constructor () ERC777("MYTOKEN","MTK",ops) {
ops.push(msg.sender);
}
...
}
如果我尝试像 ERC777("MYTOKEN",[msg.sender])
那样直接将它放入构造函数中,我会得到
修饰符调用中的参数类型无效。无效的隐式 从 address[1] 内存转换为 address[] 内存请求。
解决方法
Solidity 目前不允许在一个表达式中定义动态大小的数组。 注意:示例中的 [msg.sender]
是固定大小的数组定义。
此外,由于 EVM 处理构造函数的顺序,您定义 ops
属性的方法不起作用。
-
将子 (
MainToken
) 构造函数参数存储到内存中(在您的情况下没有参数) -
执行父构造函数。
在您的情况下,
ERC777("MYTOKEN","MTK",ops)
的执行失败,因为 storage 变量ops
尚不可用。 -
执行子构造函数(在您的情况下为
ops.push(msg.sender);
)
所以我能想到的最简单的解决方案是从 MyToken
参数传递地址。如果您可以控制部署过程并且可以在部署合同时手动传递 msg.sender
的值,这将非常有用。
pragma solidity 0.8.4;
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC777/ERC777.sol';
contract MyToken is ERC777 {
constructor(address[] memory defaultOperators)
ERC777('MYTOKEN','MTK',defaultOperators) {
}
}
如果您不打算控制部署并需要在构造函数中分配 msg.sender
,我建议在本地复制 ERC777
合约并修改其构造函数,以便它只添加 { {1}}。