CrossChainAtomicExchange

SmartRaiden 和 Lighting Network 进行去中心化跨链原子资产交换

前言

如果能够进行以太坊和比特币跨链原子资产交换,是不是一件很酷的事情?
目前链下的扩容方式有很多,最广为人知的就是比特币的闪电网络和以太坊的雷电网络,今天我就来告诉如何通过智能雷电和闪电网络来实现跨链原子资产交换。

场景

  1. Alice 在某个信息发布网站上发布信息,希望用1个 BTC 置换100个 SMT
  2. Bob 看到以后,和 Alice 进行沟通,达成交换意见 那么Alice 和 Bob 如何不需要借助任何第三方实现原子资产置换呢?


智能雷电与闪电网络测试环境

什么是智能雷电?

智能雷电是一种最新的链下扩容方案,可以实现即时的、低费用和可扩展的支付。可以运行与以太坊和光谱链,兼容ERC20 token 和 ERC233 token。
它是跨平台的,目前支持 Windows Linux MacOS Android IOS
为了更好的适用于移动设备各种复杂的网络环境,智能雷电支持无网支付,安全快捷。
同时智能雷电也是开源的,并且正在积极维护中,想要参与和详细了解请移步官方源码.

准备步骤

安装启动智能雷电

在本地搭建一个Bob和Alice的环境,让他们建立通道。假设你已经安装好了 go geth 如果没有请参考安装说明

连接以太坊测试网络

连接以太坊的测试链testnet

geth --testnet --fast --rpc --rpcapi eth,net,web3 --bootnodes "enode://20c9ad97c081d63397d7b685a412227a40e23c8bdc6688c6f37e97cfbc22d2b4d1db1510d8f61e6a8866ad7f0e17c02b14182d37ea7c3c8b9c2683aeb6b733a1@52.169.14.227:30303,enode://6ce05930c72abc632c58e2e4324f7c7ea478cec0ed4fa2528982cf34483094e9cbc9216e7aa349691242576d552a2a56aaeae426c5303ded677ce455ba1acd9d@13.84.180.240:30303"

启动节点

启动两个节点,分别是AliceBob
启动Alice

smartraiden --datadir=.smartraiden --api-address=0.0.0.0:5001 --listen-address=127.0.0.1:400001 --address="0x69c5621db8093ee9a26cc2e253f929316e6e5b92" --keystore-path ~/.ethereum/keystore  -password-file /file --eth-rpc-endpoint ws://127.0.0.1:8546 

启动Bob

smartraiden --datadir=.smartraiden --api-address=0.0.0.0:5002 --listen-address=127.0.0.1:40002 --address="0x31ddac67e610c22d19e887fb1937bee3079b56cd" --keystore-path ~/.ethereum/keystore --password-file /file --eth-rpc-endpoint ws://127.0.0.1:8546  
  • datadir 节点的本地数据存储目录
  • api-address rest api 监听端口
  • address 以太坊节点地址,如果没有可以通过geth account new创建
  • keystore-path --keystore-path 路径
  • password-file password-file 路径
  • eth-rpc-endpoint 以太坊全节点的rpc端口,默认的websocket是8546

此时你就已经成功搭建好了本地智能雷电节点网络,可以通过查询SmartRaiden api文档来创建通道。

安装启动闪电网络

本地搭建一个Bob和Alice的闪电网络测试环境,让他们建立通道。

连接Btcd测试链

默认你已经安装好了btcdlnd,如果没有请参考安装说明

运行btcd,打开终端,然后运行

btcd --txindex --testnet --rpcuser=kek --rpcpass=kek
  • txindex是必须的,以便lnd客户端能够从中查询历史交易btcd
  • testnet 指定我们正在使用的testnet网络
  • rpcuserrpcpass 设置用于对btcd实例进行身份验证的默认密码

启动节点

启动两个节点,分别是AliceBob
启动Alice

lnd --rpclisten=localhost:10001 --listen=localhost:10011 --restlisten=localhost:8001 --datadir=data --logdir=log --debuglevel=info --bitcoin.testnet --bitcoin.active --bitcoin.node=btcd --btcd.rpcuser=kek --btcd.rpcpass=kek 

  • rpclisten:host:侦听RPC服务器的端口。这是应用程序与之通信的主要方式lnd
  • listen:host:侦听传入P2P连接的端口。这是在网络层面,不同于Lightning频道网络和比特币/ Litcoin网络本身。
  • restlisten:host:port,公开REST api,用于与lndHTTP 进行交互。例如,您可以通过向GET请求获取Alice的频道余额localhost:8001/v1/channels。
  • datadir:lnd将存储数据的目录
  • logdir:记录输出的目录。
  • debuglevel:所有子系统的日志记录级别。可以设置为 trace,debug,info,warn,error,critical。
  • bitcoin.testnett:指定是否使用simnet或testnet
  • bitcoin.active:指定比特币处于活动状态。还可以包括 --litecoin.active激活Litecoin。
  • bitcoin.node=btcd:使用btcd完整节点与区块链连接。请注意,使用Litecoin时,选项是--litecoin.node=btcd。
  • btcd.rpcuser和--btcd.rpcpass:btcd实例的用户名和密码。请注意,使用Litecoin时,选项为--ltcd.rpcuser 和--ltcd.rpcpass

启动Bob

lnd --rpclisten=localhost:10002 --listen=localhost:10012--restlisten=localhost:8002 --datadir=data --logdir=log --debuglevel=info --bitcoin.testnet --bitcoin.active --bitcoin.node=btcd --btcd.rpcuser=kek --btcd.rpcpass=kek 

为了不必每次都输入一堆命令,可以修改配置文件lnd.conf

  • MacOS:lnd.conf位于:/Users/[username]/Library/Application\ Support/Lnd/lnd.conf
  • Linux:~/.lnd/lnd.conf

datadir=data
logdir=log
debuglevel=info
debughtlc=true

bitcoin.active=1
bitcoin.testnet=1
bitcoin.node=btcd
btcd.rpchost=localhost
btcd.rpcuser=kek
btcd.rpcpass=kek

现在启动Alice节点我们只需要输入

lnd --rpclisten=localhost:10001 --listen=localhost:10011 --restlisten=localhost:8001

重新打开新的终端,创建Alice钱包密码

lncli --rpcserver=localhost:10001 --macaroonpath=data/admin.macaroon create

为了避免每次都输入--rpcserver=localhost:1000X--macaroonpath标记,可以设置一些别名

alias lncli-alice="lncli --rpcserver=localhost:10001 --macaroonpath=data/admin.macaroon"
alias lncli-bob="lncli --rpcserver=localhost:10002 --macaroonpath=data/admin.macaroon"

Bob创建钱包同上

此时AliceBob就可以创建通道了,详细教程请参考lnd api

实现方法

到这里我们为了进行SmartRaiden 和 Lighting Network 进行跨链原子资产交换的准备工作就已经完成了,具体的实现方法如下。
回到我们最初的那个问题

Alice 在某个信息发布网站上发布信息,希望用1个 BTC 置换100个 SMT

Bob和Alice SmartRaiden场景

sequenceDiagram
participant A as Alice's SmartRaden
participant B as Bob's SmartRaiden 
B->>A:发送100SMT 密码=Secret
Note over A,A:收到MediatedTransfer,密码hash=Sha256(Secret)
A->>B:不断发送SecretRequest...

Bob和Alice Lnd场景

sequenceDiagram
participant A as Alice's Lnd
participant B as Bob's Lnd 
Note over B,B:Bob addinvoice:密码=Secret 1BTC
A->>B:发送:1BTC,payment_hash=Sha256(Secret)
Note over B,B:校验Payment_hash=Sha256(Secret)
Note over A,A:发送成功后,可以知道交易的Secret

1. Bob和 Alice 分别启动自己的 Atmosphere 服务

Atmosphere 服务会启动响应的SmartRaiden和Lnd
假设 Alice 在SmartRaiden的节点使用的私钥为 SA_Priv, 公钥为 SA, 在 Lnd 节点使用的私钥为 LA_Priv, 公钥为 LA
假设 Bob 在 SmartRaiden 节点使用的私钥为 SB_Priv, 公钥为 SB, 在 Lnd 节点使用的私钥为 LB_Priv, 公钥为 LB

2. Bob 的Atmosphere服务

  • 1 Bob发起交易,指定Secret,金额为100,token 为 SMT,接收方为 SA

  • 2 Bob等待是否收到一个金额为1BTC,密码 hash 为 Sha256(Secret),

  • 3 收到以后,允许自己的 SmartRaiden 响应 SecretRequest

3. Alice 的Atmosphere 服务

  • 1 Alice 在 SmartRaiden 上等待是否收到了来自 Bob 的100个 SMT交易

  • 2 一旦收到, Alice 校验该交易是否有效,比如 Expiration 时间是否足够,必须大于125分钟(500Spectrum 块)

  • 3 如果都一致,那么通过向自己的 Lnd 注册这个 PaymentReq,并指定过期时间为100分钟,secretHash

  • 4 检测 Lnd 是否收到了密码,如果收到了,立即向 自己的SmartRaiden 注册密码

跨链时序图

sequenceDiagram
participant ae as  Alice's Atmosphere
    participant al as Alice's Lnd
    participant as as Alice's SmartRaiden
    participant space
    participant bs as Bob's SmartRaiden
    participant bl as Bob's Lnd
    participant be as Bob's Atmosphere
    
    be->>ae: 可以用我100SMT换你1 BTC? 
    ae->>be: 没问题
    be->>bs: 发送MediatedTransfer 给Alice:Secret,100SMT
    be->>bl:准备接受金额为1BTC,密码为Secret的交易
    bs->>as: MediatedTransfer(Secret,100SMT,from Bob to Alice,Expiration=600)
    as->>ae: 收到了有效的 MediatedTransfer
    ae->>al: 通过Lnd向bob发送 (1BTC, secretHash, Expiration=10Block) 
  
    al->>bl: Send payment to bob(1BTC,secertHash,Expiration=10Block)
        loop alice wait
        al->>al:是否收到了Secret(包括链上注册的密码)
    end
    bl->>al: 凭借Secret换回1BTC
    bl->>be: 收到有效的 HTLC
    loop bob wait
        be->>be: 收到了来自Alice的1BTC ?
    end
    be->>bs: 响应来自Alice'SmartRaiden 的 SecretRequest 
    bs->>as: 发送 Secret给Alice 开始正常的雷电交易
    ae->>as:如果还没有收到Smarraiden交易,去链上注册密码