构建可互操作的区块链
有各种许可的和公共的区块链代表不同的资产、信息和业务流程。使用这些网络的主要要求之一是使它们能够相互交谈,这是一个需要克服的主要挑战。如果只有一个区块链来统治他们所有人那就太好了,但这肯定是不会发生的,因为在安全性、隐私性、效率、灵活性、平台复杂度、开发者易用性等等方面,不可能只有一个区块链胜出。区块链的未来将是几个公开的和许可的区块链互相操作。在本章中,我们将探讨如何实现多个法定网络之间的互操作性。
在本章中,我们将讨论以下主题:
- 了解区块链互操作性的含义以及与之相关的各种流行项目
- 检查可互操作的区块链可以实现的用例
- 查看可用于实现区块链互操作性的各种技术和模式
- 构建一个可互操作的区块链网络代表 FedCoins
了解区块链互操作性
可互操作的区块链是可以相互对话的区块链。每个区块链都能读出对方的状态。在很多情况下,您会希望让您的智能合约能够与集中式或其他分散式应用程序进行对话。当我们谈论 DApps 之间的互操作性时,我们谈论的是不同于区块链之间的互操作性。
启用以太坊智能合约来检查文件是否存在于 IPFS 是启用 DApps 之间的互操作性,而启用以太坊智能合约来获取比特币账户余额是启用区块链之间的互操作性。
让以太坊智能合约调用 REST APIs 来调用集中式应用程序被认为是实现了以太坊和 WWW 之间的互操作性。但在本章中,我们将了解区块链之间的互操作性,特别是法定网络之间的互操作性。
正在开发各种流行的项目,旨在采用分散的机制来实现区块链之间的互操作性。各种流行的项目,如 Cosmos 、 Polkadot 、 Interledger 、 Block Collider 等等,正在被积极开发,以使区块链互操作性分散化并易于实现,但在本章中我们不会涉及这些,因为它们旨在为公共区块链带来互操作性。然而,我们将学习的创建可互操作的区块链的策略正被这些项目所使用。
可互操作的区块链能实现什么?
在进一步研究如何实现区块链互操作性之前,我们需要知道互操作区块链可以实现什么。显然,互操作区块链有许多用例,但我们将着眼于区块链之间的互操作性主要旨在实现的用例。它可以实现以下一个或多个用例:
- 可移动资产:将资产从一个区块链移动到另一个。这些钉也被称为一对一钉或双向钉。
-
付款对付款和付款对交货:这些在技术上被称为 T2 原子互换。当两个用户交换位于两个不同区块链的资产时,需要担保,声明要么两个转移都发生,要么都不发生。例如,如果一个区块链持有数字化美元,另一个持有数字化欧元,那么用户应该能够自动交换这些资产。
-
获取信息并对事件做出反应:一个区块链能够读取存在于另一个区块链上的信息,或者能够对发生在另一个区块链上的交易做出反应。例如,在这种情况下,一个区块链代表租赁合同,另一个代表锁定的保证金,因此当租赁合同在第一个区块链中到期时,第二个应该自动释放保证金。
实现区块链互操作性的策略
让我们看看可以实现一个或多个先前用例的各种策略。我们将学习可以在 Quorum 中实现的策略,但不是所有可用于公共或其他区块链的策略。我们还将看看如何实施这些策略的例子。
单一保管人
实现互操作性的最简单的方法是建立一个集中的第三方,通过它区块链可以互相对话。本质上,你需要信任第三方。
但是集中式的互操作性项目,比如 Oraclize ,解决了信任问题。Oraclize 使您的以太坊智能合约能够与 WWW 通信;也就是说,它使您能够进行 REST API 调用,获取比特币账户余额,检查 IPFS 的文件状态,等等。Oraclize 还为智能合约提供了一个证明,声明结果没有被操纵;因此,Oraclize 解决了信任问题,但是单点故障仍然存在。Oraclize 对许可和公共以太坊都可用。Oraclize 的主要成就是为以太坊智能合约提供了进行 REST API 调用的能力,但是它的目的从来不是提供区块链之间的互操作性,因此它没有提供这个特性。
如果信任对您来说不是问题,那么单一保管人策略肯定是您应该考虑的,因为它支持我们前面讨论的所有三个用例。您可以轻松地编写一个集中式应用程序,对一个区块链上的事件做出反应,并调用另一个区块链上的操作。在许可的区块链,通常有监管机构或当局,你可以选择主机的集中式应用程序。单一保管人应发送使用私钥签名的交易,该私钥是区块链预编程信任的。
多重签名联盟
实现区块链之间互操作性的一个更好的选择是让一组公证人(或权威机构)控制一个多重签名,其中大多数公证人必须批准一个动作才能继续。这种设置比只有一个托管人要好,但仍能集中控制。为了实现真正的权力下放,应该仔细挑选至少具有以下特征的公证人:
- 公证人的人数不应少——例如,至少 10 人。
- 公证员的人数不能太高——比如 30 人以下,这样用户就可以验证公证员的真实性和诚实性。
- 公证人应该分布在不同的司法管辖区和国家,以防止国家攻击、胁迫和审查。
- 公证员应在地理上分散,以防止基础设施在自然灾害的情况下发生故障。
- 公证人应该是有名望的。
- 公证人不应由少数实体控制(或依赖于少数实体)。比如公证员不能是同一家银行的不同支行。
- 公证人应该能够通过物理和逻辑保护以及所需的安全程序来实现和维持特定的安全水平。
侧链或继电器
侧链是一个区块链内部的系统,可以验证和读取其他区块链中的事件和/或状态。中继是促进互操作性的一种更直接的方法,其中区块链有效地承担了自己做这件事的任务,而不是依赖可信的中介来提供关于一个区块链到另一个的信息。目前,侧链系统是使用 Merkle 树实现的。
一般方法如下。假设在区块链 B 上执行的智能合约想要了解某个特定事件是否发生在区块链 A 上,或者区块链 A 的某个特定对象是否在某个特定时间包含某个值。我们可以在区块链 B 上创建一个契约,该契约采用区块链 A 的这些块头之一,并使用区块链 A 共识算法的标准验证过程来验证该块头——在 IBFT,这将涉及验证超过 75%的验证者签名已经签署了该块头。一旦中继已经验证了块报头已经完成,中继就可以通过对照块报头验证 Merkle 树的单个分支来单独验证任何期望的交易或账户/状态条目。
使用这种所谓的轻型客户端验证技术对于中继来说是理想的,因为区块链从根本上来说是资源受限的。事实上,区块链 A 内部的机制不可能完全验证区块链 B 并且区块链 B 内部的机制不可能同时完全验证区块链 A ,因为同样简单的数学原因,两个盒子不能同时包含彼此: A 需要重新运行 B 中重新运行 A 的部分,包括 A 的部分然而,通过轻量级客户端验证,区块链 A 包含区块链 B 的小片段,区块链 B 包含区块链 A 的小片段的协议是完全可行的。区块链 B 上的中继上的智能契约想要验证区块链 A 上的特定事务、事件或状态信息,它将像传统的轻型客户端一样,验证区块链 A 的加密哈希树的分支,然后用块头验证该分支的根在内部,如果两个检查都通过,它将接受该事务、事件或状态信息是正确的。
请注意,因为区块链是完全独立的环境,没有与外界的自然连接,所以链 A 的相关位需要由用户输入到链 B 中;但是,从加密的角度来说,因为数据是自我验证的,所以提供这些信息的用户不需要被信任。
哈希锁定
哈希锁定是一种实现资产原子交换的技术。不需要任何中介。哈希锁定是这样工作的:
- 假设在两个不同的区块链中有两项资产叫做 A 和 B 。资产 A 的所有者是 X ,资产 B 的所有者是 Y 。
-
如果他们都想交换资产,那么首先, X 要生成一个秘密, S ,并计算这个秘密的 hash,也就是 H 。之后, X 与 Y 共用 H 。
-
现在, X 锁定资产 A ,声明如果 H 的 S 在 N 秒内被 Y、发现,那么该资产的所有权将转移给Y;否则,资产将在 N 秒后解锁。
- 接下来, Y 锁定资产 B ,声明如果 H 的 S 在 N/2 秒内被 X、发现,那么该资产的所有权将转移到X;否则,资产将在 N/2 秒后解锁。
- 所以现在,资产 A 和 B 分别在 N 和 N/2 秒后被锁定。现在,在 N/2 秒内, X 向 B 的区块链透露 S 要求资产的所有权。现在, Y 有同等的时间去学习 S 并向区块链 A 揭露 S 来认领所有权。
之所以 X 得到给予 Y 认领资金时间的一半,是因为只有 X 知道这个秘密,而在 Y 锁定资金后, X 几乎可以等到 N 秒结束后认领资产,这样就不会给 Y 足够的时间认领他们的资金。因此, X 可以成功盗取资产 A 和 B 。为了避免这种情况,我们给YT22】N 秒和XT26】N/2 秒,这样 Y 将有与 X 相同的时间来申请资产。
这种技术的缺点是,如果 X 在 N/2 和 N 秒之间揭示了 S 到 B ,那么 X 将无法声明对 B、的所有权,但是 Y 将了解到 S 并有时间声明对 A 的所有权。但是,这将是 X 、T23】的错误,可以避免。
盖费德科
FedCoin 是一种由中央银行发行的数字货币,与他们的法定货币一对一对冲。使用区块链将法定货币数字化有几个好处,比如方便跨境支付、节省对账工作等等。
让我们在两个不同的区块链网络上构建一些数字化的印度卢比和美元。然后,让我们创建一些原子互换合约,以原子方式实现银行之间的货币交换。这个用例要求您使用 IBFT 共识创建两个不同的法定人数网络。在每个网络中都有一个权威机构,即中央银行,以及 N 个对等机构,即其他银行。所以,你可以假设在第一个网络中,美联储系统 ( FRS )是权威,而美银 ( BOA )和 ICICI 银行是同行。同样,在第二个网络中,印度储备银行是权威机构,而印度银行和印度工业信贷银行是对等机构。
您现在不必构建这个网络,因为在构建和测试智能合约时,您可以只使用一个具有四个以太坊帐户地址的节点。这将足以模拟整个场景。
智能合约将法定货币数字化
这是一个在区块链上创建数字化美元的基本智能合约。这个智能合约允许我们发行和转移数字化货币:
pragma solidity ^0.4.19;
contract USD {
mapping (address => uint) balances;
mapping (address => mapping (address => uint)) allowed;
address owner;
function USD() {
owner = msg.sender;
}
function issueUSD(address to, uint amount) {
if(msg.sender == owner) {
balances[to] += amount;
}
}
function transferUSD(address to, uint amount) {
if(balances[msg.sender] >= amount) {
balances[msg.sender] -= amount;
balances[to] += amount;
}
}
function getUSDBalance(address account) view returns
(uint balance) {
return balances[account];
}
function approve(address spender, uint amount) {
allowed[spender][msg.sender] = amount;
}
function transferUSDFrom(address from, address to, uint amount) {
if(allowed[msg.sender][from] >= amount && balances[from]
>= amount) {
allowed[msg.sender][from] -= amount;
balances[from] -= amount;
balances[to] += amount;
}
}
}
以下是上述代码的工作原理:
- 首先,我们定义了一个映射来存储每家银行持有的美元数量。每个银行可以有多个地址来实现隐私。这些地址不一定是银行。它们也可以是其他智能合约,因为每个智能合约也有
address
。 - 接下来,我们假设中央银行部署合同。因此,我们通过将其
address
赋给owner
来定义央行为发行人。 - 然后,我们定义了中央银行可以向其他银行发行美元的函数
issueUSD
。 - 然后,我们定义了另一个函数,名为
transferUSD
,通过这个函数,银行可以在它们之间转移美元。 - 接下来,我们有一个读取账户余额的函数。
- 最后,我们有两个重要的函数:
approve
和transferUSDFrom
。transferUSDFrom
功能允许合约代表你发送美元。换句话说,您正在为同一区块链上的其他智能合约提供 API 来管理您的资金。approve
功能用于批准管理您资金的智能合同。在给approve
打电话时,你提到合同能管理你多少资金。
这里,我们使用一个名为view
的内置修改器。view
表示该函数不能修改存储,但可以读取存储(因此可以查看)。view
功能不能发送或接收以太。类似地,还有另一个名为pure
的修饰符,它表示返回值只能依赖于输入参数——也就是说,它们甚至不能读取存储,也不能发送或接收以太。您应该使用这些修饰符,因为它们有几个好处——例如,在生成与契约交互的 UI 表单时,Remix IDE 会在线查找这些修饰符。
现在部署一个类似的合同,在第二个网络中数字化 INR。将之前契约中的USD
替换为INR
并部署。它应该是这样的:
pragma solidity ^0.4.19;
contract INR {
mapping (address => uint) balances;
mapping (address => mapping (address => uint)) allowed;
address owner;
function INR() {
owner = msg.sender;
}
function issueINR(address to, uint amount) {
if(msg.sender == owner) {
balances[to] += amount;
}
}
function transferINR(address to, uint amount) {
if(balances[msg.sender] >= amount) {
balances[msg.sender] -= amount;
balances[to] += amount;
}
}
function getINRBalance(address account) view returns
(uint balance) {
return balances[account];
}
function approve(address spender, uint amount) {
allowed[spender][msg.sender] = amount;
}
function transferINRFrom(address from, address to, uint amount) {
if(allowed[msg.sender][from] >= amount && balances[from]
>= amount) {
allowed[msg.sender][from] -= amount;
balances[from] -= amount;
balances[to] += amount;
}
}
}
原子互换智能合约
我们成功地实现了法定货币的数字化。现在是时候实现原子交换智能契约了,它将提供哈希锁定机制。我们在每个区块链都部署了原子互换智能合约,也就是说,第一个区块链上的原子互换智能合约将锁定美元一段时间,并期望一家印度银行(这里是 ICICI 银行)使用该秘密在规定的时间内认领它。类似地,第二个区块链上的原子互换合同将锁定 INR 一段时间,并期望一家美国银行(这里是 BOA)使用该秘密在规定的时间内认领它。
以下是锁定美元的原子互换智能合约:
pragma solidity ^0.4.19;
import "./USD.sol";
contract AtomicSwap_USD {
struct AtomicTxn {
address from;
address to;
uint lockPeriod;
uint amount;
}
mapping (bytes32 => AtomicTxn) txns;
USD USDContract;
event usdLocked(address to, bytes32 hash, uint expiryTime,
uint amount);
event usdUnlocked(bytes32 hash);
event usdClaimed(string secret, address from, bytes32 hash);
function AtomicSwap_USD(address usdContractAddress) {
USDContract = USD(usdContractAddress);
}
function lock(address to, bytes32 hash, uint lockExpiryMinutes,
uint amount) {
USDContract.transferUSDFrom(msg.sender, address(this), amount);
txns[hash] = AtomicTxn(msg.sender, to, block.timestamp +
(lockExpiryMinutes * 60), amount);
usdLocked(to, hash, block.timestamp + (lockExpiryMinutes * 60),
amount);
}
function unlock(bytes32 hash) {
if(txns[hash].lockPeriod < block.timestamp) {
USDContract.transferUSD(txns[hash].from,
txns[hash].amount);
usdUnlocked(hash);
}
}
function claim(string secret) {
bytes32 hash = sha256(secret);
USDContract.transferUSD(txns[hash].to, txns[hash].amount);
usdClaimed(secret, txns[hash].from, hash);
}
function calculateHash(string secret) returns (bytes32 result) {
return sha256(secret);
}
}
下面是前面的智能合约的工作原理:
- 在部署智能契约时,我们提供了
USD
契约的契约地址,以便它可以调用其函数来转移资金。 - 使用
hash
锁定资金时使用了lock
方法。显然,在调用lock
方法之前,BOA 必须批准这个原子互换合同地址,以便能够访问其一定数量的资金。需要hash
,锁定一定时间的资金。amount
被指定来指示锁定多少美元,并且该金额应该小于等于批准的金额。to
地址指定了印度银行的地址——即 ICICI 银行。所以,当 ICICI 银行来认领资金时,他们会去这个地址。这个函数实际上将资金转移到其合同地址(即address(this)
)并触发一个事件,以便 ICICI 银行可以看到资金已经被锁定。 - 在
hash
到期后,如果资金未被认领,BOA 可以使用unlock
方法解锁资金。 - ICICI 银行使用
claim
方法来要求使用秘密的资金。 - 最后,我们使用了
calculateHash
方法来计算一个秘密的hash
。
在这里,我们使用 BOA 和 ICICI 作为例子来简单地解释它,但以前的智能合同将适用于任何数量的货币和银行。
将前面合约中的USD
更改为INR
,为第二个区块链提供原子互换智能合约。下面是代码的样子:
pragma solidity ^0.4.19;
import "./INR.sol";
contract AtomicSwap_INR {
struct AtomicTxn {
address from;
address to;
uint lockPeriod;
uint amount;
}
mapping (bytes32 => AtomicTxn) txns;
INR INRContract;
event inrLocked(address to, bytes32 hash, uint expiryTime,
uint amount);
event inrUnlocked(bytes32 hash);
event inrClaimed(string secret, address from, bytes32 hash);
function AtomicSwap_INR(address inrContractAddress) {
INRContract = INR(inrContractAddress);
}
function lock(address to, bytes32 hash, uint lockExpiryMinutes,
uint amount) {
INRContract.transferINRFrom(msg.sender, address(this), amount);
txns[hash] = AtomicTxn(msg.sender, to, block.timestamp +
(lockExpiryMinutes * 60), amount);
inrLocked(to, hash, block.timestamp + (lockExpiryMinutes * 60),
amount);
}
function unlock(bytes32 hash) {
if(txns[hash].lockPeriod < block.timestamp) {
INRContract.transferINR(txns[hash].from,
txns[hash].amount);
inrUnlocked(hash);
}
}
function claim(string secret) {
bytes32 hash = sha256(secret);
INRContract.transferINR(txns[hash].to, txns[hash].amount);
inrClaimed(secret, txns[hash].from, hash);
}
function calculateHash(string secret) returns (bytes32 result) {
return sha256(secret);
}
}
测试
现在,我们已经准备好在两个不同区块链的资产之间进行原子互换的智能合约。接下来,让我们编写一些 JavaScript 代码来测试前面的契约并进行原子交换。下面的代码允许您这样做。出于测试和模拟目的,您可以在一个具有四个帐户的仲裁节点中运行以下代码:
var generateSecret = function () {
return Math.random().toString(36).substr(2, 9);
};
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
var RBI_Address = "0x92764a01c43ca175c0d2de145947d6387205c655";
var FRS_Address = "0xbc37e7ba9f099ba8c61532c6fce157072798fe77";
var BOA_Address = "0x104803ea6d8696afa6e7a284a46a1e71553fcf12";
var ICICI_Address = "0x84d2dab0d783dd84c40d04692e303b19fa49bf47";
var usdContract_ABI = /* Put JSON here */;
var usdContract_Bytecode = "0x606..."
var atomicswapUSD_ABI = /* Put JSON here */;
var atomicswapUSD_Bytecode = "0x606..."
var inrContract_ABI = /* Put JSON here */;
var inrContract_Bytecode = "0x606..."
var atomicswapINR_ABI = /* Put JSON here */;
var atomicswapINR_Bytecode = "0x606..."
var usdContract = web3.eth.contract(usdContract_ABI);
var usd = usdContract.new({
from: FRS_Address,
data: usdContract_Bytecode,
gas: "4700000"
}, function (e, contract){
if (typeof contract.address !== 'undefined') {
var usdContractAddress = contract.address;
var usdContractInstance = usdContract.at(usdContractAddress)
var atomicswap_usdContract = web3.eth.contract(atomicswapUSD_ABI);
var atomicswap_usd = atomicswap_usdContract.new(usdContractAddress, {
from: FRS_Address,
data: atomicswapUSD_Bytecode,
gas: "4700000"
}, function (e, contract){
if (typeof contract.address !== 'undefined') {
var atomicSwapUSDAddress = contract.address;
var atomicSwapUSDContractInstance =
atomicswap_usdContract.at(atomicSwapUSDAddress);
var inrContract = web3.eth.contract(inrContract_ABI);
var inr = inrContract.new({
from: RBI_Address,
data: inrContract_Bytecode,
gas: "4700000"
}, function (e, contract){
if(typeof contract.address !== 'undefined') {
var inrContractAddress = contract.address;
var inrContractInstance =
inrContract.at(inrContractAddress)
var atomicswap_inrContract =
web3.eth.contract(atomicswapINR_ABI);
var atomicswap_inr = atomicswap_inrContract.new(
inrContractAddress, {
from: RBI_Address,
data: atomicswapINR_Bytecode,
gas: '4700000'
}, function (e, contract){
if (typeof contract.address !== 'undefined') {
var atomicSwapINRAddress = contract.address;
var atomicSwapINRContractInstance =
atomicswap_inrContract.at(atomicSwapINRAddress);
}
})
}
})
}
})
}
})
首先,我们部署了USD
契约,然后通过将USD
契约的地址作为参数进行传递,部署了美元的原子互换契约。我们将这些合同部署为 FRS。然后,我们部署了INR
契约,然后通过将INR
契约的地址作为参数进行传递,为 INR 部署了原子交换契约。我们将这些合同部署为 RBI。
将以下代码放在提到延续的地方:
//Issue USD
usdContractInstance.issueUSD.sendTransaction(BOA_Address, 1000,
{from: FRS_Address}, function(e, txnHash){
//Fetch USD Balance
console.log("Bank of America's USD Balance is : " +
usdContractInstance.getUSDBalance.call(BOA_Address).toString())
//Issue INR
inrContractInstance.issueINR.sendTransaction(ICICI_Address, 1000,
{from: RBI_Address}, function(e, txnHash){
//Fetch INR Balance
console.log("ICICI Bank's INR Balance is : " +
inrContractInstance.getINRBalance.call(ICICI_Address).toString())
//Generate Secret and Hash
var secret = generateSecret();
var hash = atomicSwapUSDContractInstance.calculateHash.call(secret,
{from: BOA_Address});
//Give Access to Smart Contract
usdContractInstance.approve.sendTransaction(atomicSwapUSDAddress,
1000, {from: BOA_Address}, function(e, txnHash){
//Give Access to Smart Contract
inrContractInstance.approve.sendTransaction(atomicSwapINRAddress,
1000, {from: ICICI_Address}, function(e, txnHash){
//Lock 1000 USD for 30 min
atomicSwapUSDContractInstance.lock.sendTransaction(ICICI_Address, hash,
30, 1000, {from: BOA_Address, gas: 4712388}, function(e, txnHash){
//Fetch USD Balance
console.log("USD Atomic Exchange Smart Contracts holds : " +
usdContractInstance.getUSDBalance.call
(atomicSwapUSDAddress).toString())
//Lock 1000 INR for 15 min
atomicSwapINRContractInstance.lock.sendTransaction(BOA_Address,
hash, 15, 1000, {from: ICICI_Address, gas: 4712388},
function(e, txnHash){
//Fetch INR Balance
console.log("INR Atomic Exchange Smart Contracts holds : "
+ inrContractInstance.getINRBalance.call
(atomicSwapINRAddress).toString())
atomicSwapINRContractInstance.claim(secret, {
from: BOA_Address, gas: 4712388
}, function(error, txnHash){
//Fetch INR Balance
console.log("Bank of America's INR Balance is : " +
inrContractInstance.getINRBalance.call
(BOA_Address).toString())
atomicSwapUSDContractInstance.claim(secret, {
from: ICICI_Address, gas: 4712388
}, function(error, txnHash){
//Fetch USD Balance
console.log("ICICI Bank's USD Balance is : " +
usdContractInstance.getUSDBalance.call
(ICICI_Address).toString())
})
})
})
})
})
})
})
})
以下是上述代码的工作原理:
- 在这里,联邦储备银行向美国银行发行美元,然后印度储备银行向印度工业信贷银行发行印度卢比。
- 然后,宝儿产生了一个秘密。我们使用一个非常基本的函数来生成一个秘密。显然,在现实世界的场景中,您应该使用某种基于硬件的工具来生成这些安全的秘密。
- 接下来,我们计算秘密的散列。
- 美国银行和 ICICI 银行分别向美元原子掉期和印度卢比原子合约提供资金。
- 美国银行在美元原子掉期合约中锁定了美元 30 分钟,并声明只有 ICICI 银行可以要求资金。
- 同样,ICICI 银行将印度卢比在印度卢比原子掉期合同中锁定了 15 分钟,并表示只有美国银行可以要求资金。
- 最后,BOA 继续要求 INR。ICICI 一得知这个秘密,就一意孤行,索要美元。
为了测试前面的契约,首先复制您的以太坊地址并替换我在前面的例子中生成的地址。然后,确保您解锁了节点中的所有四个帐户。最后,编译合同并填充ABI
和Bytecode
变量。
这里,我们使用一个实度函数来计算hash
,但是您可以使用 JavaScript 来计算hash
。如果你想计算sha256
hash,那么你可以使用任何 JavaScript 库,但是如果你像 Solidity 在 JavaScript 中那样计算sha3
(也就是keccak256
,那么你就需要使用web3.utils
库,它提供了一个名为soliditySha3
的函数。该函数将以与 Solidity 相同的方式计算给定输入参数的sha3
。这意味着参数在被散列之前将被转换并紧密打包。
摘要
在本章中,我们研究了构建可互操作的区块链的各种选择。总而言之,单一保管人、多重签名联盟和散列锁很容易实现,而侧链很复杂,需要大量的工程设计。很快,我们将有生产许可的区块链平台,内置侧链支持。
最后,我们通过模拟两家中央银行和商业银行实现了散列锁。您可以继续尝试构建两个不同的网络,并尝试进行原子交换。
在下一章,我们将学习如何构建一个区块链作为 Quorum 的服务器。在构建过程中,我们还将了解 DevOps 和云计算的概念。