作者:Bastien Teinturier
来源:https://github.com/t-bast/lightning-docs/blob/master/lightning-privacy.md
作者使用代码块提供了很有帮助的图示,如果在网站上无法正常显示(有些图示很长,需要横向滚动条才能正常阅读),请跳转到原文对照观看。
本文阐述了闪电网络在隐私性方面的缺陷、普通用户如何规避它们带来的影响,以及我们准备采用哪些手段来解决它们。
链上到链下隐私性
无论你何时使用闪电网络,都会留下链上足迹:你需要开启和关闭支付通道。因此,确保链上足迹不会泄露太多信息很重要。
识别闪电网络通道充值脚本
正如我们在介绍闪电网络交易的文章中指出的那样,通道充值交易使用的是 p2wsh 2/2 多签。当通道处于开启状态时,一切都很好:攻击者在区块链上看到的只是一个 p2wsh 输出,无法获得里面包含的信息。但是,关闭通道时,我们必须自曝它使用的是 2/2 多签,强烈暗示了它可能是闪电网络通道。
幸而这个问题被 Taproot 轻松化解了。我们使用的不再是 p2wsh 输出,而是带有密钥路径花费的 Musig2,看起来与一个正常的签名输出没有区别。
但是,关闭支付通道的方式有两种:在双方配合的情况下,二人共同创建一笔交易将最终余额发送给彼此;如果一方不配合,将由另一方单方面创建交易。
在第二种情况下,被广播的交易就是我们在关于闪电网络交易的文章中介绍的承诺交易。该交易利用闪电网络独有的专门脚本,让参与者能够拿回自己的资金。这些脚本在链上可见,显然会暴露背后的闪电网络通道。遗憾的是,或许没有办法能在保证资金安全性的情况下解决这一问题。节点运营者应该尽量避免单方面关闭通道:只在对等节点作恶或失联的情况下采用这种方式。
公开通道
闪电网络节点目前通过向对等节点发送 channel_announcement
消息在闪电网络中广播自己的通道。对等节点会将这个消息转发给网络中的其它对等节点。该消息包含充值交易的详细信息,可以让所有运行闪电网络节点的人知道哪些 UTXO 用于闪电网络通道。
闪电网络通道之所以会在网络中公开,是因为我们使用源路由(source routing)来确保付款隐私性:假设 Alice 想要向 Bob 发送一笔付款,Alice 必须根据现有通道找到一条触达 Bob 的路径。如果 Alice 可以获取完整的网络拓扑图,她就能自己找出路径,不向任何人透露自己要向 Bob 付款的事。
+------+ +-----+
| Node | | Bob |
+------+ +-----+
| |
| |
+-------+ +------+ +------+
| Alice |---------| Node |---------| Node |
+-------+ +------+ +------+
| |
| +------+ |
+-------------| Node |-------------+
+------+
若想保证付款匿名性,我们便无法彻底摆脱这一机制,但是我们可以改进它。我们无需公开通道的所有信息,只需让全网知道有一个给定金额的链上交易在两个节点之间创建了一条通道。我们的实现方案还有部分细节没有完全敲定,但是可能会用到一些密码学技术(例如,环签名或零知识证明)。
不公开的通道
可喜的是,不想路由付款的节点(例如,移动钱包和商家)可以选择不向全网公开其通道。
+------+ +------+
| Node |---------| Node |
+------+ +------+
| |
| |
+-------+ +------+ +------+ +------+ +-----+
| Alice |ooooooooo| Node |---------| Node |---------| Node |ooooooooo| Bob |
+-------+ +------+ +------+ +------+ +-----+
o |
o +------+ |
oooooooooooooo| Node |-------------+
+------+
注意:不公开的通道使用 “oooooooo” 来表示
但是,节点若想接收付款,必须要让收款方找到路径。为此,节点需要公开通道的部分信息。目前,节点采用的解决方案是,将部分未公开通道的全部信息放到 Bolt 11 发票中。这个方案的缺点是,发票有时会被拿来公开分享(比如被放上推特),这会泄露未公开通道的信息。
我们即将推出两个功能来解决这个问题:
利用 “Offer” 提供一个公开分享时不会泄露通道信息的静态“地址”
Route Blinding(路由盲化)可以让收款方向付款方完全隐藏其
node_id
和通道
请注意,路由节点也可以利用未公开通道来保护 UTXO 隐私性。如果两个节点之间开启了多条通道,它们可以选择只向全网公开其中一条通道,将其余通道保密。当它们收到一笔付款需要转发时,它们可以使用未公开通道,这样就没人知道它们转发了这笔交易。参见下面这则例子,其中未公开通道用 oooo
表示:
0.4 btc 1.2 btc
oooooooooooooooooooo oooooooooooooooooooooo
o o o o
+------+ 1 btc +------+ 1.5 btc +------+ 0.8 btc +------+
| Node |-----------| Node |-------------| Node |-------------| Node |
+------+ +------+ +------+ +------+
o 0.6 btc o
oooooooooooooooooooo
但是,这里面也有个小小的缺陷:寻路启发法根据节点之间的通道容量来对通道进行排名。一旦路由节点隐藏了自己的容量,会影响其路由评分。
链下到链下隐私性
一旦你开启了通道,闪电网络会为你的付款带来更高的匿名性,因为已开启的通道不会产生任何链上足迹。我们在下文探索一些细节和不足。
付款关联
闪电网络付款使用一个叫作 Sphinx 的洋葱路由方案,可以确保中间节点只知道所在路径上的前一个节点和后一个节点,但是不知道是否还有其它跳。
例如,如果 Alice 使用下方付款路径向 Dave 付款:
+-------+ +-----+ +-------+ +------+
| Alice |---------->| Bob |---------->| Carol |---------->| Dave |
+-------+ +-----+ +-------+ +------+
当 Bob 收到将付款转发给 Carol 的请求时,Bob 只知道:
付款可能来自 Alice 或 Alice 上游的某个未知节点
付款要发送给 Carol 或 Carol 下游的某个未知节点
同样地,Carol 只知道:
付款可能来自 Bob 或 Bob 上游的某个未知节点
付款要发送给 Dave 或 Dave 下游的某个未知节点
该机制极大地提高了付款隐私性。但是,它也会泄露部分数据:由于 HTLC 的工作原理,路径上的所有节点都被赋予了相同的付款标识符 payment_hash
。如果这条路径上有两个节点由同一个实体控制,它们就能发现自己转发的是同一笔付款。
+---------------------------+
| Well well well... |
| I know that payment hash! |
+---------------------------+
|
|
+-------+ +-----+ +-------+ +------+ +------+
| Alice |---------->| Bob |---------->| Carol |---------->| Bob2 |---------->| Dave |
+-------+ | +-----+ | +-------+ | +------+ | +------+
| | | |
+--------------+ +--------------+ +--------------+ +--------------+
| payment_hash | | payment_hash | | payment_hash | | payment_hash |
| 0x123456 | | 0x123456 | | 0x123456 | | 0x123456 |
+--------------+ +--------------+ +--------------+ +--------------+
我们将在下一节中解释这种付款关联会如何破坏移动钱包付款的隐私性。
幸好,Taproot 可以让我们使用 PTLC 代替 HTLC。其一大优点是,能够彻底避免付款关联攻击:有了 PTLC,路径中的每个节点会看到不同的随机付款标识符。
+-------------------------+
| Never seen that payment |
| point before... |
+-------------------------+
|
|
+-------+ +-----+ +-------+ +------+ +------+
| Alice |---------->| Bob |---------->| Carol |---------->| Bob2 |---------->| Dave |
+-------+ | +-----+ | +-------+ | +------+ | +------+
| | | |
+---------------+ +---------------+ +---------------+ +---------------+
| payment_point | | payment_point | | payment_point | | payment_point |
| 0x02123456 | | 0x03ff0123 | | 0x03abcdef | | 0x026bcad3 |
+---------------+ +---------------+ +---------------+ +---------------+
移动钱包识别
大多数用户会使用移动钱包进行闪电网络付款。移动钱包本质上有别于服务器节点:移动钱包无法向其直接对等节点隐瞒自己是移动钱包的事实。它们没有稳定的 IP 地址,大多数时间都不在线,而且不参与付款路由,因此很容易被识破。
这会导致一个后果,只要移动钱包请求其对等节点转发付款,对等节点就知道移动钱包是付款方。同样地,将付款转发给移动钱包时,节点也知道移动钱包就是收款方。
再结合上一节中提到的付款关联问题,攻击者能够发现是谁在向谁付款:
+-----------------------+
| Well well well... |
| Alice is paying Dave! |
+-----------------------+
|
mobile | mobile
+-------+ +-----+ +-------+ +------+ +------+
| Alice |---------->| Bob |---------->| Carol |---------->| Bob2 |---------->| Dave |
+-------+ | +-----+ | +-------+ | +------+ | +------+
| | | |
+--------------+ +--------------+ +--------------+ +--------------+
| payment_hash | | payment_hash | | payment_hash | | payment_hash |
| 0x123456 | | 0x123456 | | 0x123456 | | 0x123456 |
+--------------+ +--------------+ +--------------+ +--------------+
一旦闪电网络转向 PTLC,中间节点就只能知道付款方或收款方是谁,无法同时知道两个人的身份。正如我们所知,移动钱包无法隐藏该信息。但是,这还不算太糟糕,因为:
移动钱包可以使用 Tor 或 VPN 隐藏其真正的 IP 地址:
node_id
是它们在闪电网络上的唯一身份,而且可以定期更换(代价是开启新的通道)对等节点只能知道移动钱包在付款或收款,无法知道它们在向谁付款或从谁那里收款
移动钱包可以向自己付款,以此伪造流量,抵御链下分析启发法
移动钱包可以有多个对等节点,这样每个对等节点都只能窥知钱包的部分付款
请注意,本小节内容只适用于连接到由他人运行的节点的移动钱包。如果你自己运行闪电网络节点,你的移动钱包又只连接到这个节点,上述问题便不存在了:网络甚至看不到你的移动钱包,因为一切都将由你的闪电网络节点处理。
路径寻找方案
攻击者还可以利用路径寻找方案发起更高级的付款隐私性攻击。我们来探索以下两个方案:
- 多路径付款的交叉点(multi-part payment path intersection)
- 路径图过滤(graph filtering)
我们首先探索交叉的多路径付款。多路径付款可以提高针对中间节点的付款隐私性(因为它们只能看到部分付款额),但是会向收款方节点泄露更多数据(因为收款方节点会看到多部分付款从不同通道送达)。以下方的多部分付款为例:
+-------+ +------+ +------+
| Alice |----------| Node |----------| Node |------------------+
+-------+ +------+ +------+ |
| | MPP part #1
+------------------+ |
| |
+-----+ +------+ +------+ MPP part #2 +------+
| Bob |------------| Node |----------| Node |---------------| Dave |
+-----+ +------+ +------+ +------+
| |
| |
| | MPP part #3
+-------+ +------+ +------+ |
| Carol |----------| Node |----------| Node |------------------+
+-------+ +------+ +------+
Dave 可以回溯所有可能的路径,并找到它们之间的交叉点。对上图进行简单的分析之后,我们显然可以看出付款方最有可能是 Bob。在这种分析下,发送方的匿名性无法得到保证。
但是,请注意图中只是理论上的例子。如果对象是公共路径图上的真实付款,这种分析可能无法奏效,但我认为还是值得一提。
路径图过滤攻击甚至更为复杂,而且需要更多资源。但是其攻击思路很有意思,值得我们探究。
我们来想象一个只连接了一个节点(Eve)的用户(Alice):
+-------+ +-----+
| Alice |----------| Eve |
+-------+ +-----+
Alice 以为她的付款是私密的,因为付款路径是她自己计算的。但是,由于她只有一个对等节点 Eve,Alice 只能通过 Eve 获得公共路径图的更新。Eve 可以利用这一事实过滤掉一些通道,给 Alice 一个被裁剪后的路径图,让 Alice 不得不通过 Eve 控制的节点触达网络中的大部分节点。
+------+ +------+ +------+
+-------------| Node |----------| Node |----------| Eve2 |-------------+
| +------+ +------+ +------+ |
| | |
| +-----------------+ |
| | |
+-------+ +-----+ +------+ +------+ +------+ +------+
| Alice |----------| Eve |----------| Node |xxxxxxxxxx| Node |----------| Node |----------| Dave |
+-------+ +-----+ +------+ +------+ +------+ +------+
| | |
| | |
| | |
| +------+ +------+ +------+ |
+-------------| Node |xxxxxxxxxx| Node |----------| Node |-------------+
+------+ +------+ +------+
以上图为例,Eve 过滤了被标记 xxxxx
的通道。如果 Alice 想要向 Dave 付款,她只能找到经过 Eve 的第二个节点的路径,让 Eve 可以对付款进行去匿名化。
再强调一遍,这种攻击只对特定情况有效,而且大概率只有理论意义。
Trampoline(蹦床)
Trampoline 路由可以让移动钱包将部分付款路径计算交由中间节点负责。此处需要强调的是,钱包只是将部分而非全部付款路径计算交由中间节点负责,从而保障付款隐私性。
我们来看下图:
Alice's local neighborhood Dave's local neighorhood
+--------------------------------------------------+ +--------------------------------------------------+
| | | |
| +------+ | +------+ +------+ +------+ | +------+ |
| +--------------| Node |-----------------------------| N2 |----------| N3 |----------| N4 |-------------+ +------------| Node | |
| | +------+ | +------+ +------+ +------+ | | | +------+ |
| | | | | | | | | |
| | +------------------+ | | | | | | |
| | | | | | | | | |
| +-------+ +-----+ +-------+ | +------+ +------+ +------+ | +------+ +-------+ +------+ |
| | Alice |----------| Bob |-----------| Terry |----------| N1 |----------| Node |----------| Node |----------| Ted |----------| Carol |----------| Dave | |
| +-------+ +-----+ +-------+ | +------+ +------+ +------+ | +------+ +-------+ +------+ |
| | | | | |
| | +------------------+ | | |
| | | | | |
| | +------+ | | |
| +--------------| Node | | | |
| +------+ | | |
| | | |
+--------------------------------------------------+ +--------------------------------------------------+
Alice 和 Dave 无需同步完整的路径图,只需同步与自己相邻的部分路径。这样不仅节省了大量带宽,而且极大地提高了运行路径寻找算法的速度。
我们来看一个典型的 trampoline 付款例子。
第一步是收款方(Dave)创建一个支票。发票内包含与 Dave 相邻的一些 trampoline 节点,能够将付款路由给 Dave。Dave 通过对其周边路径图进行简单搜索来寻找 trampoline 节点。为简单起见,Dave 的发票中只包含了一个 trampoline 节点(Ted)。
Alice 查看了 Dave 的发票,得知自己必须触达 Ted。Alice 就近选择了 trampoline 节点 Terry。然后,Alice 创建了一条 trampoline 路径:
Alice -----> Terry -----> Ted -----> Dave
Alice 将这条 trampoline 路径加密到一个付款洋葱内。该付款洋葱在结构上与普通付款相同,但是体积更小一些。
然后,Alice 就近寻找一条触达 Terry 的路径:
Alice -----> Bob -----> Terry
Alice 为这条路径创建了一个普通付款洋葱,trampoline 洋葱被放进了给 Terry 的负载。整体来看,这个洋葱如下所示:
+---------------------------------+
| encrypted payload for Bob |
+---------------------------------+
| encrypted payload for Terry |
| +-----------------------------+ |
| | encrypted payload for Terry | |
| +-----------------------------+ |
| | encrypted payload for Ted | |
| +-----------------------------+ |
| | encrypted payload for Dave | |
| +-----------------------------+ |
| | padding | |
| +-----------------------------+ |
+---------------------------------+
| padding |
+---------------------------------+
Alice 将这笔付款发送出去:
Alice's local neighborhood Dave's local neighorhood
+--------------------------------------------------+ +--------------------------------------------------+
| | | |
| +------+ | +------+ +------+ +------+ | +------+ |
| +--------------| Node |-----------------------------| N2 |----------| N3 |----------| N4 |-------------+ +------------| Node | |
| | +------+ | +------+ +------+ +------+ | | | +------+ |
| | | | | | | | | |
| | +------------------+ | | | | | | |
| | | | | | | | | |
| +-------+ +-----+ +-------+ | +------+ +------+ +------+ | +------+ +-------+ +------+ |
| | Alice |>>>>>>>>>>| Bob |>>>>>>>>>>>| Terry |----------| N1 |----------| Node |----------| Node |----------| Ted |----------| Carol |----------| Dave | |
| +-------+ +-----+ +-------+ | +------+ +------+ +------+ | +------+ +-------+ +------+ |
| | | | | |
| | +------------------+ | | |
| | | | | |
| | +------+ | | |
| +--------------| Node | | | |
| +------+ | | |
| | | |
+--------------------------------------------------+ +--------------------------------------------------+
对于中间节点 Bob 来说,这笔付款看起来与普通付款无异。Bob 只知道:
这笔付款可能来自 Alice 或 Alice 之前的某个未知节点
这笔付款要发送给 Terry 或 Terry 之后的某个未知节点
Bob 并不知道这笔付款使用了 trampoline
当 Terry 收到付款时,他得知自己必须找到通往 Ted 的路径,并将付款转发给 Ted。Terry 只知道:
这笔付款可能来自 Bob 或 Bob 之前的某个未知节点
这笔付款要发送给 Ted 或 Ted 之后的某个未知节点
Terry 找到一条触达 Ted 的路径,并为这条路径创建一个普通洋葱,trampoline 洋葱被放进了给 Ted 的负载(这个洋葱的最上面一层未封装)。整体来看,这个洋葱如下所示:
+--------------------------------+
| encrypted payload for N1 |
+--------------------------------+
| encrypted payload for N2 |
+--------------------------------+
| encrypted payload for N3 |
+--------------------------------+
| encrypted payload for N4 |
+--------------------------------+
| encrypted payload for Ted |
| +----------------------------+ |
| | encrypted payload for Ted | |
| +----------------------------+ |
| | encrypted payload for Dave | |
| +----------------------------+ |
| | padding | |
| +----------------------------+ |
+--------------------------------+
| padding |
+--------------------------------+
Terry 将付款转发给下一个节点:
Alice's local neighborhood Dave's local neighorhood
+--------------------------------------------------+ +--------------------------------------------------+
| | | |
| +------+ | +------+ +------+ +------+ | +------+ |
| +--------------| Node |-----------------------------| N2 |>>>>>>>>>>| N3 |>>>>>>>>>>| N4 |>>>>>>>>>>>>>> +------------| Node | |
| | +------+ | +------+ +------+ +------+ | v | +------+ |
| | | | ^ | | v | |
| | +------------------+ | ^ | | v | |
| | | | ^ | | v | |
| +-------+ +-----+ +-------+ | +------+ +------+ +------+ | +------+ +-------+ +------+ |
| | Alice |>>>>>>>>>>| Bob |>>>>>>>>>>>| Terry |>>>>>>>>>>| N1 |----------| Node |----------| Node |----------| Ted |----------| Carol |----------| Dave | |
| +-------+ +-----+ +-------+ | +------+ +------+ +------+ | +------+ +-------+ +------+ |
| | | | | |
| | +------------------+ | | |
| | | | | |
| | +------+ | | |
| +--------------| Node | | | |
| +------+ | | |
| | | |
+--------------------------------------------------+ +--------------------------------------------------+
对于 N1、N2、N3 和 N4 这些中间节点来说,这笔付款看起来与普通付款无异。它们只知道:
这笔付款可能来自前一个节点或更前面的某个节点
这笔付款要发送给后一个节点或更后面的某个节点
它们不知道这笔付款使用了 trampoline
当 Ted 收到付款时,他得知自己必须找到一条触发 Dave 的路径,并将付款转发给 Dave。Ted 只知道:
这笔付款可能来自 N4 或 N4 之前的某个节点
这笔付款要发送给 Dave 或 Dave 之后的某个节点
如果 Dave 是移动钱包,Ted 就会知道 Dave 是最终收款方
但是 Dave 可以在他和 Ted 之间使用路由盲化(route blinding)来向 Ted 隐藏自己的身份!
Ted 找到通往 Dave 的路径并为该路径创建了一个普通洋葱,trampoline 洋葱被放进了给 Dave 的负载(这个洋葱的最上面一层未封装)。整体来看,这个洋葱如下所示:
+--------------------------------+
| encrypted payload for Carol |
+--------------------------------+
| encrypted payload for Dave |
| +----------------------------+ |
| | encrypted payload for Dave | |
| +----------------------------+ |
| | padding | |
| +----------------------------+ |
+--------------------------------+
| padding |
+--------------------------------+
Ted 将这笔付款发送出去:
Alice's local neighborhood Dave's local neighorhood
+--------------------------------------------------+ +--------------------------------------------------+
| | | |
| +------+ | +------+ +------+ +------+ | +------+ |
| +--------------| Node |-----------------------------| N2 |>>>>>>>>>>| N3 |>>>>>>>>>>| N4 |>>>>>>>>>>>>>> +------------| Node | |
| | +------+ | +------+ +------+ +------+ | v | +------+ |
| | | | ^ | | v | |
| | +------------------+ | ^ | | v | |
| | | | ^ | | v | |
| +-------+ +-----+ +-------+ | +------+ +------+ +------+ | +------+ +-------+ +------+ |
| | Alice |>>>>>>>>>>| Bob |>>>>>>>>>>>| Terry |>>>>>>>>>>| N1 |----------| Node |----------| Node |----------| Ted |>>>>>>>>>>| Carol |>>>>>>>>>>| Dave | |
| +-------+ +-----+ +-------+ | +------+ +------+ +------+ | +------+ +-------+ +------+ |
| | | | | |
| | +------------------+ | | |
| | | | | |
| | +------+ | | |
| +--------------| Node | | | |
| +------+ | | |
| | | |
+--------------------------------------------------+ +--------------------------------------------------+
对于中间节点 Carol 来说,这笔付款看起来与普通付款无异。Carol 只知道:
这笔付款可能来自 Ted 或 Ted 之前的某个节点
这笔付款要发送给 Dave 或 Dave 之后的某个节点
如果 Dave 是移动钱包,Carol 就会知道 Dave 是最终收款方(非 trampoline 付款同样如此)
Carol 并不知道这笔付款使用了 trampoline
由于 Alice 和 Dave 看不见绝大部分路径图,他们使用的大概率不是最佳的路由路径。例如,整个网络的实际情况可能是这样的:
Alice's local neighborhood Dave's local neighorhood
+--------------------------------------------------+ +--------------------------------------------------+
| | | |
| +------+ | +------+ +------+ +------+ | +------+ |
| +--------------| Node |-----------------------------| N2 |----------| N3 |----------| N4 |-------------+ +------------| Node | |
| | +------+ | +------+ +------+ +------+ | | | +------+ |
| | | | | | | | | |
| | +------------------+ | | | | | | |
| | | | | | | | | |
| +-------+ +-----+ +-------+ | +------+ +------+ +------+ | +------+ +-------+ +------+ |
| | Alice |----------| Bob |-----------| Terry |----------| N1 |----------| Node |----------| Node |----------| Ted |----------| Carol |----------| Dave | |
| +-------+ +-----+ +-------+ | +------+ +------+ +------+ | +------+ +-------+ +------+ |
| | | | | | |
| | +------------------+ | | | |
| | | | | | |
| | +------+ | | | |
| +--------------| Node |----------------------|-------------------------------------------------------|--------------------------+ |
| +------+ | | |
| | | |
+--------------------------------------------------+ +--------------------------------------------------+
虽然存在更高效的路径,但是 Alice 和 Dave 并不知道。这实际上有助于隐私保护,因为它增加了路径的不可预测性和随机性,可以防范攻击者利用启发法进行逆向工程。
在本例中,我们只使用了两个中间 trampoline 节点,因为这是最高效的做法,但是注重隐私的用户可能会在路径中间再随机增加一个 trampoline 节点,确保最终路径与最优路径大相径庭。
除此之外,trampoline 可与多路径付款完美结合,提高后者的可靠性和隐私性。每个 trampoline 节点都可以将自己收到的多个付款部分聚合起来,然后重新拆分成不同的部分转发出去:
150k sat +------+ 250k sat 300k sat +------+ 200k sat
+-------------| Node |-------------+ +-------------| Node |--------------+
| +------+ | | +------+ |
| | | |
| | | |
| | | |
+-------+ 250k sat +------+ 400k sat +-------+ 500k sat +------+
| Alice |---------------------------| Bob |-----------------------------| Carol |-------------------------| Dave |
+-------+ +------+ +-------+ +------+
| |
| |
| |
| +------+ |
+-------------| Node |-------------+
150k sat +------+ 300k sat
由于 trampoline 节点知道自己的本地余额(远程节点并不知道),它们能够更高效地决定如何拆分需要转发的付款。
此外,这样也能解决我们上文提到的多路径付款交叉问题。路径中的每个 trampoline 节点(包括最终收款方)都能进行路径交叉分析,但是只能推断出上一个 trampoline 节点,无法找出真正的付款方。
相关资料
(完)