System info:
Expected behavior: [What you expected to happen]
func (st StateTransition) newEVM(ctx sdk.Context, csdb *CommitStateDB, gasLimit uint64, gasPrice *big.Int, config ChainConfig) *vm.EVM {
// Create context for evm
context := vm.Context{
CanTransfer: core.CanTransfer,
Transfer: core.Transfer,
GetHash: FUNCTION_GET_HASH,
Origin: st.Sender,
Coinbase: common.Address{}, // there's no benefitiary since we're not mining
BlockNumber: big.NewInt(ctx.BlockHeight()),
Time: big.NewInt(ctx.BlockHeader().Time.Unix()),
Difficulty: big.NewInt(0), // unused. Only required in PoW context
GasLimit: gasLimit,
GasPrice: gasPrice,
}
return vm.NewEVM(context, csdb, config.EthereumConfig(st.ChainID), vm.Config{})
}
Actual behavior: [What actually happened]
func (st StateTransition) newEVM(ctx sdk.Context, csdb *CommitStateDB, gasLimit uint64, gasPrice *big.Int, config ChainConfig) *vm.EVM {
// Create context for evm
context := vm.Context{
CanTransfer: core.CanTransfer,
Transfer: core.Transfer,
Origin: st.Sender,
Coinbase: common.Address{}, // there's no benefitiary since we're not mining
BlockNumber: big.NewInt(ctx.BlockHeight()),
Time: big.NewInt(ctx.BlockHeader().Time.Unix()),
Difficulty: big.NewInt(0), // unused. Only required in PoW context
GasLimit: gasLimit,
GasPrice: gasPrice,
}
return vm.NewEVM(context, csdb, config.EthereumConfig(st.ChainID), vm.Config{})
}
Additional info: [Include gist of relevant config, logs, etc.]
- the struct "vm.Context" have a member variable called "GetHash"
// Context provides the EVM with auxiliary information. Once provided
// it shouldn't be modified.
type Context struct {
// CanTransfer returns whether the account contains
// sufficient ether to transfer the value
CanTransfer CanTransferFunc
// Transfer transfers ether from one account to the other
Transfer TransferFunc
// GetHash returns the hash corresponding to n
GetHash GetHashFunc
// Message information
Origin common.Address // Provides information for ORIGIN
GasPrice *big.Int // Provides information for GASPRICE
// Block information
Coinbase common.Address // Provides information for COINBASE
GasLimit uint64 // Provides information for GASLIMIT
BlockNumber *big.Int // Provides information for NUMBER
Time *big.Int // Provides information for TIME
Difficulty *big.Int // Provides information for DIFFICULTY
}
- function "GetHash" from "vm.Context" is used in opCode of evm
func opBlockhash(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
num := callContext.stack.peek()
num64, overflow := num.Uint64WithOverflow()
if overflow {
num.Clear()
return nil, nil
}
var upper, lower uint64
upper = interpreter.evm.BlockNumber.Uint64()
if upper < 257 {
lower = 0
} else {
lower = upper - 256
}
if num64 >= lower && num64 < upper {
num.SetBytes(interpreter.evm.GetHash(num64).Bytes())
} else {
num.Clear()
}
return nil, nil
}
- If the method opBlockhash is called when the contract is executed, it may panic because GetHash is nil
System info:
Expected behavior: [What you expected to happen]
Actual behavior: [What actually happened]
Additional info: [Include gist of relevant config, logs, etc.]