支付的模式
- 推送(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;
}
}
}