EOA 賬戶中的鎖定乙太幣:虛假合約地址
我正在閱讀這篇論文:CLUE: Towards Discovering Locked Cryptocurrencies in Ethereum,網址為: https ://www.researchgate.net/publication/346425189_CLUE_Towards_Discovering_Locked_Cryptocurrencies_in_Ethereum 它說:
Contract-creation Failure EOA: When the user deploys a smart contract in Ethereum, he/she will still receive one fake contract address if the contract-creation fails. Indeed, the received contract address does not exist in StateDB just after the contractcreation failure. However, some users might wrongly ignore the failure message and still transfer cryptocurrencies to the fake contract address, leading to cryptocurrencies locked permanently. Because the address with locked cryptocurrencies never stores code, we classify it as EOA.
是否有可能獲得虛假的合約地址?上面的文字是否正確?
祖爾菲。
也許“假”這個詞在那種情況下不適合使用。
讓我們看一下從solidity-by-example中獲取的另一個合約部署合約的這種方式:
function deploy(bytes memory bytecode, uint _salt) public payable { address addr; /* NOTE: How to call create2 create2(v, p, n, s) create new contract with code at memory p to p + n and send v wei and return the new address where new address = first 20 bytes of keccak256(0xff + address(this) + s + keccak256(mem[p…(p+n))) s = big-endian 256-bit value */ assembly { addr := create2( callvalue(), // wei sent with current call // Actual code starts after skipping the first 32 bytes add(bytecode, 0x20), mload(bytecode), // Load the size of code contained in the first 32 bytes _salt // Salt from function arguments ) if iszero(extcodesize(addr)) { revert(0, 0) } } emit Deployed(addr, _salt); } }
特別注意程式碼塊:
if iszero(extcodesize(addr)) { revert(0, 0) }
它通過檢查契約程式碼大小來檢查契約是否正確部署
extcodesize
(在此處檢查操作碼列表)。如果這個檢查不存在並且由於某種原因,合約沒有正確部署,我們將有一個地址,但沒有與之相關的程式碼。
合約的地址來源於部署者合約的資訊。因此,理論上,我們可以在不部署合約的情況下生成或獲取合約的可能地址。如果我們在實際部署合約之前將 eth 發送到該地址,那麼我們將無法將合約部署到該地址,我們將失去 eth。
例如,檢查以下合約部署程序:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; contract TestDeployContract { uint256 public counter = 1; receive() external payable {} } contract Contract { // Using keccak256 hash of the contract name to use it as the salt bytes32 public hash = keccak256("TestDeployContract"); address public testDeployContractAddress; address public testDeployContractAddressFromAssembly; // Function to derive the address of a smart contract. function getPredictedContractAddress() public view returns (address) { // Passing address(this) manually here. But we have no option to provide any address we want when actually deploying the contract with create2 bytes32 hash32 = keccak256( abi.encodePacked(bytes1(0xff), address(this), uint256(hash), keccak256(type(TestDeployContract).creationCode)) ); return address(uint160(uint(hash32))); } function deploy() public { // No option provide any creator address we want when actually deploying the contract // So it uses the address of the contract that is executing this code, // mix it with the bytecode of the TestDeployContract and the salt to produce a // keccak256 hash and derive the new contract address from it TestDeployContract testDeployContract = new TestDeployContract{salt: hash}(); testDeployContractAddress = address(testDeployContract); } function deployWithAssembly() public { uint256 _salt = uint256(hash); address addr; bytes memory bytecode = type(TestDeployContract).creationCode; assembly { addr := create2( callvalue(), // wei sent with current call // Actual code starts after skipping the first 32 bytes add(bytecode, 0x20), mload(bytecode), // Load the size of code contained in the first 32 bytes _salt // Salt from function arguments ) if iszero(extcodesize(addr)) { revert(0, 0) } } testDeployContractAddressFromAssembly = addr; } }
如果您呼叫該
getPredictedContractAddress()
函式,您將獲得deploy()
或deployWithAssembly()
將創建並返回的合約的地址。因此,如果我們getPredictedContractAddress()
在部署合約之前呼叫,並在 etherscan 中檢查返回的地址,它將看起來像一個正常的、有效的地址。我們可以向它發送 eth。但是我們沒有它的私鑰,它只是一種有效的地址格式,但它不屬於任何人,也不是合約。如果我們將 eth 發送到該地址,我們將無法將合約部署到該地址,我們將失去 eth。我做的。查看:
https://rinkeby.etherscan.io/address/0xb2216681F3bA09280E5D018f1b7C03D532bF55dc
我向它發送了一些測試 eth。然後,我呼叫該
deploy()
函式,並將“派生”地址分配給狀態變數,以便我可以看到它:但是你猜怎麼著,合約部署並沒有失敗,並且部署地址的實際地址不是預期的地址,因為它已經忙/使用了,所以它實際上部署在 address
0x26b76b352b0472f1494bc8e740cb0452fe516ed2
,但deploy()
函式說它部署在0xb2216681F3bA09280E5D018f1b7C03D532bF55dc
. 特別糟糕。檢查部署的合約:https ://rinkeby.etherscan.io/address/0x26b76b352b0472f1494bc8e740cb0452fe516ed2
所以,現在我認為我的合約的未來地址現在它只是一個普通的 EOA,並且由於我在部署合約之前已經向它發送了 eth,我無法恢復這些 eth,它們已經失去了。
因此,這是我們在部署合約時需要注意的事情之一。