从密码学看盲拍合约:智能合约的隐私与安全新革命!

文章目录

  • 前言
  • 一、什么是盲拍合约?
  • 二、盲拍合约的优势
    • 1.时间压力的缓解
    • 2.绑定与秘密的挑战
  • 三、盲拍合约的工作原理
    • 1.提交盲出价
    • 2.披露出价
    • 3.结束拍卖
    • 4.退款机制
  • 四、代码示例
  • 总结


前言

随着区块链技术的发展,智能合约在各种场景中的应用越来越广泛。盲拍合约作为一种新兴的智能合约形式,利用密码学原理为参与者提供了隐私保护和安全保障。这种合约不仅增强了竞拍的公平性,还消除了时间压力,让参与者能够在更为放松的环境中进行投标。本文将深入探讨盲拍合约的定义、优势、工作原理以及代码实现,旨在为读者提供一个全面的理解。

在这里插入图片描述


一、什么是盲拍合约?

盲拍合约是一种智能合约,允许参与者在不公开其出价的情况下进行竞拍。参与者提交一个“盲出价”,其中包含出价金额、一个虚假的标记以及一个秘密值。只有在竞拍结束时,参与者才能披露这些信息,从而验证他们的出价。

二、盲拍合约的优势

盲拍合约的好处在于,参与者在投标结束前不会感受到时间压力。在透明的计算平台上进行秘密竞拍听起来似乎矛盾,但密码学的应用使这一切成为可能。

1.时间压力的缓解

在投标期间,投标人实际上并没有发送真实出价,而只是发送出价的哈希版本。由于几乎不可能找到两个(足够长的)值,其哈希值相等,投标人可以通过这种方式提交出价。投标结束后,投标人必须公开他们的出价,合约会检查披露的出价是否与之前提交的哈希值相同。

2.绑定与秘密的挑战

另一个挑战是如何使拍卖同时做到绑定与秘密。唯一能阻止投标者在赢得拍卖后不付款的方式是让她将钱连同出价一起发送。但由于以太坊中资金转移不可隐藏,任何人都可以看到转移的资金。

合约通过接受任何大于当前最高出价的值来解决这个问题。虽然在披露阶段才进行检查,有些出价可能是无效的,但这也是故意的。投标人可以通过设置几个高或低的无效出价来迷惑竞争对手。

三、盲拍合约的工作原理

1.提交盲出价

参与者通过 bid 函数提交盲出价,计算方式为:
在这里插入图片描述

在这里,value 是实际出价金额,fake 是一个布尔值,用于隐藏真实出价,secret 是一个32字节的秘密字符串,用于防止加密前过于简单而导致容易暴力破解的情况。此计算使得盲出价在未披露前无法被识别

2.披露出价

在竞拍结束后,参与者使用 reveal 函数披露出价。只有正确披露的出价会被验证:
在这里插入图片描述
如果出价有效且未标记为假,合约会将其视为有效出价并处理

3.结束拍卖

在竞拍结束后,auctionEnd 函数将确定最高出价并将其转移给部署合约时设置的三个参数受益人:
在这里插入图片描述

4.退款机制

对于无效出价或低于最高出价的出价,合约会将存入的保证金退还给参与者。这通过 pendingReturns 映射来实现
在这里插入图片描述

四、代码示例

以下是完整的盲拍合约代码:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;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);// 定义错误error TooEarly(uint currentTime, uint endTime);error TooLate(uint currentTime, uint endTime);error AuctionAlreadyEnded();/// 使用 modifier 可以更便捷的校验函数的入参。/// `onlyBefore` 会被用于后面的 `bid` 函数:/// 新的函数体是由 modifier 本身的函数体,并用原函数体替换 `_;` 语句来组成的。// modifier onlyBefore(uint _time) { require(block.timestamp < _time); _; }// modifier onlyAfter(uint _time) { require(block.timestamp > _time); _; }modifier onlyBefore(uint _time) {if (block.timestamp >= _time) revert TooLate(block.timestamp, _time);_;}modifier onlyAfter(uint _time) {if (block.timestamp <= _time) revert TooEarly(block.timestamp, _time);_;}constructor(uint _biddingTime,uint _revealTime,address payable _beneficiary) {beneficiary = _beneficiary;biddingEnd = block.timestamp + _biddingTime;revealEnd = biddingEnd + _revealTime;}/// 可以通过 `_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)externalpayableonlyBefore(biddingEnd){// 计算 blindedBid 内部使用,仅供存储或其他用途bytes32 blindedBid = keccak256(abi.encodePacked(value, fake, secret));bids[msg.sender].push(Bid({blindedBid: blindedBid,deposit: msg.value}));}/// 披露你的秘密竞拍出价。/// 对于所有正确披露的无效出价以及除最高出价以外的所有出价,你都将获得退款。function reveal(uint[] memory _values,bool[] memory _fake,bytes32[] memory _secret)externalpayableonlyAfter(biddingEnd)onlyBefore(revealEnd){uint length = bids[msg.sender].length;require(_values.length == length, "Mismatched values length");require(_fake.length == length, "Mismatched fake flags length");require(_secret.length == length, "Mismatched secrets length");uint refund;for (uint i = 0; i < length; i++) {Bid storage bidInfo = bids[msg.sender][i];(uint value, bool fake, bytes32 secret) =(_values[i], _fake[i], _secret[i]);if (bidInfo.blindedBid != keccak256(abi.encodePacked(value, fake, secret))) {// 出价未能正确披露// 不返还订金continue;}refund += bidInfo.deposit;if (!fake && bidInfo.deposit >= value) {if (placeBid(msg.sender, value))refund -= value;}// 使发送者不可能再次认领同一笔订金bidInfo.blindedBid = bytes32(0);}// Cast msg.sender to address payableaddress payable sender = payable(msg.sender);sender.transfer(refund);}// 这是一个 "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() public payable {uint amount = pendingReturns[msg.sender];if (amount > 0) {// 这里很重要,首先要设零值。// 因为,作为接收调用的一部分,// 接收者可以在 `transfer` 返回之前重新调用该函数。(可查看上面关于‘条件 -> 影响 -> 交互’的标注)pendingReturns[msg.sender] = 0;// Cast msg.sender to address payableaddress payable sender = payable(msg.sender);sender.transfer(amount);}}/// 结束拍卖,并把最高的出价发送给受益人function auctionEnd()publicpayableonlyAfter(revealEnd){// require(!ended);if (ended) revert AuctionAlreadyEnded();emit AuctionEnded(highestBidder, highestBid);ended = true;beneficiary.transfer(highestBid);}
}

总结

通过本文,我们详细介绍了盲拍合约的定义、优势、工作原理及其代码实现。盲拍合约利用密码学原理为参与者提供隐私保护,减轻时间压力,并确保出价的绑定与秘密。我们讲解了参与者如何提交盲出价、披露出价、结束拍卖及退款机制。希望这篇文章能帮助你深入理解盲拍合约及其在区块链中的应用。如果你有任何疑问或建议,欢迎在评论区留言讨论🌹

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

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

相关文章

芝法酱学习笔记(0.5)——使用jenkins做自动打包

前言 上节讲了SpringBoot上的打包。但这些过程都是手动的&#xff0c;在实际的开发测试时&#xff0c;自动化的打包部署&#xff0c;可以大大提升团队开发的效率 一、去官网下载 1.1 官网安装命令 对于如何安装的问题&#xff0c;我向来推荐官网 wget -O /usr/share/keyri…

针对考研的C语言学习(定制化快速掌握重点2)

1.C语言中字符与字符串的比较方法 在C语言中&#xff0c;单字符可以用进行比较也可以用 > , < ,但是字符串却不能用直接比较&#xff0c;需要用strcmp函数。 strcmp 函数的原型定义在 <string.h> 头文件中&#xff0c;其定义如下&#xff1a; int strcmp(const …

ubuntu server 常用配置

这里写目录标题 0001 虚拟机静态IP0002 vim tab 4个空格0003 设置时区0004 网络端口查看端口开放端口 0005 修噶机主机名 0001 虚拟机静态IP win网络链接&#xff0c;IP地址&#xff1a;192.168.220.1 - NAT网关&#xff1a;192.168.220.2 - ubuntu静态IP设置&#xff1a; ca…

前端——Ajax和jQuery

一、Ajax Ajax即“Asynchronous Javascript And XML”&#xff08;异步 JavaScript 和 XML&#xff09;&#xff0c; 通过 JS 异步的向服务器发送请 求并接收响应数据。 同步访问&#xff1a;当客户端向服务器发送请求时&#xff0c;服务器在处理的过程中&#xff0c;浏览器…

【韩顺平Java笔记】第5章:程序控制结构

文章目录 102. 回顾上一章节103. 顺序控制103.1 顺序控制 104. 单分支使用104.1 分支控制 if-else 介绍104.2 单分支 105. 单分支流程图106. 双分支使用107. 双分支流程图108. 双分支练习题109. 多分支使用109.1 多分支的流程图 110. 多分支练习1111. 多分支练习2112. 嵌套分支…

最大正方形 Python题解

最大正方形 题目描述 在一个 n m n\times m nm 的只包含 0 0 0 和 1 1 1 的矩阵里找出一个不包含 0 0 0 的最大正方形&#xff0c;输出边长。 输入格式 输入文件第一行为两个整数 n , m ( 1 ≤ n , m ≤ 100 ) n,m(1\leq n,m\leq 100) n,m(1≤n,m≤100)&#xff0c;接…

ubuntu 开启root

sudo passwd root#输入以下命令来给root账户设置密码 sudo passwd -u root#启用root账户 su - root#要登录root账户 root 开启远程访问&#xff1a; 小心不要改到这里了&#xff1a;sudo nano /etc/ssh/ssh_config 而是&#xff1a;/etc/ssh/sshd_config sudo nano /etc/ssh…

828华为云征文|部署去中心化网络的 AI 照片管理应用 PhotoPrism

828华为云征文&#xff5c;部署去中心化网络的 AI 照片管理应用 PhotoPrism 一、Flexus云服务器X实例介绍二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置2.4 Docker 环境搭建 三、Flexus云服务器X实例部署 PhotoPrism3.1 PhotoPrism 介绍3.2 PhotoPrism…

【Redis】如何在 Ubuntu 上安装 Redis 5

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 本期内容主要介绍如何在 Ubuntu 上安装 Redis5 一些碎碎念&#xff1a; 本来这期内容介绍如何在 Centos 安装 Redis …

基于ScriptableObject设计游戏数据表

前言 本篇文章是针对之前对于ScriptableObject概念讲解的实际应用之一&#xff0c;在游戏开发中&#xff0c;我们可以使用该类来设计编辑器时的可读写数据表或者运行时的只读数据表。本文将针对运行时的只读数据表的应用进行探索&#xff0c;并且结合自定义的本地持久化存储方式…

cheese安卓版纯本地离线文字识别插件

目的 cheese自动化平台是一款可以模拟鼠标和键盘操作的自动化工具。它可以帮助用户自动完成一些重复的、繁琐的任务&#xff0c;节省大量人工操作的时间。可以采用Vscode、IDEA编写&#xff0c;支持Java、Python、nodejs、GO、Rust、Lua。cheese也包含图色功能&#xff0c;识别…

SpringBoot——基础配置

但是还需要删除pom.xml中的标签——模板的文件也同样操作 banner的选项——关闭 控制台 日志 banner图片的位置——还会分辨颜色 在 Java 的日志框架&#xff08;如 Logback、Log4j2 等&#xff09;中&#xff0c;logging.level.root主要用于设置根日志记录器的日志级别…

location指令

无前缀,必须以”/“开头 前缀""精准匹配。 前缀”^~“ 普通url匹配。 前缀”~“基于正则表达式的匹配&#xff0c; 区分大小写 前缀”~*“ 匹配优先级 locationlocation^~和无前缀/location ~或~* 1.无任何前缀 不加任何规则&#xff0c;默认大小写敏感&#x…

10.2 Linux_并发_进程相关函数

创建子进程 函数声明如下&#xff1a; pid_t fork(void); 返回值&#xff1a;失败返回-1&#xff0c;成功返回两次&#xff0c;子进程获得0(系统分配)&#xff0c;父进程获得子进程的pid 注意&#xff1a;fork创建子进程&#xff0c;实际上就是将父进程复制一遍作为子进程&…

【Linux操作系统】进程的创建与替换

目录 前言&#xff1a;一、进程创建1.fork();1.1 fork基本介绍1.2 fork的原理1.3 写时拷贝1.4 fork的使用场景1.5 fork调用失败的原因 2.clone() 二、进程替换(exec)1.替换原理2.替换函数3.函数解释4.函数理解 前言&#xff1a; 学习了Linux操作系统我们可以知道&#xff0c;进…

基于php摄影门户网站

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

Oracle架构之数据库备份和RAC介绍

文章目录 1 数据库备份1.1 数据库备份分类1.1.1 逻辑备份与物理备份1.1.2 完全备份/差异备份/增量备份 1.2 Oracle 逻辑备份1.2.1 EXP/IMP1.2.1.1 EXP导出1.2.1.2 EXP关键字说明1.2.1.3 导入1.2.1.4 IMP关键字说明 1.2.2 EXPDP/IMPDP1.2.2.1 数据泵介绍1.2.2.2 数据泵的使用 1.…

【STM32单片机_(HAL库)】4-3-2【定时器TIM】测量按键按下时间1——编程实现捕获功能

测量按键按下时长思路 测量按键按下时间实验目的 使用定时器 2 通道 2 来捕获按键 &#xff08;按键接PA0&#xff09;按下时间&#xff0c;并通过串口打印。 计一个数的时间&#xff1a;1us&#xff0c;PSC71&#xff0c;ARR65535 下降沿捕获、输入通道 2 映射在 TI2 上、不分…

华为-单臂路由

1、什么是单臂路由 单臂路由&#xff08;Single-Arm Routing&#xff09;是一种网络架构和配置技术&#xff0c;它允许路由器通过一个物理接口来管理多个虚拟局域网&#xff08;VLAN&#xff09;之间的通信。 这个物理接口被配置为Trunk模式&#xff0c;以便能够传输来自不同VL…

如何从huggingface下载

我尝试了一下若干步骤&#xff0c;莫名奇妙就成功了 命令行代理 如果有使用魔法上网&#xff0c;可以使用命令行代码&#xff0c;解决所有命令行连不上外网的问题&#xff1a; #配置http git config --global http.proxy 127.0.0.1:xxxx git config --global https.proxy 127…