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

目录

前言        

一、盲拍合约是什么?

二、盲拍合约工作原理

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.mzph.cn/diannao/55855.shtml

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

相关文章

adum1201数字隔离器中文资料与应用

ADuM1201是ADI公司推出的一款数字隔离器&#xff0c;其典型应用有工业自动化、通讯电源管理、医疗设备以及汽车等领域。本文将对ADuM1201数字隔离器进行详细的介绍和应用分析&#xff0c;以帮助读者更好地了解和使用该产品。 一、ADuM1201数字隔离器概述 1、基本参数 ADuM120…

达梦DBLINK访问ORACLE配置方法

目录 1、概述 2、测试环境 3、语法简介 4、配置访问DM的DBLINK 5、配置访问ORACLE的DBLINK 5.1 通过OCI配置 5.2 通过ODBC配置 1、概述 本文介绍了达梦DBLINK的配置方法。有3部分内容&#xff0c;1&#xff09;达梦访问到达梦的配置方法&#xff1b;2&#xff09;通过OC…

LabVIEW程序怎么解决 Bug?

在LabVIEW开发过程中&#xff0c;发现和解决程序中的Bug是确保系统稳定运行的关键环节。由于LabVIEW采用图形化编程方式&#xff0c;Bug的排查和处理与传统编程语言略有不同。以下是解决LabVIEW程序中Bug的常见方法和技巧&#xff0c;涵盖从问题发现到解决的多个步骤和角度&…

php常用的注释符号

如果没有安装vscode和小皮&#xff0c;请点击下方链接安装&#xff1a; Vscode、小皮面板安装-CSDN博客 在学习php过程中&#xff0c;肯定少不了注释&#xff0c;也可以理解为备注的信息&#xff0c;来提醒自己这段代码有什么用&#xff0c;是什么意思等&#xff0c;接下来就介…

Android Studio Koala Feature Drop 稳定版现已推出

作者 / Android Studio 产品经理 Sandhya Mohan Android Studio Koala Feature Drop (2024.1.2) 现已推出&#xff01;&#x1f428; &#x1f517; Android Studio https://developer.android.google.cn/studio 今年早些时候&#xff0c;我们宣布每个 Android Studio 动物版本…

秋天来临,猫咪又到换毛季,掉毛严重怎么办?宠物空气净化器有用吗?

秋天到了&#xff0c;新一轮的宠物换毛季又来了。谁能想到这只胖猫和之前刚接回来时的皮包骨小猫是同一只&#xff01;除了养了一年长了些肉外&#xff0c;更多的都是换毛季掉毛”膨胀“的。每天下班回家都要搞卫生&#xff0c;家里衣服上、地板上&#xff0c;目光所及之处都有…

跟《经济学人》学英文:2024年10月05日这期 Workouts for the face are a growing business

Workouts for the face are a growing business They may not help much in the quest for eternal youth 原文&#xff1a; The FaceGym studio in central London looks more like a hair salon than a fitness studio. Customers recline on chairs while staff pummel t…

若依项目搭建(黑马经验)

欢迎你搜索和了解到若依&#xff0c;这个项目是从黑马课程的一个实践&#xff0c;更多的项目经历和平台搭建期待着我们的共同学习&#xff01; 关于若依 若依是一套全部开源的快速开发平台&#xff0c;毫无保留给个人及企业免费使用。 前端采用Vue、Element UI。后端采用Sprin…

技术分享 —— JMeter接口与性能测试实战!

前言 在软件开发和运维过程中&#xff0c;接口性能测试是一项至关重要的工作。JMeter作为一款开源的Java应用&#xff0c;被广泛用于进行各种性能测试&#xff0c;包括接口性能测试。本文将详细介绍如何使用JMeter进行接口性能测试的过程和步骤。 JMeter是Apache组织开发的基…

JavaGuide(3)

一、项目背景与简介 JavaGuide由GitHub用户Snailclimb开发并维护&#xff0c;是一个全面而深入的Java学习资源库。它旨在为Java初学者和有经验的开发者提供一个系统的学习路径和丰富的资源&#xff0c;帮助他们系统地学习和巩固Java及相关技术知识。 二、项目内容与特点 Jav…

Unity实现自定义图集(四)

以下内容是根据Unity 2020.1.0f1版本进行编写的   在之前的篇章中已经把自定义图集在编辑器上的使用,以及运行时所需的信息都准备好了,接下来就是魔改UGUI的Image组件,使其能够像Image那样运行时如果引用的资源有打自定义图集,则加载对应自定义图集的Texture。 1、思路 …

IDM6.42下载器最新版本,提速你的网络生活!

&#x1f680;【速度与激情&#xff0c;IDM 6.42来袭&#xff01;】&#x1f4a3; Hey, 亲爱的下载达人们&#xff01;&#x1f44b; 今天我要给你们安利一个神器——Internet Download Manager&#xff08;简称IDM&#xff09;&#xff0c;版本6.42&#xff0c;这可不是普通的…

DeepACO:用于组合优化的神经增强蚂蚁系统解决TSP问题的代码阅读

总体概括 DeepACO与普通ACO不同的是将问题输入实例输入到一个训练的网络中&#xff0c;将网络训练成为一个类似于专家知识的模块&#xff0c;可以生成相应的启发式矩阵网络&#xff0c;从而省去相应的专家知识。 其中在训练网络的代码中&#xff1a; 是进行监督式训练通过trai…

大模型基础:基本概念、Prompt、RAG、Agent及多模态

随着大模型的迅猛发展&#xff0c;LLM 作为人工智能的核心力量&#xff0c;正以前所未有的方式重塑着我们的生活、学习和工作。无论是智能语音助手、自动驾驶汽车&#xff0c;还是智能决策系统&#xff0c;大模型都是幕后英雄&#xff0c;让这些看似不可思议的事情变为可能。本…

java中的I/O(8个案例+代码+效果图)

目录 1.File类 1&#xff09;常用构造方法 1&#xff09;File(String pathname) 2&#xff09;File(String parent, String child) 3&#xff09;File(File parent, String child) 2&#xff09;常用方法 1&#xff09;boolean canRead() 2&#xff09;boolean canWrite() 3&am…

计算机网络——ftp

在网络通信中&#xff0c;控制连接和数据连接是两种不同类型的连接&#xff0c;它们各自具有特定的功能和用途。 一、控制连接 定义与功能&#xff1a; 控制连接主要用于在通信双方之间传输控制信息&#xff0c;以建立、维护和终止数据连接。它负责协调和管理数据传输的过程&am…

Leetcode - 周赛418

目录 一&#xff0c;3309. 连接二进制表示可形成的最大数值 二&#xff0c;3310. 移除可疑的方法 三&#xff0c;3311. 构造符合图结构的二维矩阵 四&#xff0c;3312. 查询排序后的最大公约数 一&#xff0c;3309. 连接二进制表示可形成的最大数值 本题数据范围较小&#…

chatGPT模型接口分享

前言: 仅供学习和交流&#xff0c;请合理使用。 API&#xff1a;https://api.gptnet.org key&#xff1a;sk-x9Rmq3HeHh5z9EIi8wFaXCl02OfxRSk5UAFodYm1o4zo5X3i 支持模型&#xff1a;gpt-3.5-turbo、gpt-3.5-turbo-16k、gpt-4o-mini、llama-3.1-405b 暂时支持以上四个模型…

Java基础-基础知识体系小结 Q/A

文章目录 知识体系Q&AJava 中应该使用什么数据类型来代表价格?怎么将 byte 转换为 String?Java 中怎样将 bytes 转换为 long 类型?存在两个类&#xff0c;B 继承 A&#xff0c;C 继承 B&#xff0c;我们能将 B 转换为 C 么? 如 C (C) B&#xff1b;Java 中 操作符是线…

Java初阶~~四种内部类总结

文章目录 1.内部类的分类2.局部内部类2.1.基本语法2.2就近原则的理解 3.匿名内部类3.1基于接口的匿名内部类3.2基于普通类的匿名内部类3.3基于抽象类的匿名内部类3.4匿名内部类的细节3.5匿名内部类实践3.5.1作为实参进行传递3.5.2实践案例 4.成员内部类4.1基本介绍4.2外部类&am…