# 通过 Statechain 实现可转移的 DLC

By [BitSafe中文](https://paragraph.com/@bitsafe) · 2024-01-23

---

_作者：tomt1664_

_来源：_[_https://github.com/commerceblock/mercury/blob/master/doc/dlcs.md_](https://github.com/commerceblock/mercury/blob/master/doc/dlcs.md)

_参看：_[_Mercury 状态链协议详述_](https://www.btcstudy.org/2022/04/14/mercury-statechain-protocol-sepcification/)

在一个谨慎日志合约（discreet log contract）中的仓位所有权，也可以使用 statechain 这种基本机制来转移，只不过密钥轮换和备份交易需要应用在 DLC 的所有合约执行交易（CET）的每一个输出中。这种协议的本质可以总结如下：

具体的一个 DLC 的一方或者双方，都可以使用某个 Statechain 实体（SE）以备转移仓位，而且这并不需要改变 DLC 协议本身。实际上，即使某一方使用了 SE 服务来转移仓位，另一方也不需要知道，更不需要因此改变所有权。在下文中，我们描述了准备使用这种服务的其中一方的启动设置。

**初始化**
-------

希望使用 SE 服务、以备日后可以转移仓位的用户这样初始化一个 DLC。下列步骤是 DLC 创建流程的一部分：

1.  DLC 的第一个仓位所有者（Owner 1）生成两个私钥：`o1`（UTXO 私钥碎片）和 `b1`（后备私钥碎片）。
    
2.  Owner1 计算碎片 `o1` 的公钥 `O1 = o1.G`，并发送给 SE。
    
3.  收到 `O1` 的 SE 生成一个私钥`s1`（SE 的私钥碎片），计算对应的公钥 `S1 = s1.G`并发送给 Owner 1
    
4.  SE 和 Owner1 都可以通过将自己的私钥跟收到的公钥相乘，得出相同的共享公钥 `P = o1.(s1.G) = s1.(o1.G)`（该公钥背后的私钥是 `p = o1*s1`）
    
5.  Owner 1 和对手创建 DLC 注资交易 `Tx0`；该注资交易将数额 `A` 支付给一个 2-of-2 多签名输出（其中一个公钥是 `P`，另一个公钥是 `C`，代表着对手），这个输出也就是 opening UTXO
    
6.  Owner1 和对手，在确认一个断言机的公钥 `O` 之后，根据 DLC 协议 \[6\] 一起生成全部的待签名 CET：`TxDLC[i]`（其中 `i = 1, 2, ..., n`）。对手会签名所有这些 CET，然后全部发送给 Owner 1。
    
7.  然后，Owner 1 和 SE 一起签名收到的 CET（这样这些 CET 就凑齐了签名，但需要断言机的见证消息才能执行），这是通过两方的 ECDSA 签名实现的。将这些得到了 `P` 的签名的 CET 再发回给对手。
    
8.  SE 创建一系列的 _逐出交易_，花费各 CET 给 `P` 支付的输出（每个 CET 都有两笔）：`TxK[i, 1]` 和 `TxK[i, 2]`（`i = 1, ..., n`）
    
9.  Owner 1 和 SE 一起通过两方的 ECDSA 签名每一笔逐出交易 `TxK`。双方都要保存这些交易。
    
10.  Owner 1 生成 `b1`（后备私钥）比计算其公钥 `B1 = b1.G`。
    
11.  Owner 1 为每一笔逐出交易 `TxK` 支付给 `P` 的输出创建一系列的 _后备交易_，将资金支付给 `B1`，并（根据 BIP68）将 `nSequence` 设定为相对时间锁的最大值 `t0`：`Tx1[i,1]` 和 `Tx1[i,2]`（其中 `i = 1, ..., n`）。这些交易要发送给 SE。
    
12.  SE 收到所有的 `Tx1[i,1]` 和 `Tx1[i,2]`，验证每一笔交易的 `nSequence` 字段。然后 Onwer1 和 SE 使用共享密钥签名每一笔 `Tx1`，然后由 Owner 1 保存这些交易。
    
13.  然后，Owner 1 和对手广播 DLC 开启交易 `Tx0`。一旦交易得到确认，这个 DLC 就启动了。
    
14.  然后，SE 将 UTXO 输出点以及公钥 `O1` 加入到 _statechain_ 中，然后通过 Mainstay 协议在比特币区块上见证。
    

（译者注：逐出交易和后备交易的数量应该取决于 DLC 的实现，如果 DLC 的 CET 只有一个给予 P 资金的输出，那就只需要为每个 CET 创建一笔逐出交易和后备交易。）

**转移**
------

Owner 1 希望将自己在这个 DLC 中的仓位转移给另一个人（Owner 2）（可能是一种支付，也可能是一个复杂交易的一部分）。为此，新的所有权人必须知晓用来验证 SE 身份的公钥。新的所有权人可以要求当前的所有权人通过使用自己的密钥碎片（`O1`，这是发布在 statechain 上的）签名一条消息，来证明自己的唯一所有权。协议的流程如下：

在转移流程中，必须先执行转移共享密钥的步骤 1 ~ 14。然后执行以下步骤：

1.  SE 给 Owner 2 发送全部签过名的逐出交易 `TxK[i, 1]` 和 `TxK[i, 2]`（`i = 1, ..., n`）。
    
2.  Owner 2 为每一笔逐出交易 `TxK` 支付给 `P` 的输出创建一系列的 _后备交易_，将资金支付给 `B2`，并（根据 BIP68）将 `nSequence` 设定为相对时间锁的最大值 `t0 - c`：`Tx2[i,1]` 和 `Tx2[i,2]`（其中 `i = 1, ..., n`）。这些交易要发送给 SE。
    
3.  SE 收到所有的 `Tx2[i,1]` 和 `Tx2[i,2]`，验证每一笔交易的 `nSequence` 字段。然后 Onwer 2 和 SE 使用共享密钥签名每一笔 `Tx1`，然后由 Owner 2 保存这些交易。
    
4.  然后，SE 将 UTXO 输出点以及公钥 `O2` 加入到 _statechain_ 中，然后通过 Mainstay 协议在比特币区块上见证。
    

这个过程可以重复，从而将 DLC 仓位转移给另一个人。

**DLC 关闭**
----------

一旦断言机在 DLC 到期时发布了签名，让其中一笔 CET 成为有效交易（`TxCET[j]`），对手会向区块链提交有效的交易（或者，参与通道的两方可以和作品，从而签名一笔单独的交易，直接给各方的钱包地址支付 —— 这需要 SE 跟现任所有确认的配合）。只要一笔 CET 得到了广播（和确认），SE 和显然的所有权人就可以合作，从这个 CET 的输出中 “取出” 价值（或者，如果 SE 不响应，当前的所有确认可以提交对应的逐出交易 `TxK[j, 1]`，等待时间锁过期后使用 `Tx2[j, 1]` 取出价值）。如果 SE 不响应而且对手广播无效的状态，可以广播逐出交易 `TxK[j, 2]` ，等待时间锁过期后广播后备交易 `Tx2[j,2]`。

---

*Originally published on [BitSafe中文](https://paragraph.com/@bitsafe/statechain-dlc)*
