【从0学习Solidity】35. 荷兰拍卖

【从0学习Solidity】35. 荷兰拍卖

在这里插入图片描述

  • 博主简介:不写代码没饭吃,一名全栈领域的创作者,专注于研究互联网产品的解决方案和技术。熟悉云原生、微服务架构,分享一些项目实战经验以及前沿技术的见解。
  • 关注我们的主页,探索全栈开发,期待与您一起在移动开发的世界中,不断进步和创造!
  • 本文收录于 不写代码没饭吃 的学习汇报系列,大家有兴趣的可以看一看。
  • 欢迎访问我们的微信公众号:不写代码没饭吃,获取更多精彩内容、实用技巧、行业资讯等。您关注的是我们前进的动力!

这一讲,我将介绍荷兰拍卖,并通过简化版Azuki荷兰拍卖代码,讲解如何通过荷兰拍卖发售ERC721标准的NFT

荷兰拍卖

荷兰拍卖(Dutch Auction)是一种特殊的拍卖形式。 亦称“减价拍卖”,它是指拍卖标的的竞价由高到低依次递减直到第一个竞买人应价(达到或超过底价)时击槌成交的一种拍卖。

35-1.png

在币圈,很多NFT通过荷兰拍卖发售,其中包括AzukiWorld of Women,其中Azuki通过荷兰拍卖筹集了超过8000ETH

项目方非常喜欢这种拍卖形式,主要有两个原因

  1. 荷兰拍卖的价格由最高慢慢下降,能让项目方获得最大的收入。

  2. 拍卖持续较长时间(通常6小时以上),可以避免gas war

DutchAuction合约

代码基于Azuki的代码简化而成。DucthAuction合约继承了之前介绍的ERC721Ownable合约:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;import "@openzeppelin/contracts/access/Ownable.sol";
import "https://github.com/AmazingAng/WTFSolidity/blob/main/34_ERC721/ERC721.sol";contract DutchAuction is Ownable, ERC721 {

DutchAuction状态变量

合约中一共有9个状态变量,其中有6个和拍卖相关,他们是:

  • COLLECTOIN_SIZE:NFT总量。
  • AUCTION_START_PRICE:荷兰拍卖起拍价,也是最高价。
  • AUCTION_END_PRICE:荷兰拍卖结束价,也是最低价/地板价。
  • AUCTION_TIME:拍卖持续时长。
  • AUCTION_DROP_INTERVAL:每过多久时间,价格衰减一次。
  • auctionStartTime:拍卖起始时间(区块链时间戳,block.timestamp)。
    uint256 public constant COLLECTOIN_SIZE = 10000; // NFT总数uint256 public constant AUCTION_START_PRICE = 1 ether; // 起拍价(最高价)uint256 public constant AUCTION_END_PRICE = 0.1 ether; // 结束价(最低价/地板价)uint256 public constant AUCTION_TIME = 10 minutes; // 拍卖时间,为了测试方便设为10分钟uint256 public constant AUCTION_DROP_INTERVAL = 1 minutes; // 每过多久时间,价格衰减一次uint256 public constant AUCTION_DROP_PER_STEP =(AUCTION_START_PRICE - AUCTION_END_PRICE) /(AUCTION_TIME / AUCTION_DROP_INTERVAL); // 每次价格衰减步长uint256 public auctionStartTime; // 拍卖开始时间戳string private _baseTokenURI;   // metadata URIuint256[] private _allTokens; // 记录所有存在的tokenId 

DutchAuction函数

荷兰拍卖合约中共有9个函数,与ERC721相关的函数我们这里不再重复介绍,只介绍和拍卖相关的函数。

  • 设定拍卖起始时间:我们在构造函数中会声明当前区块时间为起始时间,项目方也可以通过setAuctionStartTime()函数来调整:
    constructor() ERC721("WTF Dutch Auctoin", "WTF Dutch Auctoin") {auctionStartTime = block.timestamp;}// auctionStartTime setter函数,onlyOwnerfunction setAuctionStartTime(uint32 timestamp) external onlyOwner {auctionStartTime = timestamp;}
  • 获取拍卖实时价格:getAuctionPrice()函数通过当前区块时间以及拍卖相关的状态变量来计算实时拍卖价格。

block.timestamp小于起始时间,价格为最高价AUCTION_START_PRICE

block.timestamp大于结束时间,价格为最低价AUCTION_END_PRICE

block.timestamp处于两者之间时,则计算出当前的衰减价格。

    // 获取拍卖实时价格function getAuctionPrice()publicviewreturns (uint256){if (block.timestamp < auctionStartTime) {return AUCTION_START_PRICE;}else if (block.timestamp - auctionStartTime >= AUCTION_TIME) {return AUCTION_END_PRICE;} else {uint256 steps = (block.timestamp - auctionStartTime) /AUCTION_DROP_INTERVAL;return AUCTION_START_PRICE - (steps * AUCTION_DROP_PER_STEP);}}
  • 用户拍卖并铸造NFT:用户通过调用auctionMint()函数,支付ETH参加荷兰拍卖并铸造NFT

该函数首先检查拍卖是否开始/铸造是否超出NFT总量。接着,合约通过getAuctionPrice()和铸造数量计算拍卖成本,并检查用户支付的ETH是否足够:如果足够,则将NFT铸造给用户,并退回超额的ETH;反之,则回退交易。

    // 拍卖mint函数function auctionMint(uint256 quantity) external payable{uint256 _saleStartTime = uint256(auctionStartTime); // 建立local变量,减少gas花费require(_saleStartTime != 0 && block.timestamp >= _saleStartTime,"sale has not started yet"); // 检查是否设置起拍时间,拍卖是否开始require(totalSupply() + quantity <= COLLECTOIN_SIZE,"not enough remaining reserved for auction to support desired mint amount"); // 检查是否超过NFT上限uint256 totalCost = getAuctionPrice() * quantity; // 计算mint成本require(msg.value >= totalCost, "Need to send more ETH."); // 检查用户是否支付足够ETH// Mint NFTfor(uint256 i = 0; i < quantity; i++) {uint256 mintIndex = totalSupply();_mint(msg.sender, mintIndex);_addTokenToAllTokensEnumeration(mintIndex);}// 多余ETH退款if (msg.value > totalCost) {payable(msg.sender).transfer(msg.value - totalCost); //注意一下这里是否有重入的风险}}
  • 项目方取出筹集的ETH:项目方可以通过withdrawMoney()函数提走拍卖筹集的ETH
    // 提款函数,onlyOwnerfunction withdrawMoney() external onlyOwner {(bool success, ) = msg.sender.call{value: address(this).balance}(""); // call函数的调用方式详见第22讲require(success, "Transfer failed.");}

Remix演示

  1. 合约部署:首先,部署DutchAuction.sol合约,并通过setAuctionStartTime()函数设置拍卖起始时间。
    本例采用的起始时间为,2022年7月12日 1点30分,对应的utc时间为1658338200。实验时可以在工具网站(比如这里)自行查询对应时间。
    35-2.png

  2. 荷兰拍卖:随后,可以通过getAuctionPrice()函数获取到当前的拍卖价格。可以观察到,拍卖开始前的价格为起拍价 AUCTION_START_PRICE随着拍卖进行,拍卖价格在逐渐降低,直到降低至地板价 AUCTION_END_PRICE后不再变化。
    35-3.png

  3. Mint操作:通过auctionMin()函数,完成mint,可以看见本例中,由于时间已经超过拍卖时间,因此仅耗费了地板价就完成了拍卖。
    35-4.png

  4. 提取ETH:直接通过withdrawMoney()函数,便能将筹集到的ETH通过call()发送到合约创建者的地址。

总结

这一讲,我们介绍了荷兰拍卖,并通过简化版Azuki荷兰拍卖代码,讲解如何通过荷兰拍卖发售ERC721标准的NFT。我拍卖到的最贵的NFT是音乐家Jonathan Mann的一首音乐NFT,你呢?

在这里插入图片描述

如果这份博客对大家有帮助,希望各位给作者一个免费的点赞👍作为鼓励,并评论收藏一下⭐,谢谢大家!!!
制作不易,如果大家有什么疑问或给作者的意见,欢迎评论区留言。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/140745.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

黑马JVM总结(十四)

&#xff08;1&#xff09;分代回收_1 Java虚拟机都是结合前面几种算法&#xff0c;让他们协同工作&#xff0c;具体实现是虚拟机里面一个叫做分代的垃圾回收机制&#xff0c;把我们堆内存大的区域划分为两块新生代、老年代 新生代有划分为伊甸园、幸存区Form、幸存区To 为什…

ARMv8 cache的包含策略inclusive 和 exclusive之间的区别以及Cortex-A55示例详解

Inclusive 和 Exclusive 一&#xff0c; 什么是cache的inclusive 和 exclusive二&#xff0c;Inclusive 和 Exclusive cache示例2.1 Inclusive cache2.2 Exclusive cache 三&#xff0c; inclusive cache和 exclusive cache的比较3.1 cache coherency3.2 miss rate3.3 cache ca…

使用 Docker 安装 Elasticsearch (本地环境 M1 Mac)

Elasticsearchkibana下载安装 docker pull elasticsearch:7.16.2docker run --name es -d -e ES_JAVA_OPTS“-Xms512m -Xmx512m” -e “discovery.typesingle-node” -p 9200:9200 -p 9300:9300 elasticsearch:7.16.2docker pull kibana:7.16.2docker run --name kibana -e EL…

最频繁被问到的SQL面试题

面试感叹失败的原因可能有很多&#xff0c;而做成的道路只有⼀条&#xff0c;那就是不断积累。纯手工的8291字的SQL面试题总结分享给初学者&#xff0c;俗称八股文&#xff0c;期待对新手有所帮助。 窗口函数题 窗口函数其实就是根据当前数据, 计算其在所在的组中的统计数据。…

网工基础知识——以太网

1972年Bob Metcalfe“以太网之父”被Xerox雇佣为网络专家&#xff0c;Bob Metcalfe 来到Xerox公司的Palo Alto研究中心&#xff08;PARC&#xff09;的第一个任务是把Palo Alto的计算机连接到ARPANET&#xff08;Internet的前身&#xff09;上。1972年底Bob Metcalfe以ALOHA系统…

嵌入式开发笔记:STM32的外设GPIO知识学习

GPIO简介&#xff1a; • GPIO &#xff08; General Purpose Input Output &#xff09;通用输入输出口 • 可配置为 8 种输入输出模式 • 引脚电平&#xff1a; 0V~3.3V &#xff0c;部分引脚可容忍 5V &#xff08;如舵机和驱动直流电机&#xff09; • 输出模式下可控制端口…

机器学习 day35(决策树)

决策树 上图的数据集是一个特征值X采用分类值&#xff0c;即只取几个离散值&#xff0c;同时也是一个二元分类任务&#xff0c;即标签Y只有两个值 上图为之前数据集对应的决策树&#xff0c;最顶层的节点称为根节点&#xff0c;椭圆形节点称为决策节点&#xff0c;矩形节点称…

springboot整合返回数据统一封装

1、MagCode&#xff0c;错误码枚举类 package com.mgx.common.enums;import lombok.*; import lombok.extern.slf4j.Slf4j;/*** 错误码* author mgx*/ Slf4j NoArgsConstructor AllArgsConstructor public enum MsgCode {/*** 枚举标识&#xff0c;根据业务类型进行添加*/Code…

阻塞队列-生产者消费者模型

阻塞队列介绍标准库阻塞队列使用基于阻塞队列的简单生产者消费者模型。实现一个简单型阻塞队列 &#xff08;基于数组实现&#xff09; 阻塞队列介绍 不要和之前学多线程的就绪队列搞混&#xff1b; 阻塞队列&#xff1a;也是一个队列&#xff0c;先进先出。带有特殊的功能 &…

Learn Prompt-提供示例

目前我们与 ChatGPT 交流的主要形式是文字。提示除了指令问题的形式外&#xff0c;还可以包含例子。特别是当我们需要具体的输出时&#xff0c;提供例子可以省去我们对具体任务的解释&#xff0c;帮助ChatGPT更好地理解我们的确切需求&#xff0c;从而提供更准确&#xff0c;更…

【数据结构】哈希应用——位图、布隆过滤器

文章目录 一、位图1.基本概念2.基本实现3.基本应用3.1 找100亿个整数只出现一次的数3.2 两个文件分别有100亿整数&#xff0c;1G内存&#xff0c;求交集 二、布隆过滤器1、基本实现2、基本应用2.1过滤一部分的数据2.2 两个文件&#xff0c;分别100亿个查询&#xff0c;1G内存&a…

[Linux入门]---管理者操作系统

文章目录 1.操作系统概念2.设计操作系统的目的3.操作系统如何进行管理系统调用和库函数概念 1.操作系统概念 任何计算机系统都包含一个基本的程序集合&#xff0c;称为操作系统(OS)。笼统的理解&#xff0c;操作系统包括&#xff1a; 内核&#xff08;进程管理&#xff0c;内存…

C# OpenCvSharp Yolov8 Detect 目标检测

效果 项目 代码 using OpenCvSharp; using OpenCvSharp.Dnn; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;namespace Open…

索引(含B树、B+树)

1、索引&#xff08;index&#xff09; 索引是在数据库表的字段上添加的&#xff0c;是为了提高查询效率存在的一种机制。 一张表的一个字段可以添加一个索引&#xff0c;当然&#xff0c;多个字段联合起来也可以添加索引。 索引相当于一本书的目录&#xff0c;是为了缩小扫描…

Avl树(有详细图解)

目录 介绍 引入 概念 特点 模拟实现 思路 插入 旋转 左旋 无子树 有子树 右旋 无子树 有子树 左右旋 引入(也就是有子树版本的抽象图解) 解决方法(也就是左右旋) 总结 无子树(也就是curright的位置就是newnode) 有子树 模型高度解释 旋转 更新三个…

深度学习修炼(二)全连接神经网络 | Softmax,交叉熵损失函数 优化AdaGrad,RMSProp等 对抗过拟合 全攻略

文章目录 1 多层感知机&#xff08;全连接神经网络&#xff09;1.1 表示1.2 基本概念1.3 必要组成—激活函数1.4 网络结构设计 2 损失函数2.1 SOFTMAX操作2.2 交叉熵损失函数 3 优化3.1 求导计算过于复杂&#xff1f;3.2 链式法则导致的问题&#xff1f;3.3 梯度下降算法的改进…

八大排序(二)快速排序

一、快速排序的思想 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法&#xff0c;其基本思想为&#xff1a;任取待排序元素序列中的某元素作为基准值&#xff0c;按照该排序码将待排序集合分割成两子序列&#xff0c;左子序列中所有元素均小于基准值&#xff0c;右…

免费的AI写作软件-智能AI写作工具

我们要谈的话题是AI写作&#xff0c;尤其是免费AI写作&#xff0c;以及147SEOAI写作免费工具。您是否曾经为了创作文章而感到煞费苦心&#xff1f;是否一直在寻找一种能够轻松生成高质量文章的方法&#xff1f; 147GPT批量文章生成工具​www.147seo.com/post/2801.html​编辑ht…

Flink TaskManger 内存计算实战

Flink TaskManager内存计算图 计算实例 案例一、假设Task Process内存4GB。 taskmanager.memory.process.size4096m 先排减JVM内存。 JVM Metaspace 固定内存 256mJVM Overhead 固定比例 process * 0.1 4096 * 0.1 410m 得到 Total Flink Memory 4096-256-410 3430m 计…

求生之路2服务器搭建插件安装及详细的游戏参数配置教程windows

求生之路2服务器搭建插件安装及详细的游戏参数配置教程windows 大家好我是艾西&#xff0c;最近研究了下 l4d2&#xff08;求生之路2&#xff09;这款游戏的搭建以及架设过程。今天就给喜欢l4d2这款游戏的小伙伴们分享下怎么搭建架设一个自己的服务器。毕竟自己当服主是热爱游…