# EIP-663:SWAPN、DUPN 和 EXCHANGE 指令

# 注意事項

本文並沒有經過作者外的其他審查者審核,因此若內容有誤,請到 issue 區提出問題,我會儘速修改,謝謝。

# 1. 摘要(Abstract)

  • 以前,EVM 只能使用 SWAP1SWAP16DUP1DUP16,也就是只能操作頂層的 16 個資料。
  • 現在要新增三個指令:SWAPNDUPNEXCHANGE,就能存取更深層的資料了。

# 2. 動機(Motivation)

  1. EVM 的堆疊最多可容納 1024 個資料,但原先只能輕鬆存取最頂層的 16 個項目,對於更深層的資料必須透過寫入記憶體或依賴編譯器最佳化,這會使程式變得複雜且效率降低。
  2. 在 EVM 上實作函式時,函式的輸入輸出參數數量經常超過 16 個,導致編譯器必須進行複雜的排程工作。
  3. 某些編譯器在進行堆疊最佳化(相當於變數管理)時,需要交換不同深度位置的資料,目前必須執行三條指令才能完成交換,新增的指令將可一步到位。

# 3. 新增的三個指令(Specification)

1. DUPN     (opcode = 0xe6)
2. SWAPN    (opcode = 0xe7)
3. EXCHANGE (opcode = 0xe8)
  • 在舊的「非 EOF」格式中,遇到這三個指令會直接回傳錯誤並停止執行(維持現有行為)。
  • 只有在新格式(EOF1)中才會啟用這三個指令。

# 3.1 立即參數(Immediate)

這三個指令後面都必須跟隨一個 8 位元(0~255)的參數 imm

  • DUPNSWAPN
    • n = imm + 1
  • EXCHANGE
    • n = (imm >> 4) + 1
    • m = (imm & 0x0F) + 1

# 4. 驗證規則(Validation)

  1. 禁止使用跳躍指令跳轉到這三個新指令的立即參數位元組。
  2. 當堆疊深度不足時,不能執行這三個指令:
    • DUPN:執行前必須有 ≥ n 個資料,執行後資料數【+1】
    • SWAPN:執行前必須有 ≥ n+1 個資料,執行後深度不變
    • EXCHANGE:執行前必須有 ≥ n+m+1 個資料,執行後深度不變

# 5. 執行語義(Execution Semantics)

  1. DUPN:將第 n 個資料(從上往下計算)複製到堆疊頂端
  2. SWAPN:將第 n+1 個資料和頂端資料交換位置
  3. EXCHANGE:將第 n+1 個資料和第 n+m+1 個資料交換位置

這三個指令的 Gas 費用皆為 3。

# 6. 範例說明(Examples)

為了更清楚說明,以下提供三個範例並附上 ASCII 圖示,展示各指令執行前後的堆疊狀態。

# 例子 1:DUPN 2(複製第 3 個資料)

  • 指令DUPN 2
  • 計算n = 2 + 1 = 3
  • 動作:複製第 3 個位置的資料 (C) 到堆疊頂端
初始堆疊(頂端在上):
│ E │  ← 第 1 個
│ D │  ← 第 2 個
│ C │  ← 第 3 個
│ B │  ← 第 4 個
│ A │  ← 第 5 個

執行後:
│ C │  ← 新的頂端(C 複製到頂端)
│ E │  ← 原第 1 個
│ D │  ← 原第 2 個
│ C │  ← 原第 3 個
│ B │  ← 原第 4 個
│ A │  ← 原第 5 個

# 例子 2:SWAPN 3(交換第 5 個資料與頂端)

  • 指令SWAPN 3
  • 計算n = 3 + 1 = 4,要交換第 (n+1)=5 個和頂端
  • 動作:交換 E ↔ A
初始堆疊:
│ E │  ← 頂端
│ D │  
│ C │  
│ B │  
│ A │  ← 第 5 個

執行後:
│ A │  ← 原第 5 個
│ D │  
│ C │  
│ B │  
│ E │  ← 原頂端

# 例子 3:EXCHANGE 0x02(交換第 2 個與第 5 個資料)

  • 指令EXCHANGE 0x02
  • 計算
    • n = (0x02 >> 4) + 1 = 0 + 1 = 1
    • m = (0x02 & 0x0F) + 1 = 2 + 1 = 3
    • 要交換第 (n+1)=2 個和第 (n+m+1)=5 個
  • 動作:交換 D ↔ A
初始堆疊:
│ E │  
│ D │  ← 第 2 個
│ C │  
│ B │  
│ A │  ← 第 5 個

執行後:
│ E │  
│ A │  ← 原第 5 個
│ C │  
│ B │  
│ D │  ← 原第 2 個

# 7. 設計理念(Rationale)

  • 為什麼使用立即參數? 避免動態參數變化,讓靜態分析更簡單,方便於程式檢查。
  • 為什麼限制在 255? 堆疊最深也只有 1024,256 的深度除了已經比 16 有顯著改善,且以達 1/4 的總深度。在日常使用情境中不容易出現更多的需求,此外,再增加一個位元會將會帶來過大的成本且也沒如此強烈的需求。
  • 為什麼要有 EXCHANGE? 編譯器有時需要一次交換兩個不同深度的位置,EXCHANGE 能夠一條指令完成,不需要使用三條指令。

# 8. 向前相容性(Backwards Compatibility)

  • 這三個 opcode 在之前並未被使用,不會影響現有程式碼;只有在 EOFv1 格式中才會生效。
Last Updated: 2025/5/21 下午3:18:25