## 0x00: 背景: 不同区块链的状态是相互隔离的,当想要把A区块链的资产换成B区块链的资产,可以怎么做呢?简单的就是中心化交易所啦,但是体现不出**去中心化**的精神。而在本文章,会介绍一种去中心化的方法——基于**哈希时间锁**实现跨链交易。 <br> ## 0x01: 具体场景: Alice想将以太坊的ETH换成BSC上的BNB,而恰巧Bob想把BNB换成ETH,他们一拍即合。在谈妥兑换率后,却遇到了问题:他们都不愿意**先**转账。这时候哈希时间锁就可以派上用场了。 整个过程:  <br> **步骤1**:Alice设定一个secret,并生成secret的hash; **步骤2**:Alice部署HTLC-A合约,存入1 ETH,并设定只有Bob在时间timeA内输入secrect才能提款; **步骤3**:Bob也获得该hash,接着部署HTLC-B合约和存入5 BNB,并设定只有Alice在时间timeB内输入secrect才能提款; **步骤4**:Alice与HTLC-B合约交互,输入secret,提出Bob存入的5 BNB; **步骤5**:在上一步中已经暴露了secrect,所以Bob可以与HTLC-A交互,输入secrect,提出1 ETH; > 大概的过程是这样,具体细节可以看下面的代码 <br> ## 0x02: 代码实现: HTLC合约: ```solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.18; contract HTLC { uint public startTime; uint public lockTime = 1 hours; string public secret; // SecretOfAlice bytes32 public hash = 0x7a1737ec6bb58706b3b2d9ccd17ebd3701d3fe55bfc71fba515df41512b63dc8; address public recipient; address public owner; uint public amount; constructor(address _recipient) { recipient = _recipient; owner = msg.sender; } function deposit() external { startTime = block.timestamp; amount = msg.value; } function withdraw(string memory _secret) external { require(keccak256(abi.encodePacked(_secret)) == hash, "wrong secret"); secret = _secret; (bool sent, ) = recipient.call{value: amount}(""); require(sent, "Failed to send ETH"); } function refund() external { require(block.timestamp > startTime + lockTime, "too early"); (bool sent, ) = owner.call{value: amount}(""); require(sent, "Failed to send ETH"); } } ``` HTLC-A和HTLC-B合约可以都部署成这样。注意拥有secret的一方的锁定时间应该比另一方的长,防止Alice在锁定时间快结束时领取了HTLC-B的钱,但Bob可能会来不及调用领取HTLC-A的钱,而Alice却可以提回之前存入HTLC-A的钱。 <br> 另外,一开始哈希的计算,可以部署个合约,执行相同的代码进行计算: ```solidity // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.18; contract Hash { function calculateHash(string memory _key) external pure returns(bytes32){ return keccak256(abi.encodePacked(_key)); } } ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up