术语表 /闪电网络与 Layer 2
关闭脚本
- 关闭脚本是什么?
- 关闭脚本是闪电网络通道协作关闭时,您的闪电网络余额所支付到的链上地址,在 BOLT 2的 shutdown 消息中以原始 scriptpubkey 的形式给出。
正在关闭的通道的每一方都会指定各自的收款目的地,关闭交易会把双方的余额分别支付到该处。BOLT 2为该消息分配的类型是38,并且只接受见证版本0的脚本,除非双方节点已协商启用功能位26和27。将闪电网络资金转回冷存储的用户,应当在关闭通道之前而不是之后检查该目的地。
运作方式
关闭脚本包含在类型为38的 BOLT 2消息中,该消息依次携带通道 ID、两字节的长度和脚本本身的字节。
任何一方节点都可以发送该消息,当没有待处理的更新时,另一方必须回复自己的 shutdown 消息。从此刻起,通道进入关闭流程:shutdown 之后不得再出现 update_add_htlc,节点应拒绝路由此后到达的任何 HTLC。该消息可以在 channel_ready 之前发送,因此注资交易仍在确认中的通道可以被提前放弃。
规范对脚本的形式限制很严。始终合法的有两种:OP_0 加20字节的数据推送(即 pay to witness public key hash 输出),或 OP_0 加32字节的数据推送(即 pay to witness script hash)。见证版本1至16加2至40字节的数据推送,只有在协商了 option_shutdown_anysegwit(功能位26和27)时才合法,因此向 Taproot 地址支付取决于对方节点是否支持。第三种形式随 option_simple_close(功能位60和61)出现:OP_RETURN 加6至75字节的数据推送,或用于76至80字节的 OP_PUSHDATA1 变体,上限的原因是 OP_RETURN 脚本在比特币上只有不超过83字节时才属于标准脚本。它适用于您的份额小到不值得单独设一个输出的情形,此时金额必须为零,因此该份额会作为手续费归矿工所有。
节点还可以在通道开启时锁定自己的目的地,方法是使用 open_channel 和 accept_channel 中类型为0的 upfront_shutdown_script TLV 记录(功能位4和5)。如果双方都声明支持该功能,且提供了长度不为零的脚本,那么此后任何指定其他目的地的 shutdown 消息都必须使连接失败。BOLT 2对这一做法的作用并不讳言:它把这种预先承诺称为 "a weak commitment (a malevolent implementation tends to ignore specifications like this one!)",认为值得作为渐进式改进,因为事后更改目的地需要对方节点的配合。
在哪里会遇到它
关闭脚本属于通道的所有者,而所有者并不总是您。
在本站评测的41款钱包中,可比较 Phoenix(评分4.0)和 Wallet of Satoshi(评分2.7,其托管模式被标注为需谨慎):前者在手机上运行真正的独立闪电网络节点,通道归您所有,因此协作关闭时,shutdown 消息中放入的是您所掌控的地址。在 Wallet of Satoshi 的托管模式下(已从美国和欧盟撤出),通道属于该公司,脚本指定的是该公司的地址,您持有的是一项债权,而不是私钥。
第二种情形是关闭悄然失败。旧版节点仍可能发送非隔离见证的关闭脚本,BOLT 2指出,如果关闭交易中的非隔离见证输出低于546聪(当 dust_limit_satoshis 设置得更低时有可能出现),该交易很可能永远不会到达矿工。资金不会面临风险,但必须强制关闭通道,而不是协作结算。在 option_simple_close 下,新的 closing_complete 会覆盖上一条,因此手续费和输出脚本都可以修改,除非预先锁定的变体已在通道开启时冻结了目的地。
关闭脚本 vs 强制关闭
关闭脚本只在协作关闭中决定资金的去向。
强制关闭跳过协商:您发布最新的承诺交易,其输出支付给由通道开启时交换的基点派生出的密钥,而不是您指定的地址。您精心设置的脚本,对这条无需对方许可的唯一退出路径不起任何作用。请为您打算采用的关闭方式设置它,并为意料之外的关闭方式保留一份通道备份。