Solidity
isContract 函式使用 EVM 程序集獲取地址的程式碼大小
我的問題是我需要確保我的合約只處理來自 EOA(外部擁有的賬戶)的交易。為此,我需要確定我正在處理的帳戶類型。在這個問題中,我找到了一個解決方案,程式碼如下:
function isContract(address addr) returns (bool) { uint size; assembly { size := extcodesize(addr) } return size > 0; }
由於我根本不懂彙編,所以我不知道那裡發生了什麼。
- 此功能是否按描述工作?
- 有沒有辦法讓契約愚弄它?
- 當網路過渡到 POS 時,這個功能會起作用嗎?
謝謝!
**編輯:**如果從合約的建構子呼叫該函式,它將返回 false(因為尚未部署合約)。
如果有的話,應該非常小心地使用程式碼,以避免安全黑客攻擊,例如:
https://www.reddit.com/r/ethereum/comments/916xni/how_to_pwn_fomo3d_a_beginners_guide/(存檔)
重複:_
不要使用 EXTCODESIZE 檢查來阻止智能合約呼叫函式。這不是萬無一失的,它可以被建構子呼叫破壞,因為在建構子執行時,該地址的 EXTCODESIZE 返回 0。
請參閱欺騙 EXTCODESIZE 返回 0 的合約的範常式式碼。
如果你想確保外部擁有的賬戶 (EOA) 正在呼叫你的合約,一個簡單的方法是
require(msg.sender == tx.origin)
. 但是,阻止契約是一種具有安全性和互操作性考慮的反模式。當實施帳戶抽象時,這將需要重新審視。
之前的回答。**是的,**該功能有效。
EXTCODESIZE 是用於獲取地址處程式碼大小的 EVM 操作碼。
0x3b EXTCODESIZE 獲取賬戶程式碼的大小
合約不能欺騙 EXTCODESIZE 為合約的大小返回零。
此外,外部擁有的帳戶 (EOA) 無法欺騙此程式碼,使其認為 EOA 是契約。這是因為 EOA 沒有程式碼(零長度),並且您無法將程式碼放入 EOA 比查找合約的私鑰更可行。
該功能對權益證明沒有任何依賴,並將繼續工作。