盲拍合约:让竞拍更公平与神秘的创新解决方案

目录

前言        

一、盲拍合约是什么?

二、盲拍合约工作原理

1、合约创建与初始化

2、用户出价(Bid)

3、出价结束

4、披露出价(Reveal)

5、处理最高出价

6、结束拍卖

7、退款与提款

三、解析盲拍合约代码

1、数据结构

2、合约状态变量

3、事件

4、 错误处理

5、 修饰符

6、构造函数​编辑

7、出价功能

8、 披露出价

9、 处理最高出价

10、 提款功能

11、结束拍卖

四、盲拍合约用途

五、完整代码示例

总结


前言        

        盲拍合约是一种创新的拍卖机制,旨在通过保护买家的隐私和增强出价的公平性来提高交易效率。在这种合约中,参与者在未透露具体出价的情况下,基于对商品的描述或估值进行匿名竞标。盲拍合约不仅适用于艺术品和收藏品的拍卖,还能广泛应用于房地产、商品销售等多个领域,从而确保每位参与者都有平等的机会,降低了价格操纵的风险。

可访问文档:https://learnblockchain.cn/docs/solidity/0.5.9/examples/blind-auction.html#simple-auction

一、盲拍合约是什么?

        盲拍合约是一种在拍卖或交易中使用的合同形式,特别是在拍卖艺术品、收藏品或其他资产时,买家在未实际查看商品的情况下提交竞标或购买意向。这种合约的特点在于,买家对拍卖品的具体情况(如质量、状态等)没有事先了解,而是基于对商品的描述或估值来做出购买决定。

二、盲拍合约工作原理

1、合约创建与初始化

合约部署: 创建盲拍合约时,设置拍卖的受益人地址出价时间披露时间。这些参数定义了拍卖的基本规则。

2、用户出价(Bid)

匿名出价: 用户通过调用 bid 函数提交出价。用户提供三个参数:出价金额(value真假标记(fake秘密(secret

加密出价: 合约使用 keccak256 哈希函数计算出一个加密出价(blindedBid),该出价结合了用户的真实出价和其他参数。这确保了在拍卖期间用户的出价保持匿名

存储出价: 合约将加密出价和用户存款存储在 bids 映射中。

3、出价结束

结束出价: 在设置的出价时间结束后,用户无法再提交新的出价。这是通过 onlyBefore 修饰符控制的。

4、披露出价(Reveal)

出价披露: 在出价结束后,用户可以调用 reveal 函数,提交真实的出价信息,包括真实值、真假标记和秘密

验证出价: 合约验证用户披露的出价是否与之前提交的加密出价匹配。如果匹配且不是假出价,合约会更新最高出价并可能会退款。

退款机制: 对于不符合条件的出价,合约会保留存款。用户可以在出价被超越后提取退款。

5、处理最高出价

更新最高出价: 当用户披露有效的真实出价时,合约会检查是否高于当前最高出价。如果是,合约会更新最高出价和最高出价者的地址,并将之前的最高出价退还给原持有者。

6、结束拍卖

拍卖结束: 在披露时间结束后,合约通过 auctionEnd 函数结束拍卖。合约会将最高出价发送给受益人,并触发相应的事件记录结果。

7、退款与提款

提款功能: 用户可以通过调用 withdraw 函数提取未使用的存款,确保合约能够安全处理资金。

三、解析盲拍合约代码

1、数据结构

  • Bid: 定义了一个结构体,包含两个字段:
  • blindedBid: 存储用户加密的出价(bytes32 类型)。
  • deposit: 用户为出价提供的存款(uint 类型)。

2、合约状态变量

  • beneficiary: 合约的受益人地址,拍卖结束后,最高出价将转移到该地址。
  • biddingEnd: 表示出价结束的时间戳。
  • revealEnd: 表示出价披露结束的时间戳。
  • ended: 布尔值,指示拍卖是否已结束。
  • bids: 映射,每个用户地址对应一个出价数组,存储用户的所有出价。
  • highestBidder: 当前最高出价的用户地址。
  • highestBid: 当前最高出价的金额。
  • pendingReturns: 映射,存储待退还的金额。


3、事件

  • AuctionEnded: 当拍卖结束时触发的事件,记录赢家和最高出价。

4、 错误处理

定义了一些错误,描述可能的失败情况:

  • TooEarly: 调用函数过早。

  • TooLate: 调用函数过晚。

  • AuctionEndAlreadyCalled: 拍卖结束函数已被调用。

5、 修饰符

  • onlyBefore(uint time): 用于限制函数只能在指定时间之前调用。

  • onlyAfter(uint time): 用于限制函数只能在指定时间之后调用。


6、构造函数

  • constructor: 在合约部署时被调用,初始化受益人地址和拍卖的时间限制。

7、出价功能

bid(uint value, bool fake, bytes32 secret):

  • 用户通过此函数提交出价。出价通过 keccak256 生成加密值(blindedBid),将其与存款一起存储。

  • fake 参数用于指示出价是否为假,允许用户隐藏真实出价。


8、 披露出价

reveal(...):

  • 用户在出价披露阶段调用该函数,提交之前的出价信息(真实值、真假标记和秘密)。

  • 检查提交的出价是否与之前的加密出价匹配。如果匹配且不是假出价,可能会更新最高出价并退款。

  • 未能正确披露的出价将不会退还存款。


9、 处理最高出价

placeBid(address bidder, uint value):

  • 内部函数,用于检查新出价是否高于当前最高出价。

  • 如果新出价更高,更新最高出价并处理之前的最高出价的退款。


10、 提款功能

withdraw():

  • 允许用户提取之前被超越的出价。

  • 在提款前,将待退还金额设为零,以防止重入攻击。


11、结束拍卖

auctionEnd():

  • 在出价披露结束后调用,结束拍卖并将最高出价发送给受益人。

  • 触发 AuctionEnded 事件,记录赢家和最高出价。

四、盲拍合约用途

盲拍合约的用途广泛,主要适用于需要公平竞争和保护隐私的场景。以下是一些具体的应用领域:

  1. 艺术品拍卖: 在艺术品市场中,盲拍合约可以确保买家在出价时不受到其他买家影响,从而更真实地反映出对艺术品的价值评估。

  2. 房地产拍卖: 房地产拍卖中,买家可以在不透露出价的情况下参与竞标,避免价格上涨的心理战,促使更公平的交易。

  3. 商品销售: 在线市场和电商平台可以使用盲拍机制来售卖稀缺商品,确保所有参与者都有平等机会获取商品。

  4. 融资和投资: 在众筹或投资项目中,盲拍合约可以用来收集投资者的出价,确保所有出价在披露前保持匿名,促进公平竞争。

  5. 资源分配: 在需要分配有限资源的情况下(如频谱拍卖),盲拍合约能够确保各方以匿名方式出价,最大化资源的有效利用。

  6. 游戏和竞赛: 在游戏或竞赛中,盲拍合约可以用于奖励机制,确保参赛者在竞标奖励时不会受到其他参赛者的影响。

  7. 政府拍卖: 政府在拍卖公共资产(如土地、许可证)时,可以使用盲拍合约来确保出价过程的公正性和透明度。

        通过在这些场景中使用盲拍合约,可以提高交易的公平性、透明度和效率,同时保护参与者的隐私,减少潜在的欺诈行为。

五、完整代码示例

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.2;contract BlindAuction {struct Bid {bytes32 blindedBid;uint deposit;}address payable public beneficiary;uint public biddingEnd;uint public revealEnd;bool public ended;mapping(address => Bid[]) public bids;address public highestBidder;uint public highestBid;// 可以取回的之前的出价mapping(address => uint) public pendingReturns;event AuctionEnded(address winner, uint highestBid);// Errors that describe failures./// The function has been called too early./// Try again at `time`.error TooEarly(uint time);/// The function has been called too late./// It cannot be called after `time`.error TooLate(uint time);/// The function auctionEnd has already been called.error AuctionEndAlreadyCalled();/// 使用 modifier 可以更便捷的校验函数的入参。/// `onlyBefore` 会被用于后面的 `bid` 函数:/// 新的函数体是由 modifier 本身的函数体,并用原函数体替换 `_;` 语句来组成的。modifier onlyBefore(uint time) {if (block.timestamp >= time) revert TooLate(time);_;}modifier onlyAfter(uint time) {if (block.timestamp <= time) revert TooEarly(time);_;}constructor(uint biddingTime,uint revealTime,address payable beneficiaryAddress) {beneficiary = beneficiaryAddress;biddingEnd = block.timestamp + biddingTime;revealEnd = biddingEnd + revealTime;}// blindedBid1=..keccak256(abi.encodePacked(2, true, bytes32("sdfadf")));/// 可以通过 `blindedBid` = keccak256(value, fake, secret)/// 设置一个秘密竞拍。/// 只有在出价披露阶段被正确披露,已发送的以太币才会被退还。/// 如果与出价一起发送的以太币至少为 “value” 且 “fake” 不为真,则出价有效。/// 将 “fake” 设置为 true ,然后发送满足订金金额但又不与出价相同的金额是隐藏实际出价的方法。/// 同一个地址可以放置多个出价。/*function bid(bytes32 blindedBid)externalpayableonlyBefore(biddingEnd){bids[msg.sender].push(Bid({blindedBid: blindedBid,deposit: msg.value}));}*/function bid(uint value, bool fake, bytes32 secret)externalpayableonlyBefore(biddingEnd){// 计算 blindedBid 内部使用,仅供存储或其他用途bytes32 blindedBid = keccak256(abi.encodePacked(value, fake, secret));bids[msg.sender].push(Bid({blindedBid: blindedBid,deposit: msg.value}));}/// 披露你的秘密竞拍出价。/// 对于所有正确披露的无效出价以及除最高出价以外的所有出价,你都将获得退款。function reveal(uint[] calldata values,bool[] calldata fakeFlags,bytes32[] calldata secrets)externalonlyAfter(biddingEnd)onlyBefore(revealEnd){uint length = bids[msg.sender].length;require(values.length == length, "Mismatched values length");require(fakeFlags.length == length, "Mismatched fake flags length");require(secrets.length == length, "Mismatched secrets 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], fakeFlags[i], secrets[i]);// 使用 abi.encodePacked 将多个参数打包成一个 bytes 类型if (bid.blindedBid != keccak256(abi.encodePacked(value, fake, secret))) {// 出价未能正确披露// 不返还订金// console.log("披露失败!");continue;}refund += bid.deposit;if (!fake && bid.deposit >= value) {if (placeBid(msg.sender, value))refund -= value;}// 使发送者不可能再次认领同一笔订金bid.blindedBid = bytes32(0);}// 使用 call 代替 transfer,推荐在 Solidity 0.8.x 版本中使用(bool success, ) = msg.sender.call{value: refund}("");require(success, "Refund failed");}// 这是一个 "internal" 函数, 意味着它只能在本合约(或继承合约)内被调用function placeBid(address bidder, uint value) internalreturns (bool success){if (value <= highestBid) {return false;}if (highestBidder != address(0)) {// 返还之前的最高出价pendingReturns[highestBidder] += highestBid;}highestBid = value;highestBidder = bidder;return true;}/// 取回出价(当该出价已被超越)function withdraw() external {uint amount = pendingReturns[msg.sender];if (amount > 0) {// 这里很重要,首先要设零值。// 因为,作为接收调用的一部分,// 接收者可以在 `call` 返回之前重新调用该函数。(可查看上面关于‘条件 -> 影响 -> 交互’的标注)pendingReturns[msg.sender] = 0;// 使用 call 代替 transfer,推荐在 Solidity 0.8.x 版本中使用(bool success, ) = msg.sender.call{value: amount}("");require(success, "Withdrawal failed");}}/// 结束拍卖,并把最高的出价发送给受益人function auctionEnd()externalonlyAfter(revealEnd){if (ended) revert AuctionEndAlreadyCalled();emit AuctionEnded(highestBidder, highestBid);ended = true;// 使用 call 代替 transfer,推荐在 Solidity 0.8.x 版本中使用(bool success, ) = beneficiary.call{value: highestBid}("");require(success, "Transfer to beneficiary failed");}
}

总结

        盲拍合约通过其独特的机制,实现了透明与隐私的平衡,推动了更公平的市场环境。合约的设计允许参与者在不泄露个人信息的情况下进行出价,有效防止了心理战和价格操控。在现代数字经济中,盲拍合约的应用潜力巨大,为各种交易场景提供了新方式,有助于提高交易的信任度和效率,促进了公平竞争。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里云域名解析和备案

文章目录 1、域名解析2、新手引导3、ICP备案 1、域名解析 2、新手引导 3、ICP备案

类的特殊成员函数——三之法则、五之法则、零之法则

系统中的动态资源、文件句柄&#xff08;socket描述符、文件描述符&#xff09;是有限的&#xff0c;在类中若涉及对此类资源的操作&#xff0c;但是未做到妥善的管理&#xff0c;常会造成资源泄露问题&#xff0c;严重的可能造成资源不可用&#xff0c;如申请内存失败、文件句…

【redis-05】redis保证和mysql数据一致性

redis系列整体栏目 内容链接地址【一】redis基本数据类型和使用场景https://zhenghuisheng.blog.csdn.net/article/details/142406325【二】redis的持久化机制和原理https://zhenghuisheng.blog.csdn.net/article/details/142441756【三】redis缓存穿透、缓存击穿、缓存雪崩htt…

57.对称二叉树

迭代 class Solution {public boolean isSymmetric(TreeNode root) {if(rootnull){return true;}Deque<TreeNode> denew LinkedList<>();TreeNode l,r;int le;de.offer(root.left);de.offer(root.right);while(!de.isEmpty()){lde.pollFirst();rde.pollLast();if(…

BMC pam认证的使用

1.说明 1.1 文档参考资料 https://www.chiark.greenend.org.uk/doc/libpam-doc/html/Linux-PAM_ADG.htmlhttp://www.fifi.org/doc/libpam-doc/html/pam_appl-3.htmlpdf文档: https://fossies.org/linux/Linux-PAM-docs/doc/adg/Linux-PAM_ADG.pdflinux-pam 中文文档pam 旧文p…

<数据集>工程机械识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;2644张 标注数量(xml文件个数)&#xff1a;2644 标注数量(txt文件个数)&#xff1a;2644 标注类别数&#xff1a;3 标注类别名称&#xff1a;[dump truck, wheel loader, excavators] 序号类别名称图片数框数1dum…

SpringBootWeb快速入门!详解如何创建一个简单的SpringBoot项目?

在现代Web开发中&#xff0c;SpringBoot以其简化的配置和快速的开发效率而受到广大开发者的青睐。本篇文章将带领你从零开始&#xff0c;搭建一个基于SpringBoot的简单Web应用~ 一、前提准备 想要创建一个SpringBoot项目&#xff0c;需要做如下准备&#xff1a; idea集成开发…

wordpress Contact form 7发件人邮箱设置

此教程仅适用于演示站有留言的主题&#xff0c;演示站没有留言的主题&#xff0c;就别往下看了&#xff0c;免费浪费时间。 使用了Contact form 7插件的简站WordPress主题&#xff0c;在有人留言时&#xff0c;就会发邮件到网站的系统邮箱(一般与管理员邮箱为同一个)里。上面显…

SpringCloud简介 Ribbon Eureka 远程调用RestTemplate类 openfeign

〇、SpringCloud 0.区别于单体项目和soa架构&#xff0c;微服务架构每个服务独立&#xff0c;灵活。 1. spring cloud是一个完整的微服务框架&#xff0c;springCloud包括三个体系&#xff1a; spring cloud Netflix spring cloud Alibaba spring 其他 2.spring cloud 版本命名…

论文阅读笔记-LogME: Practical Assessment of Pre-trained Models for Transfer Learning

前言 在NLP领域,预训练模型(准确的说应该是预训练语言模型)似乎已经成为各大任务必备的模块了,经常有看到文章称后BERT时代或后XXX时代,分析对比了许多主流模型的优缺点,这些相对而言有些停留在理论层面,可是有时候对于手上正在解决的任务,要用到预训练语言模型时,面…

软件设计师(软考学习)

数据库技术 数据库基础知识 1. 数据库中的简单属性、多值属性、复合属性、派生属性简单属性&#xff1a;指不能够再分解成更小部分的属性&#xff0c;通常是数据表中的一个列。例如学生表中的“学号”、“姓名”等均为简单属性。 多值属性&#xff1a;指一个属性可以有多个值…

sql-labs:42~65

less42&#xff08;单引号闭合、报错回显&#xff09; login_useradmin login_password123 and if(11,sleep(2),1) # # 单引号闭合 ​ login_useradmin login_password123and updatexml(1,concat(0x7e,database(),0x7e),1)# # 报错回显…

mysql UDF提权(实战案例)

作者&#xff1a;程序那点事儿 日期&#xff1a;2024/09/29 16:10 什么是UDF? 全称 User Define Function &#xff08;用户自定义函数&#xff09;UDF提权&#xff0c;就是通过自定义函数&#xff0c;实现执行系统的命令。 dll&#xff08;windows&#xff0c;dll文件是c语…

5.人员管理模块(以及解决运行Bug)——帝可得管理系统

目录 前言一、页面修改表单展示修改 二、新增对话框修改三、修改对话框修改修改时展示创建时间 四、解决页面展示错误五 、 解决【java.lang.NullPointerException: null】 Bug 前言 提示&#xff1a;本篇完成人员管理模块的开发&#xff0c;具体需求、修改代码的路径和最终效…

车辆种类分类识别数据集,可以识别7种汽车类型,已经按照7:2:1比 例划分数据集,训练集1488张、验证集507张,测试集31张, 共计2026张。

车 车辆种类分类识别数据集&#xff0c;可以识别7种汽车类型&#xff0c;已经按照7:2:1比 例划分数据集&#xff0c;训练集1488张、验证集507张,测试集31张&#xff0c; 共计2026张。 数据集分为一类客车(tinycar) &#xff0c;类客车(midcar) &#xff0c;三类 客车(bigcar) ,…

重学SpringBoot3-集成Redis(六)之消息队列

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-集成Redis&#xff08;六&#xff09;之消息队列 1. 什么是发布/订阅&#xff08;Pub/Sub&#xff09;&#xff1f;2. 场景应用3. Spring Boot 3 整合 R…

感知机学习算法

感知机 一、感知机简介二、感知机模型2.1 感知机的基本组成2.2 求和函数2.2.1 时间总合2.2.2 空间总合 2.3 激活函数2.4 学习算法2.4.1 赫布学习规则2.4.2 Delta学习规则 三、 结论参考文献 一、感知机简介 M-P神经元模型因其对生物神经元激发过程的极大简化而成为神经网络研究…

微信小程序学习实录10:轻松获取用户昵称、头像与登录openid实战攻略

在微信小程序开发中&#xff0c;获取用户的个人信息&#xff08;如昵称和头像&#xff09;以及用户的唯一标识OpenID是非常常见的需求。本文将详细介绍如何通过微信提供的API来实现这些功能&#xff0c;并提供一个完整的实战案例。 用户选择头像 微信提供了chooseAvatar组件&…

ROS基础入门——实操教程

ROS基础入门——实操教程 前言 本教程实操为主&#xff0c;少说书。可供参考的文档中详细的记录了ROS的实操和理论&#xff0c;只是过于详细繁杂了&#xff0c;看得脑壳疼&#xff0c;于是做了这个笔记。 Ruby Rose&#xff0c;放在这里相当合理 本文初编辑于2024年10月4日 C…

使用vscode调试wails项目(golang桌面GUI)

文章目录 安装 Golang 环境安装 NPM安装 VSCode安装 Go 插件安装 Go 插件依赖工具安装 Wails系统检查 准备项目Visual Studio Code 配置安装和构建步骤参考资料 安装 Golang 环境 访问 golang 官网下载环境安装包&#xff1a;https://go.dev/dl/ 安装 NPM 从 Node 下载页面 …