尝鲜使用微众银行WeCross实现基于哈希时间锁定的跨链转账
jasonruan 2020.05.13
[TOC]
0 前言
微众银行在最近(2020年5月12日)发布了WeCross v1.0.0-rc2,WeCross
是微众区块链跨链协作平台,新版本对Stub
(跨链路由)进行了插件化封装,开发者只需根据插件规范进行开发,即可让WeCross
接入不同类型的链,此外,还基于HTLC(哈希时间锁定)
事务机制,实现了跨链转账,让资产能够在不同链之间流转。本文就将带你尝鲜使用WeCross
实现基于哈希时间锁定的跨链转账,文章最后再介绍下HTLC(哈希时间锁定)
的原理。我们开始吧。
1 环境搭建
1.1 软件包下载
1.1.1 WeCross
[jason@RUAN:~/Blockchain/WeBankFinTech]$ git clone git@github.com:WeBankFinTech/WeCross.git
[jason@RUAN:~/Blockchain/WeBankFinTech/WeCross] (master)$ git checkout -b v1.0.0-rc2 v1.0.0-rc2
切换到一个新分支 'v1.0.0-rc2'
[jason@RUAN:~/Blockchain/WeBankFinTech/WeCross] (v1.0.0-rc2)$ ./gradlew assemble
BUILD SUCCESSFUL
1.1.2 WeCross-Console
[jason@RUAN:~/Blockchain/WeBankFinTech]$ git clone git@github.com:WeBankFinTech/WeCross-Console.git
[jason@RUAN:~/Blockchain/WeBankFinTech/WeCross-Console] (master)$ git checkout -b v1.0.0-rc2 v1.0.0-rc2
切换到一个新分支 'v1.0.0-rc2'
[jason@RUAN:~/Blockchain/WeBankFinTech/WeCross-Console] (v1.0.0-rc2)$ ./gradlew assemble
BUILD SUCCESSFUL
1.1.3 FISCO-BCOS
[jason@RUAN:~/Blockchain/WeBankFinTech] (master)$ git clone git@github.com:WeBankFinTech/FISCO-BCOS.git
[jason@RUAN:~/Blockchain/WeBankFinTech/FISCO-BCOS] (master)$ git checkout -b v2.4.0 v2.4.0
切换到一个新分支 'v2.4.0'
2 联盟链搭建
本节我们将分别搭建FISCO-BCOS联盟链
以及Hyperledger Fabric联盟链
。
2.1 FISCO-BCOS联盟链搭建
参考资料:https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/installation.html#
2.1.1 网络配置创建
[jason@RUAN:~]$ cd ~ && mkdir -p fisco && cd fisco
# -p选项指定起始端口,分别是p2p_port,channel_port,jsonrpc_port
[jason@RUAN:~/fisco]$ ~/Blockchain/WeBankFinTech/FISCO-BCOS/tools/build_chain.sh -l "127.0.0.1:4" -p 30300,20200,8545
[INFO] Downloading fisco-bcos binary from https://github.com/FISCO-BCOS/FISCO-BCOS/releases/download/v2.4.0/fisco-bcos.tar.gz ...
==============================================================
Generating CA key...
==============================================================
Generating keys and certificates ...
Processing IP:127.0.0.1 Total:4 Agency:agency Groups:1
==============================================================
Generating configuration files ...
Processing IP:127.0.0.1 Total:4 Agency:agency Groups:1
==============================================================
[INFO] Start Port : 30300 20200 8545
[INFO] Server IP : 127.0.0.1:4
[INFO] Output Dir : /home/jason/fisco/nodes
[INFO] CA Path : /home/jason/fisco/nodes/cert/
==============================================================
[INFO] Execute the download_console.sh script in directory named by IP to get FISCO-BCOS console.
e.g. bash /home/jason/fisco/nodes/127.0.0.1/download_console.sh -f
==============================================================
[INFO] All completed. Files in /home/jason/fisco/nodes
2.1.2 启动网络
[jason@RUAN:~/fisco]$ bash nodes/127.0.0.1/start_all.sh
try to start node0
try to start node1
try to start node2
try to start node3
node0 start successfully
node2 start successfully
node3 start successfully
node1 start successfully
2.1.3 下载控制台
[jason@RUAN:~/fisco]$ curl -LO https://github.com/FISCO-BCOS/console/releases/download/v1.0.9/download_console.sh && bash download_console.sh
# 拷贝控制台配置文件
[jason@RUAN:~/fisco]$ cp -n console/conf/applicationContext-sample.xml console/conf/applicationContext.xml
# 配置控制台证书
[jason@RUAN:~/fisco]$ cp nodes/127.0.0.1/sdk/* console/conf/
2.1.4 启动控制台
[jason@RUAN:~/fisco]$ cd ~/fisco/console && bash start.sh
=============================================================================================
Welcome to FISCO BCOS console(1.0.9)!
Type 'help' or 'h' for help. Type 'quit' or 'q' to quit console.
________ ______ ______ ______ ______ _______ ______ ______ ______
| | \/ \ / \ / \ | \ / \ / \ / \
| $$$$$$$$\$$$$$| $$$$$$| $$$$$$| $$$$$$\ | $$$$$$$| $$$$$$| $$$$$$| $$$$$$\
| $$__ | $$ | $$___\$| $$ \$| $$ | $$ | $$__/ $| $$ \$| $$ | $| $$___\$$
| $$ \ | $$ \$$ \| $$ | $$ | $$ | $$ $| $$ | $$ | $$\$$ \
| $$$$$ | $$ _\$$$$$$| $$ __| $$ | $$ | $$$$$$$| $$ __| $$ | $$_\$$$$$$\
| $$ _| $$_| \__| $| $$__/ | $$__/ $$ | $$__/ $| $$__/ | $$__/ $| \__| $$
| $$ | $$ \\$$ $$\$$ $$\$$ $$ | $$ $$\$$ $$\$$ $$\$$ $$
\$$ \$$$$$$ \$$$$$$ \$$$$$$ \$$$$$$ \$$$$$$$ \$$$$$$ \$$$$$$ \$$$$$$
=============================================================================================
# 获取客户端版本
[group:1]> getNodeVersion
{
"Build Time":"20200430 03:22:53",
"Build Type":"Linux/clang/Release",
"Chain Id":"1",
"FISCO-BCOS Version":"2.4.0",
"Git Branch":"HEAD",
"Git Commit Hash":"0d94de1e0f2dc7ce7d226dbd68001a4b43029cf6",
"Supported Version":"2.4.0"
}
# 获取节点链接信息
[group:1]> getPeers
[
{
"Agency":"agency",
"IPAndPort":"127.0.0.1:36016",
"Node":"node3",
"NodeID":"6408d27fd18d7fd80786381701355366ebcb39c9acd04accfba23167da724d40ba386d398cd60769d263602028d63c9158248d309a137b702343275a93ec70c2",
"Topic":[
]
},
{
"Agency":"agency",
"IPAndPort":"127.0.0.1:36418",
"Node":"node1",
"NodeID":"b43fd771052bd72e86f3ba7129e2b554ce8c4e737d87a5fabf84bf518a2649ca017645c7eed438d36a785e7350f302044dd46ed05b6ea9b49d4a9db5751798f8",
"Topic":[
]
},
{
"Agency":"agency",
"IPAndPort":"127.0.0.1:36014",
"Node":"node2",
"NodeID":"c647130eb8f2e1e6b33aa818634b532086c89afa1da927b2d20e0d5d694f06cd42bd37e4eb0566b6a640e63bd57da544ba3679fb92e6884339a10e299e833129",
"Topic":[
]
}
]
2.2 Hyperledger Fabric联盟链搭建
请参看:快速带你上手Hyperledger Fabric环境搭建+开发测试
3 跨链网络搭建
本节将基于上节搭建好的FISCO-BCOS联盟链
以及Hyperledger Fabric联盟链
,来搭建WeCross
跨链网络。
参考资料:https://wecross.readthedocs.io/zh_CN/latest/docs/tutorial/networks.html
3.1 搭建网络示意图
3.2 跨链路由部署
# 下载WeCross
[jason@RUAN:~/wecross]$ bash <(curl -sL https://github.com/WeBankFinTech/WeCross/releases/download/resources/download_wecross.sh)
[INFO] Checking latest release
[INFO] Latest release: v1.0.0-rc2
[INFO] Try to Download checksum from https://www.fisco.com.cn/cdn/wecross/releases/download//v1.0.0-rc2/WeCross.tar.gz.md5
[INFO] Try to download from: https://www.fisco.com.cn/cdn/wecross/releases/download//v1.0.0-rc2/WeCross.tar.gz
[INFO] Download completed. WeCross is in: ./WeCross/
# 创建ipfile文件
[jason@RUAN:~/wecross]$ cat ipfile
127.0.0.1:8250:25500
127.0.0.1:8251:25501
# 使用脚本build_wecross.sh生成两个跨链路由
[jason@RUAN:~/wecross]$ bash ./WeCross/build_wecross.sh -n payment -o routers-payment -f ipfile
Generating RSA private key, 2048 bit long modulus (2 primes)
[INFO] Build ca cert successful!
[INFO] Generate key for node
Signature ok
subject=CN = fisco-bcos, O = fisco-bcos, OU = ssl
Getting CA Private Key
read EC key
[INFO] Build node cert successful!
[INFO] Generate key for node0
Signature ok
subject=CN = fisco-bcos, O = fisco-bcos, OU = ssl
Getting CA Private Key
read EC key
[INFO] Build node0 cert successful!
[INFO] Generate key for node1
Signature ok
subject=CN = fisco-bcos, O = fisco-bcos, OU = ssl
Getting CA Private Key
read EC key
[INFO] Build node1 cert successful!
================================================================
[INFO] Create routers-payment/127.0.0.1-8250-25500 successfully
[INFO] Create routers-payment/127.0.0.1-8251-25501 successfully
[INFO] All completed. WeCross routers are generated in: routers-payment/
# 在routers-payment目录下生成了两个跨链路由
[jason@RUAN:~/wecross]$ tree routers-payment/ -L 1
routers-payment/
├── 127.0.0.1-8250-25500
├── 127.0.0.1-8251-25501
└── cert
# 启动跨链路由
cd ~/wecross/routers-payment/127.0.0.1-8250-25500/
bash start.sh
cd ~/wecross/routers-payment/127.0.0.1-8251-25501/
bash start.sh
3.3 WeCross控制台部署
# 下载WeCross控制台
[jason@RUAN:~/wecross]$ bash <(curl -sL https://github.com/WeBankFinTech/WeCross/releases/download/resources/download_console.sh)
[INFO] Checking latest release
[INFO] Latest release: v1.0.0-rc2
[INFO] Try to Download checksum from https://www.fisco.com.cn/cdn/wecross-console/releases/download//v1.0.0-rc2/WeCross-Console.tar.gz.md5
[INFO] Try to download from: https://www.fisco.com.cn/cdn/wecross-console/releases/download//v1.0.0-rc2/WeCross-Console.tar.gz
[INFO] Download completed. WeCross Console is in: ./WeCross-Console/
[INFO] Please configure "./WeCross-Console/conf/console.xml" according with "console-sample.xml" and "bash start.sh" to start.
# 配置控制台
[jason@RUAN:~/wecross]$ cd ~/wecross/WeCross-Console
[jason@RUAN:~/wecross/WeCross-Console]$ cp ~/wecross/routers-payment/cert/sdk/* conf/
# 启动控制台
[jason@RUAN:~/wecross/WeCross-Console]$ bash start.sh
========================================================================
Welcome to WeCross console(v1.0.0-rc2)!
Type 'help' or 'h' for help. Type 'quit' or 'q' to quit console.
========================================================================
[WeCross]>
# 功能测试
[WeCross]> supportedStubs
[BCOS2.0, GM_BCOS2.0, Fabric1.4]
[WeCross]> help
-------------------------------------------------------------------------
quit Quit console.
supportedStubs List supported stubs of WeCross router.
listAccounts List all accounts stored in WeCross router.
listLocalResources List local resources configured by WeCross server.
listResources List all resources including remote resources.
status Check if the resource exists.
detail Get resource information.
call Call constant method of smart contract.
sendTransaction Call non-constant method of smart contract.
genTimelock Generate two valid timelocks.
genSecretAndHash Generate a secret and its hash.
newHTLCTransferProposal Create a htlc transfer proposal .
checkTransferStatus Check htlc transfer status by hash.
WeCross.getResource Init resource by path and account name, and assign it to a custom variable.
[resource].[command] Equal to: command [path] [account name].
3.4 接入BCOS链
3.4.1 添加账户
在router中添加用于向链上发交易的账户。账户配置好后,可通过跨链网络向相应的链发交易,交易可被router转发至对应的链上。
3.4.1.1 创建bcos_sender
[jason@RUAN:~/fisco]$ cd ~/wecross/routers-payment/127.0.0.1-8250-25500/
# 用脚本生成BCOS账户:账户类型(BCOS2.0),账户名(bcos_sender)
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8250-25500]$ bash add_account.sh -t BCOS2.0 -n bcos_sender
Initializing StubManager...
operator: account type: BCOS2.0 path: conf/accounts/bcos_sender
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8250-25500]$ tree conf/accounts/bcos_sender
conf/accounts/bcos_sender
├── account.key
└── account.toml
3.4.1.2 创建bcos_receiver
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8250-25500]$ bash add_account.sh -t BCOS2.0 -n bcos_receiver
Initializing StubManager...
operator: account type: BCOS2.0 path: conf/accounts/bcos_receiver
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8250-25500]$ tree conf/accounts/bcos_receiver
conf/accounts/bcos_receiver
├── account.key
└── account.toml
3.4.2 生成接入BCOS链配置
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8250-25500]$ bash add_chain.sh -t BCOS2.0 -n bcos
Initializing StubManager...
operator: connection type: BCOS2.0 path: conf/chains/bcos
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8250-25500]$ tree conf/chains/bcos
conf/chains/bcos
└── stub.toml
3.4.3 拷贝证书
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8250-25500]$ cp ~/fisco/nodes/127.0.0.1/sdk/* conf/chains/bcos/
3.5 接入Fabric链
参考资料:https://wecross.readthedocs.io/zh_CN/latest/docs/stubs/fabric.html
3.5.1 添加账户
3.5.1.1 创建fabric_admin
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8251-25501]$ bash add_account.sh -t Fabric1.4 -n fabric_admin
Initializing StubManager...
operator: account type: Fabric1.4 path: conf/accounts/fabric_admin
$ tree conf/accounts/fabric_admin
conf/accounts/fabric_admin
└── account.toml
$ cat conf/accounts/fabric_admin/account.toml
[account]
type = 'Fabric1.4'
mspid = 'Org1MSP'
keystore = 'admin.key'
signcert = 'admin.crt'
3.5.1.2 创建fabric_user1
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8251-25501]$ bash add_account.sh -t Fabric1.4 -n fabric_user1
Initializing StubManager...
operator: account type: Fabric1.4 path: conf/accounts/fabric_user1
$ tree conf/accounts/fabric_user1
conf/accounts/fabric_user1
└── account.toml
$ cat conf/accounts/fabric_user1/account.toml
[account]
type = 'Fabric1.4'
mspid = 'Org1MSP'
keystore = 'user1.key'
signcert = 'user1.crt'
3.5.2 添加账户身份
3.5.2.1 添加fabric_admin
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8251-25501]$ scp vagrant@FABRIC:/opt/gopath/src/github.com/hyperledger/fabric-samples/first-network//crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/*_sk conf/accounts/fabric_admin/admin.key
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8251-25501]$ scp vagrant@FABRIC:/opt/gopath/src/github.com/hyperledger/fabric-samples/first-network//crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/*.pem conf/accounts/fabric_admin/admin.crt
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8251-25501]$ tree conf/accounts/fabric_admin/
conf/accounts/fabric_admin/
├── account.toml
├── admin.crt
└── admin.key
3.5.2.2 添加fabric_user1
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8251-25501]$ scp vagrant@FABRIC:/opt/gopath/src/github.com/hyperledger/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/keystore/*_sk conf/accounts/fabric_user1/user1.key
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8251-25501]$ scp vagrant@FABRIC:/opt/gopath/src/github.com/hyperledger/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/signcerts/*.pem conf/accounts/fabric_user1/user1.crt
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8251-25501]$ tree conf/accounts/fabric_user1/
conf/accounts/fabric_user1/
├── account.toml
├── user1.crt
└── user1.key
3.5.3 生成接入Fabric链配置
[jason@RUAN:~]$ cd ~/wecross/routers-payment/127.0.0.1-8251-25501
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8251-25501]$ bash add_chain.sh -t Fabric1.4 -n fabric
Initializing StubManager...
operator: connection type: Fabric1.4 path: conf/chains/fabric
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8251-25501]$ tree conf/chains/fabric
conf/chains/fabric
└── stub.toml
- 修改stub.toml内容
$ cat conf/chains/fabric/stub.toml
[common]
# 指定的连接的链的名字,对应path中的{zone}/{chain}/{resource}的chain
name = 'fabric'
type = 'Fabric1.4'
[fabricServices]
channelName = 'jschannel'
orgName = 'Org1'
mspId = 'Org1MSP'
orgUserName = 'fabric_admin'
orgUserAccountPath = 'classpath:accounts/fabric_admin'
ordererTlsCaFile = 'orderer-tlsca.crt'
ordererAddress = 'grpcs://FABRIC:7050'
[peers]
[peers.org1]
peerTlsCaFile = 'org1-tlsca.crt'
peerAddress = 'grpcs://FABRIC:7051'
[peers.org2]
peerTlsCaFile = 'org2-tlsca.crt'
peerAddress = 'grpcs://FABRIC:9051'
# resources is a list
[[resources]]
# name cannot be repeated
name = 'abac'
type = 'FABRIC_CONTRACT'
chainCodeName = 'mycc'
chainLanguage = "go"
peers=['org1','org2']
3.5.4 拷贝链证书
# 拷贝 orderer证书
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8251-25501]$ scp vagrant@FABRIC:/opt/gopath/src/github.com/hyperledger/fabric-samples/first-network/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem conf/chains/fabric/orderer-tlsca.crt
# 拷贝 peer.org1 证书
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8251-25501]$ scp vagrant@FABRIC:/opt/gopath/src/github.com/hyperledger/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt conf/chains/fabric/org1-tlsca.crt
# 拷贝 peer.org2 证书
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8251-25501]$ scp vagrant@FABRIC:/opt/gopath/src/github.com/hyperledger/fabric-samples/first-network/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt conf/chains/fabric/org2-tlsca.crt
4 跨链转账
参考资料:https://wecross.readthedocs.io/zh_CN/latest/docs/routine/htlc.html
4.1 跨链转账示意图
WeCross基于哈希时间锁合约实现了异构链之间资产的原子互换,跨链转账涉及两条链、两个用户、四个账户,两条链上的资产转出者各自通过WeCross控制台创建一个转账提案,之后router会自动完成跨链转账。
示意如下:
4.2 控制台搭建
搭建两个WeCross控制台,分别连接两个router:
- WeCross-Console1
已经安装好了控制台1,默认连接的时
BCOS
网络的router-8250
[jason@RUAN:~/wecross/WeCross-Console]$
- WeCross-Console2
搭建控制台2,并连接
Fabric
网络的router-8251
[jason@RUAN:~/wecross]$ cp -r WeCross-Console WeCross-Console2
# 修改配置:WeCross-Console2/conf/application.toml
server = '127.0.0.1:8250' => server = '127.0.0.1:8251'
4.3 FISCO BCOS前期准备
4.3.1 拷贝合约
[jason@RUAN:~/fisco]$ cp ~/wecross/WeCross/conf/chains-sample/bcos/htlc/* console/contracts/solidity/
4.3.2 部署合约
[jason@RUAN:~/fisco/console]$ bash start.sh
[group:1]> deploy BACHTLC
contract address: 0xdf6387c0739146e92b6d6b4d7e30853cd28b7e80
4.3.3 发行资产
FISCO BCOS提供了标准的资产合约
BAC001
,可借助bac工具完成资产的发行、转账和授权
[jason@RUAN:~/fisco]$ git clone https://github.com/Shareong/bactool.git
[jason@RUAN:~/fisco/bactool] (master)$ gradle build
# 拷贝sdk证书,以便工具包和节点通讯
[jason@RUAN:~/fisco/bactool] (master)$ cp ~/fisco/nodes/127.0.0.1/sdk/* dist/conf/
# 根据金额发行资产
[jason@RUAN:~/fisco/bactool/dist] (master)$ java -cp 'apps/*:lib/*:conf' Application init 100000000
# 输出BAC资产地址,以及资产的拥有者
assetAddress: 0x3e8e1e8d878e185d0fd816293766888cae3808aa
owner: 0x55f934bcbe1e9aef8337f5551142a442fdde781c
4.3.4 资产授权
要完成跨链转账,资产拥有者需要将资产的转移权授权给哈希时间锁合约
# approve [BAC资产地址] [哈希时间锁定合约地址] [授权金额]
[jason@RUAN:~/fisco/bactool/dist] (master)$ java -cp 'apps/*:lib/*:conf' Application approve 0x3e8e1e8d878e185d0fd816293766888cae3808aa 0xdf6387c0739146e92b6d6b4d7e30853cd28b7e80 1000000
approve successfully
amount: 1000000
4.3.4 哈希时间锁定合约初始化
需要将资产合约的地址和对手方的哈希时间锁合约地址保存到自己的哈希时间锁合约。
# 在FISCO BCOS控制台执行,此处约定Fabric的合约名为fabric_htlc,之后将以该名称安装和初始化链码
[group:1]> call BACHTLC 0xdf6387c0739146e92b6d6b4d7e30853cd28b7e80 init ["0x3e8e1e8d878e185d0fd816293766888cae3808aa","fabric_htlc"]
transaction hash: 0x42d92016052a76a697b4b0f20f7fb0d76be89f51026310ad52cda9b378c88906
---------------------------------------------------------------------------------------------
Output
function: init(string[])
return type: (string[])
return value: ([success])
# 查看owner余额,检查是否初始化成功
[group:1]> call BACHTLC 0xdf6387c0739146e92b6d6b4d7e30853cd28b7e80 balanceOf ["0x55f934bcbe1e9aef8337f5551142a442fdde781c"]
[1000000000]
4.4 Fabric前期准备
4.4.1 拷贝链码
# 拷贝链码到Fabric联盟链部署环境
[jason@RUAN:~]$ scp -r ~/wecross/WeCross/conf/chains-sample/fabric/ vagrant@FABRIC:~
# 登录Fabric联盟链环境
[jason@RUAN:~/Vagrant/js-fabric]$ vagrant ssh
# 将链码拷贝到Fabric cli容器中的chaincode目录下
[vagrant@RUAN:~]$ docker cp fabric/ledger/ cli:/opt/gopath/src/github.com/chaincode/ledger
[vagrant@RUAN:~]$ docker cp fabric/htlc b7cd5007ca42:/opt/gopath/src/github.com/chaincode/htlc
# 查看是否拷贝成功
[vagrant@RUAN:~]$ docker exec -it cli bash
root@b7cd5007ca42:/opt/gopath/src/github.com/hyperledger/fabric/peer# ls /opt/gopath/src/github.com/chaincode/htlc/ /opt/gopath/src/github.com/chaincode/ledger/
/opt/gopath/src/github.com/chaincode/htlc/:
htlc.go htlc_sample.go
/opt/gopath/src/github.com/chaincode/ledger/:
ledger ledger_sample.go
4.4.2 部署链码
4.4.2.1 部署资产链码
- 安装链码
root@b7cd5007ca42:~# peer chaincode install -n ledgerSample -v 1.0 -p github.com/chaincode/ledger/
[chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
[chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
[chaincodeCmd] install -> INFO 003 Installed remotely response:<status:200 payload:"OK" >
- 实例化链码
root@b7cd5007ca42:~# peer chaincode instantiate -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C jschannel -n ledgerSample -l golang -v 1.0 -c '{"Args":["init","HTLCoin","htc","100000000"]}' -P 'OR ('\''Org1MSP.peer'\'','\''Org2MSP.peer'\'')'
[chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
[chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
- 链码容器
链码成功实例化后,可以看到启动的链码容器
[vagrant@RUAN:~]$ docker ps
CONTAINER ID IMAGE
c02a2fddb6ba dev-peer0.org1.example.com-ledgersample-1.0-c5fef2fffd47d911918adabd9b6fb3d16fe68c05501318269129550a30b9f040
- 查看账户余额
root@b7cd5007ca42:~# peer chaincode query -C jschannel -n ledgerSample -c '{"Args":["balanceOf","Admin@org1.example.com"]}'
100000000
4.4.2.2 部署哈希时间锁定链码
- 安装链码
root@b7cd5007ca42:~# peer chaincode install -n fabric_htlc -v 1.0 -p github.com/chaincode/htlc/
[chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
[chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
[chaincodeCmd] install -> INFO 003 Installed remotely response:<status:200 payload:"OK" >
- 实例化链码
# 需要指定己方资产合约名和对手方的哈希时间锁合约地址
# init [己方资产合约名] [channel] [对手方哈希时间锁合约地址]
root@b7cd5007ca42:~# peer chaincode instantiate -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C jschannel -n fabric_htlc -l golang -v 1.0 -c '{"Args":["init","ledgerSample","jschannel","0xdf6387c0739146e92b6d6b4d7e30853cd28b7e80"]}'
- 链码容器
[vagrant@RUAN:~]$ docker ps
CONTAINER ID IMAGE
2ccf95eb9fa6 dev-peer0.org1.example.com-fabric_htlc-1.0-c168d9778bfda06b14c028f8dda3d1ac4f7ab668c38c3b28bbeeb91cf3cff6f5
- 查看账户余额
root@b7cd5007ca42:~# peer chaincode query -C jschannel -n fabric_htlc -c '{"Args":["balanceOf","Admin@org1.example.com"]}'
100000000
4.4.3 资产授权
ledgerSample合约通过创建一个托管账户实现资产的授权
# 该命令默认使用admin账户发交易,即admin账户完成了一次授权
root@b7cd5007ca42:~# peer chaincode invoke -C jschannel -n ledgerSample -c '{"Args":["createEscrowAccount","1000000"]}' -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
[chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200 payload:"HTLCoin-Admin@org1.example.com-EscrowAccount"
- 再次查看admin余额
变少了,因为有一部资产已经转到了托管账户。
root@b7cd5007ca42:~# peer chaincode query -C jschannel -n fabric_htlc -c '{"Args":["balanceOf","Admin@org1.example.com"]}'
99000000
4.5 哈希时间锁合约配置
4.5.1 配置FISCO BCOS端router
- 修改
~/wecross/routers-payment/127.0.0.1-8250-25500/conf/chains/bcos/stub.toml
[common]
name = 'bcos'
type = 'BCOS2.0' # BCOS
[chain]
groupId = 1 # default 1
chainId = 1 # default 1
[channelService]
caCert = 'ca.crt'
sslCert = 'sdk.crt'
sslKey = 'sdk.key'
timeout = 300000 # ms, default 60000ms
connectionsStr = ['127.0.0.1:20200']
# resources is a list
[[resources]]
# name cannot be repeated
name = 'htlc'
type = 'BCOS_CONTRACT'
contractAddress = '0xdf6387c0739146e92b6d6b4d7e30853cd28b7e80'
- 修改
~/wecross/routers-payment/127.0.0.1-8250-25500/conf/wecross.toml
[common]
zone = 'payment'
visible = true
[chains]
path = 'classpath:chains'
[rpc] # rpc ip & port
address = '127.0.0.1'
port = 8250
caCert = 'classpath:ca.crt'
sslCert = 'classpath:ssl.crt'
sslKey = 'classpath:ssl.key'
[p2p]
listenIP = '0.0.0.0'
listenPort = 25500
caCert = 'classpath:ca.crt'
sslCert = 'classpath:ssl.crt'
sslKey = 'classpath:ssl.key'
peers = ['127.0.0.1:25501']
[[htlc]]
#本地配置的哈希时间锁资源路径
selfPath = 'payment.bcos.htlc'
#确保已在router的accounts目录配置
account1 = 'bcos_sender'
#对手方的哈希时间锁资源路径
counterpartyPath = 'payment.fabric.htlc'
#确保已在router的accounts目录配置
account2 = 'fabric_user1'
4.5.2 配置Fabric端router
- 修改
~/wecross/routers-payment/127.0.0.1-8251-25501/conf/chains/fabric/stub.toml
[common]
name = 'fabric'
type = 'Fabric1.4'
[fabricServices]
channelName = 'jschannel'
orgName = 'Org1'
mspId = 'Org1MSP'
orgUserName = 'fabric_admin'
orgUserAccountPath = 'classpath:accounts/fabric_admin'
ordererTlsCaFile = 'orderer-tlsca.crt'
ordererAddress = 'grpcs://FABRIC:7050'
[peers]
[peers.org1]
peerTlsCaFile = 'org1-tlsca.crt'
peerAddress = 'grpcs://FABRIC:7051'
[peers.org2]
peerTlsCaFile = 'org2-tlsca.crt'
peerAddress = 'grpcs://FABRIC:9051'
# resources is a list
[[resources]]
# name cannot be repeated
name = 'htlc'
type = 'FABRIC_CONTRACT'
chainCodeName = 'fabric_htlc'
chainLanguage = "go"
peers=['org1']
- 修改
~/wecross/routers-payment/127.0.0.1-8251-25501/conf/wecross.toml
[common]
zone = 'payment'
visible = true
[chains]
path = 'classpath:chains'
[rpc] # rpc ip & port
address = '127.0.0.1'
port = 8251
caCert = 'classpath:ca.crt'
sslCert = 'classpath:ssl.crt'
sslKey = 'classpath:ssl.key'
[p2p]
listenIP = '0.0.0.0'
listenPort = 25501
caCert = 'classpath:ca.crt'
sslCert = 'classpath:ssl.crt'
sslKey = 'classpath:ssl.key'
peers = ['127.0.0.1:25500']
[[htlc]]
#本地配置的哈希时间锁资源路径
selfPath = 'payment.fabric.htlc'
#确保已在router的accounts目录配置
account1 = 'fabric_admin'
#对手方的哈希时间锁资源路径
counterpartyPath = 'payment.bcos.htlc'
#确保已在router的accounts目录配置
account2 = 'bcos_sender'
4.6 配置账户
两个router需要在accounts目录下配置发送者的账户,因为跨链提案只能由资产的转出者创建
4.6.1 BCOS发送者账户配置
BCOS的发送者是
bcos_sender
,故将bactool/dist/conf
目录下的私钥文件配置到conf/accounts/bcos_sender
中
# 拷贝私钥文件
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8250-25500/conf/accounts/bcos_sender]$ cp ~/fisco/bactool/dist/conf/0x55f934bcbe1e9aef8337f5551142a442fdde781c.pem .
# 修改配置文件
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8250-25500/conf/accounts/bcos_sender]$ cat account.toml
[account]
type='BCOS2.0'
accountFile='0x55f934bcbe1e9aef8337f5551142a442fdde781c.pem'
password=''
4.6.2 BCOS接收者账户配置
我们使用BCOS提供的命令行工具创建一个接收者的账户
# 创建接收者账户
[jason@RUAN:~/fisco/console]$ ./get_account.sh
[INFO] Account Address : 0x3331fec4d765a25e8c7aaf14599d8fa1a84a3811
[INFO] Private Key (pem) : accounts/0x3331fec4d765a25e8c7aaf14599d8fa1a84a3811.pem
[INFO] Public Key (pem) : accounts/0x3331fec4d765a25e8c7aaf14599d8fa1a84a3811.public.pem
# 拷贝私钥文件
[jason@RUAN:~/fisco/console]$ cp accounts/0x3331fec4d765a25e8c7aaf14599d8fa1a84a3811.pem ~/wecross/routers-payment/127.0.0.1-8250-25500/conf/accounts/bcos_receiver/
# 修改配置文件
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8250-25500/conf/accounts/bcos_receiver]$ cat account.toml
[account]
type='BCOS2.0'
accountFile='0x3331fec4d765a25e8c7aaf14599d8fa1a84a3811.pem'
password=''
- 软链
fabric_user1
账户
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8250-25500/conf/accounts]$ ln -s ~/wecross/routers-payment/127.0.0.1-8251-25501/conf/accounts/fabric_user1/ .
4.6.3 Fabric发送者账户配置
Fabric的发送者是
fabric_admin
,由于前面我们已经将私钥拷如conf/accounts/fabric_admin
,这里忽略。
4.6.4 Fabric接收者账户配置
Fabric的接收者是
fabric_user1
,由于前面我们已经将私钥拷如conf/accounts/fabric_user1
,这里忽略。
- 软链
bcos_sender
账户
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8251-25501/conf/accounts]$ ln -s ~/wecross/routers-payment/127.0.0.1-8250-25500/conf/accounts/bcos_sender/ .
4.7 重启两个router
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8250-25500]$ bash stop.sh && bash start.sh
Stop WeCross successfully
WeCross booting up ......
WeCross start successfully!
[jason@RUAN:~/wecross/routers-payment/127.0.0.1-8251-25501]$ bash stop.sh && bash start.sh
Stop WeCross successfully
WeCross booting up ......
WeCross start successfully!
注:若需要重建,还需删除
db
目录:jason@RUAN:~/wecross/routers-payment/127.0.0.1-8251-25501]$ /bin/rm -rf db/
4.8 发起跨链转账
4.8.1 协商内容
分类 | 字段 | 设置值 |
---|---|---|
BCOS | 资产转出者(bcos_sender ) |
0x55f934bcbe1e9aef8337f5551142a442fdde781c |
资产接收者(fabric_user1 ) |
0x3331fec4d765a25e8c7aaf14599d8fa1a84a3811 |
|
转账金额 | 700 | |
Fabric | 资产转出者(fabric_admin ) |
Admin@org1.example.com |
资产接收者(fabric_user1 ) |
User1@org1.example.com |
|
转账金额 | 500 | |
其他属性 | 哈希原相<br />(协商时只有发起方知道) | 819e356d63c34728bb8504a867fb7e1149056eb63674ad8293e21a7bafe28c0d |
哈希<br />(原相的sha256) | 7ae6319341ddecb190b6c103321f3b8fdb369b6285aa40052e8a97b0994732e4 |
|
时间戳t0 | 1589379749 | |
时间戳t1 | 1589379449 |
注:哈希原相和哈希可以通过控制台命令生成:
[WeCross]> genSecretAndHash secret: 819e356d63c34728bb8504a867fb7e1149056eb63674ad8293e21a7bafe28c0d hash : 7ae6319341ddecb190b6c103321f3b8fdb369b6285aa40052e8a97b0994732e4
注:可以通过跨链转账辅助命令,根据时间差生成两个合法的时间戳:
时间戳需要满足条件:t0 > t1 + 300 > now + 300
[WeCross]> genTimelock 300 timelock0: 1589379749 timelock1: 1589379449
4.8.2 创建跨链转账提案
两条链的资产转出者通过WeCross控制台创建跨链转账提案,将协商的转账信息写入各自的区块链。
使用命令:newHTLCTransferProposal
参数说明:
参数:
path
,account
(资产转出者账户名),hash
,secret
,role
,sender0
,receiver0
,amount0
,timelock0
,sender1
,receiver1
,amount1
,timelock1
- 其中下标为0的参数是发起方信息。
- 发起方
secret
传入哈希原像,role
传入true;参与方secret
传入null,role
传入false。
4.8.2.1 发起方创建转账提案
在
WeCross-Console
执行:
[WeCross]> listAccounts
name: fabric_user1, type: Fabric1.4
name: bcos_sender, type: BCOS2.0
name: bcos_receiver, type: BCOS2.0
total: 3
[WeCross]> newHTLCTransferProposal payment.bcos.htlc bcos_sender 7ae6319341ddecb190b6c103321f3b8fdb369b6285aa40052e8a97b0994732e4 819e356d63c34728bb8504a867fb7e1149056eb63674ad8293e21a7bafe28c0d true 0x55f934bcbe1e9aef8337f5551142a442fdde781c 0x3331fec4d765a25e8c7aaf14599d8fa1a84a3811 700 2000010000 Admin@org1.example.com User1@org1.example.com 500 2000000000
Txhash: 0x279dbc39836b2bb8244f3323dd297a86aadb5ad2f7fdd785089c0f5f1817db3c
BlockNum: 8
Result: create a htlc transfer proposal successfully
4.8.2.2 参与方创建转账提案
在
WeCross-Console2
执行:
[jason@RUAN:~/wecross/WeCross-Console2]$ bash start.sh
[WeCross]> listAccounts
name: fabric_user1, type: Fabric1.4
name: fabric_admin, type: Fabric1.4
name: bcos_sender, type: BCOS2.0
total: 3
[WeCross]> newHTLCTransferProposal payment.fabric.htlc fabric_admin 7ae6319341ddecb190b6c103321f3b8fdb369b6285aa40052e8a97b0994732e4 null false 0x55f934bcbe1e9aef8337f5551142a442fdde781c 0x3331fec4d765a25e8c7aaf14599d8fa1a84a3811 700 2000010000 Admin@org1.example.com User1@org1.example.com 500 2000000000
Txhash: bbc4b674d303e6ee0530da0d3f1e81865516edee8dba372f798358d8fb5e444e
BlockNum: 8
Result: create a htlc transfer proposal successfully
4.8.3 结果确认
哈希时间锁合约提供了查询余额的接口,可通过WeCross控制台调用,查看两方的接收者是否到账
4.8.3.1 FISCO BCOS用户确认
[WeCross]> call payment.bcos.htlc bcos_sender balanceOf 0x3331fec4d765a25e8c7aaf14599d8fa1a84a3811
Result: [700]
4.8.3.2 Fabric用户确认
[WeCross]> call payment.fabric.htlc fabric_admin balanceOf User1@org1.example.com
Result: [500]
5 哈希时间锁定原理
哈希时间锁定(HTLC
)只是跨链机制的一种,典型的还有:公证人机制、侧链、中继链、分布式秘钥控制等。
哈希时间锁定最早出现在比特币的闪电网络,跨链资产交换支持一定数量的A链资产和一定数量的B链资产进行原子交换。哈希时间锁定巧妙地采用了哈希锁和时间锁,迫使资产的接收方在最后期限内确定收款并产生一种收款证明给打款人,否则资产会归还给打款人。收款证明能够被付款人用来获取接收人区块链上的等量价值的数量资产或触发其他事件。
如下图所示,我们用一个例子来阐述如何使用哈希时间锁定进行跨链的原子资产交换,假设 Alice 和 Bob 有资产交换的需求,Alice
想用1个BTC
和Bob
换20个ETH
。那么首先需要在两条链上设置哈希时间锁定合约,然后执行如下步骤:
-
Alice
随机构建一个字符串s
,并计算出其哈希h = hash(s)
-
Alice
将h
发送给Bob
的合约 -
Alice
锁定自己的1个BTC
资产,并设置一个较长的锁定时间t1
, 并设置了获取该BTC
的一个条件:如果Bob
能够提供h
的原始值s
就可以得到该BTC
-
Bob
观察到Alice
合约中锁定了一个BTC
, 然后Bob
锁定自己的20个ETH
资产,并设置一个相对较短的锁定时间t2
,t2 < t1
,Bob
也设置了获取条件:如果Alice
能提供h
的原始值s
就可以获取20个ETH
-
Alice
将自己最初生成的字符串s
发送到Bob
的合约里取得了20个ETH
-
Bob
观察到步骤5中Alice
的s
值,将其发送给Alice
的合约成功获取1个BTC
- 至此 Alice 和 Bob 完成了资产的交换
在WeCross
的技术方案中,以上环节都是在提案发起后,通过跨链路由调用对应的合约来自动完成。
6 后记
后续文章将分析下WeCross
的跨链智能合约以及对跨链的原理和主要方案做下介绍。
7 参考资料
https://github.com/WeBankFinTech/WeCross