创建新的 ERC-777 时如何定义运算符?

问题描述

我的理解是,您可以在实例化自定义 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 属性的方法不起作用。

  1. 将子 (MainToken) 构造函数参数存储到内存中(在您的情况下没有参数)

  2. 执行父构造函数。

    在您的情况下,ERC777("MYTOKEN","MTK",ops) 的执行失败,因为 storage 变量 ops 尚不可用。

  3. 执行子构造函数(在您的情况下为 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}}。