本文介绍了 Commit-Reveal 方案,这是一种承诺方案,用于在智能合约中存储数据并保持秘密,直到稍后选择公开。文章通过石头剪刀布游戏的例子,说明了如何在智能合约中使用 Solidity 实现该方案,包括提交和揭示两个阶段,并提供了代码示例。
是否曾经想在链上存储一条信息,但在稍后才公开?在这篇快速文章中,我们将探讨 commit-reveal 方案,并提供一个示例,说明如何在智能合约中使用 Solidity 实现它。
commit-reveal 方案是一种承诺方案,可用于在智能合约中存储值,并在稍后选择公开它们之前保持其秘密。
一个常见的例子是延迟公开 NFT 系列;用户可以铸造 NFT,但这些 NFT 的底层数据(例如图像、名称、特征等)直到稍后才会公开。
在这篇文章中,我们将使用流行的石头剪刀布游戏作为示例,说明你可能希望如何以及为什么将此范例实现到你的智能合约中。
顾名思义,commit reveal 方案使用一个两步过程:
提交(Commit):将数据写入智能合约,但保持其加粗隐藏;通过对数据本身以及密钥短语进行哈希处理,即 hash(data, secret)
。
公开(Reveal):稍后,通过提供相同的 data
和 secret
值来公开数据。如果新提供的 data
和 secret
值的哈希值等于原始 data
和 secret
值的哈希值,则数据将被公开。
例如,在石头剪刀布游戏中,我们希望在交易中提交我们的移动操作,而另一位玩家不知道我们的操作。否则,他们可以通过检查我们交易中的移动操作来轻松赢得每场游戏。
相反,我们创建一个密钥或密码,并对这两个值的组合进行哈希处理。使用 solidity,我们可以使用 keccak256
和 abi.encodePacked
来实现这一点:
复制
复制
// 生成数据和密钥组合的哈希值
bytes32 hash = keccak256(
abi.encodePacked(
"scissors" // 我们的移动操作
bytes32("player1-secret") // 我们的密钥或密码
)
);
现在,我们可以安全地将此信息存储在智能合约中。其他人将能够看到 hash
值,但是,他们加粗无法解码它;因为他们不知道我们的密钥值。
只有知道我们原始移动操作和密钥的用户才能在以后公开我们的承诺;因为 data
和 secret
的哈希输出将始终是相同的值。
这也意味着我们以后不能更改我们的 data
;例如,我们不能将我们的移动操作从剪刀更改为布,因为 hash(paper,secret)
的输出将不同于 hash(scissors,secret)
的输出;即我们“承诺”了我们的答案。
稍后,例如,当两个玩家都在石头剪刀布游戏中提交了他们的移动操作时,我们可以安全地公开我们的承诺;通过提供原始数据和密钥来生成相同的哈希值,例如:
复制
复制
// 通过提供我们最初使用的值和密钥来生成一个新的哈希值
bytes32 newHash = keccak256(
abi.encodePacked(newMove, newSecret)
);
// 如果 hash(newMove, newSecret) == hash(originalMove, originalSecret),则公开!
require(
hash == newHash, "错误的移动操作或错误的密码:哈希值不匹配。"
);
此时,如果两个哈希值匹配,则在公开阶段提供的移动操作(上面的代码片段中的 加粗newMove
)就是“已公开”的数据;用户通过证明他们知道密钥以及原始移动操作来解码了他们的哈希值。
总而言之,commit-reveal 方案是一个两步过程,可有效地将数据以隐藏方式存储在智能合约中,以后可以使用哈希进行公开:
提交(Commit): 存储数据 + 密钥组合的哈希值
公开(Reveal): 提供数据和密钥以重新计算新的哈希值。如果哈希值与提交阶段的哈希值相同,则公开数据。
这是对 commit-reveal 方案的快速介绍。有关 Solidity 中的完整代码示例,请查看以下存储库:
https://github.com/jarrodwatts/rock-paper-scissors
如有任何疑问,请随时在 Twitter 上与我联系 @jarrodwattsdev。
- 原文链接: blog.jarrodwatts.com/und...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!