首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >如何编写一个拍卖的智能合约

如何编写一个拍卖的智能合约

作者头像
用户7634691
发布于 2023-02-24 02:38:18
发布于 2023-02-24 02:38:18
72700
代码可运行
举报
运行总次数:0
代码可运行

拍卖的方式有几种,其中有两种概念你需要先了解下,一种是公开拍卖(open auction),一种叫盲拍(blind auction)。简单来讲就是,前一种拍卖大家都能互相看到对方的出价,而后一种则看不到。

先看一个简单的公开拍卖。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
contract SimpleAuction {

    //拍卖的受益人
    address payable public beneficiary;
    //拍卖的结束时间
    uint public auctionEndTime;

    // 最高出价的人
    address public highestBidder;
    // 最高出价的价格
    uint public highestBid;

    // 这个map用来存放出价的人以及对应的出价,便于拍卖结束后退还
    mapping(address => uint) pendingReturns;

    //标识拍卖结束了,一旦结束就不能改了
    bool ended;

payable表示这个地址可以接收以太币。因为存放的是受益人的地址当然是可以接受以太币的。uctionEndTime是一个时间戳变量,表示拍卖的结束时间。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 用来记录当前出价最高的事件
event HighestBidIncreased(address bidder, uint amount);
// 用来记录拍卖结束后
event AuctionEnded(address winner, uint amount);

这里是定义两个事件,用来记录状态的变更。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/// 拍卖已经结束
error AuctionAlreadyEnded();

/// 已经有更高的出价者了
error BidNotHighEnough(uint highestBid);

/// 拍卖还未结束
error AuctionNotYetEnded();

/// auctionEnd 方法已经被调用了
error AuctionEndAlreadyCalled();

这里有几个之前没讲过的知识点,首先是注释用/// 三斜杠,这样的注释可以用来生成文档(natSpec)。这里只是一个简单的示例,还可以定义的很复杂,比如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/// @title A simulator for trees
/// @author Larry A. Gardner
/// @notice You can use this contract for only the most basic simulation
/// @dev All function calls are currently implemented without side effects
/// @custom:experimental This is an experimental contract.
contract Tree {
    /// @notice Calculate tree age in years, rounded up, for live trees
    /// @dev The Alexandr N. Tetearing algorithm could increase precision
    /// @param rings The number of rings from dendrochronological sample
    /// @return Age in years, rounded up for partial years
    function age(uint256 rings) external virtual pure returns (uint256) {
        return rings + ;
    }

    /// @notice Returns the amount of leaves the tree has.
    /// @dev Returns only a fixed number.
    function leaves() external virtual pure returns(uint256) {
        return ;
    }
}

另外就是error关键字,我们可以用error来定义一个错误,然后当某个条件满足时,我们再用revert关键字报告一个错误,同时错误背后的原因通过natSpec做了解释。后面的代码会看到调用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 通过构造函数初始化受益人和拍卖的结束时间
constructor(
        uint biddingTime,
        address payable beneficiaryAddress
) {
    beneficiary = beneficiaryAddress;
    auctionEndTime = block.timestamp + biddingTime;
}

block.timestamp 向合约提供当前区块的时间戳。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function bid() external payable {

        if (block.timestamp > auctionEndTime)
            revert AuctionAlreadyEnded();

        if (msg.value <= highestBid)
            revert BidNotHighEnough(highestBid);

        if (highestBid != ) {

            pendingReturns[highestBidder] += highestBid;
        }
        highestBidder = msg.sender;
        highestBid = msg.value;
        emit HighestBidIncreased(msg.sender, msg.value);
    }

拍卖的核心流程就是这个方法。同样payable表示这个方法可以接收以太币。external则表示这个方法是在外部被调用的,也就是被合约的用户通过接口调用。逻辑上也不复杂,pendingReturns会记录所有出价成功的人(注意不是拍卖成功)和他们的总出价。

同时,当前最高的出价人和出价会被当成日志记录在以太坊的区块链上,对这个日志感兴趣的人可以监听这个日志做一些事情。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  function withdraw() external returns (bool) {
        uint amount = pendingReturns[msg.sender];
        if (amount > ) {
            pendingReturns[msg.sender] = ;

            if (!payable(msg.sender).send(amount)) {
                // No need to call throw here, just reset the amount owing
                pendingReturns[msg.sender] = amount;
                return false;
            }
        }
        return true;
    }

拍卖结束后,没有赢得最终拍卖的那些出价者需要有一个接口进行退款,就是这个withdraw方法。payable(msg.sender).send这句的意思是将以太币发送回调用者的地址。用payable修饰表示这个地址可以接收以太币。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    function auctionEnd() external {

        if (block.timestamp < auctionEndTime)
            revert AuctionNotYetEnded();
        if (ended)
            revert AuctionEndAlreadyCalled();

        ended = true;
        emit AuctionEnded(highestBidder, highestBid);
        beneficiary.transfer(highestBid);
    }

调用这个方法可以结束拍卖。前面先进行检查,看是否满足结束的条件。如果满足就更新状态并且记录日志。最后就是把拍卖的钱转给受益人。

我们把这段程序放在remix运行下,看看效果。

首先传入一个结束时间和受益人地址进行初始化。

我这里设置的受益人地址说:0x5B38Da6a701c568545dCfcB03FcB875f56beddC4

获取下变量的初始值看看,

看着都没啥问题。我们现在模拟一次出价,点击bid方法,然后value那里我们先默认用0,点击后发现报错:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[vm]from: 0x5B3...eddC4to: SimpleAuction.bid() 0xD7A...F771Bvalue:  weidata: 0x199...8aeeflogs: hash: 0x9b7...a19d1
transact to SimpleAuction.bid errored: VM error: revert.

revert
    The transaction has been reverted to the initial state.
Error provided by the contract:
BidNotHighEnough : 已经有更高的出价者了
Parameters:
{
 "highestBid": {
  "value": "0"
 }
}

有没有注意到,我们通过注释的写的error的描述,在错误出现的时候打印出来了。这样验证了我们前面的内容。

我么首先让用户a(地址是:0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2)出价11 wei,然后让用户b (地址是:0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db)出价 20 wei,你会看到出价成功后对应的地址上的余额就会减少(同时也会扣除gas fee)。

点击拍卖结束后,受益人的地址上余额就会增加。同时我们可以选择对应的没有拍卖成功的出价人的地址,然后点击withdraw,他的出价会返回来。


参考:

  • https://docs.soliditylang.org/en/v0.8.10/solidity-by-example.html
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-08-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 犀牛的技术笔记 微信公众号,前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
如何编写一个拍卖的智能合约-续
拍卖的方式有几种,其中有两种概念你需要先了解下,一种是公开拍卖(open auction),一种叫盲拍(blind auction)。简单来讲就是,前一种拍卖大家都能互相看到对方的出价,而后一种则看不到。
用户7634691
2023/02/24
4180
如何编写一个拍卖的智能合约-续
【以太坊篇】-简单的拍卖合约解析
最近学习了一个通用型的拍卖合约,具体解析也可参照solidity学习官网中的例子。
帆说区块链
2022/04/26
1K1
【以太坊篇】-简单的拍卖合约解析
<Solidity学习系列一>根据例子学习Solidity
声明:本系列文章是自己在http://solidity-cn.readthedoc... 学习solidity时,因为英语水平不够,被迫用谷歌粗略翻译的。仅为了方便学习,中间肯定有很多错误的地方。请勘误。
Charlie_W
2018/10/19
5160
Solidity 文档--第三章:Solidity 编程实例
接下来的合约非常复杂,但展示了很多Solidity的特性。它实现了一个投票合约。当然,电子选举的主要问题是如何赋予投票权给准确的人,并防止操纵。我们不能解决所有的问题,但至少我们会展示如何委托投票可以同时做到投票统计是自动和完全透明。
程序新视界
2022/05/06
3590
以太坊智能合约安全开发建议
请求不可信的合约时可能会引入一些意外风险或错误。在调用外部合约时,外部合约或其依赖的其它合约中可能存在恶意代码。因此,每个外部合约的请求都应该被认为是有风险的。如必须请求外部合约,请参考本节中的建议以最大程度的减小风险。
Tiny熊
2020/12/29
1.2K0
solidity之智能拍卖案例
角色分析:4类角色(拍卖师actioneer,委托人seller,竞买人bidder,买受人buyer)
timerring
2023/06/11
4350
solidity之智能拍卖案例
NFT铸造拍卖交易平台怎么开发?合约部署流程
拍卖,顾名思义就是在规定的时间和场所,按照一定的章程和规则,将要拍卖的货物向买主进行展示,公开叫价竞购,最后由拍卖人把货物卖给出价最高的买主的一种交易方式。传统的拍卖一般都是实体物品,随着nft的发展,拍卖从传统的实物衍生到了nft数字艺术,也给疫情之下的拍卖行业寻求了一条转型之路。
开发v_hkkf5566
2023/03/02
6670
以太坊合约审计 CheckList 之“以太坊智能合约编码设计问题”影响分析报告
在知道创宇404区块链安全研究团队整理输出的《知道创宇以太坊合约审计CheckList》中,把“地址初始化问题”、“判断函数问题”、“余额判断问题”、“转账函数问题”、“代码外部调用设计问题”、“错误处理”、“弱随机数问题”等问题统一归类为“以太坊智能合约编码设计问题”。
Seebug漏洞平台
2018/10/23
5970
以太坊合约审计 CheckList 之“以太坊智能合约编码设计问题”影响分析报告
“以太坊智能合约编码设计问题”影响分析报告
以太坊智能合约是以太坊概念中非常重要的一个概念,以太坊实现了基于solidity语言的以太坊虚拟机(Ethereum Virtual Machine),它允许用户在链上部署智能合约代码,通过智能合约可以完成人们想要的合约。
LoRexxar
2023/02/21
5560
“以太坊智能合约编码设计问题”影响分析报告
以太坊智能合约审计 CheckList
在以太坊合约审计checkList中,我将以太坊合约审计中遇到的问题分为5大种,包括编码规范问题、设计缺陷问题、编码安全问题、编码设计问题、编码问题隐患。其中涵盖了超过29种会出现以太坊智能合约审计过程中遇到的问题。帮助智能合约的开发者和安全工作者快速入门智能合约安全。
Seebug漏洞平台
2018/12/13
1.1K0
Solidity开发的智能合约安全建议
调用不受信任的外部合约可能会引发一系列意外的风险和错误。外部调用可能在其合约和它所依赖的其他合约内执行恶意代码。因此,每一个外部调用都会有潜在的安全威胁,尽可能的从你的智能合约内移除外部调用。当无法完全去除外部调用时,可以使用这一章节其他部分提供的建议来尽量减少风险。
rectinajh
2021/11/24
1.4K0
智能合约中常见的漏洞总结复现#技术创作101训练营#
一个小朋友,他可以数着手指运算十以内的运算,比如 1+1=2,他可以用两个手指算出来,但是如果你问他 5+6 等于多少,他数完十个手指之后发现手指不够用了,就会把手指扳回来,说:结果为 1,对于小朋友来说,这个问题就超纲“溢出”了
yichen
2020/09/23
3K0
智能合约开发中13种最常见的漏洞
在智能合约开发过程中,确实存在多种类型的漏洞,这些漏洞可能导致资金损失、合约功能失效或被恶意利用。以下是智能合约开发中常见的漏洞类型:
终有链响
2024/07/29
8970
智能合约:Ethernaut题解(四)
题目声明了 Building 接口中的那个 isLastFloor 函数,我们可以自己编写
yichen
2020/05/24
9120
DDOS概述
对智能合约进行DOS攻击的方法有很多种,其根本的目的是使合约在一段时间内或者永久无法正常运行,通过拒绝服务攻击,也可以使合约中的ether永远无法提取出来,下面将会列出几种常见的攻击场景:
Al1ex
2021/03/25
2.6K0
DDOS概述
智能合约安全审计技术概览
智能合约是区块链技术的重要组成部分,它能够自动执行代码并将结果写入区块链以实现各种业务场景,然而由于智能合约本质上是代码,因此也存在着相应的安全风险,如果智能合约存在漏洞,黑客就有可能利用这些漏洞进行攻击,导致资产损失甚至系统崩溃,因此对智能合约进行安全审计是至关重要的,本文将概述智能合约安全审计技术的相关知识为读者带来更深入的了解
Al1ex
2023/08/10
1.1K0
智能合约安全审计技术概览
以太坊蜜罐智能合约分析
作者:dawu&0x7F@知道创宇404区块链安全研究团队 时间:2018/06/26
Seebug漏洞平台
2018/07/26
1.5K0
以太坊蜜罐智能合约分析
智能合约安全审计之路-返回值检查漏洞
描述:未检查低级别调用的返回值,在solidity中的低级别调用与其他函数调用不同,如果调用中发生了异常并不会将异常传递,而只是返回true或false。因此程序中必须对低级别调用的返回值进行检查,而不能期待其出错后促使整个调用回滚。
字节脉搏实验室
2020/03/31
1.3K0
彻底理解solidity中的事件
我们可以通过emit调用事件方法,然后这个事件就作为日志记录到了以太坊区块链中。日志是以太坊区块链中一种特殊的数据结构,你可以把它当作区块链的一部分,只要区块链在,日志就在。日志和产生它的智能合约的地址事绑定的。
用户7634691
2023/02/24
3640
彻底理解solidity中的事件
defi质押挖矿智能合约dapp系统开发详解
本文介绍通过质押底层币(以太坊)资产获取收益的一般逻辑及其实现方法,该方案在很多defi项目得到应用;本文中的收益为ERC20通证,收益获取也可以理解为挖矿行为。
开发v_hkkf5566
2022/10/21
8740
推荐阅读
相关推荐
如何编写一个拍卖的智能合约-续
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档