14. 面向资产互换的原子性保障应用使用指南
14.1. 概述
14.1.1. 跨链原子性协议概述
本应用支持基于哈希时间锁合约HTLC
、哈希时间锁优化合约Lilac
实现具有事务原子性保障的跨链资产互换。应用用户客户端实现了提案筛选、事件监听、自动取款、自动退款等操作。
了解跨链原子性协议设计方案,请看该链接: 跨链原子性协议设计方案
14.2. 部署流程
14.2.1. 源码下载
下载源码到本地
git clone https://git.chainmaker.org.cn/ibpc/atomic_assets_swap.git
14.3. 应用代码整体目录结构
.
├── bin # 区块链必要的可执行文件
├── chainclient # 链SDK接口
├── chainmaker_contract_test.sh # 长安链合约测试脚本
├── chainmaker_restart.sh # 长安链重启脚本
├── client # 用户客户端接口
├── client_test.md # 用户客户端测试示例文档
├── commod.md # 用户客户端测试命令文档
├── config # 链用户私钥、证书接口
├── config_files # 链配置文件、测试用户私钥、证书
├── contracts # 链上合约
├── deploy # 合约部署脚本
├── fabric_restart.sh # Fabric重启脚本
├── go.mod
├── go.sum
├── install-deploy-contract.sh # 启动合约部署脚本
├── keystore
├── main.go # 用户连接客户端
├── Makefile
├── presentation # 性能测试
├── projectinterface # 链接入的标准接口
├── README.md
├── restart.sh # 系统重启脚本
├── scripts # 其它脚本
├── stop.sh # 关闭链脚本
├── test # Fabric合约测试
├── test.sh # 覆盖率测试脚本
├── ut_cover.sh # ut测试脚本
├── utils
├── 设计方案.md
└── 部署和使用文档.md
14.3.1. 部署本地链环境,安装并启动区块链
进入应用文件夹,部署链环境
cd atomic-assets-swap/
make && ./restart.sh
14.3.2. 安装必要的合约
执行
install-deploy-contract.sh
脚本,编译并安装合约
bash install-deploy-contract.sh
14.3.3. 启动客户端
在应用根目录下, 打开两个
terminal
,模拟用户1
和用户2
用户1
终端执行
go run main.go client1
用户2
终端执行
go run main.go client2
在两个终端会看到类似的输出
tips: [当前工作空间: /home/.../atomic-assets-swap]
info: [chain1_user1 address: 99fecbbd54840df106f652f571c05384b4bafba8]
info: [chain2_user1 address: e70f6e47003083409c43392665c72a37115dc07f]
info: [配置文件: ./config_files/fabric/user.yaml]
info: [call assets getAddress]
info: [call assets reset]
info: [fabric_user1 address: 63642b1ad5a7f5dcb03372bee094b0851bef668dc5a04e8033388d4184b1f424]
Please input command line :info: [订阅lilac的withdraw]
info: [订阅lilac的newProposal]
info: [订阅htlc的newProposal]
info: [订阅htlc的withdraw]
通过输入对应的命令执行对应的操作
输入
exit
或者break
退出客户端
14.4. 使用方法
通过在控制台输入相应的交互命令执行对应的操作
当输入命令错误的时候会提示命令
tips: [###### usage ######]
newHtlcProposal chainName userName toAddr amount Preimage hashlock timelock chain2 amount
newLilacProposal chainName userName toAddr amount Preimage hashlock timelock chain2 amount
refund chainName userName contractName proposalID
withdraw chainName userName contractName proposalID preimage
getProposal chainName userName proposalType proposalID
getBalance chainName userName
getAddress chainName userName
break
exit
tips: [###### end ######]
14.4.1. 退出
在终端输入命令进行退出
exit/break
# 输出如下:
info: [login out client.]
14.4.2. 获取用户的地址
获取链
chainName
上用户userName
的地址比如在链
chain1
上获取用户user1
的地址
# getAddress chainName userName
getAddress chain1 user1
# 输出如下:
info: [address:18bea55343220196ce02038b147c149e275b38cc]
14.4.3. 获取用户余额
获取链
chainName
上用户userName
的余额比如在链
chain1
上获取用户user2
的余额
# getBalance chainName userName
getBalance chain1 user2
# 输出如下:
info: [chain1 user2 balance: 1000]
14.4.4. 发起一个新的htlc proposal
发起一个新的
htlc proposal
,是从chainName
的用户userName
,发送给目的地址toAddr
为4d8bae757deae72905c6cbc6bc688dc74f634c77
的用户amount
个token,并以preimage
为原像,锁定timelock
秒的时间,兑换chain2
的amount
个token如果
preimage
设置不为nil
则会自动计算哈希锁hashlock
,此时hashlock
的输入没有作用如果
preimage
字段设置为nil
,则将会使用hashlock
字段作为哈希锁比如链
chain1
上的用户user1
,发起一个htlc proposal
, 发给链chain1
的4d8bae757deae72905c6cbc6bc688dc74f634c77
地址用户10
个币,并从链chain2
获得1
个币,设置原像为preimage
, 时间锁timelock
设置为600
秒, 命令为
# newHtlcProposal chainName userName toAddr amount Preimage hashlock timelock chain2 amount
newHtlcProposal chain1 user1 4d8bae757deae72905c6cbc6bc688dc74f634c77 10 preimage nil 600 chain2 1
# 输出如下:
info: [preimage preimage]
info: [hashlock 107661134f21fc7c02223d50ab9eb3600bc3ffc3712423a1e47bb1f9a9dbf55f]
info: [timelock 600]
tips: [发起时的hashlock 107661134f21fc7c02223d50ab9eb3600bc3ffc3712423a1e47bb1f9a9dbf55f]
info: [newProposal:705b7fb6cd2c28ad848a00abda4708856d6f20706ba93021a5fc4d44c8eb45a4]
tips: [proposal加入完成 705b7fb6cd2c28ad848a00abda4708856d6f20706ba93021a5fc4d44c8eb45a4]
info: [{18bea55343220196ce02038b147c149e275b38cc 4d8bae757deae72905c6cbc6bc688dc74f634c77 10 1682062662 600 107661134f21fc7c02223d50ab9eb3600bc3ffc3712423a1e47bb1f9a9dbf55f preimage false false false 705b7fb6cd2c28ad848a00abda4708856d6f20706ba93021a5fc4d44c8eb45a4 chain1 user1 htlc htlc chain2 1}]
同时在客户端2看到输出
info: [===== chain1 监听到proposal ===== 705b7fb6cd2c28ad848a00abda4708856d6f20706ba93021a5fc4d44c8eb45a4]
info: [{18bea55343220196ce02038b147c149e275b38cc 4d8bae757deae72905c6cbc6bc688dc74f634c77 10 1682062661 600 107661134f21fc7c02223d50ab9eb3600bc3ffc3712423a1e47bb1f9a9dbf55f null true false false 705b7fb6cd2c28ad848a00abda4708856d6f20706ba93021a5fc4d44c8eb45a4 chain1 user2 htlc htlc 0}]
表示客户端2收到一个关于自己用户的proposal
客户端2上的链2用户2发起一个对应的proposal, 发给链
chain2
上的用户user1
地址d9053ab1c1088feaab4f727eeeac69aa327eb28c
1个token,并以同样的哈希锁107661134f21fc7c02223d50ab9eb3600bc3ffc3712423a1e47bb1f9a9dbf55f
,设置时间锁hashlock
为300
秒, 期望获得链chain1
的10
个token
newHtlcProposal chain2 user2 d9053ab1c1088feaab4f727eeeac69aa327eb28c 1 nil 107661134f21fc7c02223d50ab9eb3600bc3ffc3712423a1e47bb1f9a9dbf55f 300 chain1 10
# 输出如下:
info: [preimage ]
info: [hashlock 107661134f21fc7c02223d50ab9eb3600bc3ffc3712423a1e47bb1f9a9dbf55f]
info: [timelock 300]
tips: [发起时的hashlock 107661134f21fc7c02223d50ab9eb3600bc3ffc3712423a1e47bb1f9a9dbf55f]
info: [newProposal:8caefc5171998eafd5ff7d19116c795be5435c50ffce9e57517a8f1d24d80863]
tips: [proposal加入完成 8caefc5171998eafd5ff7d19116c795be5435c50ffce9e57517a8f1d24d80863]
info: [{e525a7ff7b740539b9bb36c3fd081acb3a0d20c2 d9053ab1c1088feaab4f727eeeac69aa327eb28c 1 1682062882 300 107661134f21fc7c02223d50ab9eb3600bc3ffc3712423a1e47bb1f9a9dbf55f false false false 8caefc5171998eafd5ff7d19116c795be5435c50ffce9e57517a8f1d24d80863 chain2 user2 htlc htlc chain1 10}]
同时会在客户端1看到输出, 表示进入了自动取款程序
info: [===== chain2 监听到proposal ===== 8caefc5171998eafd5ff7d19116c795be5435c50ffce9e57517a8f1d24d80863]
info: [{e525a7ff7b740539b9bb36c3fd081acb3a0d20c2 d9053ab1c1088feaab4f727eeeac69aa327eb28c 1 1682062881 300 107661134f21fc7c02223d50ab9eb3600bc3ffc3712423a1e47bb1f9a9dbf55f null true false false 8caefc5171998eafd5ff7d19116c795be5435c50ffce9e57517a8f1d24d80863 chain2 user1 htlc htlc 0}]
tips: [等待1秒]
info: [===== new proposal切换到对端链取钱 =====]
info: [{"sender":"e525a7ff7b740539b9bb36c3fd081acb3a0d20c2","receiver":"d9053ab1c1088feaab4f727eeeac69aa327eb28c","amount":0,"posaltime":1682062881,"timelock":300,"hashlock":"107661134f21fc7c02223d50ab9eb3600bc3ffc3712423a1e47bb1f9a9dbf55f","preimage":"preimage","locked":false,"unlocked":true,"rolledback":false}]
info: [====== 取钱成功 ======: 705b7fb6cd2c28ad848a00abda4708856d6f20706ba93021a5fc4d44c8eb45a4]
info: [======= chain1 =======]
info: [自己的proposal被取钱了]
info: [{18bea55343220196ce02038b147c149e275b38cc 4d8bae757deae72905c6cbc6bc688dc74f634c77 0 1682062661 600 107661134f21fc7c02223d50ab9eb3600bc3ffc3712423a1e47bb1f9a9dbf55f preimage false true false 705b7fb6cd2c28ad848a00abda4708856d6f20706ba93021a5fc4d44c8eb45a4 chain1 user1 htlc htlc 0}]
warning: [监听到属于自己的Propsal, 但是没在本地找到匹配的proposal异常]
随后在客户端2看到输出, 表示看到了
info: [======= chain2 =======]
info: [自己的proposal被取钱了]
info: [{e525a7ff7b740539b9bb36c3fd081acb3a0d20c2 d9053ab1c1088feaab4f727eeeac69aa327eb28c 0 1682062881 300 107661134f21fc7c02223d50ab9eb3600bc3ffc3712423a1e47bb1f9a9dbf55f preimage false true false 8caefc5171998eafd5ff7d19116c795be5435c50ffce9e57517a8f1d24d80863 chain2 user2 htlc htlc 0}]
info: [withdraw切换到对端链取钱]
info: [{"sender":"18bea55343220196ce02038b147c149e275b38cc","receiver":"4d8bae757deae72905c6cbc6bc688dc74f634c77","amount":0,"posaltime":1682062661,"timelock":600,"hashlock":"107661134f21fc7c02223d50ab9eb3600bc3ffc3712423a1e47bb1f9a9dbf55f","preimage":"preimage","locked":false,"unlocked":true,"rolledback":false}]
链1用户1和链2用户1查看余额
getBalance chain1 user1
getBalance chain2 user1
# 输出如下:
info: [chain1 user1 balance: 990]
info: [chain2 user1 balance: 1001]
客户端2同理
14.4.5. 发起一个新的lilac proposal
和
htlc proposal
一样,唯一的不同是preimage
字段需要写入多个原像,并以,
隔开发起一个新的
lilac proposal
,是从chainName
的用户userName
,发送给目的地址toAddr
为4d8bae757deae72905c6cbc6bc688dc74f634c77
的用户amount
个token,并以preimage1
和preimage2
为原像,锁定timelock
秒的时间,兑换chain2
的amount
个token,其中preimage
字段有多个用户,以英文逗号,
分割如果
preimage
设置不为nil
则会自动计算哈希锁hashlock
,此时hashlock
的输入没有作用如果
preimage
字段设置为nil
,则将会使用hashlock
字段作为哈希锁比如链
chain1
上的用户user1
,发起一个lilac proposal
, 发给链chain1
的4d8bae757deae72905c6cbc6bc688dc74f634c77
地址用户10
个币,并期望从链chain2
兑换1
个币,设置原像为preimage1,preimage2
, 时间锁hashlock
设置为10
, 等待10秒会自动退款, 命令为
# newLilacProposal chainName userName toAddr amount Preimage hashlock timelock chain2 amount
newLilacProposal chain1 user1 4d8bae757deae72905c6cbc6bc688dc74f634c77 10 preimage1,preimage2 nil 10 chain2 1
有如下输出, 其中
04dac20d774781d9a0814cbbb84a8634e24b684d100f32203068d9228700a854
为proposal id
info: [vPreimage: [preimage1 preimage2]]
info: [vHashlock: [5144f34d1b8edc707120dc254bf56e00bd9f5a6f5e6892f72103408f43ee9ded 7a869987c84cbd23568dab928f0229581c2658e61a1ee37214c83ea16ba9cba7]]
info: [timelock 10]
tips: [发起时的hashlock [5144f34d1b8edc707120dc254bf56e00bd9f5a6f5e6892f72103408f43ee9ded 7a869987c84cbd23568dab928f0229581c2658e61a1ee37214c83ea16ba9cba7]]
info: [newProposal:04dac20d774781d9a0814cbbb84a8634e24b684d100f32203068d9228700a854]
tips: [proposal加入完成 04dac20d774781d9a0814cbbb84a8634e24b684d100f32203068d9228700a854]
info: [{18bea55343220196ce02038b147c149e275b38cc 4d8bae757deae72905c6cbc6bc688dc74f634c77 10 1682063920 10 [5144f34d1b8edc707120dc254bf56e00bd9f5a6f5e6892f72103408f43ee9ded 7a869987c84cbd23568dab928f0229581c2658e61a1ee37214c83ea16ba9cba7] [preimage1 preimage2] false false false 04dac20d774781d9a0814cbbb84a8634e24b684d100f32203068d9228700a854 chain1 user1 lilac lilac chain2 1}]
等待10秒会自动退款,有如下输出
info: [proposa超时,进入退款程序:{18bea55343220196ce02038b147c149e275b38cc 4d8bae757deae72905c6cbc6bc688dc74f634c77 10 1682063920 10 [5144f34d1b8edc707120dc254bf56e00bd9f5a6f5e6892f72103408f43ee9ded 7a869987c84cbd23568dab928f0229581c2658e61a1ee37214c83ea16ba9cba7] [preimage1 preimage2] false false false 04dac20d774781d9a0814cbbb84a8634e24b684d100f32203068d9228700a854 chain1 user1 lilac lilac chain2 1}]
info: [{"sender":"18bea55343220196ce02038b147c149e275b38cc","receiver":"4d8bae757deae72905c6cbc6bc688dc74f634c77","amount":0,"posaltime":1682063920,"timelock":10,"hashlock":["5144f34d1b8edc707120dc254bf56e00bd9f5a6f5e6892f72103408f43ee9ded","7a869987c84cbd23568dab928f0229581c2658e61a1ee37214c83ea16ba9cba7"],"preimage":[],"locked":false,"unlocked":true,"rolledback":true}]
14.4.6. 手动退款
用户
userName
在链chainName
上发起一个contractName
的退款请求比如用户
user1
对在链chain1
上proposalid
为04dac20d774781d9a0814cbbb84a8634e24b684d100f32203068d9228700a854
的lilac proposal
退款,命令如下
# refund chainName userName contractName proposalID
refund chain1 user1 lilac 04dac20d774781d9a0814cbbb84a8634e24b684d100f32203068d9228700a854
由于这个
proposal id
已经被取款了,所以会失败, 报锁定状态错误
info: [run commond: [refund chain1 user1 lilac 04dac20d774781d9a0814cbbb84a8634e24b684d100f32203068d9228700a854]]
funcName->run commond error->funcName->c.refund error->c.Refund error: funcName->contractinvoke.RefundLilac error->=== IncokeContract ===
resp.Message->
resp.ContractsResult->code:1 result:"proposal \"locked\" state error" message:"Fail" gas_used:11625
error->=== client.InvokeContract ===
resp.Message->
resp.ContractsResult->code:1 result:"proposal \"locked\" state error" message:"Fail" gas_used:11625
比如用户
user1
对在链chain1
上proposalid
为04dac20d774781d9a0814cbbb84a8634e24b684d100f32203068d9228700a854
的htlc proposal
退款,命令如下
# refund chainName userName contractName proposalID
refund chain1 user1 htlc 04dac20d774781d9a0814cbbb84a8634e24b684d100f32203068d9228700a854
14.4.7. 对某个proposal id取款
用户
userName
在链chainName
上对id为propsalID
的contractName
类型的proposal取款withdraw
, 同时提供原像preimage
比如链
chain1
用户user1
,对proposal id
为04dac20d774781d9a0814cbbb84a8634e24b684d100f32203068d9228700a854
的lilac
类型proposal取款,使用withdraw
命令,需要提前知道preimage
,命令如下
# withdraw chainName userName contractName proposalID preimage
withdraw chain1 user1 lilac 04dac20d774781d9a0814cbbb84a8634e24b684d100f32203068d9228700a854 preimage1,preimage2
取款
htlc
类型的proposal,和lilac
一样,示例命令如下比如链
chain1
用户user1
,对proposal id
为04dac20d774781d9a0814cbbb84a8634e24b684d100f32203068d9228700a854
的htlc
类型proposal取款,使用withdraw
命令,需要提前知道preimage
,命令如下
# withdraw chainName userName contractName proposalID preimage
withdraw chain1 user1 htlc 705b7fb6cd2c28ad848a00abda4708856d6f20706ba93021a5fc4d44c8eb45a4 preimage