|
|
@@ -496,6 +496,38 @@ func opExtCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, sta
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
+// opExtCodeHash returns the code hash of a specified account.
|
|
|
+// There are several cases when the function is called, while we can relay everything
|
|
|
+// to `state.GetCodeHash` function to ensure the correctness.
|
|
|
+// (1) Caller tries to get the code hash of a normal contract account, state
|
|
|
+// should return the relative code hash and set it as the result.
|
|
|
+//
|
|
|
+// (2) Caller tries to get the code hash of a non-existent account, state should
|
|
|
+// return common.Hash{} and zero will be set as the result.
|
|
|
+//
|
|
|
+// (3) Caller tries to get the code hash for an account without contract code,
|
|
|
+// state should return emptyCodeHash(0xc5d246...) as the result.
|
|
|
+//
|
|
|
+// (4) Caller tries to get the code hash of a precompiled account, the result
|
|
|
+// should be zero or emptyCodeHash.
|
|
|
+//
|
|
|
+// It is worth noting that in order to avoid unnecessary create and clean,
|
|
|
+// all precompile accounts on mainnet have been transferred 1 wei, so the return
|
|
|
+// here should be emptyCodeHash.
|
|
|
+// If the precompile account is not transferred any amount on a private or
|
|
|
+// customized chain, the return value will be zero.
|
|
|
+//
|
|
|
+// (5) Caller tries to get the code hash for an account which is marked as suicided
|
|
|
+// in the current transaction, the code hash of this account should be returned.
|
|
|
+//
|
|
|
+// (6) Caller tries to get the code hash for an account which is marked as deleted,
|
|
|
+// this account should be regarded as a non-existent account and zero should be returned.
|
|
|
+func opExtCodeHash(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
+ slot := stack.peek()
|
|
|
+ slot.SetBytes(evm.StateDB.GetCodeHash(common.BigToAddress(slot)).Bytes())
|
|
|
+ return nil, nil
|
|
|
+}
|
|
|
+
|
|
|
func opGasprice(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
|
|
stack.push(evm.interpreter.intPool.get().Set(evm.GasPrice))
|
|
|
return nil, nil
|