在以太坊上,智能合约并非“上传即运行”,而是经过部署、创建账户、执行初始化代码、调用函数等多个阶段,最终形成可被调用的链上代码单元。理解这一流程,有助于开发者编写更可靠的合约,也有助于安全分析和调试优化。

✦ 1. 合约部署流程概述

部署合约是一笔特殊交易,其特点是:

📌 部署流程图见图 1:合约部署流程图

[EOA 构造交易]
     ↓
[交易签名与广播]
     ↓
[交易进入区块 → 被打包]
     ↓
[节点执行交易(含部署)]
     ↓
[EVM 执行部署代码(Constructor)]
     ↓
[返回 Runtime Bytecode]
     ↓
[将 Runtime Bytecode 写入新地址账户的 code 字段]
     ↓
[更新 StorageRoot 与 StateRoot]

解释:
1️⃣ 构造交易:由外部账户(EOA)发起,data 字段为合约部署字节码。
2️⃣ 签名与广播:本地签名 → 节点广播 → Mempool 等待打包。
3️⃣ 区块打包:交易被矿工/验证者打包进新区块。
4️⃣ 节点执行交易:启动 EVM → 执行字节码(constructor 部分)。
5️⃣ EVM 返回 Runtime Bytecode:通过 RETURN 指令返回 runtime code。
6️⃣ 创建新账户地址 → 存储 codeHash 与 runtime bytecode。
7️⃣ 状态树更新 → 写入 storageRoot、stateRoot。

✦ 2. 部署交易结构

合约部署交易的关键字段如下:

字段 含义
nonce 部署者账户的交易计数
to null,表示创建新合约
value 部署时附带的 ETH(可选)
data 包含 constructor 初始化代码
gasLimit 执行合约初始化的资源限制

✦ 3. 合约地址生成机制

合约部署后会生成一个20 字节的合约地址,通常有两种生成方式:

✅ 常规部署(CREATE)

address = keccak256(rlp(sender, nonce))[-20:]

🧪 特殊部署(CREATE2)

address = keccak256(0xFF ++ sender ++ salt ++ keccak256(init_code))[-20:]