背景
秘密竞拍案例 秘密竞拍注释案例 注释较全
在理解该智能合约的代码前,需要先了解它适用的背景。该智能合约适合完成一次秘密竞拍的流程。这个竞拍应分为3个阶段,竞拍期、展示期、竞拍结束。在竞拍期间,需要让竞拍者能向合约提供报价的同时,不向其它人暴露自己的报价。在展示期间,竞拍者们公布自己的报价,并决定最高报价。竞拍结束后,向卖方打款。
合约只约束了在竞拍期间的报价是被隐藏的,但这些报价在展示期不再需要隐藏。
似乎本合约只讲述了如何秘密竞拍并向受益者付款,没讲如何将物品的所属权转交给竞拍胜者。在生产环境还应该加上这部分逻辑。
各时期分析
整个竞拍分为3个阶段:
- 拍卖期,时间区间(
?
∞
-\infty
?∞, biddingEnd)。竞拍者各自调用
bid 秘密出价。 - 展示期,时间区间(biddingEnd, revealEnd)。竞拍者各自调用
reveal 展示自己的报价,可能调用placeBid 设置最高竞价。reveal 会将确定失效的竞价发还竞拍者。 - 展示结束,时间区间(revealEnd,
+
∞
+\infty
+∞)。任意人可以调用
auctionEnd ,将最高出价的代币发给受益者。
任何时候,竞拍者可以调用withdraw 取回自己竞拍失败的保证金。
拍卖期
仅在biddingEnd时间戳以前调用才能成功。竞拍者会调用bid ,并在交易中附带自己的以太币,以及由竞拍信息生成的哈希值_blindedBid 。竞拍者可以通过_blindedBid = keccak256(value, fake, secret) 设置一个秘密竞拍。
fake 字段使得报价可以是真的或者假的。所以通过提出多个不同价格的报价,其中大部分报价是虚假的,用于迷惑对手。keccak256 ,可以令其他人无法确定自己的真实出价value ,但又能在展示期用于鉴定自己的报价。deposit 是保证金,它必须高于真实出价value ,否则在展示期视为无效。- 当调用
bid 函数后,保证金就已经转到合约账户上了,只有在展示期才会归还。
function bid(bytes32 _blindedBid)
public
payable
onlyBefore(biddingEnd)
{
bids[msg.sender].push(Bid({
blindedBid: _blindedBid,
deposit: msg.value
}));
}
展示期
在展示期,不在接受任何新报价,用户需要公开自己的报价。此时,每个用户以自己事先设置的secret 为参数,调用reveal 。鉴定有效的报价将会参与竞拍。
function reveal(
uint[] _values,
bool[] _fake,
bytes32[] _secret
)
public
onlyAfter(biddingEnd)
onlyBefore(revealEnd)
{
uint length = bids[msg.sender].length;
require(_values.length == length);
require(_fake.length == length);
require(_secret.length == length);
uint refund;
for (uint i = 0; i < length; i++) {
Bid storage bid = bids[msg.sender][i];
(uint value, bool fake, bytes32 secret) =
(_values[i], _fake[i], _secret[i]);
if (bid.blindedBid != keccak256(value, fake, secret)) {
// 出价未能正确披露
// 不返还订金
continue;
}
// 添加退款
refund += bid.deposit;
if (!fake && bid.deposit >= value) {
// 这个报价是真实的,且保证金充足,参与竞拍
if (placeBid(msg.sender, value))
// 该报价暂时赢得了竞价,在此次调用不退款。
refund -= value;
}
// 使发送者不可能再次认领同一笔订金
bid.blindedBid = bytes32(0);
}
msg.sender.transfer(refund);
}
- 如果不能正确披露某个报价,则直接跳过。(hash都对不上,当然不应该为其退款)
- hash一致的情况下:只有保证金充足,且pk当前的最高价成功,合约才应暂时扣留这笔款项。否则应当退保证金。
竞拍结束
展示期结束后,已确定优胜者。任何人调用auctionEnd 可以将款项打给卖家。各竞拍者可以调用withdraw 取回在展示期间落选的保证金。
|