以太坊虛擬機

EVM 預編譯合約

預編譯合約是一個位於固定合約地址、卻根本不是用 EVM 位元組碼寫成的內建函式——它直接以快速的原生程式碼實作在用戶端軟體(Geth、Nethermind 等)裡。對合約而言,它看起來就像一個你 CALL 進去、給點輸入、拿回輸出的普通地址;但在底層,用戶端認出這個特殊地址,改執行手工最佳化的原生程式碼,而非逐個解讀操作碼。它們的存在,是為了那些若在 EVM 裡一條指令一條指令執行就會貴得離譜的運算。

經典的預編譯合約位於較低的地址。地址 0x01 是 ecrecover,從一個 ECDSA 簽章還原出簽署者的地址——這是以太坊上簽章驗證的支柱。0x02 與 0x03 是 SHA-256 與 RIPEMD-160(對比特幣互通有用)。0x04 是恆等函式(一次廉價的記憶體複製)。0x05 是模指數運算(modexp),用於 RSA 與其他數論檢查。地址 0x06、0x07、0x08 在 alt-bn128(BN254)曲線上提供橢圓曲線加法、純量乘法與配對檢查——這正是讓 EVM 能廉價到足以在鏈上驗證 zk-SNARK 證明的密碼學引擎。0x09 是 Blake2 壓縮函式,0x0A 則是 EIP-4844 為驗證 blob 承諾而新增的 KZG 點求值預編譯合約。

預編譯合約以各自量身打造、反映真實原生成本的 gas 公式定價,往往取決於輸入大小(例如 modexp 與配對檢查,會對較大的輸入或較多的配對收更多費)。這套定價影響極大:bn128 配對預編譯合約之所以負擔得起,正是鏈上 SNARK 驗證——進而 ZK 彙整——在經濟上可行的關鍵。

由於新增或重新定價一個預編譯合約會改動共識,它只能透過硬分叉完成,且每個用戶端都必須逐位元完全一致地實作。多年來,這套預編譯合約恰恰隨著新密碼學對生態日益重要而擴充,各種提案持續被討論,要加入像 BLS12-381(現正透過 EIP-2537 落地)這類曲線以支援 BLS 簽章,以及更高效的證明系統。

預編譯合約沒有位元組碼,因此對其地址呼叫 EXTCODESIZE 會回傳零;那些靠檢查程式碼大小來判斷「這是合約嗎?」的函式庫,可能錯把預編譯合約當成一般帳戶。