solidity秘密竞拍案例

背景

秘密竞拍案例
秘密竞拍注释案例 注释较全

在理解该智能合约的代码前,需要先了解它适用的背景。该智能合约适合完成一次秘密竞拍的流程。这个竞拍应分为3个阶段,竞拍期、展示期、竞拍结束。在竞拍期间,需要让竞拍者能向合约提供报价的同时,不向其它人暴露自己的报价。在展示期间,竞拍者们公布自己的报价,并决定最高报价。竞拍结束后,向卖方打款。

合约只约束了在竞拍期间的报价是被隐藏的,但这些报价在展示期不再需要隐藏。

似乎本合约只讲述了如何秘密竞拍并向受益者付款,没讲如何将物品的所属权转交给竞拍胜者。在生产环境还应该加上这部分逻辑。

各时期分析

整个竞拍分为3个阶段:

  1. 拍卖期,时间区间( − ∞ -\infty , biddingEnd)。竞拍者各自调用bid秘密出价。
  2. 展示期,时间区间(biddingEnd, revealEnd)。竞拍者各自调用reveal展示自己的报价,可能调用placeBid设置最高竞价。reveal会将确定失效的竞价发还竞拍者。
  3. 展示结束,时间区间(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取回在展示期间落选的保证金。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值