我最近在重新学以太坊opcodes,也写一个“WTF EVM Opcodes极简入门”,供小白们使用。
所有代码和教程开源在github: github.com/WTFAcademy/WTF-Opcodes
这一讲,我们介绍EVM中的CREATE
指令,它可以让合约创建新的合约。
initcode 初始代码
之前我们提到过,以太坊有两种交易,一种是合约调用,而另一种是合约创建。在合约创建的交易中,to
字段设为空,而data
字段应填写为合约的初始代码(initcode
)。initcode
也是字节码,但它只在合约创建时执行一次,目的是为新合约设置必要的状态和返回最终的合约字节码(contract code
)。
下面,我们看一个简单的initcode
:63ffffffff6000526004601cf3
。它的指令形式为:
它先用MSTORE
指令把ffffffff
拷贝到内存中,然后用RETURN
指令将它拷贝到返回数据中。这段initcode
会把新合约的字节码设置为ffffffff
。
CREATE
在EVM中,当一个合约想要创建一个新的合约时,会使用CREATE
指令。它的简化流程:
- 从堆栈中弹出
value
(向新合约发送的ETH)、mem_offset
和length
(新合约的initcode
在内存中的初始位置和长度)。 - 计算新合约的地址,计算方法为:
- 更新ETH余额。
- 初始化新的EVM上下文
evm_create
,用于执行initcode
。 - 在
evm_create
中执行initcode
。 - 如果执行成功,则更新创建的账户状态:更新
balance
,将nonce
初始化为0
,将code
字段设为evm_create
的返回数据,将storage
字段设置为evm_create
的storage
。 - 如果成功,则将新合约地址推入堆栈;若失败,将
0
推入堆栈。
下面,我们在极简EVM中实现CREATE
指令:
测试
-
使用
CREATE
指令部署一个新合约,发送9
wei,但不部署任何代码: -
使用
CREATE
指令部署一个新合约,并将代码设置为ffffffff
:
总结
这一讲,我们介绍了EVM
中创建合约的指令CREATE
,通过它,合约可以创造其他合约,从而实现更为复杂的逻辑和功能。我们已经学习了144个操作码中的141个(98%)!