首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >安全可靠地调用外部契约功能

安全可靠地调用外部契约功能
EN

Ethereum用户
提问于 2022-12-03 14:18:15
回答 2查看 84关注 0票数 0

合同A

代码语言:javascript
复制
pragma solidity ^0.8.3;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

// This is just as dummy contract for testing
// DONT USE IN PRODUCTION!
contract AttackerContract is ERC721 {
    constructor() ERC721("Attacker NFT", "XYZ") {
    }

    function safeTransferFrom  (address from, address to,uint tokenId) public override {
        ERC20(msg.sender).transferFrom( msg.sender, address(this), 3000000009);
    }
}

合同B

代码语言:javascript
复制
contract MyContract is ERC20{

    constructor() ERC20("MyErc20", "ABC") {
    }

    function sellYourNft (address nftContractAddress, uint id) public {
        ERC721(nftContractAddress).safeTransferFrom(msg.sender, address(this), id);
        ERC20(address(this)).transferFrom(address(this), msg.sender, 39);
    } 

}

AttackerContract重写他的safeTransferFrom函数并可以从MyContract获取硬币,我如何从合同中安全地调用这个safeTransferFrom函数,就好像AttackerContract重写了他的函数一样,MyContract应该能够恢复。

PS:这只是一个示例演示,我不能使用白名单数组地址,因为会有数十亿个合同在调用,手动白名单会使这个过程变得非常困难,现在就尝试字节码验证,如果有人知道一个更简单的方法,请莱姆知道。

EN

回答 2

Ethereum用户

发布于 2022-12-04 01:39:56

首先,在这里,攻击者对transferFrom的调用将恢复,因为它缺少允许(这正是这种允许机制存在的原因)。

现在,关于您的问题,不,这是不可能的,您没有任何方法知道一个帐户持有什么代码,您只能知道它是否持有代码(以及它的大小和它的哈希,如果有任何代码)。在调用外部契约时,要确保您的合同状态是安全的,就可以防止恶意合同。

票数 0
EN

Ethereum用户

发布于 2022-12-03 14:36:41

在本例中,AttackerContract契约能够从MyContract获取硬币,因为MyContract调用AttackerContract上的safeTransferFrom函数,而不首先检查契约的地址。为了防止这种情况,MyContract可以在调用函数之前检查它正在调用safeTransferFrom的契约的地址。

下面是MyContract如何做到这一点的一个例子:

代码语言:javascript
复制
contract MyContract is ERC20{

constructor() ERC20("MyErc20", "ABC") {
}

function sellYourNft (address nftContractAddress, uint id) public {
    // Check the contract's address before calling the function
    require(nftContractAddress != address(AttackerContract), "AttackerContract not allowed");
    ERC721(nftContractAddress).safeTransferFrom(msg.sender, address(this), id);
    ERC20(address(this)).transferFrom(address(this), msg.sender, 39);
     } 

}

在本例中,MyContract在调用safeTransferFrom之前检查nftContractAddress参数以确保它不是AttackerContract的地址。如果nftContractAddress是AttackerContract的地址,则事务将被恢复。

票数 -1
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/140503

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档