11. 面向资产互换的原子性保障应用
11.1. 概述
面向资产互换的原子性保障应用包含两种事务原子性保障协议,哈希时间锁合约协议(hash time lock contract, HTLC)
和哈希时间锁合约优化协议Lilac
。该应用在长安链(ChainMaker)上实现支持具有跨链事务原子性保障的跨链资产互换功能,支持长安链与长安链ChainMaker(v2.3.0 && v2.3.1)
同构跨链、长安链ChainMaker
与Fabric(release1.4)
异构跨链。
在同构跨链与异构跨链基础上,该应用实现了基于哈希时间锁协议HTLC
和优化协议Lilac
的跨链用户客户端,以支持用户自动取款和时间锁超时失效后自动退款等操作。
客户端
具备如下功能:
查询用户账户相关跨链资产信息
发起
HTLC
事务原子性保障跨链资产互换提案发起
Lilac
事务原子性保障跨链资产互换提案自动对发给用户的跨链资产互换提案取款
自动对发给用户的超时跨链资产互换提案退款
快速部署和使用实例,请按如下链接内容进行: 部署和使用文档
11.2. 设计
11.2.1. 整体设计逻辑
整体设计逻辑如下图所示
应用整体分为两部分,链上部分和链下部分。
链上部分主要包括三个合约:跨链资产合约Assets、哈希时间锁合约Htlc、哈希时间锁优化合约Lilac
链下用户客户端主要包括,长安链SDK、Fabric SDK、用户可用的功能模块,如查询用户账户地址、查询用户账户资产情况、发起跨链资产互换提案、对提案发起取款、对超时提案发起退款等
11.2.1.1. 链上合约设计
链上合约主要实现三个合约,分别是跨链资产
Assets
合约,哈希时间锁HTLC
合约,哈希时间锁优化Lilac
合约Assets
合约主要包括以下功能:
approve
授权其他账户能够从当前账户中花费一定金额的tokenallowance
获取当前账户能够从指定账户中花费的token数量transfer
转移一定数量的token给指定用户balanceOf
获取当前账户剩余token数量transferFrom
转移被授权人的token给指定用户getAddress
获取当前用户的地址
HTLC
合约主要包括以下功能:
newProposal
发起一个新的哈希时间锁提案getProposal
根据proposal id获取完整的提案信息withdraw
根据proposal id获取转给自己的tokenrefund
对一个超时的提案,取回自己锁定的token
Lilac
合约主要包括以下功能:
newProposal
发起一个新的Lilac
提案getProposal
根据proposal id获取完整的提案信息withdraw
根据proposal id获取转给自己的tokenrefund
对一个超时的提案,取回自己锁定的token
11.2.1.2. 链下用户客户端
链下用户客户端为用户开放部分可操作方法。用户通过连接客户端,输入命令的方式与系统交互。用户输入命令交由客户端后台解析命令,调用对应链的SDK接口,由对应区块链方法完成上链等相关工作。 用户客户端主要包括以下功能
newHtlcProposal
发起一个新的哈希时间锁提案newLilacProposal
发起一个新的Lilac提案refund
对一个属于自己的提案进行退款withdraw
对一个属于自己的提案取款getProposal
根据proposal id查询提案具体信息getBalance
查询自己的token余额getAddress
获取自己的地址break
退出用户客户端exit
退出用户客户端
11.3. 接口及结构说明
为了屏蔽不同链之间的区别并适配更多的链,提高应用的扩展性并减少未来的适配成本,应用设计了
链SDK接口
与本地提案结构
11.3.1. 链SDK接口说明
为了更好的进行多链适配与模块化,设计了
链SDK接口
抽象接口,任何想要接入该系统客户端的区块链,只要实现响应的接口即可。
// ChainClientInterface 客户端实现这个接口, 定义功能
type ChainClientInterface interface {
// 在链chainName发起一个proposalType的proposal, 参数为params
// @param proposalType 发起的proposal类型
// @param toAddr 接收者地址
// @param amount 发送的数量
// @param hashlock 哈希锁
// @param timelock 时间锁, 单位秒
// @return string proposalID
// @return error 错误信息
NewProposal(propsalType, toAddr, amount string, hashlock, timelock any) (string, error)
// 撤销一个proposal
// @param proposalType proposal类型"htlc","lilac"
// @param proposalID 被撤销的id
Refund(proposalType, proposalID string) error
// 取钱
// @param proposalType proposal类型"htlc","lilac"
// @param proposalID 取这个proposal的钱
// @param preimage 原像
Withdraw(proposalType, proposlID string, preimage any) error
// 监听一个链的事件
// @param contractName 被监听的合约名
// @param eventName 被监听的事件名称
// @param resultChain 获取监听结果的通道
SubscribeEvent(contractName, eventName string, resultChan chan<- any)
// 解析订阅事件为一个proposal结构体
// @param eventInfo 每个链对应的事件信息
// @return proposal 解析出来的proposal
// @return error 解析失败
ParseEventToProposal(eventInfo any) (proposalstruct.Proposal, error)
// 获取余额
// @param address 地址,如果为""则返回自己的余额
// @return string 余额
// @return error err
GetBalance(address string) (string, error)
// 获取proposal
// @param proposalID proposalID
// @return proposal 这个proposalID对应的proposal
// @return error err
GetProposal(proposalType, proposalID string) (proposalstruct.Proposal, error)
// 获取地址
// @return string 地址
// @return error err
GetAddress() (string, error)
// 获取chainID
// @return string id
// @return error err
GetChainID() (string, error)
// 关闭客户端
// 最后 defer
Close()
}
11.3.2. 本地提案结构
为了屏蔽不同区块链信息解析的障碍,应用设计了
本地提案结构
,实现链SDK接口
的链,在与用户客户端进行通信时,需要将链上信息解析为指定结构,便于客户端对信息的管理
// Proposal 提案结构, 用于本地存储
type Proposal struct {
Sender string `json:"sender"` // sender account Address
Receiver string `json:"receiver"` // receiver account Address
Amount int64 `json:"amount"` // transfer/lock token amounts
PosalTime int64 `json:"posaltime"` // proposal generation time
TimeLock int64 `json:"timelock"` // timelock
// hashlock, 在htlc中是string, 在lilac中是[]string, 需要先转换成any/[]any
HashLock any `json:"hashlock"`
// 原像, 在htlc中是string, 在Lilac中是[]string, 需要先转换成any/[]any
Preimage any `json:"preimage"`
// BlockDepth int64 `json:"blockdepth"`
Locked bool `json:"locked"` // proposal locked status
Unlocked bool `json:"unlocked"` // proposal unlocked status
Rolledback bool `json:"rolledback"` // propsoal rolledback status
// 以下是为了实现proposal匹配而额外增加的属性
ProposalID string `json:"proposalID"` // proposal id
ChainName string `json:"chainName"` // proposal chain name
UserName string `json:"userName"` // proposal user name
ContractName string `json:"contractName"` // 这个proposal合约名
ProposalType string `json:"proposalType"` //proposal type such as 'htlc' 'lilac'
CorrespondingChainName string `json:"correChainName"` // 对端的名字
CorrespondingAmount int64 `json:"correAmount"` // 对端应该转给我多少钱
}