@ -41,7 +41,7 @@ type (
)
// run runs the given contract and takes care of running precompiles with a fallback to the byte code interpreter.
func run ( evm * EVM , contract * Contract , input [ ] byte ) ( [ ] byte , error ) {
func run ( evm * EVM , contract * Contract , input [ ] byte , readOnly bool ) ( [ ] byte , error ) {
if contract . CodeAddr != nil {
precompiles := PrecompiledContractsHomestead
if evm . ChainConfig ( ) . IsByzantium ( evm . BlockNumber ) {
@ -61,7 +61,7 @@ func run(evm *EVM, contract *Contract, input []byte) ([]byte, error) {
} ( evm . interpreter )
evm . interpreter = interpreter
}
return interpreter . Run ( contract , input )
return interpreter . Run ( contract , input , readOnly )
}
}
return nil , ErrNoCompatibleInterpreter
@ -210,7 +210,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
evm . vmConfig . Tracer . CaptureEnd ( ret , gas - contract . Gas , time . Since ( start ) , err )
} ( )
}
ret , err = run ( evm , contract , input )
ret , err = run ( evm , contract , input , false )
// When an error was returned by the EVM or when setting the creation code
// above we revert to the snapshot and consume any gas remaining. Additionally
@ -255,7 +255,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
contract := NewContract ( caller , to , value , gas )
contract . SetCallCode ( & addr , evm . StateDB . GetCodeHash ( addr ) , evm . StateDB . GetCode ( addr ) )
ret , err = run ( evm , contract , input )
ret , err = run ( evm , contract , input , false )
if err != nil {
evm . StateDB . RevertToSnapshot ( snapshot )
if err != errExecutionReverted {
@ -288,7 +288,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
contract := NewContract ( caller , to , nil , gas ) . AsDelegate ( )
contract . SetCallCode ( & addr , evm . StateDB . GetCodeHash ( addr ) , evm . StateDB . GetCode ( addr ) )
ret , err = run ( evm , contract , input )
ret , err = run ( evm , contract , input , false )
if err != nil {
evm . StateDB . RevertToSnapshot ( snapshot )
if err != errExecutionReverted {
@ -310,13 +310,6 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
if evm . depth > int ( params . CallCreateDepth ) {
return nil , gas , ErrDepth
}
// Make sure the readonly is only set if we aren't in readonly yet
// this makes also sure that the readonly flag isn't removed for
// child calls.
if ! evm . interpreter . IsReadOnly ( ) {
evm . interpreter . SetReadOnly ( true )
defer func ( ) { evm . interpreter . SetReadOnly ( false ) } ( )
}
var (
to = AccountRef ( addr )
@ -331,7 +324,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
// When an error was returned by the EVM or when setting the creation code
// above we revert to the snapshot and consume any gas remaining. Additionally
// when we're in Homestead this also counts for code storage gas errors.
ret , err = run ( evm , contract , input )
ret , err = run ( evm , contract , input , true )
if err != nil {
evm . StateDB . RevertToSnapshot ( snapshot )
if err != errExecutionReverted {
@ -382,7 +375,7 @@ func (evm *EVM) create(caller ContractRef, code []byte, gas uint64, value *big.I
}
start := time . Now ( )
ret , err := run ( evm , contract , nil )
ret , err := run ( evm , contract , nil , false )
// check whether the max code size has been exceeded
maxCodeSizeExceeded := evm . ChainConfig ( ) . IsEIP158 ( evm . BlockNumber ) && len ( ret ) > params . MaxCodeSize