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