Solidity

isContract 函式使用 EVM 程序集獲取地址的程式碼大小

  • February 6, 2019

我的問題是我需要確保我的合約只處理來自 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 比查找合約的私鑰更可行。

該功能對權益證明沒有任何依賴,並將繼續工作。

引用自:https://ethereum.stackexchange.com/questions/14015