github.com/ethereum/go-ethereum@v1.16.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 "math" 22 "sort" 23 24 "github.com/ethereum/go-ethereum/common" 25 "github.com/ethereum/go-ethereum/core/tracing" 26 "github.com/ethereum/go-ethereum/params" 27 "github.com/holiman/uint256" 28 ) 29 30 var activators = map[int]func(*JumpTable){ 31 5656: enable5656, 32 6780: enable6780, 33 3855: enable3855, 34 3860: enable3860, 35 3529: enable3529, 36 3198: enable3198, 37 2929: enable2929, 38 2200: enable2200, 39 1884: enable1884, 40 1344: enable1344, 41 1153: enable1153, 42 4762: enable4762, 43 7702: enable7702, 44 } 45 46 // EnableEIP enables the given EIP on the config. 47 // This operation writes in-place, and callers need to ensure that the globally 48 // defined jump tables are not polluted. 49 func EnableEIP(eipNum int, jt *JumpTable) error { 50 enablerFn, ok := activators[eipNum] 51 if !ok { 52 return fmt.Errorf("undefined eip %d", eipNum) 53 } 54 enablerFn(jt) 55 return nil 56 } 57 58 func ValidEip(eipNum int) bool { 59 _, ok := activators[eipNum] 60 return ok 61 } 62 func ActivateableEips() []string { 63 var nums []string 64 for k := range activators { 65 nums = append(nums, fmt.Sprintf("%d", k)) 66 } 67 sort.Strings(nums) 68 return nums 69 } 70 71 // enable1884 applies EIP-1884 to the given jump table: 72 // - Increase cost of BALANCE to 700 73 // - Increase cost of EXTCODEHASH to 700 74 // - Increase cost of SLOAD to 800 75 // - Define SELFBALANCE, with cost GasFastStep (5) 76 func enable1884(jt *JumpTable) { 77 // Gas cost changes 78 jt[SLOAD].constantGas = params.SloadGasEIP1884 79 jt[BALANCE].constantGas = params.BalanceGasEIP1884 80 jt[EXTCODEHASH].constantGas = params.ExtcodeHashGasEIP1884 81 82 // New opcode 83 jt[SELFBALANCE] = &operation{ 84 execute: opSelfBalance, 85 constantGas: GasFastStep, 86 minStack: minStack(0, 1), 87 maxStack: maxStack(0, 1), 88 } 89 } 90 91 func opSelfBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 92 balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address()) 93 scope.Stack.push(balance) 94 return nil, nil 95 } 96 97 // enable1344 applies EIP-1344 (ChainID Opcode) 98 // - Adds an opcode that returns the current chain’s EIP-155 unique identifier 99 func enable1344(jt *JumpTable) { 100 // New opcode 101 jt[CHAINID] = &operation{ 102 execute: opChainID, 103 constantGas: GasQuickStep, 104 minStack: minStack(0, 1), 105 maxStack: maxStack(0, 1), 106 } 107 } 108 109 // opChainID implements CHAINID opcode 110 func opChainID(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 111 chainId, _ := uint256.FromBig(interpreter.evm.chainConfig.ChainID) 112 scope.Stack.push(chainId) 113 return nil, nil 114 } 115 116 // enable2200 applies EIP-2200 (Rebalance net-metered SSTORE) 117 func enable2200(jt *JumpTable) { 118 jt[SLOAD].constantGas = params.SloadGasEIP2200 119 jt[SSTORE].dynamicGas = gasSStoreEIP2200 120 } 121 122 // enable2929 enables "EIP-2929: Gas cost increases for state access opcodes" 123 // https://eips.ethereum.org/EIPS/eip-2929 124 func enable2929(jt *JumpTable) { 125 jt[SSTORE].dynamicGas = gasSStoreEIP2929 126 127 jt[SLOAD].constantGas = 0 128 jt[SLOAD].dynamicGas = gasSLoadEIP2929 129 130 jt[EXTCODECOPY].constantGas = params.WarmStorageReadCostEIP2929 131 jt[EXTCODECOPY].dynamicGas = gasExtCodeCopyEIP2929 132 133 jt[EXTCODESIZE].constantGas = params.WarmStorageReadCostEIP2929 134 jt[EXTCODESIZE].dynamicGas = gasEip2929AccountCheck 135 136 jt[EXTCODEHASH].constantGas = params.WarmStorageReadCostEIP2929 137 jt[EXTCODEHASH].dynamicGas = gasEip2929AccountCheck 138 139 jt[BALANCE].constantGas = params.WarmStorageReadCostEIP2929 140 jt[BALANCE].dynamicGas = gasEip2929AccountCheck 141 142 jt[CALL].constantGas = params.WarmStorageReadCostEIP2929 143 jt[CALL].dynamicGas = gasCallEIP2929 144 145 jt[CALLCODE].constantGas = params.WarmStorageReadCostEIP2929 146 jt[CALLCODE].dynamicGas = gasCallCodeEIP2929 147 148 jt[STATICCALL].constantGas = params.WarmStorageReadCostEIP2929 149 jt[STATICCALL].dynamicGas = gasStaticCallEIP2929 150 151 jt[DELEGATECALL].constantGas = params.WarmStorageReadCostEIP2929 152 jt[DELEGATECALL].dynamicGas = gasDelegateCallEIP2929 153 154 // This was previously part of the dynamic cost, but we're using it as a constantGas 155 // factor here 156 jt[SELFDESTRUCT].constantGas = params.SelfdestructGasEIP150 157 jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP2929 158 } 159 160 // enable3529 enabled "EIP-3529: Reduction in refunds": 161 // - Removes refunds for selfdestructs 162 // - Reduces refunds for SSTORE 163 // - Reduces max refunds to 20% gas 164 func enable3529(jt *JumpTable) { 165 jt[SSTORE].dynamicGas = gasSStoreEIP3529 166 jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP3529 167 } 168 169 // enable3198 applies EIP-3198 (BASEFEE Opcode) 170 // - Adds an opcode that returns the current block's base fee. 171 func enable3198(jt *JumpTable) { 172 // New opcode 173 jt[BASEFEE] = &operation{ 174 execute: opBaseFee, 175 constantGas: GasQuickStep, 176 minStack: minStack(0, 1), 177 maxStack: maxStack(0, 1), 178 } 179 } 180 181 // enable1153 applies EIP-1153 "Transient Storage" 182 // - Adds TLOAD that reads from transient storage 183 // - Adds TSTORE that writes to transient storage 184 func enable1153(jt *JumpTable) { 185 jt[TLOAD] = &operation{ 186 execute: opTload, 187 constantGas: params.WarmStorageReadCostEIP2929, 188 minStack: minStack(1, 1), 189 maxStack: maxStack(1, 1), 190 } 191 192 jt[TSTORE] = &operation{ 193 execute: opTstore, 194 constantGas: params.WarmStorageReadCostEIP2929, 195 minStack: minStack(2, 0), 196 maxStack: maxStack(2, 0), 197 } 198 } 199 200 // opTload implements TLOAD opcode 201 func opTload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 202 loc := scope.Stack.peek() 203 hash := common.Hash(loc.Bytes32()) 204 val := interpreter.evm.StateDB.GetTransientState(scope.Contract.Address(), hash) 205 loc.SetBytes(val.Bytes()) 206 return nil, nil 207 } 208 209 // opTstore implements TSTORE opcode 210 func opTstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 211 if interpreter.readOnly { 212 return nil, ErrWriteProtection 213 } 214 loc := scope.Stack.pop() 215 val := scope.Stack.pop() 216 interpreter.evm.StateDB.SetTransientState(scope.Contract.Address(), loc.Bytes32(), val.Bytes32()) 217 return nil, nil 218 } 219 220 // opBaseFee implements BASEFEE opcode 221 func opBaseFee(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 222 baseFee, _ := uint256.FromBig(interpreter.evm.Context.BaseFee) 223 scope.Stack.push(baseFee) 224 return nil, nil 225 } 226 227 // enable3855 applies EIP-3855 (PUSH0 opcode) 228 func enable3855(jt *JumpTable) { 229 // New opcode 230 jt[PUSH0] = &operation{ 231 execute: opPush0, 232 constantGas: GasQuickStep, 233 minStack: minStack(0, 1), 234 maxStack: maxStack(0, 1), 235 } 236 } 237 238 // opPush0 implements the PUSH0 opcode 239 func opPush0(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 240 scope.Stack.push(new(uint256.Int)) 241 return nil, nil 242 } 243 244 // enable3860 enables "EIP-3860: Limit and meter initcode" 245 // https://eips.ethereum.org/EIPS/eip-3860 246 func enable3860(jt *JumpTable) { 247 jt[CREATE].dynamicGas = gasCreateEip3860 248 jt[CREATE2].dynamicGas = gasCreate2Eip3860 249 } 250 251 // enable5656 enables EIP-5656 (MCOPY opcode) 252 // https://eips.ethereum.org/EIPS/eip-5656 253 func enable5656(jt *JumpTable) { 254 jt[MCOPY] = &operation{ 255 execute: opMcopy, 256 constantGas: GasFastestStep, 257 dynamicGas: gasMcopy, 258 minStack: minStack(3, 0), 259 maxStack: maxStack(3, 0), 260 memorySize: memoryMcopy, 261 } 262 } 263 264 // opMcopy implements the MCOPY opcode (https://eips.ethereum.org/EIPS/eip-5656) 265 func opMcopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 266 var ( 267 dst = scope.Stack.pop() 268 src = scope.Stack.pop() 269 length = scope.Stack.pop() 270 ) 271 // These values are checked for overflow during memory expansion calculation 272 // (the memorySize function on the opcode). 273 scope.Memory.Copy(dst.Uint64(), src.Uint64(), length.Uint64()) 274 return nil, nil 275 } 276 277 // opBlobHash implements the BLOBHASH opcode 278 func opBlobHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 279 index := scope.Stack.peek() 280 if index.LtUint64(uint64(len(interpreter.evm.TxContext.BlobHashes))) { 281 blobHash := interpreter.evm.TxContext.BlobHashes[index.Uint64()] 282 index.SetBytes32(blobHash[:]) 283 } else { 284 index.Clear() 285 } 286 return nil, nil 287 } 288 289 // opBlobBaseFee implements BLOBBASEFEE opcode 290 func opBlobBaseFee(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 291 blobBaseFee, _ := uint256.FromBig(interpreter.evm.Context.BlobBaseFee) 292 scope.Stack.push(blobBaseFee) 293 return nil, nil 294 } 295 296 // enable4844 applies EIP-4844 (BLOBHASH opcode) 297 func enable4844(jt *JumpTable) { 298 jt[BLOBHASH] = &operation{ 299 execute: opBlobHash, 300 constantGas: GasFastestStep, 301 minStack: minStack(1, 1), 302 maxStack: maxStack(1, 1), 303 } 304 } 305 306 // enable7516 applies EIP-7516 (BLOBBASEFEE opcode) 307 func enable7516(jt *JumpTable) { 308 jt[BLOBBASEFEE] = &operation{ 309 execute: opBlobBaseFee, 310 constantGas: GasQuickStep, 311 minStack: minStack(0, 1), 312 maxStack: maxStack(0, 1), 313 } 314 } 315 316 // enable6780 applies EIP-6780 (deactivate SELFDESTRUCT) 317 func enable6780(jt *JumpTable) { 318 jt[SELFDESTRUCT] = &operation{ 319 execute: opSelfdestruct6780, 320 dynamicGas: gasSelfdestructEIP3529, 321 constantGas: params.SelfdestructGasEIP150, 322 minStack: minStack(1, 0), 323 maxStack: maxStack(1, 0), 324 } 325 } 326 327 func opExtCodeCopyEIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 328 var ( 329 stack = scope.Stack 330 a = stack.pop() 331 memOffset = stack.pop() 332 codeOffset = stack.pop() 333 length = stack.pop() 334 ) 335 uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow() 336 if overflow { 337 uint64CodeOffset = math.MaxUint64 338 } 339 addr := common.Address(a.Bytes20()) 340 code := interpreter.evm.StateDB.GetCode(addr) 341 paddedCodeCopy, copyOffset, nonPaddedCopyLength := getDataAndAdjustedBounds(code, uint64CodeOffset, length.Uint64()) 342 consumed, wanted := interpreter.evm.AccessEvents.CodeChunksRangeGas(addr, copyOffset, nonPaddedCopyLength, uint64(len(code)), false, scope.Contract.Gas) 343 scope.Contract.UseGas(consumed, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) 344 if consumed < wanted { 345 return nil, ErrOutOfGas 346 } 347 scope.Memory.Set(memOffset.Uint64(), length.Uint64(), paddedCodeCopy) 348 349 return nil, nil 350 } 351 352 // opPush1EIP4762 handles the special case of PUSH1 opcode for EIP-4762, which 353 // need not worry about the adjusted bound logic when adding the PUSHDATA to 354 // the list of access events. 355 func opPush1EIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 356 var ( 357 codeLen = uint64(len(scope.Contract.Code)) 358 integer = new(uint256.Int) 359 ) 360 *pc += 1 361 if *pc < codeLen { 362 scope.Stack.push(integer.SetUint64(uint64(scope.Contract.Code[*pc]))) 363 364 if !scope.Contract.IsDeployment && !scope.Contract.IsSystemCall && *pc%31 == 0 { 365 // touch next chunk if PUSH1 is at the boundary. if so, *pc has 366 // advanced past this boundary. 367 contractAddr := scope.Contract.Address() 368 consumed, wanted := interpreter.evm.AccessEvents.CodeChunksRangeGas(contractAddr, *pc+1, uint64(1), uint64(len(scope.Contract.Code)), false, scope.Contract.Gas) 369 scope.Contract.UseGas(wanted, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) 370 if consumed < wanted { 371 return nil, ErrOutOfGas 372 } 373 } 374 } else { 375 scope.Stack.push(integer.Clear()) 376 } 377 return nil, nil 378 } 379 380 func makePushEIP4762(size uint64, pushByteSize int) executionFunc { 381 return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 382 var ( 383 codeLen = len(scope.Contract.Code) 384 start = min(codeLen, int(*pc+1)) 385 end = min(codeLen, start+pushByteSize) 386 ) 387 scope.Stack.push(new(uint256.Int).SetBytes( 388 common.RightPadBytes( 389 scope.Contract.Code[start:end], 390 pushByteSize, 391 )), 392 ) 393 394 if !scope.Contract.IsDeployment && !scope.Contract.IsSystemCall { 395 contractAddr := scope.Contract.Address() 396 consumed, wanted := interpreter.evm.AccessEvents.CodeChunksRangeGas(contractAddr, uint64(start), uint64(pushByteSize), uint64(len(scope.Contract.Code)), false, scope.Contract.Gas) 397 scope.Contract.UseGas(consumed, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) 398 if consumed < wanted { 399 return nil, ErrOutOfGas 400 } 401 } 402 403 *pc += size 404 return nil, nil 405 } 406 } 407 408 func enable4762(jt *JumpTable) { 409 jt[SSTORE] = &operation{ 410 dynamicGas: gasSStore4762, 411 execute: opSstore, 412 minStack: minStack(2, 0), 413 maxStack: maxStack(2, 0), 414 } 415 jt[SLOAD] = &operation{ 416 dynamicGas: gasSLoad4762, 417 execute: opSload, 418 minStack: minStack(1, 1), 419 maxStack: maxStack(1, 1), 420 } 421 422 jt[BALANCE] = &operation{ 423 execute: opBalance, 424 dynamicGas: gasBalance4762, 425 minStack: minStack(1, 1), 426 maxStack: maxStack(1, 1), 427 } 428 429 jt[EXTCODESIZE] = &operation{ 430 execute: opExtCodeSize, 431 dynamicGas: gasExtCodeSize4762, 432 minStack: minStack(1, 1), 433 maxStack: maxStack(1, 1), 434 } 435 436 jt[EXTCODEHASH] = &operation{ 437 execute: opExtCodeHash, 438 dynamicGas: gasExtCodeHash4762, 439 minStack: minStack(1, 1), 440 maxStack: maxStack(1, 1), 441 } 442 443 jt[EXTCODECOPY] = &operation{ 444 execute: opExtCodeCopyEIP4762, 445 dynamicGas: gasExtCodeCopyEIP4762, 446 minStack: minStack(4, 0), 447 maxStack: maxStack(4, 0), 448 memorySize: memoryExtCodeCopy, 449 } 450 451 jt[CODECOPY] = &operation{ 452 execute: opCodeCopy, 453 constantGas: GasFastestStep, 454 dynamicGas: gasCodeCopyEip4762, 455 minStack: minStack(3, 0), 456 maxStack: maxStack(3, 0), 457 memorySize: memoryCodeCopy, 458 } 459 460 jt[SELFDESTRUCT] = &operation{ 461 execute: opSelfdestruct6780, 462 dynamicGas: gasSelfdestructEIP4762, 463 constantGas: params.SelfdestructGasEIP150, 464 minStack: minStack(1, 0), 465 maxStack: maxStack(1, 0), 466 } 467 468 jt[CREATE] = &operation{ 469 execute: opCreate, 470 constantGas: params.CreateNGasEip4762, 471 dynamicGas: gasCreateEip3860, 472 minStack: minStack(3, 1), 473 maxStack: maxStack(3, 1), 474 memorySize: memoryCreate, 475 } 476 477 jt[CREATE2] = &operation{ 478 execute: opCreate2, 479 constantGas: params.CreateNGasEip4762, 480 dynamicGas: gasCreate2Eip3860, 481 minStack: minStack(4, 1), 482 maxStack: maxStack(4, 1), 483 memorySize: memoryCreate2, 484 } 485 486 jt[CALL] = &operation{ 487 execute: opCall, 488 dynamicGas: gasCallEIP4762, 489 minStack: minStack(7, 1), 490 maxStack: maxStack(7, 1), 491 memorySize: memoryCall, 492 } 493 494 jt[CALLCODE] = &operation{ 495 execute: opCallCode, 496 dynamicGas: gasCallCodeEIP4762, 497 minStack: minStack(7, 1), 498 maxStack: maxStack(7, 1), 499 memorySize: memoryCall, 500 } 501 502 jt[STATICCALL] = &operation{ 503 execute: opStaticCall, 504 dynamicGas: gasStaticCallEIP4762, 505 minStack: minStack(6, 1), 506 maxStack: maxStack(6, 1), 507 memorySize: memoryStaticCall, 508 } 509 510 jt[DELEGATECALL] = &operation{ 511 execute: opDelegateCall, 512 dynamicGas: gasDelegateCallEIP4762, 513 minStack: minStack(6, 1), 514 maxStack: maxStack(6, 1), 515 memorySize: memoryDelegateCall, 516 } 517 518 jt[PUSH1] = &operation{ 519 execute: opPush1EIP4762, 520 constantGas: GasFastestStep, 521 minStack: minStack(0, 1), 522 maxStack: maxStack(0, 1), 523 } 524 for i := 1; i < 32; i++ { 525 jt[PUSH1+OpCode(i)] = &operation{ 526 execute: makePushEIP4762(uint64(i+1), i+1), 527 constantGas: GasFastestStep, 528 minStack: minStack(0, 1), 529 maxStack: maxStack(0, 1), 530 } 531 } 532 } 533 534 // enable7702 the EIP-7702 changes to support delegation designators. 535 func enable7702(jt *JumpTable) { 536 jt[CALL].dynamicGas = gasCallEIP7702 537 jt[CALLCODE].dynamicGas = gasCallCodeEIP7702 538 jt[STATICCALL].dynamicGas = gasStaticCallEIP7702 539 jt[DELEGATECALL].dynamicGas = gasDelegateCallEIP7702 540 }