0

我正在尝试在 rinkeby 测试网络上测试智能合约功能,它将多个代币迁移到新合约。即我想烧掉 ERC-721 代币(将它们发送到烧毁地址),这些代币存储在 Opensea 合约上,然后在新合约上重新进行。

当我在本地以太坊网络分支(使用 ganache-cli)上测试该功能时,一切正常,但在 rinkeby 网络上,我收到以下错误:

errors.js:87 Uncaught (in promise) Error: Transaction has been reverted by the EVM:
{
  "blockHash": "0x1b6f3907c56626ed6e66a090fdc5c4e14723fa4be11137227c5fcb20f89a7c8c",
  "blockNumber": 9780743,
  "contractAddress": null,
  "cumulativeGasUsed": 823380,
  "effectiveGasPrice": "0x9502f90a",
  "from": "0x4e3a2cd1904ba26f9bbcd196802dceec94cf97fd",
  "gasUsed": 204890,
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "status": false,
  "to": "0x33a7bbd2f44c012ee19c0e0a9190bb6ba555ffb4",
  "transactionHash": "0x8e2cbd9bc333fd56788b51e21568be02a62548468f43ac86859766655818dce1",
  "transactionIndex": 6,
  "type": "0x2",
  "events": {}
}
    at Object.TransactionError (errors.js:87)
    at Object.TransactionRevertedWithoutReasonError (errors.js:98)
    at index.js:395

在 Etherscan.io 上,我在“状态”下收到此附加错误消息:

Fail with error 'AssetContractShared#_requireMintable: ONLY_CREATOR_ALLOWED'

这是我正在调用的智能合约功能。Opensea(openseaSharedAddress).safeTransferFrom(msg.sender, burnAddress, oldIds[j], 1, "");当我用函数删除for循环时它工作正常

function batchMigration(uint256[] memory oldIds, uint256[] memory newIds, bytes32[] memory leaves, bytes32[][] memory proofs) external {
        for (uint i = 0; i < oldIds.length; i++) {
            // Don't allow reminting
            require(!_exists(newIds[i]), "Token already minted");

            // Verify that (oldId, newId) correspond to the Merkle leaf
            require(keccak256(abi.encodePacked(oldIds[i], newIds[i])) == leaves[i], "Ids don't match Merkle leaf");

            // Verify that (oldId, newId) is a valid pair in the Merkle tree
            //require(verify(merkleRoot, leaves[i], proofs[i]), "Not a valid element in the Merkle tree");

            // Verify that msg.sender is the owner of the old token
            require(Opensea(openseaSharedAddress).balanceOf(msg.sender, oldIds[i]), "Only token owner can mintAndBurn");
        }

        for (uint j = 0; j < oldIds.length; j++) {
            Opensea(openseaSharedAddress).safeTransferFrom(msg.sender, burnAddress, oldIds[j], 1, "");
        }
    }

这里是我调用批量迁移功能的 web3 部分:

await smartContract.methods
           .batchMigration(oldIds, newIds, leaves, proofs)
           .send({
               from: walletAddress, //accounts[0]
               gasLimit: 6721975,
           }).on('transactionHash', function (hash) {
                console.log(hash)
           });

在我调用批量迁移函数之前,我正在设置 ApprovalForAll,所以这应该不是问题:

await openseaContract.methods.setApprovalForAll(SMART_CONTRACT_ADDRESS, true).send({
            from: walletAddress,
        });

有谁知道为什么会发生此错误?谢谢

4

1 回答 1

0

我遇到了同样的问题,经过一番测试,我可以找到解决方案。

正如我刚刚在这里发布的https://ethereum.stackexchange.com/questions/111077/error-execution-reverted-assetcontractsharedcreatoronly-only-creator-allowed,合约在转移令牌之前调用铸币函数。调用铸币函数会导致调用修饰符,该修饰符本身会检查 tokenOwner。

解决方案是检查令牌是否已被铸造并铸造,然后才能通过其他地址(已批准)转移。

  • 测试代币余额
  • 如果没有余额,请先铸造(来自转账账户)
  • 然后你可以 setApprovalForAll
  • 那么转移应该有效
于 2022-01-03T22:57:45.747 回答