北大肖臻老师《区块链技术与应用》系列课程学习笔记[25]以太坊-智能合约-5

这篇具有很好参考价值的文章主要介绍了北大肖臻老师《区块链技术与应用》系列课程学习笔记[25]以太坊-智能合约-5。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

智能合约-1

智能合约-2

智能合约-3

智能合约-4

解决重入攻击

网上竞拍第二版:由投标者自己取回出价

//使用withdraw模式
//由投标者自己取回出价,返回是否成功
function withdraw( ) public returns (bool) {
    //拍卖已截止
    require(now > auctionEnd);
    //竞拍成功者需要把钱给受益人,不可取回出价,如果不是最高出价者
    require(msg.sender != highestBidder);
    //当前地址有钱可取
    require(bids[msg.sender] > 0);//账户余额是否为正

    uint amount = bids[msg.sender];//账户余额
    if(msg.sender.call.value(amount)()) {//把账户余额转给msg.sender
        bids[msg.sender] = 0;//把账户余额清成0
        return true;
    }
    return false;
}

//把最高出价给这个受益人,也是判断一下拍卖已经结束了
//最高出价的金额大于零,下面再把它转过去
event Pay2Beneficiary( address winner,uint amount);
//结束拍卖,把最高的出价发送给受益人

function pay2Beneficiary ()public returns(bool) {
    //拍卖已截止
    require(now > auctionEnd);
    //有钱可以支付
    require(bids[highestBidder] > 0);//最高出价的金额大于零
    
    uint amount = bids[highestBidder];
    bids[highestBidder] = 0;
    emit Pay2Beneficiary(highestBidder,bids[highestBidder]);
    if(!beneficiary.call.value(amount)()){
        bids[highestBidder] = amount;
        return false;
    }
    return true;
}

(1)存在的问题

        重入攻击,如果有黑客写了一个如下方程序会怎么样?

pragma solidity ^0.4.21;

import "./simpleAuctionv2.sol";

contract HackV2 {
    uint stack = 0;
    function hack_bid( address addr) payable public {
        simpleAuctionv2 sa = simpleAuctionv2(addr);
        sa.bid.value(msg.value)();
    }
    
    function hack_withdraw(address addr) public payable{
        SimpleAuctionv2(addr).withdraw();
    }

    function() public payable{
        stack += 2;
        //当前调用的剩余汽油,msg.gas还有6000个单位以上,调用栈的深度不超过500
        if (msg.sender.balance >= msg.value && msg.gas > 6000 && stack < 500{
            SimpleAuctionV2(msg.sender).withdraw();
        }
    }
}

        这个hack_bid跟前面的那个黑客合约hack_bid合约是一样的,通过调用拍卖bid函数参与竞拍,hack_withdraw就在拍卖结束的时候调用withdraw函数,把钱取回来,这两个看上去好像都没有问题,问题在于fallback函数,他又把钱取了一遍。

        在hack_withdraw调用withdraw函数的时候,执行到“if(msg.sender.call.value(amount)())”会向黑客合约转账,这个msg.sender就是黑客的合约,把当初出价的金额转给他,而在这个合约中,又调用了拍卖函数的withdraw函数“SimpleAuctionV2(msg.sender).withdraw();”,又去取钱,fallback函数这里的msg.sender就是这个拍卖合约,因为是拍卖合约把这个钱转给这个合约的,这个左边的拍卖合约执行到if那里,再给他转一次钱,注意这个清零的操作,把黑客合约账户清零的操作,只有在转账交易完成之后,才会进行,而前面if这个转账的语句已经陷入到了跟黑客合约当中的递归调用当中,根本执行不到下面这个清零操作,所以最后的结果就是这个黑客一开始出价的时候给出了一个价格,拍卖结束之后,就按照这个价格不停地从这个智能合约中去取钱,第一次取得是他自己的出价,后面取得就是别人的钱了。

        递归重复取钱,持续到什么时候会结束?有三种情况,一个是这个拍卖合约上的余额不够了,不足以在支持这个转账的语句,第二种情况是汽油费不够了,因为每次调用的时候还是消耗汽油费的,到最后没有足够的汽油剩下来了,第三种情况,调用栈溢出了,所以黑客合约的fallback函数判断一下这个拍卖合约的余额还足以支持转账,当前调用的剩余汽油,msg.gas还有6000个单位以上,调用栈的深度不超过500。那么就再发起一轮攻击,那怎么办呢?

(2)如何处理

        最简单的就是先清零再转账,就是Pay2Beneficiary的这种写法,把highestBidder的账户余额清成零了(在bids哈希表里面的余额已经清成0了),然后再转账,转账如果不成功的话,再把余额恢复。这个实际上是对于可能跟其他合约发生交互的情况的一种经典的编程模式,就先要判断条件,然后改变条件,最后再跟别的合约发生交互。在区块链上,任何未知的合约都可能使有恶意的,所以每次你向对方转账或者使调用对方某个函数的时候,都要提醒下自己,这个合约,这个函数有可能反过来调用你当前的这个合约,并且修改状态,小心一点总是好的。

另一种修改方式:

图2-2

        除了这个修改方式以外,还有一种方法,如图2-2所示,不用call.value的形式转账,对比一下修改前后的两段代码(绿框的部分),把清零的位置提前了(先清零再转账);而且转账的时候用的是sender,用transfer也可以,sender和transfer一个共同的特点就是转账的时候发送过去的汽油费只有2300个单位,这个不足以让接收的那个合约再发起一个新的调用,只够写一个log而已。

        这个时候就没有问题了。

        另外,下图2-3所示,这个黑客合约没有写fallback函数,如果这个不是一个黑客合约,就是一个普通的账户,他忘了写fallback函数。怎么办?没有办法,就算这个账户愿意改,也是改不了的,他没有办法把fallback函数补上了,因为发布到区块链上去了,这个账户可以再创建一个新的合约,但是这个合约已经参与这个拍卖了,已经被记录在这个循环里面了,也没有办法。文章来源地址https://www.toymoban.com/news/detail-838544.html

图2-3

到了这里,关于北大肖臻老师《区块链技术与应用》系列课程学习笔记[25]以太坊-智能合约-5的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 北大肖臻老师《区块链技术与应用》系列课程学习笔记[17]以太坊-GHOST协议

    目录 一、以太坊的出块时间及可能带来的问题         1.以太坊的出块时间         2.以太坊与比特币系统的平均出块时间对比         3.带来的问题 二、GHOST协议         1.GHOST协议的核心思想         2.GHOST协议的缺陷         3.改进后的GHOST协议    

    2024年02月09日
    浏览(51)
  • 北大肖臻老师《区块链技术与应用》系列课程学习笔记[22]以太坊-智能合约-2

    智能合约-1 目录 一、智能合约的创建和运行         1.智能合约的创建         2.汽油费         3.错误处理         4.嵌套调用 二、思考         1.GasLimit和GasUsed         2.以太坊中的GasLimit跟比特币的区别 1.智能合约的创建         智能合约 由一个外

    2024年02月19日
    浏览(49)
  • 北大肖臻老师《区块链技术与应用》系列课程学习笔记[15]以太坊-交易树和收据树

     目录 一、以太坊中的三种树 二、状态树、交易树和收据树的区别 三、交易树和收据树的用途         1.交易树和收据树的用途         2.如何实现复杂的查询操作         3.以太坊中Bloom Filter的用途 四、以太坊的运行过程        在以太坊中,存在三种基于树的

    2024年02月05日
    浏览(54)
  • 《区块链技术与应用》北大肖臻老师——课程笔记【21-23】

    提示:以下内容只是个人在学习过程中记录的笔记,图片均是肖老师课程的截图,可供参考。如有错误或不足之处,请大家指正。 权益证明proof of stake 比特币和 以太坊目前都是使用基于工作量的证明,这种共识机制受到一个普遍的批评——浪费电。 Y轴是TWH=Terawatt hours 10的

    2023年04月08日
    浏览(41)
  • 《区块链技术与应用》北大肖臻老师——课程笔记【19-20】

    提示:以下内容只是个人在学习过程中记录的笔记,图片均是肖老师课程的截图,可供参考。如有错误或不足之处,请大家指正。 Block chain is secured by mining. 对于基于工作量证明的系统来说,挖矿是保障区块链安全的一个重要手段。 比特币的挖矿算法总的来说比较成功,没有

    2024年02月09日
    浏览(38)
  • 《区块链技术与应用》北大肖臻老师——课程笔记【11-12】

    提示:以下内容只是个人在学习过程中记录的笔记,图片均是肖老师课程的截图,可供参考。如有错误或不足之处,请大家指正。 1. 转账交易时如果接收者不在线(没有连接到比特币网络上)怎么办? 转账交易不需要接收者在线,这个交易只是在区块链上记录一下,把发送

    2024年01月22日
    浏览(48)
  • 《区块链技术与应用》北大肖臻老师——课程笔记【6-8】

    提示:以下内容只是个人在学习过程中记录的笔记,图片均是肖老师课程的截图,可供参考。如有错误或不足之处,请大家指正。 比特币网络传播的工作原理(the BitCoin network): 比特币工作在应用层(application layer),底层是P2P的overlay network(覆盖网络)。 比特币的 P2P网络

    2024年01月18日
    浏览(44)
  • 北大肖臻老师<<区块链技术>>笔记1

    课程的大纲 密码学基础 比特币的数据结构 共识协议和系统实现 挖矿算法和难度调整 比特币的脚本 软分叉和硬分叉 匿名和隐私保护 以太坊是后面的 首先是密码学基础的学习: crypto-currency(虚拟货币) 是不加密的,区块链上所有的教以都是公开的。其中有转账金额和地址。

    2024年02月02日
    浏览(38)
  • [北大肖臻-区块链技术与应用笔记]第八节课——BTC 脚本

    比特币系统中使用的脚本语言很简单, 唯一能访问的内存空间就是一个栈 ,这点和通用脚本语言的区别很大。 这个交易有一个输入和两个输出,其中一个输出已经被花出去了,另一个没有被花出去。 输入脚本 输入脚本包含两个操作,分别将两个很长的数压入栈中。 输出脚

    2024年01月21日
    浏览(68)
  • [北大肖臻-区块链技术与应用笔记]第八节课——BTC 分叉

    state fork 如果两个节点差不多同时挖到一个区块,这两个区块都是挂在当前的区块上的,不同节点先收到的区块不同,就会各自沿着先收到的区块往下扩展,这种时候就会出现临时性的分叉,称为 state fork ,即由于对区块链当前的状态有意见分歧而产生的分叉。 分叉攻击(

    2024年02月08日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包