github.com/theQRL/go-zond@v0.1.1/core/vm/eips.go (about) 1 // Copyright 2019 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package vm 18 19 import ( 20 "fmt" 21 "sort" 22 23 "github.com/theQRL/go-zond/common" 24 "github.com/theQRL/go-zond/params" 25 "github.com/holiman/uint256" 26 ) 27 28 var activators = map[int]func(*JumpTable){ 29 5656: enable5656, 30 6780: enable6780, 31 3855: enable3855, 32 3860: enable3860, 33 3529: enable3529, 34 3198: enable3198, 35 2929: enable2929, 36 2200: enable2200, 37 1884: enable1884, 38 1344: enable1344, 39 1153: enable1153, 40 } 41 42 // EnableEIP enables the given EIP on the config. 43 // This operation writes in-place, and callers need to ensure that the globally 44 // defined jump tables are not polluted. 45 func EnableEIP(eipNum int, jt *JumpTable) error { 46 enablerFn, ok := activators[eipNum] 47 if !ok { 48 return fmt.Errorf("undefined eip %d", eipNum) 49 } 50 enablerFn(jt) 51 return nil 52 } 53 54 func ValidEip(eipNum int) bool { 55 _, ok := activators[eipNum] 56 return ok 57 } 58 func ActivateableEips() []string { 59 var nums []string 60 for k := range activators { 61 nums = append(nums, fmt.Sprintf("%d", k)) 62 } 63 sort.Strings(nums) 64 return nums 65 } 66 67 // enable1884 applies EIP-1884 to the given jump table: 68 // - Increase cost of BALANCE to 700 69 // - Increase cost of EXTCODEHASH to 700 70 // - Increase cost of SLOAD to 800 71 // - Define SELFBALANCE, with cost GasFastStep (5) 72 func enable1884(jt *JumpTable) { 73 // Gas cost changes 74 jt[SLOAD].constantGas = params.SloadGasEIP1884 75 jt[BALANCE].constantGas = params.BalanceGasEIP1884 76 jt[EXTCODEHASH].constantGas = params.ExtcodeHashGasEIP1884 77 78 // New opcode 79 jt[SELFBALANCE] = &operation{ 80 execute: opSelfBalance, 81 constantGas: GasFastStep, 82 minStack: minStack(0, 1), 83 maxStack: maxStack(0, 1), 84 } 85 } 86 87 func opSelfBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 88 balance, _ := uint256.FromBig(interpreter.evm.StateDB.GetBalance(scope.Contract.Address())) 89 scope.Stack.push(balance) 90 return nil, nil 91 } 92 93 // enable1344 applies EIP-1344 (ChainID Opcode) 94 // - Adds an opcode that returns the current chain’s EIP-155 unique identifier 95 func enable1344(jt *JumpTable) { 96 // New opcode 97 jt[CHAINID] = &operation{ 98 execute: opChainID, 99 constantGas: GasQuickStep, 100 minStack: minStack(0, 1), 101 maxStack: maxStack(0, 1), 102 } 103 } 104 105 // opChainID implements CHAINID opcode 106 func opChainID(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 107 chainId, _ := uint256.FromBig(interpreter.evm.chainConfig.ChainID) 108 scope.Stack.push(chainId) 109 return nil, nil 110 } 111 112 // enable2200 applies EIP-2200 (Rebalance net-metered SSTORE) 113 func enable2200(jt *JumpTable) { 114 jt[SLOAD].constantGas = params.SloadGasEIP2200 115 jt[SSTORE].dynamicGas = gasSStoreEIP2200 116 } 117 118 // enable2929 enables "EIP-2929: Gas cost increases for state access opcodes" 119 // https://eips.ethereum.org/EIPS/eip-2929 120 func enable2929(jt *JumpTable) { 121 jt[SSTORE].dynamicGas = gasSStoreEIP2929 122 123 jt[SLOAD].constantGas = 0 124 jt[SLOAD].dynamicGas = gasSLoadEIP2929 125 126 jt[EXTCODECOPY].constantGas = params.WarmStorageReadCostEIP2929 127 jt[EXTCODECOPY].dynamicGas = gasExtCodeCopyEIP2929 128 129 jt[EXTCODESIZE].constantGas = params.WarmStorageReadCostEIP2929 130 jt[EXTCODESIZE].dynamicGas = gasEip2929AccountCheck 131 132 jt[EXTCODEHASH].constantGas = params.WarmStorageReadCostEIP2929 133 jt[EXTCODEHASH].dynamicGas = gasEip2929AccountCheck 134 135 jt[BALANCE].constantGas = params.WarmStorageReadCostEIP2929 136 jt[BALANCE].dynamicGas = gasEip2929AccountCheck 137 138 jt[CALL].constantGas = params.WarmStorageReadCostEIP2929 139 jt[CALL].dynamicGas = gasCallEIP2929 140 141 jt[CALLCODE].constantGas = params.WarmStorageReadCostEIP2929 142 jt[CALLCODE].dynamicGas = gasCallCodeEIP2929 143 144 jt[STATICCALL].constantGas = params.WarmStorageReadCostEIP2929 145 jt[STATICCALL].dynamicGas = gasStaticCallEIP2929 146 147 jt[DELEGATECALL].constantGas = params.WarmStorageReadCostEIP2929 148 jt[DELEGATECALL].dynamicGas = gasDelegateCallEIP2929 149 150 // This was previously part of the dynamic cost, but we're using it as a constantGas 151 // factor here 152 jt[SELFDESTRUCT].constantGas = params.SelfdestructGasEIP150 153 jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP2929 154 } 155 156 // enable3529 enabled "EIP-3529: Reduction in refunds": 157 // - Removes refunds for selfdestructs 158 // - Reduces refunds for SSTORE 159 // - Reduces max refunds to 20% gas 160 func enable3529(jt *JumpTable) { 161 jt[SSTORE].dynamicGas = gasSStoreEIP3529 162 jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP3529 163 } 164 165 // enable3198 applies EIP-3198 (BASEFEE Opcode) 166 // - Adds an opcode that returns the current block's base fee. 167 func enable3198(jt *JumpTable) { 168 // New opcode 169 jt[BASEFEE] = &operation{ 170 execute: opBaseFee, 171 constantGas: GasQuickStep, 172 minStack: minStack(0, 1), 173 maxStack: maxStack(0, 1), 174 } 175 } 176 177 // enable1153 applies EIP-1153 "Transient Storage" 178 // - Adds TLOAD that reads from transient storage 179 // - Adds TSTORE that writes to transient storage 180 func enable1153(jt *JumpTable) { 181 jt[TLOAD] = &operation{ 182 execute: opTload, 183 constantGas: params.WarmStorageReadCostEIP2929, 184 minStack: minStack(1, 1), 185 maxStack: maxStack(1, 1), 186 } 187 188 jt[TSTORE] = &operation{ 189 execute: opTstore, 190 constantGas: params.WarmStorageReadCostEIP2929, 191 minStack: minStack(2, 0), 192 maxStack: maxStack(2, 0), 193 } 194 } 195 196 // opTload implements TLOAD opcode 197 func opTload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 198 loc := scope.Stack.peek() 199 hash := common.Hash(loc.Bytes32()) 200 val := interpreter.evm.StateDB.GetTransientState(scope.Contract.Address(), hash) 201 loc.SetBytes(val.Bytes()) 202 return nil, nil 203 } 204 205 // opTstore implements TSTORE opcode 206 func opTstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 207 if interpreter.readOnly { 208 return nil, ErrWriteProtection 209 } 210 loc := scope.Stack.pop() 211 val := scope.Stack.pop() 212 interpreter.evm.StateDB.SetTransientState(scope.Contract.Address(), loc.Bytes32(), val.Bytes32()) 213 return nil, nil 214 } 215 216 // opBaseFee implements BASEFEE opcode 217 func opBaseFee(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 218 baseFee, _ := uint256.FromBig(interpreter.evm.Context.BaseFee) 219 scope.Stack.push(baseFee) 220 return nil, nil 221 } 222 223 // enable3855 applies EIP-3855 (PUSH0 opcode) 224 func enable3855(jt *JumpTable) { 225 // New opcode 226 jt[PUSH0] = &operation{ 227 execute: opPush0, 228 constantGas: GasQuickStep, 229 minStack: minStack(0, 1), 230 maxStack: maxStack(0, 1), 231 } 232 } 233 234 // opPush0 implements the PUSH0 opcode 235 func opPush0(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 236 scope.Stack.push(new(uint256.Int)) 237 return nil, nil 238 } 239 240 // enable3860 enables "EIP-3860: Limit and meter initcode" 241 // https://eips.ethereum.org/EIPS/eip-3860 242 func enable3860(jt *JumpTable) { 243 jt[CREATE].dynamicGas = gasCreateEip3860 244 jt[CREATE2].dynamicGas = gasCreate2Eip3860 245 } 246 247 // enable5656 enables EIP-5656 (MCOPY opcode) 248 // https://eips.ethereum.org/EIPS/eip-5656 249 func enable5656(jt *JumpTable) { 250 jt[MCOPY] = &operation{ 251 execute: opMcopy, 252 constantGas: GasFastestStep, 253 dynamicGas: gasMcopy, 254 minStack: minStack(3, 0), 255 maxStack: maxStack(3, 0), 256 memorySize: memoryMcopy, 257 } 258 } 259 260 // opMcopy implements the MCOPY opcode (https://eips.ethereum.org/EIPS/eip-5656) 261 func opMcopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 262 var ( 263 dst = scope.Stack.pop() 264 src = scope.Stack.pop() 265 length = scope.Stack.pop() 266 ) 267 // These values are checked for overflow during memory expansion calculation 268 // (the memorySize function on the opcode). 269 scope.Memory.Copy(dst.Uint64(), src.Uint64(), length.Uint64()) 270 return nil, nil 271 } 272 273 // opBlobHash implements the BLOBHASH opcode 274 func opBlobHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 275 index := scope.Stack.peek() 276 if index.LtUint64(uint64(len(interpreter.evm.TxContext.BlobHashes))) { 277 blobHash := interpreter.evm.TxContext.BlobHashes[index.Uint64()] 278 index.SetBytes32(blobHash[:]) 279 } else { 280 index.Clear() 281 } 282 return nil, nil 283 } 284 285 // enable4844 applies EIP-4844 (DATAHASH opcode) 286 func enable4844(jt *JumpTable) { 287 // New opcode 288 jt[BLOBHASH] = &operation{ 289 execute: opBlobHash, 290 constantGas: GasFastestStep, 291 minStack: minStack(1, 1), 292 maxStack: maxStack(1, 1), 293 } 294 } 295 296 // enable6780 applies EIP-6780 (deactivate SELFDESTRUCT) 297 func enable6780(jt *JumpTable) { 298 jt[SELFDESTRUCT] = &operation{ 299 execute: opSelfdestruct6780, 300 dynamicGas: gasSelfdestructEIP3529, 301 constantGas: params.SelfdestructGasEIP150, 302 minStack: minStack(1, 0), 303 maxStack: maxStack(1, 0), 304 } 305 }