ERC-1967 規範邏輯合約地址在代理合約上的統一儲存位置,能夠讓區塊鏈瀏覽器分辨某合約地址是否為代理合約,並讓其取得邏輯合約的位置,得知代理合約真正會執行的函式邏輯。
作為與用戶直接互動的代理合約 (proxy),當用戶呼叫函式時,會使用 delegatecall
呼叫邏輯合約,執行邏輯合約上的函式邏輯,但是合約的資料卻是儲存是在代理合約身上。亦即,邏輯合約只用來跑函式邏輯,資料不會儲存在該合約上。
代理合約的用處,通常是讓合約的邏輯可以被升級,透過更換代理合約所指向的邏輯合約的位址,來更新程式碼邏輯。
因此,雖然合約經部署至區塊鏈上就不能做更動,但若有可升級合約的設計,便能夠透過一筆交易來更換程式邏輯。對開發者而言,若發現合約有安全漏洞,可升級的話是再好不過。但對用戶而言,與可升級的合約互動,代表你必須小心某天安全的合約會不會升級成壞合約,偷偷把你的錢拿走。
能夠升級合約是一個很大的權力,誰能升級合約要規範好,不能隨便讓每個人都能升級。
--
Implementation 所在 slot 位置:
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc
來自 bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
Admin (可升級合約的人的地址) 所在 slot 位置:
0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103
來自 bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)
--
使用 cast storage
檢查是否為 proxy,如果結果不是 zero address 那就是 proxy:
cast storage --rpc-url $base \
0x0b74a419f5528234ec7b5781d8d15df8be5804e5 \
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc
上面例子是某人的合約帳戶地址,它也是一個 Kernel 的 proxy 地址,查詢後,可以得到邏輯地址是 0xbac849bb641841b44e965fb01a4bf5f074f84b4d
。(每個人的 Kernel 合約帳戶所指向的邏輯地址都是這裡,因此你不能叫別人把代幣打進邏輯合約,它不是你的合約帳戶地址。)