Openzeppelin库第九期:支付模式Push与Pull

支付的模式

  • 推送(push):合约主动维护
  • 拉取(pull):用户主动调用
  • 实例:简单竞标说明
  • 只有一个功能:在竞标过程中,当有更高的价格产生时,对出价最高竞标者的信息进行更新,合约把之前那一个的竞价退回去。
pragma solidity ^0.4.18;

// 竞标合约实例
// 1. 推送模式的支付
contract PushPayment{
    // 出价最高的人
    address highestBidder;
    // 竞标价格
    uint highestBid;

    // 有出价更高的人出现,竞标者信息需要更新,如果原有的竞标者在合约的回退函数中植入
    // 恶意代码使得send退款一直失败,就会导致始终无法更新竞标成功者的信息,可能就可以
    // 使得自己以低价竞标成功
    function() payable {
        throw;
    }

    // 竞标函数
    function bid() {
        if(msg.value < highestBid) throw; // 如果出的价格小于当前最高价,抛出
        if(highestBidder != 0) {
            if(!highestBidder.send(highestBid)) {
                throw;
            }
        }
        // 更换出价最高的竞标者
        highestBidder = msg.sender;
        // 更换最高价格
        highestBid = msg.value;
    }
}
// 拉取模式
// 在出现出价更高的竞标者之后,由用户自己来调用退款函数
contract PullContract {
    address highestBidder; 
    uint highestBid;
    // 存储每一个待退款的竞标者的信息
    mapping(address=>uint) refunds; 

    function bid() {
        if(msg.value < highestBid) throw;
        if (highestBidder != 0) {
            refunds[highestBidder] += msg.value;
        }
        highestBidder = msg.sender;
         // 更换最高价格
        highestBid = msg.value;
    }

    // 用户自己调用,单独处理退款,由于不是合约去进行维护,就算退款失败也不会影响
    // 竞标成功者的更换
    function withdrawBid() external {
        uint refund = refunds[msg.sender];
        refunds[msg.sender] = 0;
        if (!msg.sender.send(refund)) {
            refunds[msg.sender] = refund;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/super_lixiang/article/details/83380551