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的正确使用场景/


程序新视界

关注程序员的职场生涯,大量优质学习资源、技术文章分享

csdn-微信公众号

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Solidity智能合约语⾔ 智能合约语⾔ 语⾔本⾝ 语⾔本⾝ ethereum官⽹ 笔记 笔记 uint[] result = new uint[](3); uint[] memory result = new uint[](ownerZombieCount[_owner]); 状态修饰符 view    不写 数据, pure    不读写 这两个从合约外部调⽤不费gas,内部调⽤会耗费gas ⾃定义modifiers 参数可为 被调⽤函数的参数 payable  可⽀付,可接受ether 以太 ERC20 代币像货币⼀样,按⾯值算,例如0.273以太 ERC721 代币是不能互换的,因为每个代币都被认为是唯⼀且不可分割的。 你只能以整个单位交易它们,并且每个单位都有唯⼀的 ID。(不过ERC721还没有正式的官⽅标准) 多继承 contract A is B,C {} 官⽹⽂档 官⽹⽂档 ⽂(更新很慢) 英⽂ (最新进度) 附上环境部分使⽤说明 附上环境部分使⽤说明 注意:NPM安装路径默认是当前⽬录,修改参见 记得将全局模块⽬录加⼊PATH REMIX-IDE 如果需要python2/3共存,只需要⽤改名法,具体如下 [类型] [只能被__调⽤] private 合约内部 internal 合约内部/继承的合约 external 合约外部 public 任何 function test(n个参数) external view onlyOwner anotherModifier { /* ... */ } 在重新打开命令⾏即可使得变量⽣效 记得使⽤ npm install remix-ide -g --python=python2 指定python2.exe VS2017安装 安装solidity插件 插件 浏览器打开 下载插件(此处安装会失败,提⽰不兼容VS2017问题),然后根据Q&A⾥热⼼⽤户的教程 也就是以压缩包形式打开,编辑压缩包⾥的extension.vsixmanifest,搜索')'替换为']',然后保存压缩包,双击安装即可 然后新建Solidity项⽬并查看项⽬⾥的 README.html 部署环境并操作 如果npm安装失败,查看⽇志发现是⽹络问题,请 Remix 在线 在线IDE(新版 新版)使⽤教程 使⽤教程 先激活3个基本插件 Debugger Debug Deploy & Run Transactions Solidity Compiler FWIW If you have VS community 2017 then 1-Open the extension using something like 7zip or winzip, 2-Edit the file 'extension.vsixmanifest' simply replacing three ')' with ']' 3-Save it and it appears to work. 4-Double click the extension and it installs (though it does give a warning which you can ignore). 5-You can then do a new Solidity project and compile it. By shaun pryszlak 2018/12/3 1. 编译当前打开的合约 2. 部署 选择合约sol⽂件并点击黄⾊的Deploy按钮 ( Deploy会调⽤构造函数 我这⾥不传⼊参数,表⽰调⽤⽆参构造⽅法 当然也可以传⼊⼀个uint8值调⽤构造函数 constructor(uint8 _numProposals) ) 部署成功如下图 点击展开, 填⼊参数(如我这⾥填4)并点击前⾯的按钮即可调⽤对应的函数(如我的vote函数) 运⾏结果在控制台可见 基本使⽤就是这样,更多请⾃⼰探究,调试功能是⽀持的

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序新视界

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值