如何使用 smartraiden 以及 lnd 进行跨链原子资产交换

去中心化交易所 MVP

smartraiden 和 lighting network 进行跨链原子资产交换

问题

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

实现方法

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

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

2. Bob 的Exchange服务

2.1 Bob发起交易,指定Secret,金额为100,token 为 SMT,接收方为 SA
  • -->调用 Transfer 接口

    2.2 Bob等待是否收到一个金额为1BTC,密码 hash 为 Sha256(Secret),
  • -->通过 listinvoices接口轮询

    2.3 收到以后,允许自己的 SmartRaiden 响应 SecretRequest
  • -->通过/api/1/allowrevealsecret 接口

    3. Alice 的ExChange 服务

    3.1 Alice 在 SmartRaiden 上等待是否收到了来自 Bob 的100个 SMT交易
  • -->通过/api/1/getunfinishedreceivedtransfer/:tokenaddress/:locksecrethash接口轮询

    3.2 一旦收到, Alice 校验该交易是否有效,比如 Expiration 时间是否足够,必须大于125分钟(500Spectrum 块)
    3.3 如果都一致,那么通过向自己的 Lnd 注册这个 PaymentReq,并指定过期时间为100分钟,secretHash
  • -->SendPaymentSync 接口

    3.5 检测 Lnd 是否收到了密码,如果收到了,立即向 自己的SmartRaiden 注册密码
  • -->根据 SendPaymentSync 的返回得到密码,调用/api/1/registersecret注册密码

时序图

sequenceDiagram
    participant ae as  Alice's Exchange
    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 Exchange
    
    be->>ae:可以用我的100SMT 换你的1个 BTC?
    ae->>be:没问题
    be->>bs: send Transfer to Alice ,Secret,100,SMT
    be->>bl: 准备好接收金额为1BTC,密码为 Secret 的交易
    bs->>as: MediatedTransfer(Secret,100SMT,from Bob to Alice,Expiration=600)
    as->>ae:收到了有效的 MediatedTransfer
    ae->>al:向bob发起闪电网络交易(1BTC,secertHash,Expiration=10Block)
    al->>bl:send payment to bob(1BTC,secertHash,Expiration=10Block)
    bl->>al:凭 Secret 换回1BTC
    bl->>be: 收到了有效的 HTLC
    loop bob wait
        be->>be: 收到了来自 Alice 的1BTC?
    end    
    be->>bs:响应来自Alice's smartraiden 的 SecretRequest
    bs->>as: send secret to Alice,开始正常雷电交易
    loop alice wait
        al->>al: 是否收到了 Secret( 包括链上注册的密码)
    end
    ae->>as: 注册密码

smartraiden 接口设计

  1. 发起交易
    POST /api/1/transfer/:token/:receipt

    type TransferData struct {
    	Initiator      string   `json:"initiator_address"`
    	Target         string   `json:"target_address"`
    	Token          string   `json:"token_address"`
    	Amount         *big.Int `json:"amount"`
    	Secret       string   `json:"secret"`
    	Fee            *big.Int `json:"fee"`
    IsDirect       bool     `json:"is_direct"`
    }
    
  2. 允许响应 SecretRequest
    POST /api/1/allowrevealsecret/

    {
      "lock_secret_hash":"0xaaaa",
      "token_address":"0xbbbbb",
    }
    

    设置交易发起方对应的这个 SecretRequest 允许响应

  3. 查询未完成收到交易
    GET /api/1/getunfinishedreceivedtransfer/:tokenaddress/:locksecrethash

    type TransferData struct {
    	Initiator      string   `json:"initiator_address"`
    	Target         string   `json:"target_address"`
    	Token          string   `json:"token_address"`
    	Amount         *big.Int `json:"amount"`
    LockSecretHash       string   `json:"lock_secret_hash"`
    Expiration uint64  //相对于当前块还有多少块过期
    }
    
  4. 注册密码
    POST /api/1/registersecret

    {
      "secret":"0xaaaaaaa",
      "token_address":"0xbbbbbbb",
    }
    

    将密码注册到相应的 channel 中,并且将 secret 也注册到对应的 TargetStateManager

其他

闪电网络中密码的 hash 值计算方式为
rHash := sha256.Sum256(paymentPreimage[:])