solidity 源碼
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.15;
contract Demo {
uint256 a;
constructor() {
a = 1;
}
}
變成 bytecode
======= Demo.sol:Demo =======
Binary:6080604052348015600f57600080fd5b506001600081905550603f8060256000396000f3fe6080604052600080fdfea26469706673582212204ca38d4a605f03f1487b9cb337c0853cca3c62a6c42f942ecb021fb7357002b564736f6c634300080f0033
看看字節碼的構造,我們在上面的字節碼中搜索 fe,可以看到其中有兩個 fe,同時查詢 Opcodes 對照表,可知 fe 是無效操作符(INVALID)。它的作用其實是分隔符,它將字節碼分成了三部分:
<aside> 💡 bytecode = opcode + 數字 = init bytecode + rumetime bytecode + metadata
</aside>
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>
在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 不會更動目標合約的狀態。所以要怎麼處理變數,就是一門學問了。(資料來源)
<aside> 💡 其實智能合約是可以變化的,也就是重新佈署,這類合約稱為 metamorphic smart contract。
</aside>
https://a16zcrypto.com/metamorphic-smart-contract-detector-tool/
原理是staticcall調用getImplementation方法,獲取implementation合約地址,再用extcodecopy把implementation合約的runtime bytecode複製到memory,做為當前部署合約的runtime bytecode,以此來動態替換合約的runtime bytecode,而合約地址又不變。(資料來源)