【问题标题】:How to detect emit in a receiving contract using hardhat?如何使用安全帽检测接收合同中的发射?
【发布时间】:2022-10-09 12:22:59
【问题描述】:

我正在尝试从 @openzeppelin/test-helpers 复制 expectEvent.inTransaction() 以用于安全帽。

场景:token 正在从 owner 转移到 receiverContract。我想检查接收者 Contract 是否发出了 Received 事件。

交易看起来像这样,由所有者发起。

const tx = await token.transferFrom(
  owner.address, // <- From this wallet
  receiverContract.address, // <- To this contract
  tokenId,
  {
    from: owner.address,
  }
);

该测试显示令牌发出了Transfer 事件。

await expect(tx)
  .to.emit(this.token, "Transfer")
  .withArgs(owner.address, receiverContract.address, tokenId);

但是我想写这样的东西......

await expect(tx) // <- Not sure what to put here
  .to.emit(receiverContract, "Received") // <- This may also be off
  .withArgs(token, owner.address, tokenId, null);

或者,我可以查看接收者的收据对象,但我不知道如何得到它......通常它是通过......

const tx = await token.transferFrom(owner.address, receiverContract.address, tokenId, {from: owner.address});
const receipt = await tx.wait();
console.log("receipt", receipt); // <- This will show an events array 
// which I can check. But how do I get this same receipt object for
// the receiverContract

【问题讨论】:

    标签: ethereum solidity hardhat openzeppelin


    【解决方案1】:

    这可能会迟到,但它可以帮助其他人。

    一个合约不能代表另一个合约发出事件。这意味着您的receiverContract 是需要发出此“已接收”事件的那个。

    如果您是receiverContract 的部署者,您可以实现这一点。 (由于您在 transferFrom() 函数中有一个“tokenId”,我想这个代币合约是 ERC721 或类似的) 为了实现这一点,您需要在receiverContract 合约中拥有一个onERC721received() 函数,例如:

    function onERC721received(address, address _from, uint256 _tokenID) public returns (bytes4) {
        emit Received(msg.sender, _sender, _tokenID) 
        //msg.sender will be the contract that made the transfer call.
        return this.onERC721Received.selector;
    }
    

    注意:如果receiverContract 也是ERC721 合约,则需要在其中包含override 关键字。

    然后,令牌合约将需要在传输完成之前调用此函数选择器。 基于 OpenZeppelin 模板的 ERC721 合约在 _checkOnERC721Received() 检查中包含此调用仅用于 safeTransferFrom()而不是在 transferFrom() 函数中。如果您要实现自己的合约,则需要在像 _beforeTokenTransfer() 这样的函数中调用 onERC721received 选择器,该函数在任何传输之前调用。

    最后,您应该小心调用其他合约并阅读有关重入攻击的更多信息,并且还要注意任何人都可以在没有真正转移的情况下调用 onERC721Received 函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-13
      • 2021-09-26
      • 2021-07-20
      • 2022-12-11
      • 2013-02-13
      • 2021-10-18
      • 2022-12-23
      • 2022-07-21
      相关资源
      最近更新 更多