github.com/klaytn/klaytn@v1.12.1/blockchain/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 22 "github.com/holiman/uint256" 23 "github.com/klaytn/klaytn/common" 24 "github.com/klaytn/klaytn/params" 25 ) 26 27 // EnableEIP enables the given EIP on the config. 28 // This operation writes in-place, and callers need to ensure that the globally 29 // defined jump tables are not polluted. 30 func EnableEIP(eipNum int, jt *JumpTable) error { 31 switch eipNum { 32 case 4844: 33 enable4844(jt) 34 case 7516: 35 enable7516(jt) 36 case 6780: 37 enable6780(jt) 38 case 5656: 39 enable5656(jt) 40 case 3860: 41 enable3860(jt) 42 case 3855: 43 enable3855(jt) 44 case 4399: 45 enable4399(jt) 46 case 3529: 47 enable3529(jt) 48 case 2929: 49 enable2929(jt) 50 case 2200: 51 enable2200(jt) 52 case 1884: 53 enable1884(jt) 54 case 1344: 55 enable1344(jt) 56 case 1153: 57 enable1153(jt) 58 default: 59 return fmt.Errorf("undefined eip %d", eipNum) 60 } 61 return nil 62 } 63 64 // enable1884 applies EIP-1884 to the given jump table: 65 // - Increase cost of BALANCE to 700 66 // - Increase cost of EXTCODEHASH to 700 67 // - Increase cost of SLOAD to 800 68 // - Define SELFBALANCE, with cost GasFastStep (5) 69 func enable1884(jt *JumpTable) { 70 // Gas cost changes 71 jt[SLOAD].constantGas = params.SloadGasEIP1884 72 jt[BALANCE].constantGas = params.BalanceGasEIP1884 73 jt[EXTCODEHASH].constantGas = params.ExtcodeHashGasEIP1884 74 75 // New opcode 76 jt[SELFBALANCE] = &operation{ 77 execute: opSelfBalance, 78 constantGas: GasFastStep, 79 minStack: minStack(0, 1), 80 maxStack: maxStack(0, 1), 81 computationCost: params.SelfBalanceComputationCost, 82 } 83 } 84 85 func opSelfBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 86 balance, _ := uint256.FromBig(interpreter.evm.StateDB.GetBalance(scope.Contract.Address())) 87 scope.Stack.push(balance) 88 return nil, nil 89 } 90 91 // enable1344 applies EIP-1344 (ChainID Opcode) 92 // - Adds an opcode that returns the current chain’s EIP-155 unique identifier 93 func enable1344(jt *JumpTable) { 94 // New opcode 95 jt[CHAINID] = &operation{ 96 execute: opChainID, 97 constantGas: GasQuickStep, 98 minStack: minStack(0, 1), 99 maxStack: maxStack(0, 1), 100 computationCost: params.ChainIDComputationCost, 101 } 102 } 103 104 // opChainID implements CHAINID opcode 105 func opChainID(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 106 chainId, _ := uint256.FromBig(interpreter.evm.chainConfig.ChainID) 107 scope.Stack.push(chainId) 108 return nil, nil 109 } 110 111 // enable2200 applies EIP-2200 (Rebalance net-metered SSTORE) 112 func enable2200(jt *JumpTable) { 113 jt[SLOAD].constantGas = params.SloadGasEIP2200 114 jt[SSTORE].dynamicGas = gasSStoreEIP2200 115 } 116 117 // enableIstanbulComputationCostModification modifies ADDMOD, MULMOD, NOT, XOR, SHL, SHR, SAR computation cost 118 // The modification is activated with istanbulCompatible change activation. 119 func enableIstanbulComputationCostModification(jt *JumpTable) { 120 jt[ADDMOD].computationCost = params.AddmodComputationCostIstanbul 121 jt[MULMOD].computationCost = params.MulmodComputationCostIstanbul 122 jt[NOT].computationCost = params.NotComputationCostIstanbul 123 jt[XOR].computationCost = params.XorComputationCostIstanbul 124 jt[SHL].computationCost = params.ShlComputationCostIstanbul 125 jt[SHR].computationCost = params.ShrComputationCostIstanbul 126 jt[SAR].computationCost = params.SarComputationCostIstanbul 127 } 128 129 // enable1153 applies EIP-1153 "Transient Storage" 130 // - Adds TLOAD that reads from transient storage 131 // - Adds TSTORE that writes to transient storage 132 func enable1153(jt *JumpTable) { 133 jt[TLOAD] = &operation{ 134 execute: opTload, 135 constantGas: params.WarmStorageReadCostEIP2929, 136 minStack: minStack(1, 1), 137 maxStack: maxStack(1, 1), 138 computationCost: params.TloadComputationCost, 139 } 140 141 jt[TSTORE] = &operation{ 142 execute: opTstore, 143 constantGas: params.WarmStorageReadCostEIP2929, 144 minStack: minStack(2, 0), 145 maxStack: maxStack(2, 0), 146 computationCost: params.TstoreComputationCost, 147 } 148 } 149 150 // opTload implements TLOAD opcode 151 func opTload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 152 loc := scope.Stack.peek() 153 hash := common.Hash(loc.Bytes32()) 154 val := interpreter.evm.StateDB.GetTransientState(scope.Contract.Address(), hash) 155 loc.SetBytes(val.Bytes()) 156 return nil, nil 157 } 158 159 // opTstore implements TSTORE opcode 160 func opTstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 161 if interpreter.readOnly { 162 return nil, ErrWriteProtection 163 } 164 loc := scope.Stack.pop() 165 val := scope.Stack.pop() 166 interpreter.evm.StateDB.SetTransientState(scope.Contract.Address(), loc.Bytes32(), val.Bytes32()) 167 return nil, nil 168 } 169 170 // enable3198 applies EIP-3198 (BASEFEE Opcode) 171 // - Adds an opcode that returns the current block's base fee. 172 func enable3198(jt *JumpTable) { 173 // New opcode 174 jt[BASEFEE] = &operation{ 175 execute: opBaseFee, 176 constantGas: GasQuickStep, 177 minStack: minStack(0, 1), 178 maxStack: maxStack(0, 1), 179 computationCost: params.BaseFeeComputationCost, 180 } 181 } 182 183 // opBaseFee implements BASEFEE opcode 184 func opBaseFee(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 185 baseFee, _ := uint256.FromBig(interpreter.evm.Context.BaseFee) 186 scope.Stack.push(baseFee) 187 return nil, nil 188 } 189 190 // enable2929 enables "EIP-2929: Gas cost increases for state access opcodes" 191 // https://eips.ethereum.org/EIPS/eip-2929 192 func enable2929(jt *JumpTable) { 193 jt[SSTORE].dynamicGas = gasSStoreEIP2929 194 195 jt[SLOAD].constantGas = 0 196 jt[SLOAD].dynamicGas = gasSLoadEIP2929 197 198 jt[EXTCODECOPY].constantGas = params.WarmStorageReadCostEIP2929 199 jt[EXTCODECOPY].dynamicGas = gasExtCodeCopyEIP2929 200 201 jt[EXTCODESIZE].constantGas = params.WarmStorageReadCostEIP2929 202 jt[EXTCODESIZE].dynamicGas = gasEip2929AccountCheck 203 204 jt[EXTCODEHASH].constantGas = params.WarmStorageReadCostEIP2929 205 jt[EXTCODEHASH].dynamicGas = gasEip2929AccountCheck 206 207 jt[BALANCE].constantGas = params.WarmStorageReadCostEIP2929 208 jt[BALANCE].dynamicGas = gasEip2929AccountCheck 209 210 jt[CALL].constantGas = params.WarmStorageReadCostEIP2929 211 jt[CALL].dynamicGas = gasCallEIP2929 212 213 jt[CALLCODE].constantGas = params.WarmStorageReadCostEIP2929 214 jt[CALLCODE].dynamicGas = gasCallCodeEIP2929 215 216 jt[STATICCALL].constantGas = params.WarmStorageReadCostEIP2929 217 jt[STATICCALL].dynamicGas = gasStaticCallEIP2929 218 219 jt[DELEGATECALL].constantGas = params.WarmStorageReadCostEIP2929 220 jt[DELEGATECALL].dynamicGas = gasDelegateCallEIP2929 221 222 // This was previously part of the dynamic cost, but we're using it as a constantGas 223 // factor here 224 jt[SELFDESTRUCT].constantGas = params.SelfdestructGas 225 jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP2929 226 } 227 228 // enable3529 enabled "EIP-3529: Reduction in refunds": 229 // - Removes refunds for selfdestructs 230 // - Reduces refunds for SSTORE 231 // - Reduces max refunds to 20% gas 232 func enable3529(jt *JumpTable) { 233 jt[SSTORE].dynamicGas = gasSStoreEIP3529 234 jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP3529 235 } 236 237 // enable4399 applies EIP-4399 (PREVRANDAO Opcode) 238 // - Change the 0x44 opcode from returning difficulty value to returning prev blockhash value 239 func enable4399(jt *JumpTable) { 240 jt[PREVRANDAO] = &operation{ 241 execute: opRandom, 242 constantGas: GasQuickStep, 243 minStack: minStack(0, 1), 244 maxStack: maxStack(0, 1), 245 computationCost: params.RandomComputationCost, 246 } 247 } 248 249 // enable3855 applies EIP-3855 (PUSH0 opcode) 250 func enable3855(jt *JumpTable) { 251 jt[PUSH0] = &operation{ 252 execute: opPush0, 253 constantGas: GasQuickStep, 254 minStack: minStack(0, 1), 255 maxStack: maxStack(0, 1), 256 computationCost: params.Push0ComputationCost, 257 } 258 } 259 260 // opPush0 implements the PUSH0 opcode 261 func opPush0(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 262 scope.Stack.push(new(uint256.Int)) 263 return nil, nil 264 } 265 266 // enable3860 enables "EIP-3860: Limit and meter initcode" 267 // https://eips.ethereum.org/EIPS/eip-3860 268 func enable3860(jt *JumpTable) { 269 jt[CREATE].dynamicGas = gasCreateEip3860 270 jt[CREATE2].dynamicGas = gasCreate2Eip3860 271 } 272 273 // enable5656 enables EIP-5656 (MCOPY opcode) 274 // https://eips.ethereum.org/EIPS/eip-5656 275 func enable5656(jt *JumpTable) { 276 jt[MCOPY] = &operation{ 277 execute: opMcopy, 278 constantGas: GasFastestStep, 279 dynamicGas: gasMcopy, 280 minStack: minStack(3, 0), 281 maxStack: maxStack(3, 0), 282 memorySize: memoryMcopy, 283 computationCost: params.McopyComputationCost, 284 } 285 } 286 287 // opMcopy implements the MCOPY opcode (https://eips.ethereum.org/EIPS/eip-5656) 288 func opMcopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 289 var ( 290 dst = scope.Stack.pop() 291 src = scope.Stack.pop() 292 length = scope.Stack.pop() 293 ) 294 // These values are checked for overflow during memory expansion calculation 295 // (the memorySize function on the opcode). 296 scope.Memory.Copy(dst.Uint64(), src.Uint64(), length.Uint64()) 297 return nil, nil 298 } 299 300 // enable6780 applies EIP-6780 (deactivate SELFDESTRUCT) 301 func enable6780(jt *JumpTable) { 302 jt[SELFDESTRUCT] = &operation{ 303 execute: opSelfdestruct6780, 304 dynamicGas: gasSelfdestructEIP3529, 305 constantGas: params.SelfdestructGas, 306 minStack: minStack(1, 0), 307 maxStack: maxStack(1, 0), 308 computationCost: params.SelfDestructComputationCost, 309 } 310 } 311 312 // opBlobHash implements the BLOBHASH opcode 313 // Since blob data is generated in dank sharding, opBlobHash will perform only the default action of setting the top of the stack as zero 314 // as long as the blob txType is not fully supported in Klaytn. 315 func opBlobHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 316 index := scope.Stack.peek() 317 index.Clear() 318 319 return nil, nil 320 } 321 322 // opBlobBaseFee implements BLOBBASEFEE opcode 323 // Since blob data is generated in dank sharding, opBlobBaseFee will use only the zeroBaseFee 324 // as long as the blob txType is not fully supported in Klaytn. 325 func opBlobBaseFee(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 326 blobBaseFee := uint256.NewInt(params.ZeroBaseFee) 327 scope.Stack.push(blobBaseFee) 328 return nil, nil 329 } 330 331 // enable4844 applies EIP-4844 (BLOBHASH opcode) 332 func enable4844(jt *JumpTable) { 333 jt[BLOBHASH] = &operation{ 334 execute: opBlobHash, 335 constantGas: GasFastestStep, 336 minStack: minStack(1, 1), 337 maxStack: maxStack(1, 1), 338 computationCost: params.BlobHashComptationCost, 339 } 340 } 341 342 // enable7516 applies EIP-7516 (BLOBBASEFEE opcode) 343 func enable7516(jt *JumpTable) { 344 jt[BLOBBASEFEE] = &operation{ 345 execute: opBlobBaseFee, 346 constantGas: GasQuickStep, 347 minStack: minStack(0, 1), 348 maxStack: maxStack(0, 1), 349 computationCost: params.BlobBaseFeeComputationCost, 350 } 351 } 352 353 func enable1052(jt *JumpTable) { 354 jt[EXTCODEHASH] = &operation{ 355 execute: opExtCodeHash1052, 356 constantGas: params.ExtcodeHashGasConstantinople, 357 minStack: minStack(1, 1), 358 maxStack: maxStack(1, 1), 359 computationCost: params.ExtCodeHashComputationCost, 360 } 361 } 362 363 // As the cpu performance has been improved a lot, and as the storage size has increased a lot 364 // recalculated the computation cost of some opcodes 365 func enableCancunComputationCostModification(jt *JumpTable) { 366 jt[SDIV].computationCost = params.SdivComputationCostCancun 367 jt[MOD].computationCost = params.ModComputationCostCancun 368 jt[ADDMOD].computationCost = params.AddmodComputationCostCancun 369 jt[MULMOD].computationCost = params.MulmodComputationCostCancun 370 jt[EXP].computationCost = params.ExpComputationCostCancun 371 jt[SHA3].computationCost = params.Sha3ComputationCostCancun 372 jt[MSTORE8].computationCost = params.Mstore8ComputationCostCancun 373 374 jt[SLOAD].computationCost = params.SloadComputationCostCancun 375 jt[SSTORE].computationCost = params.SstoreComputationCostCancun 376 jt[LOG1].computationCost = params.Log1ComputationCostCancun 377 jt[LOG2].computationCost = params.Log2ComputationCostCancun 378 jt[LOG3].computationCost = params.Log3ComputationCostCancun 379 jt[LOG4].computationCost = params.Log4ComputationCostCancun 380 }