背景知識:EVM bytecode 結構

深入理解 EVM(一)

  1. solidity 源碼

    // SPDX-License-Identifier: UNLICENSED
    pragma solidity 0.8.15;
    
    contract Demo {
        uint256 a;
        constructor() {
          a = 1;
        }
    }
    
  2. 變成 bytecode

    ======= Demo.sol:Demo =======
    Binary:6080604052348015600f57600080fd5b506001600081905550603f8060256000396000f3fe6080604052600080fdfea26469706673582212204ca38d4a605f03f1487b9cb337c0853cca3c62a6c42f942ecb021fb7357002b564736f6c634300080f0033
    

看看字節碼的構造,我們在上面的字節碼中搜索 fe,可以看到其中有兩個 fe,同時查詢 Opcodes 對照表,可知 fe 是無效操作符(INVALID)。它的作用其實是分隔符,它將字節碼分成了三部分:

Untitled

<aside> 💡 bytecode = opcode + 數字 = init bytecode + rumetime bytecode + metadata

</aside>

背景知識:create2

The Promise and the Peril of Metamorphic Contracts

The Constantinople hardfork includes the infamous EIP-1014, which introduces a new opcode, CREATE2. This opcode enables a new form of wild magic where, under the right conditions, a contract can be destroyed, then redeployed to the same address with new bytecode.

<aside> 💡 create2 opcode 可以利用某些方式,創造設定好的合約地址。

</aside>

Metamorphic合约原理介绍

在Constantinople硬分叉後,EVM增加了create2這個opcode,允許傳入待創建合約的creation bytecode和salt,部署合約在指定的地址,這個地址可以用keccak256(0xff ++ deployersAddr ++ salt ++ keccak256(bytecode))[12:]計算出來。

而EVM裡還有另外一個opcode,叫做selfdestruct,可以用來銷毀當前合約,銷毀後合約的runtime code會變成0,而且storage也會全部清空。

<aside> 💡 利用 selfdestruct 與 create2 就可以巧妙「升級」合約。

</aside>

背景知識:鑽石合約

可升級合約簡單來說是透過 proxy contract(代理合約)來達成,藉由代理合約去呼叫欲執行的合約,若要升級,則把代理合約中的指向的地址換為新的合約地址即可。而執行的方式則是透過 delegateCall,但 delegateCall 不會更動目標合約的狀態。所以要怎麼處理變數,就是一門學問了。(資料來源)

可變合約 Metamorphic smart contract

介紹

<aside> 💡 其實智能合約是可以變化的,也就是重新佈署,這類合約稱為 metamorphic smart contract。

</aside>

https://a16zcrypto.com/metamorphic-smart-contract-detector-tool/

https://a16zcrypto.com/metamorphic-smart-contract-detector-tool/

原理是staticcall調用getImplementation方法,獲取implementation合約地址,再用extcodecopy把implementation合約的runtime bytecode複製到memory,做為當前部署合約的runtime bytecode,以此來動態替換合約的runtime bytecode,而合約地址又不變。(資料來源)

判斷方式