[solidity语法学习二]基于Remix以太坊的BlindAuction模板代码分析

本文介绍了基于Remix的以太坊BlindAuction和Simple Open Auction智能合约代码分析,讲解了msg.value、payable变量、address payable的区别,以及send和transfer函数的使用。内容涵盖合约的构造函数、竞标和返还函数,以及状态机合同Safe Remote Purchase的介绍,深入探讨了以太币单位转换和智能合约中的时间管理。
摘要由CSDN通过智能技术生成

前言

编译环境:Remix.
代码来源:SolidityDoc.
疑难解决来源:Ethereum gitter.
例子三参考:例图.
以太币单位换算:以太币单位.
本文主要由三个例子构成。分别是Simple Open Auction 以及延伸版本Blind Auction 、此外还有一个涉及到状态机类型的合同为Safe Remote Purchase。
该例子在基于(一)之上引入了相关语法,接下来我会尽力以自己的理解结合网上的资料进行分析解释,从而帮助我更好地理解相关语法的知识点。

本次例子中引入了msg.value变量以及payable变量,重点在于强调value这个价值。只有当地址中包含payable变量的时候,才能引入value这个功能。因此,我们正常输入函数需要在value中设置相应的以太币,如:
在这里插入图片描述

一、Simple Open Auction代码分析

a、初始化相应变量
address payable public beneficiary;//引入受益人地址[注1]
    uint public auctionEndTime;//定义拍卖停止时间
    
    address public highestBidder;//提出最高价格的竞标人地址
    uint public highestBid;//竞标最高价格
    
    mapping (address => uint) pendingReturns;//将每个地址隐射一个退还金额的变量
    
    bool ended;//判断竞标是否结束的变量
    
    event HighestBidIncreased(address bidder, uint amount);//最高竞价增加的log事件(涉及地址以及数量信息)
    event AuctionEnded(address winner, uint amount);//竞标成功的地址和数量信息的的log事件

[注1]:address payable
首先,我们得明确address和address payable的差别。
address指的是一个20字节的值,也就是以太坊账户地址。
address payable除了代表以太坊账户地址,还额外具备transfer和send函数的功能。
常见用法会在接下来函数具体应用中说明,并且会在该例子结束后具体对比说明。

b、构造函数
    constructor(
        uint _biddingTime,//定义一个时间间隔
        address payable _beneficiary)//定义受益人地址
    {
   
        beneficiary = _beneficiary;//赋值到全局变量
        auctionEndTime = block.timestamp + _biddingTime;//[注2]
    }

[注2]:这里定义一个整数型变量_biddingTime,实际上可以理解为定义一个时间间隔。比如赋值600 也就等价于600秒。
block.timestamp是获取当前时间,该值主要指的是获取当前时间。
PS:当然有些小伙伴会发现这个solidity7.0版本之前是使用now来代替,在solidity7.0语法升级以后,统一使用block.timestamp来获取当前时间,具体更新改动可以通过阅读Solidity v0.7.0 Breaking Changes 来进一步了解其他方面的变动,当然这里只是扩展一下。

c、竞标函数
function bid() public payable{
   
        require(
                block.timestamp <= auctionEndTime,
                "Auction already ended."
            );//判断是否处于竞标期间
        require(
                msg.value > highestBid,
                "There already is a higher bid"
            );//判断竞标金额是否大于最高竞标金额
        if (highestBid != 0){
   
            pendingReturns[highestBidder] += highestBid;
        }//[注3]
        highestBidder = msg.sender;//赋值竞标价格最高者地址
        highestBid = msg.value;//赋值竞标价格
        emit HighestBidIncreased(msg.sender, msg.value);
        //声明log日志用于显示竞标最高者地址以及价格
    }

[注3]由于当前竞标价格为最高价格,因此过往的价格都返还到原有地址的返还数组:pendingReturn[highestBidder] 里面。因此,可以调用d中函数把返还数组里面的以太币返还到指定账户。

d、返还竞标金额函数
 function withdraw() public returns (bool) {
   
        uint amount = pendingReturns[msg.sender];//定义一个整型变量amount存储返回数组的具体金额
        if(amount > 0){
   
            pendingReturns[msg.sender] = 0;//若amount>0,则清空返回数组的数据
            if(!msg.sender.send(amount))//[注4]{
   
                pendingReturns[msg.sender] = amount;
                return false;
            }
        }
        return true;
    }

[注4]通过判断amount是否为0,若不为0则把pendingReturns[msg.sender] = 0; 同时这里运用了msg.sender.send(amount) 函数。也就是前文提到的address payable的特性。
这里先介绍一下send函数的用法以及原理:
msg.sender.send(amount) 指的是将amount的金额发送到msg.sender的账户上。send除了传递金额以后还会发出一个bool型的返回值。
若成功执行则返回的是true,因此该if条件不满足可以直接return true。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值