# EIP-7620:EOF 合約部署新方式
# 注意事項
本文並沒有經過作者外的其他審查者審核,因此若內容有誤,請到 issue 區提出問題,我會儘速修改,謝謝。
# 簡介
在過去我們用 CREATE 或 CREATE2 指令來部署新合約,但在 EOF 格式出現後,由於合約結構的改變,這些舊指令與模式就不再適用了。因此,我們迫切需要定義一套新的機制來處理 EOF 格式的合約部署。
本 EIP 引入了兩個新指令:
- EOFCREATE:用來建立新的 EOF 合約
- RETURNCODE:用來指定要實際部署的程式碼內容
# 新的合約部署流程
+—————––+      +——————+      +——————+
| 工廠合約內有多個 |      | 執行 EOFCREATE   |      | 執行成功後透過   |
| 子容器(合約程式碼)|  ->  | 選擇其中一個子容器 |  ->  | RETURNCODE 指定 |
|                    |      | 作為初始程式碼     |      | 要部署的容器     |
+—————––+      +——————+      +——————+
# EOFCREATE 範例
假設我們有一個工廠合約,想用它來建立一個簡單的 ERC20 代幣合約:
+———————————————————+
| 工廠合約(Factory Contract)                           |
|                                                         |
| +———————+    +–––––––––––+     |
| | 子容器 #0(主程式碼)|    | 子容器 #1(初始程式碼)|     |
| |                     |    |                      |     |
| | EOFCREATE{1}        |    | 讀取輸入參數         |     |
| |(選擇子容器 #1 作為 |    | 設定代幣名稱和符號    |     |
| | 初始程式碼)        |    | RETURNCODE{2}        |     |
| +———————+    +–––––––––––+     |
|                                                         |
| +————————————————+      |
| | 子容器 #2(ERC20 合約程式碼)                 |      |
| |                                                |      |
| | 名稱:<待填入>                                 |      |
| | 符號:<待填入>                                 |      |
| | transfer()                                     |      |
| | balanceOf()                                    |      |
| | … 其他 ERC20 功能 …                        |      |
| +————————————————+      |
+———————————————————+
使用流程範例:
- 使用者呼叫工廠合約的部署函式,並傳入所需的參數,比如:代幣名稱、代幣符號、salt 值等
- 工廠合約執行 EOFCREATE{1} 指令,選擇子容器 #1 為初始程式碼
- 初始程式碼執行時讀取參數,設定代幣名稱與符號
- 初始程式碼最後執行 RETURNCODE{2},選擇子容器 #2 作為實際部署合約
- 新的 ERC20 合約會被部署到一個新地址:keccak256(0xff || 工廠合約地址 || salt)[12:]
# 執行流程
+—————+     +——————+     +——————+     +––––––––+
| 使用者呼叫工廠 |     | 工廠合約執行     |     | 初始程式碼執行   |     | 部署 ERC20 合約 |
| 合約並傳入參數 | –> | EOFCREATE{1}     | –> | 並使用           | –> | 到新地址,      |
|               |     | 選擇子容器 #1    |     | RETURNCODE{2}    |     | 參數已設定完成  |
+—————+     +——————+     +——————+     +––––––––+
# 指令說明
# EOFCREATE(0xec)
 這個指令是新版專屬 EOF 的合約部署方式,概念上更類似於 CREATE2。
使用步驟:
- 從堆疊中讀取 salt、輸入資料位置與大小、部署時的初始餘額
- 選定工廠合約內某個子容器作為初始程式碼
- 初始程式碼執行後,透過 RETURNCODE指定要實際部署的合約
- 最後的合約地址是:keccak256(0xff || 工廠合約地址 || salt)[12:]
# RETURNCODE(0xee)
 這個指令是用來指定部署時應使用哪個容器作為最終合約程式碼。
使用方式:
- 從堆疊讀取額外資料位置與大小
- 選擇一個容器作為部署對象
- 將額外資料附加在容器的資料區段中
# 資料區段的生命週期
合約在部署前後,資料區段會發生變化:
部署前:
+———————––+
| 預部署資料區段          |
+———————––+
|<–– 預部署資料大小 —>|
部署後:
+———————––+–––––+———––+
| 預部署資料區段          | 靜態額外 | 動態額外    |
|                         | 資料     | 資料        |
+———————––+–––––+———––+
|<–– 預部署資料大小 —>|                       |
|                         |<–– 額外資料 —––>|
|<––––––– 最終資料大小 ——————>|
# 驗證規則
為了確保部署安全與正確性,必須符合以下驗證規則:
- EOFCREATE的- initcontainer_index必須小於容器總數
- EOFCREATE指向的子容器資料大小必須正確
- 初始程式碼不能包含 RETURN或STOP
- RETURNCODE的目標容器索引必須合法
- 被部署的容器不得含有 RETURNCODE
- 容器不得同時含有 RETURNCODE與RETURN/STOP
- 子容器必須在父容器中有被正確引用
- 同一容器不得同時被 EOFCREATE和RETURNCODE引用
- 跳躍指令不得跳到 EOFCREATE或RETURNCODE之後的位置
# 結語
本 EIP 讓我們可以在以太坊的新 EOF 格式下,更安全、更清楚地部署智慧合約。透過 EOFCREATE 和 RETURNCODE 的組合,我們能動態地創建像 ERC20 這樣的合約,也可以根據輸入參數自訂內容,保有合約部署的彈性。如同原本部署舊有合約的方式一樣。