@ -510,64 +510,59 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
contract . SetCodeOptionalHash ( & address , codeAndHash )
contract . SetCodeOptionalHash ( & address , codeAndHash )
contract . IsDeployment = true
contract . IsDeployment = true
ret , err = evm . initNewContract ( contract , address , value )
if err != nil && ( evm . chainRules . IsHomestead || err != ErrCodeStoreOutOfGas ) {
evm . StateDB . RevertToSnapshot ( snapshot )
if err != ErrExecutionReverted {
contract . UseGas ( contract . Gas , evm . Config . Tracer , tracing . GasChangeCallFailedExecution )
}
}
return ret , address , contract . Gas , err
}
// initNewContract runs a new contract's creation code, performs checks on the
// resulting code that is to be deployed, and consumes necessary gas.
func ( evm * EVM ) initNewContract ( contract * Contract , address common . Address , value * uint256 . Int ) ( [ ] byte , error ) {
// Charge the contract creation init gas in verkle mode
// Charge the contract creation init gas in verkle mode
if evm . chainRules . IsEIP4762 {
if evm . chainRules . IsEIP4762 {
if ! contract . UseGas ( evm . AccessEvents . ContractCreateInitGas ( address , value . Sign ( ) != 0 ) , evm . Config . Tracer , tracing . GasChangeWitnessContractInit ) {
if ! contract . UseGas ( evm . AccessEvents . ContractCreateInitGas ( address , value . Sign ( ) != 0 ) , evm . Config . Tracer , tracing . GasChangeWitnessContractInit ) {
err = ErrOutOfGas
return nil , ErrOutOfGas
}
}
}
}
if err == nil {
ret , err := evm . interpreter . Run ( contract , nil , false )
ret , err = evm . interpreter . Run ( contract , nil , false )
if err != nil {
return ret , err
}
}
// Check whether the max code size has been exceeded, assign err if the case.
// Check whether the max code size has been exceeded, assign err if the case.
if err == nil && evm . chainRules . IsEIP158 && len ( ret ) > params . MaxCodeSize {
if evm . chainRules . IsEIP158 && len ( ret ) > params . MaxCodeSize {
err = ErrMaxCodeSizeExceeded
return ret , ErrMaxCodeSizeExceeded
}
}
// Reject code starting with 0xEF if EIP-3541 is enabled.
// Reject code starting with 0xEF if EIP-3541 is enabled.
if err == nil && len ( ret ) >= 1 && ret [ 0 ] == 0xEF && evm . chainRules . IsLondon {
if len ( ret ) >= 1 && ret [ 0 ] == 0xEF && evm . chainRules . IsLondon {
err = ErrInvalidCode
return ret , ErrInvalidCode
}
}
// if the contract creation ran successfully and no errors were returned
// calculate the gas required to store the code. If the code could not
// be stored due to not enough gas set an error and let it be handled
// by the error checking condition below.
if err == nil {
if ! evm . chainRules . IsEIP4762 {
if ! evm . chainRules . IsEIP4762 {
createDataGas := uint64 ( len ( ret ) ) * params . CreateDataGas
createDataGas := uint64 ( len ( ret ) ) * params . CreateDataGas
if ! contract . UseGas ( createDataGas , evm . Config . Tracer , tracing . GasChangeCallCodeStorage ) {
if ! contract . UseGas ( createDataGas , evm . Config . Tracer , tracing . GasChangeCallCodeStorage ) {
err = ErrCodeStoreOutOfGas
return ret , ErrCodeStoreOutOfGas
}
}
} else {
} else {
// Contract creation completed, touch the missing fields in the contract
// Contract creation completed, touch the missing fields in the contract
if ! contract . UseGas ( evm . AccessEvents . AddAccount ( address , true ) , evm . Config . Tracer , tracing . GasChangeWitnessContractCreation ) {
if ! contract . UseGas ( evm . AccessEvents . AddAccount ( address , true ) , evm . Config . Tracer , tracing . GasChangeWitnessContractCreation ) {
err = ErrCodeStoreOutOfGas
return ret , ErrCodeStoreOutOfGas
}
}
if err == nil && len ( ret ) > 0 && ! contract . UseGas ( evm . AccessEvents . CodeChunksRangeGas ( address , 0 , uint64 ( len ( ret ) ) , uint64 ( len ( ret ) ) , true ) , evm . Config . Tracer , tracing . GasChangeWitnessCodeChunk ) {
if len ( ret ) > 0 && ! contract . UseGas ( evm . AccessEvents . CodeChunksRangeGas ( address , 0 , uint64 ( len ( ret ) ) , uint64 ( len ( ret ) ) , true ) , evm . Config . Tracer , tracing . GasChangeWitnessCodeChunk ) {
err = ErrCodeStoreOutOfGas
return ret , ErrCodeStoreOutOfGas
}
}
}
}
if err == nil {
evm . StateDB . SetCode ( address , ret )
evm . StateDB . SetCode ( address , ret )
}
return ret , nil
}
// 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.
if err != nil && ( evm . chainRules . IsHomestead || err != ErrCodeStoreOutOfGas ) {
evm . StateDB . RevertToSnapshot ( snapshot )
if err != ErrExecutionReverted {
contract . UseGas ( contract . Gas , evm . Config . Tracer , tracing . GasChangeCallFailedExecution )
}
}
return ret , address , contract . Gas , err
}
}
// Create creates a new contract using code as deployment code.
// Create creates a new contract using code as deployment code.