本篇意在通过简单的描述总结这篇博客:[《Nick 的方法 - 以太坊无密钥执行/部署方法》](https://learnblockchain.cn/article/9795)。它描述了,如何使用无密钥的方式去构建一个交易,并使其顺利执行, 我们可以在一些特殊的使用场景中,利用这样的机制,帮我们绕过一些问题。
Activity
SpaceStation09 commentedon Feb 14, 2025
工作原理
Tx的构造
一个在以太坊上valid的交易(签名后),会包含以下字段:
通过以上的例子,我们会发现,交易中并没有“from”的字段(即,并没有描述交易的签署者)。那么,节点如何知道谁在执行交易呢?A:使用
ecrecover从签名中恢复出地址。Aha!
如果我们随意修改这个交易的签名(v,r,s的值)会发生什么呢?交易并不会被视为无效。只要签名恢复出的地址所对应的账户,符合交易的condition(例如,足够支付交易费用或者调用合约时,满足合约规定的条件)。那么,我们就可以:
将
(v,r,s)的值改为随机生成的值,此时,我们可以通过我们build的tx,以及随机生成的签名来恢复出一个地址,随后我们为这个地址手动提供一些Ether 以cover 交易的费用,并将我们build的tx广播到网络中,就可以使得交易从我们恢复的地址成功执行。总的来说,这样我们就可以无密钥得构造一个符合我们需求的可执行的交易,不过这个交易地址是一次性的,是个单次使用的不可控的地址。
SpaceStation09 commentedon Feb 14, 2025
Use Case
如何像11,440人发送Ether
这个方法当时被用于在DAO黑客事件之后,向链上的11,440个地址发送Ether。
困境:资金由多重签名控制,每次需要从多签账户转账到某个地址时,要求多个签名是很麻烦且消耗资源的(时间,gas cost)。
利用以上section描述的机制,我们有一个新方法:
MultiSend合约,该合约将一组的资金发送给一组接收者,合约代码如下:MultiSend合约发起104次交易。这个图查看的时候,我们可以这样理解,真正执行流程的时候,顺序是自顶向下的,而当我们作为开发者build的时候,是自下向上的。
MultiSend)。我们生成原始的Tx后,为104个交易分别生成随机的(r, s, v), 并计算出,它们对应的104个branch addresses。MultiSend来发送对应的资金给104个branch addresses。构建出原始的Tx后,我们随机生成(r, s, v), 并计算出该交易对应的Root address。Root address转账对应的资金。这样以来,我们要用多签账户给11,440个地址发送资金,只需要一个签名就可以完成。
在同一地址上进行多链部署
提到这个使用场景,想必,我们脑子里已经有现成的解决方案了,比如人工控制部署的EOA地址相同,nonce相同;或者,利用合约工厂+
CREATE2。上述机制,为我们提供了另一个有趣的解决方案: 我们可以使用一个不受控制的地址作为from,这样它的的nonce极大概率就是0,然后我们可以在不同的链上发起这个交易,这样被部署的合约地址就是一样的了。但必须要强调的是,这个思路只是一个看起来有趣的方案,但实际存在不少问题,所以放在这里作为一个趣味脑洞。 存在的问题有:
chainId防止在多链上重放交易的机制,我们签名中的v就是与chainID有关的,这意味着,我们换了一条链时,v也会随之改变。进而导致签名,生成地址的改变和被部署合约地址的改变。