如何测试合约接收 ERC721 代币的能力?

How to test a contract's ability to receive an ERC721 token?

我正在用 Truffle 测试我的合约。我启用合约以接收 ERC721 代币:

function onERC721Received(address, address _from, uint256 _tokenId, bytes calldata) external override returns(bytes4) {
    nftContract = ERC721(msg.sender);
    tokenId = _tokenId;
    tokenAdded = true;

    return 0x150b7a02;
}

有没有一种方法可以使用 Mocha 和 Chai 模拟将代币发送到该合约?

在 EVM 之外(例如在 JS 测试中),无法检查交易的 return 值。只有它的状态(succeeded/reverted)、发出的事件(在你的情况下不是)和一些其他元数据。您还可以检查调用的 return 值,如 assert.equal 语句中所示。

contract('MyContract', () => {
    it('receives a token', async () => {
        const tx = await myContract.onERC721Received(
            '0x123',      // address
            '0x456',      // address _from
            1,            // uint256 _tokenId
            [0x01, 0x02]  // bytes calldata
        );

        assert.equal(tx.receipt.status, true); // tx succeeded

        assert.equal(await contract.nftContract, '0x123');
        assert.equal((await contract.tokenId).toNumber(), 1);
        assert.equal(await contract.tokenAdded, true);
    });
});

文档:

  • 松露 contract 而不是摩卡 describe - docs
  • 收据状态 - Truffle docs, Web3 docs(Truffle 文档中的 link 到 Web3 已过时)
  • 不必在 Truffle 中使用 .send().call(),因为它会自动选择 tx 或从合约 ABI 调用 - docs

我也在测试中使用 ERC721 模拟合约对此进行了测试。 所以我部署了两个合约并为它们创建了新实例,然后从 ERC721 调用 mint 函数到测试地址下的合约。 然后查看ERC721余额:

ERC721.balanceOf(underTest.address, 1)