前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >solidity之智能拍卖案例

solidity之智能拍卖案例

作者头像
timerring
发布2023-06-11 09:56:40
2820
发布2023-06-11 09:56:40
举报
文章被收录于专栏:TechBlogTechBlog

实现一个简易的拍卖

角色分析:4类角色(拍卖师actioneer,委托人seller,竞买人bidder,买受人buyer)

功能分析:拍卖的基本原则是价高者得,在设定的拍卖时限内,出价最高者最终获得拍卖得标物(提示:在数据结构上,不用太复杂的设计,只需能记录当前最高价的竞买人及其金额、拍卖结束时间即可。)

  • 竞拍功能:竞买人可以多次出价,价格必须高于当前记录的最高价,并将最高价和竞买人替换。
  • 竞拍结束:竞拍结束时,宣布胜利者。

状态变量定义和初始化

定义变量:委托人、拍卖师、买受人、竞拍结束标志、时间限制、竞拍最高金额。(提示:调用者为拍卖师,如果涉及到角色需要用address payable,构造函数可以初始化拍卖师[即msg.sender]、拍卖时限、竞拍结束标志,竞买人在程序中选择不同account,根据account和msg.value更新买受人和最高金额)

竞拍功能

只要竞拍未结束都可以发起竞拍(提示:从调用信息窗口选择买家,输入竞拍价格,用msg.sender和msg.value获得买家和价格信息)

但需要满足以下条件:竞拍未结束;竞拍时的价格一定要比之前的价格高;竞拍在时限内;

当竞拍被允许时,需要退钱给上一个买家,并替换原有的最高价格和买受人。

结束竞拍

判断是否超过时限,并且是第一次执行本操作,确认通过后给委托人。

代码

代码语言:javascript
复制
pragma solidity ^0.8.4;
contract auction {
    uint auctionEndTime;
    address public auctioneer;
    address public buyer;
    address payable public seller;
    uint public auctionAmount;

    // Allowed withdrawals of previous bids
    mapping(address => uint) pendingReturns;

    // A sign to judge whether the auction is over
    // Set to true at the end, disallows any change.
    bool ended;

    // Events that will be emitted on changes.
    event auctionAmountIncreased(address bidder, uint amount);
    event AuctionEnded(address winner, uint amount);

    // Errors that describe failures.
    /// The auction has already ended.
    error AuctionAlreadyEnded();
    /// There is already a higher or equal bid.
    error BidNotHighEnough(uint auctionAmount);
    /// The auction has not ended yet.
    error AuctionNotYetEnded();
    /// The function auctionEnd has already been called.
    error AuctionEndAlreadyCalled();

    constructor(
        uint biddingTime,
        address payable sellerAddress
    ) {
        seller = sellerAddress;
        auctionEndTime = block.timestamp + biddingTime;
        auctioneer = msg.sender;
    }

    /// Bid function
    function bid() external payable {
        // Revert the call if the bidding period is over.
        if (block.timestamp > auctionEndTime)
            revert AuctionAlreadyEnded();

        // Return money if the bid is not high enough
        if (msg.value <= auctionAmount)
            revert BidNotHighEnough(auctionAmount);

        if (auctionAmount != 0) {
            pendingReturns[buyer] += auctionAmount;
        }
        buyer = msg.sender;
        auctionAmount = msg.value;
        emit auctionAmountIncreased(msg.sender, msg.value);
    }

    /// End the auction and send the highest bid to the seller.
    function auctionEnd() external payable {

        // Analyzing conditions
        if (block.timestamp < auctionEndTime)
            revert AuctionNotYetEnded();
        if (ended)
            revert AuctionEndAlreadyCalled();
        ended = true;
        emit AuctionEnded(buyer, auctionAmount);
        // transfer
        seller.transfer(auctionAmount);
    }
}

首先,按照要求deploy拍卖,按照要求设置相关参数,其中seller的地址是 0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB ,竞拍的时间是 120

如下所示:

deploy.png
deploy.png

deploy成功之后,进行初始查询,右下可知,auctioneer即为调用者的地址,seller地址与刚刚输入的地址一致。初始buyer地址默认为0,出价也为0。

prequery.png
prequery.png

然后进行第一次竞拍,切换至地址结尾为 35cb2 的账户,出价为1949 ,进行竞拍:

firstbid.png
firstbid.png

查询后可知,竞拍成功,并且出现在当前buyer位置:

firstquery.png
firstquery.png

然后进行第二次竞拍,切换至地址结尾为 C02db 的账户,出价为6666,进行竞拍:

secondbid.png
secondbid.png

查询后可知,竞拍成功,并且出现在当前buyer位置:

secondquery.png
secondquery.png

然后进行第三次竞拍,切换至地址结尾为 5E7f2 的账户,出价为9999,进行竞拍:

thirdbid.png
thirdbid.png

查询后可知,竞拍成功,并且出现在当前buyer位置:

thirdquery.png
thirdquery.png

最后,待拍卖时间结束后进行auctionEnd,根据定义,价高者得,因此winner是出价9999 的账户,结果如下:

auctionEnd.png
auctionEnd.png
本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-06-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实现一个简易的拍卖
  • 状态变量定义和初始化
  • 竞拍功能
  • 结束竞拍
  • 代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com