尝鲜使用微众银行WeCross实现基于哈希时间锁定的跨链转账

尝鲜使用微众银行WeCross实现基于哈希时间锁定的跨链转账

jasonruan 2020.05.13

[TOC]

0 前言

微众银行在最近(2020年5月12日)发布了WeCross v1.0.0-rc2WeCross是微众区块链跨链协作平台,新版本对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联盟链

image.png

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 搭建网络示意图

image.png

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 添加账户

image.png

在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 添加账户

image.png

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会自动完成跨链转账。

示意如下:

image.png

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(资产转出者账户名), hashsecretrolesender0receiver0amount0timelock0sender1receiver1amount1timelock1

  • 其中下标为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个BTCBob换20个ETH。那么首先需要在两条链上设置哈希时间锁定合约,然后执行如下步骤:

image.png
  1. Alice 随机构建一个字符串s,并计算出其哈希 h = hash(s)
  2. Aliceh发送给Bob的合约
  3. Alice锁定自己的1个BTC资产,并设置一个较长的锁定时间 t1, 并设置了获取该BTC的一个条件:如果Bob能够提供h的原始值s就可以得到该BTC
  4. Bob观察到Alice合约中锁定了一个BTC, 然后Bob锁定自己的20个ETH资产,并设置一个相对较短的锁定时间t2, t2 < t1, Bob也设置了获取条件:如果Alice能提供h的原始值s就可以获取20个ETH
  5. Alice将自己最初生成的字符串s发送到Bob的合约里取得了20个ETH
  6. Bob观察到步骤5中Alices值,将其发送给Alice的合约成功获取1个BTC
  7. 至此 Alice 和 Bob 完成了资产的交换

WeCross的技术方案中,以上环节都是在提案发起后,通过跨链路由调用对应的合约来自动完成。

6 后记

后续文章将分析下WeCross的跨链智能合约以及对跨链的原理和主要方案做下介绍。

7 参考资料

https://github.com/WeBankFinTech/WeCross

https://wecross.readthedocs.io/zh_CN/latest/

https://www.chainnews.com/articles/111290317221.htm

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345