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

news2024/11/22 22:24:30

目录

前言        

一、盲拍合约是什么?

二、盲拍合约工作原理

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)
        external
        payable
        onlyBefore(biddingEnd)
    {
        bids[msg.sender].push(Bid({
            blindedBid: blindedBid,
            deposit: msg.value
        }));
    }
    */

    function bid(uint value, bool fake, bytes32 secret)
        external
        payable
        onlyBefore(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
    )
        external
        onlyAfter(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) internal
            returns (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()
        external
        onlyAfter(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.coloradmin.cn/o/2188663.html

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

相关文章

02:(寄存器开发)流水灯/按键控制LED

寄存器开发 1、LED流水灯2、按键控制LED 1、LED流水灯 通过第一章的学习&#xff0c;我们已然知晓了LED的点亮和熄灭的方式&#xff0c;下面学习流水灯的制作流程。 流水灯呈现的样子&#xff1a;就是第一个LED灯点亮&#xff0c;延迟一段时间&#xff0c;第一个LED灯熄灭第二…

2020大厂web前端面试常见问题总结

本篇收录了一些面试中经常会遇到的经典面试题以及自己面试过程中遇到的一些问题。通过对本篇知识的整理以及经验的总结&#xff0c;希望能帮到更多的前端面试者。 1.web前端项目的结构是怎样的&#xff1f;文件有哪些命名规范&#xff1f; 项目结构规范 页面文件&#xff1a;以…

树莓派5:换源(针对Debian12)+安装包管理器Archiconda(图文教程+详细+对初学者超级友好)

目录 一、安装官方发行版系统&#xff08;Debian&#xff09;二、换源&#xff08;记得参考上述教程ssh连接到树莓派Terminal&#xff0c;or外接一块Hdmi显示屏&#xff09;2.1 查看自己安装的树莓派镜像架构2.2 查询自己的系统版本2.3 打开清华大学开源软件镜像站网站2.3.1 传…

浅析Golang的Context

文章目录 1. 简介2. 常见用法2.1 控制goroutine的生命周期&#xff08;cancel&#xff09;2.2 传递超时&#xff08;Timeout&#xff09;信息2.3 传递截止时间&#xff08;Deadline&#xff09;2.4 传递请求范围内的全局数据 &#xff08;value&#xff09; 3 特点3.1 上下文的…

FWA(固定无线接入),CPE(客户终端设备)简介

文章目录 FWA&#xff08;Fixed Wireless Access&#xff09;&#xff0c;固定无线接入CPE&#xff08;Customer Premise Equipment&#xff09;&#xff0c;用户驻地设备 FWA&#xff08;Fixed Wireless Access&#xff09;&#xff0c;固定无线接入 固定无线接入&#xff08…

Geogebra009—构建正六边形

继续巩固一下基础&#xff0c;本篇我们来做一个正六边形 目录 一、成品展示二、涉及内容三、做图步骤1. 绘制一个以A点为圆心过B点的圆circle1&#xff1b;2. 以B点为圆心过A点绘制另外一个圆circle2&#xff1b;3. 绘制两个圆的交点&#xff0c;得到顶点C和D&#xff1b;4. 以…

Leetcode: 0001-0010题速览

Leetcode: 0001-0010题速览 本文材料来自于LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer&#xff08;第 2 版&#xff09;》、《程序员面试金典&#xff08;第 6 版&#xff09;》题解 遵从开源协议为知识共享 版权归属-相同方式…

奔驰GLS450升级原厂电吸门效果怎么样

奔驰GLS450升级原厂电吸门后&#xff0c;能带来以下效果&#xff1a; • 关门更优雅&#xff1a;只需轻轻推车门到基本关闭的位置&#xff0c;当车门距离车门锁大约6毫米时&#xff0c;传感器便会启动电动马达将车门安静地拉入&#xff0c;然后固定住&#xff0c;告别传统关门…

HTML+CSS基础用法介绍五

目录&#xff1a; 结构伪类选择器盒子模型-边框线盒子模型-内边距盒子模型-解决盒子被撑大盒子模型-外边距与版心居中小知识&#xff1a;清除浏览器中所有标签的默认样式内容溢出控制显示方式盒子模型-圆角 &#x1f40e;正片开始 结构伪类选择器 什么是结构伪类选择器&…

18.安卓逆向-frida基础-调试实战2

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;图灵Python学院 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要盲目相信。 工…

Windows UAC权限详解以及因为权限不对等引发软件工具无法正常使用的实例分析

目录 ​1、什么是UAC&#xff1f; 2、微软为什么要设计UAC&#xff1f; 3、标准用户权限与管理员权限 4、程序到底以哪种权限运行&#xff1f;与哪些因素有关&#xff1f; 4.1、给程序设置以管理员权限运行的属性 4.2、当前登录用户的类型 4.3、如何通过代码判断某个进程…

智能 AI 写作软件:开启创作新纪元

不论你在哪行哪业应该都躲不开写作这件事被。写作已经成为了我们生活和工作中不可或缺的一部分。随着人工智能技术的飞速发展&#xff0c;AI 智能写作工具应运而生。接下来&#xff0c;让我们一起揭开智能ai写作工具的神秘面纱。 1.笔灵AI写作 直通车&#xff1a;https://ibi…

②EtherCAT转ModbusTCP, EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关

EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关https://item.taobao.com/item.htm?ftt&id822721028899 协议转换通信网关 EtherCAT 转 Modbus TCP (接上一章&#xff09; GW系列型号 配置说明 上载 网线连接电脑到模块上的 WEB 网页设置网口&#…

论文笔记:Online Class-Incremental Continual Learning with Adversarial Shapley Value

这篇工作的focus 是 memory-based approach 1. 挑战/问题&#xff1a; 灾难性遗忘&#xff1a;深度神经网络在学习新任务时往往会忘记先前任务的知识。内存和计算效率&#xff1a;在个人设备上执行深度学习任务时&#xff0c;需要最小化内存占用和计算成本。数据流增量学习&am…

系统安全 - 大数据组件的安全及防护

文章目录 导图1. Hadoop的安全风险2. 常见攻击方式3. Hadoop的自带安全功能4. Apache Knox和Apache Ranger等安全框架5. 安全策略建议 导图 1. Hadoop的安全风险 Hadoop最初设计为在可信网络中运行&#xff0c;因此默认安全性较低。常见的安全风险包括&#xff1a; 未经授权的…

探索未来:揭秘pymqtt,AI与物联网的新桥梁

文章目录 探索未来&#xff1a;揭秘pymqtt&#xff0c;AI与物联网的新桥梁背景&#xff1a;为什么选择pymqtt&#xff1f;什么是pymqtt&#xff1f;如何安装pymqtt&#xff1f;简单的库函数使用方法1. 配置MQTT连接2. 创建Mqtt对象3. 发布消息4. 订阅主题5. 运行MQTT客户端 场景…

Java项目实战II基于Java+Spring Boot+MySQL的小徐影城管理系统设计与实现(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者 一、前言 随着文化娱乐产业的快速发展&#xff0c;影城管理面临着日益复杂的挑战&#xff0c;包括票务管理、座…

Redis操作常用API

说明&#xff1a;Redis应用于java项目中&#xff0c;操作Redis数据可以使用API&#xff0c;相较于命令行更方便。使用前&#xff0c;需先添加依赖。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-re…

HIKVISION 海康威视对讲服务配置平台弱口令

漏洞描述 杭州海康威视系统技术有限公司对讲服务配置平台存在弱口令 漏洞复现 FOFA "document.write(TITLE_SYSTEM);" POC admin #账号 12345 #密码 登录成功

利用Spring Boot打造新闻推荐解决方案

1系统概述 1.1 研究背景 如今互联网高速发展&#xff0c;网络遍布全球&#xff0c;通过互联网发布的消息能快而方便的传播到世界每个角落&#xff0c;并且互联网上能传播的信息也很广&#xff0c;比如文字、图片、声音、视频等。从而&#xff0c;这种种好处使得互联网成了信息传…