首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >`msg.sender`而不是`tx.origin`

`msg.sender`而不是`tx.origin`
EN

Ethereum用户
提问于 2022-08-31 09:18:07
回答 1查看 105关注 0票数 0

我是刚接触过稳健性的人,但我多次读到应该避免使用tx.origin &应该使用msg.sender。在solidity 页面中有一个给出的演示。上面写着:-

不要使用tx.origin进行授权。假设你有这样的钱包合同:

代码语言:javascript
运行
复制
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
// THIS CONTRACT CONTAINS A BUG - DO NOT USE
contract TxUserWallet {
    address owner;

    constructor() {
        owner = msg.sender;
    }

    function transferTo(address payable dest, uint amount) public {
        // THE BUG IS RIGHT HERE, you must use msg.sender instead of tx.origin
        require(tx.origin == owner);
        dest.transfer(amount);    // .transfer is a global variable
    }
}

现在有人骗你把以太送到这个攻击钱包的地址:

代码语言:javascript
运行
复制
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
interface TxUserWallet {
    function transferTo(address payable dest, uint amount) external;
}

contract TxAttackWallet {
    address payable owner;

    constructor() {
        owner = payable(msg.sender);
    }

    receive() external payable {
        TxUserWallet(msg.sender).transferTo(owner, msg.sender.balance);   //  **LINE 1**
    }
}

现在,我想知道第1行将如何从TxUserWallet中抽走全部资金。我认为transfer()是一个全局变量,它将在攻击钱包的dest中传递要处理的数量。.transfer()将如何触发合同TxAttackWalletreceive()函数。其次,在TxUserWallet(msg.sender).transferTo(owner, msg.sender.balance);行中,为什么我们要将它写成TxUserWallet(msg.sender),比如为什么我们在合同名称之后添加(msg.sender),以及通过编写msg.sender.balance传递什么值?

EN

回答 1

Ethereum用户

发布于 2022-08-31 10:21:43

接收功能由接收eth触发。

该行中的msg.sender是易受攻击的钱包/合同的地址。钱包名是该类型契约的实例或接口,它需要该地址来实例化它以与其交互。

msg.sender.balance正在从易受攻击的契约中获得平衡,所以攻击契约可以知道它能从易受攻击的契约中转移多少。

该行调用易受攻击契约的transferTo函数,传递攻击者控制的to地址,以及易受攻击契约的整个余额的amount

钱包合同试图限制它的transferTo被任何人使用,而不是它的所有者,方法是确保只有它的所有者可以用tx.origin而不是msg.sender调用该函数。

tx.origin将永远保持不变。即启动交易链的EOA。msg.sender不保持不变,在本例中,当攻击契约调用transferTo函数时,将更改为攻击契约地址。

如果攻击契约的所有者被诱骗在攻击契约上发起事务,则攻击契约可以调用易受攻击契约上的transferTo函数,而易受攻击合同的检查仍然会结束它来自其所有者的检查,因为它使用tx.origin作为检查。它将允许转移。

如果它使用msg.sender进行检查,它将“看到”该函数不是由所有者直接调用的,而是由合同调用的,因此不允许传输,因为攻击契约地址不是易受攻击的合同所有者。

对于要降级的攻击场景,易受攻击的契约需要一个回退/接收函数,这样就可以为其提供资金并取得平衡。是的,可以用强制发送来代替,但那是愚蠢的。

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

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

复制
相关文章

相似问题

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