Openzeppelin庫第九期:支付模式Push與Pull
阿新 • • 發佈:2018-12-17
支付的模式
- 推送(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; } } }