教程 | 简易锁定合约:Part 1

hongji   |     |   1441 次阅读

1

软件设计有两种构建方法:一种是明显没有缺陷的简单方法,另一种是没有明显错误的复杂方法。前者要难得多。——C.A.R Hoare

哈希盒子

这可能是我编写过的最简单的区块链代码之一。不过,就像介绍所有的区块链概念那样,我会通过一个非常复杂的故事引入,其中涉及一些虚拟人物。我想Bob和Alice这两个名字出现频率太高了,因此我倾向于使用在Cryptopia平台上鲜有人知的人物来举例。因为都是些虚拟人物,所以他们姓甚名谁真的不重要。

Victor与竞赛

Victor 宣布在他的所有朋友中举办一场竞赛。他会奖励给最佳的歌曲创作者5枚货币。Victor 有一些朋友知道自己不擅长写歌,不过他们愿意赞助这场竞赛。由于 Victor 不想将所有捐款都存放在自己的账户里(他的朋友其实也不想这样), Victor决定制作一个带锁的树脂玻璃捐款箱,并将它放在城镇中央。这下所有人都可以看到这场竞赛筹集到了多少捐款,愿意的话还能投钱进去。因为所有人都在监督这笔捐款,Victor只需保证钥匙的安全即可。他已经宣布会将盒子的钥匙交给竞赛获胜者,由对方去索取里面的全部捐款。

构建一把锁(a Lock)和一个盒子(a Box)

在区块链(即数字世界的“城镇中央”)上,我们有几个构建锁的工具。可用于以太坊区块链的最便宜的安全锁是 SHA-256 算法。SHA-256 算法会生成一个几乎独一无二的固定大小的256位(32字节)哈希函数。哈希属于单向函数——无法逆向反推。如今,大多数区块链都将它作为构建块(building block)。它包含在原始的以太坊代码中,是一种预编译合约。这意味着在任何合约中,只需很少的 gas 就可以使用哈希函数。

因为任何数据都能产生一个几乎独一无二的 SHA-256,所以这有助于我们达成目的。一开始,我们会创造一个独特的短语作为我们盒子的密钥。我们将 Alice and Bob sitting in a tree.(“Alice和Bob坐在树下”)这句密语作为示例。

你可以用任何想用的方法来得到这句密语的哈希函数,只要使用了SHA-256,(同样的数据)总会返回相同的32字节。我们会将合约中的哈希函数设置为一个公共变量,因此任何人都能读取它。由于哈希函数是一种单向函数,允许其他人读取并验证不会带来风险。

bytes32 public hashLock = e839dfa428e99c99630742d1086c99c51e5be27d702c47a786be6f17c8a3a16;

为了让合约能接收和存储 Ether,我们将需要将它的 fall back 方程设为可支付的(让它成为一个简单的募款箱)。

function () payable public{}

现在,我们已经构建了一个允许任何人放入资金的盒子并为这个盒子构建了一把锁/钥匙。我们还需要添加一种能让任何持有钥匙的人索取盒中内容物的方法。

function claim(string WhatIsTheMagicKey) public {

require(sha256(WhatIsTheMagicKey) == hashLock);

selfdestruct(msg.sender);

}

让我们了解一下该 claim(“索取”)函数的步骤。有人调用该索取函数时,他也会调整我们调用的字符串,该字符串被称之为“_WhatIsTheMagicKey(那把神奇钥匙是什么)”。该函数的第一步是测试该字符串的 SHA-256 哈希函数是否与我们的HashLock(哈希锁)相匹配。如果不匹配的话,该函数就会失败。如果二者相匹配,盒子内的所有资金都将赠予提供那把神奇钥匙的人。不是满载而归就是分文不得(这又称作原子性)。之后该合约就会自我毁灭,取消公共状态,因为已经不再需要它了。

在自然状态下

有多种方式可以编译字节代码。我使用的是Parity里的内置编译器,不过也可以使用 Remix 或 Truffle。我将使用 MyEtherWallet.com 部署合约并与之交互。

步骤一:部署合约

2

-将字节代码粘贴在钱包上的部署合约部分。将会生成一个新的合约。-

步骤二:为合约注资

3

-此时就会建立起一个带锁的盒子。你可以任意往里面添加资金,而钥匙是唯一取出资金的方法。-

步骤三:验证哈希函数

4

-因为哈希锁是恒定的,所以可以自由查看。-

步骤四:解锁盒子

5

-这时,任何持有钥匙的人都能调用该“索取”函数,从账户中取出全部资金。-

完整合约

pragma solidity ^0.4.18;

contract HashLock {

bytes32 public hashLock = 0x007YourHashGoesHere;

function () payable public{}

function claim(string WhatIsTheMagicKey) public {

require(sha256(WhatIsTheMagicKey) == hashLock);

selfdestruct(msg.sender);

}

}

结束语

哈希盒子有多种用途,例如漏洞报告奖励、竞赛、简单托管等。我将 gas 价格设置为 10 Gwei,因此我的整个系列测试的成本大约是0.002美元。这是用于原子交换的哈希/时间锁定合约的简单化版本,将在未来的公共混合服务中成为一个关键的建置区块。

敬请期待Part 2:将“box”变成“xob”


原文链接: https://medium.com/@DontPanicBurns/a-simple-hash-locked-contract-part-1-28d7c6065417
作者: Cody Burns
翻译&校对: 闵敏 & Elisa

本文由作者授权 EthFans 翻译及再出版。


你可能还会喜欢:

Slock - 区块锁,去中心化的共享经济
IPFS:替代HTTP的分布式网络协议
减少数字广告欺诈:BAT的新政

 
0 人喜欢