如果我將合約部署到已經擁有 eth 的地址會發生什麼?
我知道使用 create2 操作碼可以可靠地計算合約地址。
假設我將 1 個乙太幣轉移到一個隨機地址。
然後我在該地址上部署了一個具有應付轉賬功能的契約。
是否可以部署該合約並轉出乙太幣?
我知道使用 create2 操作碼可以可靠地計算合約地址。假設我將 1 個乙太幣轉移到一個隨機地址。然後我在該地址上部署了一個具有應付轉賬功能的契約。
地址不應該是隨機的。這應該是你預計算未來智能合約地址後得到的地址。
如果我將合約部署到已經擁有 eth 的地址會發生什麼?
乙太幣將保留在地址上,屬於新部署的智能合約。因此,如果沒有實現處理這些乙太的函式,它們將永遠失去。另一方面,是的,應付函式應該能夠轉移它們。
我們可以在乙太坊黃皮書中用方程 (83) 和 (86) 驗證這一點,第 7 部分“合約創建”。
是在初始化程式碼執行之前創建期間計算的智能合約的變異帳戶狀態。*它由四個欄位組成,第二個欄位是帳戶餘額。
因此,合約一旦創建就會收到v+v’ Wei:
- v是部署期間發送給合約的金額(endowment)
- v’被黃皮書定義為賬戶的預先存在的價值,如果它之前存在的話。實際上,在賬戶存在的假設下,表示賬戶的目前餘額。
我們也可以檢查黃皮書的乙太坊 go 實現。
創建2函式
Github 文件:https ://github.com/ethereum/go-ethereum/blob/master/core/vm/evm.go 。
這是用於
create2
OPCODE 的函式:// Create2 creates a new contract using code as deployment code. // // The different between Create2 with Create is Create2 uses sha3(0xff ++ msg.sender ++ salt ++ sha3(init_code))[12:] // instead of the usual sender-and-nonce-hash as the address where the contract is initialized at. func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *big.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { codeAndHash := &codeAndHash{code: code} contractAddr = crypto.CreateAddress2(caller.Address(), salt.Bytes32(), codeAndHash.Hash().Bytes()) return evm.create(caller, codeAndHash, gas, endowment, contractAddr) }
創建函式
Github 文件:https ://github.com/ethereum/go-ethereum/blob/master/core/vm/evm.go 。
如您所見,
Create2
呼叫一個create
函式。這個很大,所以我只在這裡展示相關部分:// Create a new account on the state snapshot := evm.StateDB.Snapshot() evm.StateDB.CreateAccount(address)
呼叫一個
CreateAccount
方法在計算的地址上儲存一個新帳戶。創建帳號
Github 文件:https ://github.com/ethereum/go-ethereum/blob/master/core/state/statedb.go 。
// CreateAccount explicitly creates a state object. If a state object with the address // already exists the balance is carried over to the new account. // // CreateAccount is called during the EVM CREATE operation. The situation might arise that // a contract does the following: // // 1. sends funds to sha(account ++ (nonce + 1)) // 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1) // // Carrying over the balance ensures that Ether doesn't disappear. func (s *StateDB) CreateAccount(addr common.Address) { newObj, prev := s.createObject(addr) if prev != nil { newObj.setBalance(prev.data.Balance) } }
請注意
CreateAccount explicitly creates a state object. If a state object with the address already exists the balance is carried over to the new account.
向我們確認醚被保留的評論。這裡,state object
指的是世界狀態樹的帳戶狀態。乙太幣通過這一行“轉移”到新帳戶對象:
newObj.setBalance(prev.data.Balance)
。