mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
params, core/vm: deprecating gastable, part 1
This commit is contained in:
parent
d6ccfd92f7
commit
7ef08f1166
7 changed files with 77 additions and 107 deletions
|
|
@ -18,8 +18,6 @@ package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/params"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Gas costs
|
// Gas costs
|
||||||
|
|
@ -34,10 +32,10 @@ const (
|
||||||
|
|
||||||
// calcGas returns the actual gas cost of the call.
|
// calcGas returns the actual gas cost of the call.
|
||||||
//
|
//
|
||||||
// The cost of gas was changed during the homestead price change HF. To allow for EIP150
|
// The cost of gas was changed during the homestead price change HF.
|
||||||
// to be implemented. The returned gas is gas - base * 63 / 64.
|
// As part of EIP 150 (TangerineWhistle), the returned gas is gas - base * 63 / 64.
|
||||||
func callGas(gasTable params.GasTable, availableGas, base uint64, callCost *big.Int) (uint64, error) {
|
func callGas(isEip150 bool, availableGas, base uint64, callCost *big.Int) (uint64, error) {
|
||||||
if gasTable.CreateBySuicide > 0 {
|
if isEip150 {
|
||||||
availableGas = availableGas - base
|
availableGas = availableGas - base
|
||||||
gas := availableGas - availableGas/64
|
gas := availableGas - availableGas/64
|
||||||
// If the bit length exceeds 64 bit we know that the newly calculated "gas" for EIP150
|
// If the bit length exceeds 64 bit we know that the newly calculated "gas" for EIP150
|
||||||
|
|
|
||||||
|
|
@ -278,10 +278,6 @@ func gasExtCodeCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Sta
|
||||||
return gas, nil
|
return gas, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasExtCodeHash(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
|
||||||
return gt.ExtcodeHash, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func gasMLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
func gasMLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
var overflow bool
|
var overflow bool
|
||||||
gas, err := memoryGasCost(mem, memorySize)
|
gas, err := memoryGasCost(mem, memorySize)
|
||||||
|
|
@ -353,18 +349,6 @@ func gasCreate2(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack,
|
||||||
return gas, nil
|
return gas, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasBalance(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
|
||||||
return gt.Balance, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func gasExtCodeSize(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
|
||||||
return gt.ExtcodeSize, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func gasSLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
|
||||||
return gt.SLoad, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func gasExp(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
func gasExp(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
expByteLen := uint64((stack.data[stack.len()-2].BitLen() + 7) / 8)
|
expByteLen := uint64((stack.data[stack.len()-2].BitLen() + 7) / 8)
|
||||||
|
|
||||||
|
|
@ -383,7 +367,8 @@ func gasCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem
|
||||||
gas = gt.Calls
|
gas = gt.Calls
|
||||||
transfersValue = stack.Back(2).Sign() != 0
|
transfersValue = stack.Back(2).Sign() != 0
|
||||||
address = common.BigToAddress(stack.Back(1))
|
address = common.BigToAddress(stack.Back(1))
|
||||||
eip158 = evm.ChainConfig().IsEIP158(evm.BlockNumber)
|
eip158 = evm.chainRules.IsEIP158
|
||||||
|
eip150 = evm.chainRules.IsEIP150
|
||||||
)
|
)
|
||||||
if eip158 {
|
if eip158 {
|
||||||
if transfersValue && evm.StateDB.Empty(address) {
|
if transfersValue && evm.StateDB.Empty(address) {
|
||||||
|
|
@ -404,7 +389,7 @@ func gasCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem
|
||||||
return 0, errGasUintOverflow
|
return 0, errGasUintOverflow
|
||||||
}
|
}
|
||||||
|
|
||||||
evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
|
evm.callGasTemp, err = callGas(eip150, contract.Gas, gas, stack.Back(0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
@ -428,7 +413,7 @@ func gasCallCode(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack,
|
||||||
return 0, errGasUintOverflow
|
return 0, errGasUintOverflow
|
||||||
}
|
}
|
||||||
|
|
||||||
evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
|
evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
@ -449,20 +434,17 @@ func gasRevert(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, m
|
||||||
func gasSuicide(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
func gasSuicide(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
var gas uint64
|
var gas uint64
|
||||||
// EIP150 homestead gas reprice fork:
|
// EIP150 homestead gas reprice fork:
|
||||||
if evm.ChainConfig().IsEIP150(evm.BlockNumber) {
|
if evm.chainRules.IsEIP150 {
|
||||||
gas = gt.Suicide
|
gas = params.SuicideGasEip150
|
||||||
var (
|
var address = common.BigToAddress(stack.Back(0))
|
||||||
address = common.BigToAddress(stack.Back(0))
|
|
||||||
eip158 = evm.ChainConfig().IsEIP158(evm.BlockNumber)
|
|
||||||
)
|
|
||||||
|
|
||||||
if eip158 {
|
if evm.chainRules.IsEIP158 {
|
||||||
// if empty and transfers value
|
// if empty and transfers value
|
||||||
if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 {
|
if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 {
|
||||||
gas += gt.CreateBySuicide
|
gas += params.CreateBySuicideGas
|
||||||
}
|
}
|
||||||
} else if !evm.StateDB.Exist(address) {
|
} else if !evm.StateDB.Exist(address) {
|
||||||
gas += gt.CreateBySuicide
|
gas += params.CreateBySuicideGas
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -482,7 +464,7 @@ func gasDelegateCall(gt params.GasTable, evm *EVM, contract *Contract, stack *St
|
||||||
return 0, errGasUintOverflow
|
return 0, errGasUintOverflow
|
||||||
}
|
}
|
||||||
|
|
||||||
evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
|
evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
@ -502,7 +484,7 @@ func gasStaticCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stac
|
||||||
return 0, errGasUintOverflow
|
return 0, errGasUintOverflow
|
||||||
}
|
}
|
||||||
|
|
||||||
evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
|
evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,10 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
|
||||||
cfg.JumpTable = constantinopleInstructionSet
|
cfg.JumpTable = constantinopleInstructionSet
|
||||||
case evm.ChainConfig().IsByzantium(evm.BlockNumber):
|
case evm.ChainConfig().IsByzantium(evm.BlockNumber):
|
||||||
cfg.JumpTable = byzantiumInstructionSet
|
cfg.JumpTable = byzantiumInstructionSet
|
||||||
|
case evm.ChainConfig().IsEIP158(evm.BlockNumber):
|
||||||
|
cfg.JumpTable = spuriousDragonInstructionSet
|
||||||
|
case evm.ChainConfig().IsEIP150(evm.BlockNumber):
|
||||||
|
cfg.JumpTable = tangerineWhistleInstructionSet
|
||||||
case evm.ChainConfig().IsHomestead(evm.BlockNumber):
|
case evm.ChainConfig().IsHomestead(evm.BlockNumber):
|
||||||
cfg.JumpTable = homesteadInstructionSet
|
cfg.JumpTable = homesteadInstructionSet
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -54,10 +54,12 @@ type operation struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
frontierInstructionSet = newFrontierInstructionSet()
|
frontierInstructionSet = newFrontierInstructionSet()
|
||||||
homesteadInstructionSet = newHomesteadInstructionSet()
|
homesteadInstructionSet = newHomesteadInstructionSet()
|
||||||
byzantiumInstructionSet = newByzantiumInstructionSet()
|
tangerineWhistleInstructionSet = newTangerineWhistleInstructionSet()
|
||||||
constantinopleInstructionSet = newConstantinopleInstructionSet()
|
spuriousDragonInstructionSet = newSpuriousDragonInstructionSet()
|
||||||
|
byzantiumInstructionSet = newByzantiumInstructionSet()
|
||||||
|
constantinopleInstructionSet = newConstantinopleInstructionSet()
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewConstantinopleInstructionSet returns the frontier, homestead
|
// NewConstantinopleInstructionSet returns the frontier, homestead
|
||||||
|
|
@ -87,11 +89,11 @@ func newConstantinopleInstructionSet() [256]operation {
|
||||||
valid: true,
|
valid: true,
|
||||||
}
|
}
|
||||||
instructionSet[EXTCODEHASH] = operation{
|
instructionSet[EXTCODEHASH] = operation{
|
||||||
execute: opExtCodeHash,
|
execute: opExtCodeHash,
|
||||||
dynamicGas: gasExtCodeHash,
|
constantGas: params.ExtcodeHashGas,
|
||||||
minStack: minStack(1, 1),
|
minStack: minStack(1, 1),
|
||||||
maxStack: maxStack(1, 1),
|
maxStack: maxStack(1, 1),
|
||||||
valid: true,
|
valid: true,
|
||||||
}
|
}
|
||||||
instructionSet[CREATE2] = operation{
|
instructionSet[CREATE2] = operation{
|
||||||
execute: opCreate2,
|
execute: opCreate2,
|
||||||
|
|
@ -110,7 +112,7 @@ func newConstantinopleInstructionSet() [256]operation {
|
||||||
// byzantium instructions.
|
// byzantium instructions.
|
||||||
func newByzantiumInstructionSet() [256]operation {
|
func newByzantiumInstructionSet() [256]operation {
|
||||||
// instructions that can be executed during the homestead phase.
|
// instructions that can be executed during the homestead phase.
|
||||||
instructionSet := newHomesteadInstructionSet()
|
instructionSet := newSpuriousDragonInstructionSet()
|
||||||
instructionSet[STATICCALL] = operation{
|
instructionSet[STATICCALL] = operation{
|
||||||
execute: opStaticCall,
|
execute: opStaticCall,
|
||||||
dynamicGas: gasStaticCall,
|
dynamicGas: gasStaticCall,
|
||||||
|
|
@ -148,6 +150,20 @@ func newByzantiumInstructionSet() [256]operation {
|
||||||
return instructionSet
|
return instructionSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newSpuriousDragonInstructionSet() [256]operation {
|
||||||
|
instructionSet := newTangerineWhistleInstructionSet()
|
||||||
|
return instructionSet
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTangerineWhistleInstructionSet() [256]operation {
|
||||||
|
instructionSet := newHomesteadInstructionSet()
|
||||||
|
instructionSet[BALANCE].constantGas = params.BalanceGasEip150
|
||||||
|
instructionSet[EXTCODESIZE].constantGas = params.ExtcodeSizeGasEip150
|
||||||
|
instructionSet[SLOAD].constantGas = params.SloadGasEip150
|
||||||
|
return instructionSet
|
||||||
|
}
|
||||||
|
|
||||||
// NewHomesteadInstructionSet returns the frontier and homestead
|
// NewHomesteadInstructionSet returns the frontier and homestead
|
||||||
// instructions that can be executed during the homestead phase.
|
// instructions that can be executed during the homestead phase.
|
||||||
func newHomesteadInstructionSet() [256]operation {
|
func newHomesteadInstructionSet() [256]operation {
|
||||||
|
|
@ -346,11 +362,11 @@ func newFrontierInstructionSet() [256]operation {
|
||||||
valid: true,
|
valid: true,
|
||||||
},
|
},
|
||||||
BALANCE: {
|
BALANCE: {
|
||||||
execute: opBalance,
|
execute: opBalance,
|
||||||
dynamicGas: gasBalance,
|
constantGas: params.BalanceGasFrontier,
|
||||||
minStack: minStack(1, 1),
|
minStack: minStack(1, 1),
|
||||||
maxStack: maxStack(1, 1),
|
maxStack: maxStack(1, 1),
|
||||||
valid: true,
|
valid: true,
|
||||||
},
|
},
|
||||||
ORIGIN: {
|
ORIGIN: {
|
||||||
execute: opOrigin,
|
execute: opOrigin,
|
||||||
|
|
@ -418,11 +434,11 @@ func newFrontierInstructionSet() [256]operation {
|
||||||
valid: true,
|
valid: true,
|
||||||
},
|
},
|
||||||
EXTCODESIZE: {
|
EXTCODESIZE: {
|
||||||
execute: opExtCodeSize,
|
execute: opExtCodeSize,
|
||||||
dynamicGas: gasExtCodeSize,
|
constantGas: params.ExtcodeSizeGasFrontier,
|
||||||
minStack: minStack(1, 1),
|
minStack: minStack(1, 1),
|
||||||
maxStack: maxStack(1, 1),
|
maxStack: maxStack(1, 1),
|
||||||
valid: true,
|
valid: true,
|
||||||
},
|
},
|
||||||
EXTCODECOPY: {
|
EXTCODECOPY: {
|
||||||
execute: opExtCodeCopy,
|
execute: opExtCodeCopy,
|
||||||
|
|
@ -507,11 +523,11 @@ func newFrontierInstructionSet() [256]operation {
|
||||||
valid: true,
|
valid: true,
|
||||||
},
|
},
|
||||||
SLOAD: {
|
SLOAD: {
|
||||||
execute: opSload,
|
execute: opSload,
|
||||||
dynamicGas: gasSLoad,
|
constantGas: params.SloadGasFrontier,
|
||||||
minStack: minStack(1, 1),
|
minStack: minStack(1, 1),
|
||||||
maxStack: maxStack(1, 1),
|
maxStack: maxStack(1, 1),
|
||||||
valid: true,
|
valid: true,
|
||||||
},
|
},
|
||||||
SSTORE: {
|
SSTORE: {
|
||||||
execute: opSstore,
|
execute: opSstore,
|
||||||
|
|
|
||||||
|
|
@ -306,8 +306,6 @@ func (c *ChainConfig) GasTable(num *big.Int) GasTable {
|
||||||
return GasTableHomestead
|
return GasTableHomestead
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
case c.IsConstantinople(num):
|
|
||||||
return GasTableConstantinople
|
|
||||||
case c.IsEIP158(num):
|
case c.IsEIP158(num):
|
||||||
return GasTableEIP158
|
return GasTableEIP158
|
||||||
case c.IsEIP150(num):
|
case c.IsEIP150(num):
|
||||||
|
|
|
||||||
|
|
@ -18,22 +18,10 @@ package params
|
||||||
|
|
||||||
// GasTable organizes gas prices for different ethereum phases.
|
// GasTable organizes gas prices for different ethereum phases.
|
||||||
type GasTable struct {
|
type GasTable struct {
|
||||||
ExtcodeSize uint64
|
|
||||||
ExtcodeCopy uint64
|
ExtcodeCopy uint64
|
||||||
ExtcodeHash uint64
|
|
||||||
Balance uint64
|
|
||||||
SLoad uint64
|
|
||||||
Calls uint64
|
Calls uint64
|
||||||
Suicide uint64
|
|
||||||
|
|
||||||
ExpByte uint64
|
ExpByte uint64
|
||||||
|
|
||||||
// CreateBySuicide occurs when the
|
|
||||||
// refunded account is one that does
|
|
||||||
// not exist. This logic is similar
|
|
||||||
// to call. May be left nil. Nil means
|
|
||||||
// not charged.
|
|
||||||
CreateBySuicide uint64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Variables containing gas prices for different ethereum phases.
|
// Variables containing gas prices for different ethereum phases.
|
||||||
|
|
@ -41,53 +29,23 @@ var (
|
||||||
// GasTableHomestead contain the gas prices for
|
// GasTableHomestead contain the gas prices for
|
||||||
// the homestead phase.
|
// the homestead phase.
|
||||||
GasTableHomestead = GasTable{
|
GasTableHomestead = GasTable{
|
||||||
ExtcodeSize: 20,
|
|
||||||
ExtcodeCopy: 20,
|
ExtcodeCopy: 20,
|
||||||
Balance: 20,
|
|
||||||
SLoad: 50,
|
|
||||||
Calls: 40,
|
Calls: 40,
|
||||||
Suicide: 0,
|
|
||||||
ExpByte: 10,
|
ExpByte: 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
// GasTableEIP150 contain the gas re-prices for
|
// GasTableEIP150 contain the gas re-prices for
|
||||||
// the EIP150 phase.
|
// the EIP150 phase (a.k.a TangerineWhistle).
|
||||||
GasTableEIP150 = GasTable{
|
GasTableEIP150 = GasTable{
|
||||||
ExtcodeSize: 700,
|
|
||||||
ExtcodeCopy: 700,
|
ExtcodeCopy: 700,
|
||||||
Balance: 400,
|
|
||||||
SLoad: 200,
|
|
||||||
Calls: 700,
|
Calls: 700,
|
||||||
Suicide: 5000,
|
|
||||||
ExpByte: 10,
|
ExpByte: 10,
|
||||||
|
|
||||||
CreateBySuicide: 25000,
|
|
||||||
}
|
}
|
||||||
// GasTableEIP158 contain the gas re-prices for
|
// GasTableEIP158 contain the gas re-prices for
|
||||||
// the EIP155/EIP158 phase.
|
// the EIP155/EIP158 phase (a.k.a Spurious Dragon).
|
||||||
GasTableEIP158 = GasTable{
|
GasTableEIP158 = GasTable{
|
||||||
ExtcodeSize: 700,
|
|
||||||
ExtcodeCopy: 700,
|
ExtcodeCopy: 700,
|
||||||
Balance: 400,
|
|
||||||
SLoad: 200,
|
|
||||||
Calls: 700,
|
Calls: 700,
|
||||||
Suicide: 5000,
|
|
||||||
ExpByte: 50,
|
ExpByte: 50,
|
||||||
|
|
||||||
CreateBySuicide: 25000,
|
|
||||||
}
|
|
||||||
// GasTableConstantinople contain the gas re-prices for
|
|
||||||
// the constantinople phase.
|
|
||||||
GasTableConstantinople = GasTable{
|
|
||||||
ExtcodeSize: 700,
|
|
||||||
ExtcodeCopy: 700,
|
|
||||||
ExtcodeHash: 400,
|
|
||||||
Balance: 400,
|
|
||||||
SLoad: 200,
|
|
||||||
Calls: 700,
|
|
||||||
Suicide: 5000,
|
|
||||||
ExpByte: 50,
|
|
||||||
|
|
||||||
CreateBySuicide: 25000,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,20 @@ const (
|
||||||
MemoryGas uint64 = 3 // Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL.
|
MemoryGas uint64 = 3 // Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL.
|
||||||
TxDataNonZeroGas uint64 = 68 // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions.
|
TxDataNonZeroGas uint64 = 68 // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions.
|
||||||
|
|
||||||
|
// These have been changed during the course of the chain
|
||||||
|
BalanceGasFrontier uint64 = 20 // The cost of a BALANCE operation
|
||||||
|
BalanceGasEip150 uint64 = 400 // The cost of a BALANCE operation after Tangerine Whistle
|
||||||
|
ExtcodeSizeGasFrontier uint64 = 20 // Cost of EXTCODESIZE before EIP 150 (T.W)
|
||||||
|
ExtcodeSizeGasEip150 uint64 = 700 // Cost of EXTCODESIZE after EIP 150 (T.W)
|
||||||
|
SloadGasFrontier uint64 = 50
|
||||||
|
SloadGasEip150 uint64 = 200
|
||||||
|
ExtcodeHashGas uint64 = 400 // Cost of EXTCODEHASH (introduced in Constantinople)
|
||||||
|
SuicideGasEip150 uint64 = 5000 // Cost of SELFDESTRUCT post T.W
|
||||||
|
// CreateBySuicide occurs when the refunded account is one that does
|
||||||
|
// not exist. This logic is similar to call.
|
||||||
|
// Introduced in Tangerine Whistle (Eip 150)
|
||||||
|
CreateBySuicideGas uint64 = 25000
|
||||||
|
|
||||||
MaxCodeSize = 24576 // Maximum bytecode to permit for a contract
|
MaxCodeSize = 24576 // Maximum bytecode to permit for a contract
|
||||||
|
|
||||||
// Precompiled contract gas prices
|
// Precompiled contract gas prices
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue