温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

solidity智能合约[52]-安全-storage陷阱

发布时间:2020-06-20 04:43:05 阅读:170 作者:jonson_jackson 栏目:开发技术
开发者测试专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>

storage陷阱

下面的合约是一个锁定金额的合约,用户将资金存储在此合约中,只有当过了一段时间时候才能够提取出来。
下面的案例是为了说明storage属性预设性带来的陷阱。payIn函数是当用户存储金额时调用的函数。传递的参数似乎解锁的时间。在合约payIn中,HoldRecord newRecord; 其实默认为storage类型,并且,当不为storage变量赋值的时候,变量默认引用的位置是storage空间中的0号位置。这也意味着在当前的案例中,newRecord指针指向了ownerAmount,当对newRecord 执行newRecord.amount += msg.value; 实则将ownerAmount即合约拥有者的金额增加了。 这时,合约拥有者就可以调用ownerWithdrawal将用户存储在合约的钱转移出来。

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
pragma solidity ^0.4.23;contract HodlFraud {    uint public ownerAmount;  //合约拥有者的金钱    uint public  numberOfPayouts; //次数    address public owner;  //合约的拥有者    struct HoldRecord {        uint amount;  //存储的金钱        uint unlockTime;  //解锁的时间    }    mapping (address => HoldRecord) public balance;  //地址  => 存储的金钱,时间    //构造函数初始化    function HodlFraud () public payable {        owner = msg.sender;        ownerAmount = msg.value;    }    //某一个用户存储金钱,    //@param  holdTime 代表的是解锁时间    function payIn(uint holdTime) public payable {        require(msg.value > 0);        HoldRecord  newRecord;        newRecord.amount += msg.value;        newRecord.unlockTime = now + holdTime;        balance[msg.sender] = newRecord;    }    //转账,使用这笔钱    function withdraw () public {        require(balance[msg.sender].unlockTime < now && balance[msg.sender].amount > 0);        msg.sender.transfer(balance[msg.sender].amount);        balance[msg.sender].amount = 0;        numberOfPayouts++;    }    //合约的拥有着,转移自己的钱    function ownerWithdrawal () public {        require(msg.sender == owner && ownerAmount > 0);        msg.sender.transfer(ownerAmount);        ownerAmount = 0;    }}

解决办法

HoldRecord newRecord 修改为 HoldRecord memory newRecord

总结

123
// 这个例子是要举出在 smart contract 中 storage 预设行为的危险性。其实只要维持一个原则就可以避免这个问题。// 养成明确定义使用 storage 还是 memory 的好习惯// 一般来说,指定 storage 时就直接给初始值;而在 function 里面需要用到的缓存器都用 memory,除非想要直接修改链上的值。现在 compiler 都会很聪明的提醒开发者要定义 storage 还是 memory,而当 storage pointer 没有初始值时也会提醒开发者。
  • 本文链接: https://dreamerjonson.com/2018/11/25/solidity-52-security-storage/

  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY 4.0 CN协议 许可协议。转载请注明出处!

solidity智能合约[52]-安全-storage陷阱

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI

开发者交流群×