github.com/aidoskuneen/adk-node@v0.0.0-20220315131952-2e32567cb7f4/core/vm/instructions.go (about) 1 // Copyright 2021 The adkgo Authors 2 // This file is part of adkgo. 3 // 4 // adkgo is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU 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 // adkgo 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 General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with adkgo. If not, see <http://www.gnu.org/licenses/>. 16 17 package vm 18 19 import ( 20 "github.com/aidoskuneen/adk-node/common" 21 "github.com/aidoskuneen/adk-node/core/types" 22 "github.com/aidoskuneen/adk-node/params" 23 "github.com/holiman/uint256" 24 "golang.org/x/crypto/sha3" 25 "github.com/AidosKuneen/gadk" 26 //"math/big" 27 //"bytes" 28 ) 29 30 func opAdd(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 31 x, y := scope.Stack.pop(), scope.Stack.peek() 32 y.Add(&x, y) 33 return nil, nil 34 } 35 36 func opSub(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 37 x, y := scope.Stack.pop(), scope.Stack.peek() 38 y.Sub(&x, y) 39 return nil, nil 40 } 41 42 func opMul(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 43 x, y := scope.Stack.pop(), scope.Stack.peek() 44 y.Mul(&x, y) 45 return nil, nil 46 } 47 48 func opDiv(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 49 x, y := scope.Stack.pop(), scope.Stack.peek() 50 y.Div(&x, y) 51 return nil, nil 52 } 53 54 func opSdiv(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 55 x, y := scope.Stack.pop(), scope.Stack.peek() 56 y.SDiv(&x, y) 57 return nil, nil 58 } 59 60 func opMod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 61 x, y := scope.Stack.pop(), scope.Stack.peek() 62 y.Mod(&x, y) 63 return nil, nil 64 } 65 66 func opSmod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 67 x, y := scope.Stack.pop(), scope.Stack.peek() 68 y.SMod(&x, y) 69 return nil, nil 70 } 71 72 func opExp(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 73 base, exponent := scope.Stack.pop(), scope.Stack.peek() 74 exponent.Exp(&base, exponent) 75 return nil, nil 76 } 77 78 func opSignExtend(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 79 back, num := scope.Stack.pop(), scope.Stack.peek() 80 num.ExtendSign(num, &back) 81 return nil, nil 82 } 83 84 func opNot(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 85 x := scope.Stack.peek() 86 x.Not(x) 87 return nil, nil 88 } 89 90 func opLt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 91 x, y := scope.Stack.pop(), scope.Stack.peek() 92 if x.Lt(y) { 93 y.SetOne() 94 } else { 95 y.Clear() 96 } 97 return nil, nil 98 } 99 100 func opGt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 101 x, y := scope.Stack.pop(), scope.Stack.peek() 102 if x.Gt(y) { 103 y.SetOne() 104 } else { 105 y.Clear() 106 } 107 return nil, nil 108 } 109 110 func opSlt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 111 x, y := scope.Stack.pop(), scope.Stack.peek() 112 if x.Slt(y) { 113 y.SetOne() 114 } else { 115 y.Clear() 116 } 117 return nil, nil 118 } 119 120 func opSgt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 121 x, y := scope.Stack.pop(), scope.Stack.peek() 122 if x.Sgt(y) { 123 y.SetOne() 124 } else { 125 y.Clear() 126 } 127 return nil, nil 128 } 129 130 func opEq(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 131 x, y := scope.Stack.pop(), scope.Stack.peek() 132 if x.Eq(y) { 133 y.SetOne() 134 } else { 135 y.Clear() 136 } 137 return nil, nil 138 } 139 140 func opIszero(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 141 x := scope.Stack.peek() 142 if x.IsZero() { 143 x.SetOne() 144 } else { 145 x.Clear() 146 } 147 return nil, nil 148 } 149 150 func opAnd(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 151 x, y := scope.Stack.pop(), scope.Stack.peek() 152 y.And(&x, y) 153 return nil, nil 154 } 155 156 func opOr(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 157 x, y := scope.Stack.pop(), scope.Stack.peek() 158 y.Or(&x, y) 159 return nil, nil 160 } 161 162 func opXor(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 163 x, y := scope.Stack.pop(), scope.Stack.peek() 164 y.Xor(&x, y) 165 return nil, nil 166 } 167 168 func opByte(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 169 th, val := scope.Stack.pop(), scope.Stack.peek() 170 val.Byte(&th) 171 return nil, nil 172 } 173 174 func opAddmod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 175 x, y, z := scope.Stack.pop(), scope.Stack.pop(), scope.Stack.peek() 176 if z.IsZero() { 177 z.Clear() 178 } else { 179 z.AddMod(&x, &y, z) 180 } 181 return nil, nil 182 } 183 184 func opMulmod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 185 x, y, z := scope.Stack.pop(), scope.Stack.pop(), scope.Stack.peek() 186 z.MulMod(&x, &y, z) 187 return nil, nil 188 } 189 190 // opSHL implements Shift Left 191 // The SHL instruction (shift left) pops 2 values from the stack, first arg1 and then arg2, 192 // and pushes on the stack arg2 shifted to the left by arg1 number of bits. 193 func opSHL(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 194 // Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards 195 shift, value := scope.Stack.pop(), scope.Stack.peek() 196 if shift.LtUint64(256) { 197 value.Lsh(value, uint(shift.Uint64())) 198 } else { 199 value.Clear() 200 } 201 return nil, nil 202 } 203 204 // opSHR implements Logical Shift Right 205 // The SHR instruction (logical shift right) pops 2 values from the stack, first arg1 and then arg2, 206 // and pushes on the stack arg2 shifted to the right by arg1 number of bits with zero fill. 207 func opSHR(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 208 // Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards 209 shift, value := scope.Stack.pop(), scope.Stack.peek() 210 if shift.LtUint64(256) { 211 value.Rsh(value, uint(shift.Uint64())) 212 } else { 213 value.Clear() 214 } 215 return nil, nil 216 } 217 218 // opSAR implements Arithmetic Shift Right 219 // The SAR instruction (arithmetic shift right) pops 2 values from the stack, first arg1 and then arg2, 220 // and pushes on the stack arg2 shifted to the right by arg1 number of bits with sign extension. 221 func opSAR(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 222 shift, value := scope.Stack.pop(), scope.Stack.peek() 223 if shift.GtUint64(256) { 224 if value.Sign() >= 0 { 225 value.Clear() 226 } else { 227 // Max negative shift: all bits set 228 value.SetAllOne() 229 } 230 return nil, nil 231 } 232 n := uint(shift.Uint64()) 233 value.SRsh(value, n) 234 return nil, nil 235 } 236 237 func opSha3(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 238 offset, size := scope.Stack.pop(), scope.Stack.peek() 239 data := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) 240 241 isCURL := false 242 curlCommand := "" 243 if len(data) > 12 && string(data[0:6]) == "{CURL}"{ 244 curlCommand = string(data[6:12]) 245 isCURL = true 246 } 247 248 if !isCURL { 249 if interpreter.hasher == nil { 250 interpreter.hasher = sha3.NewLegacyKeccak256().(keccakState) 251 } else { 252 interpreter.hasher.Reset() 253 } 254 interpreter.hasher.Write(data) 255 interpreter.hasher.Read(interpreter.hasherBuf[:]) 256 257 evm := interpreter.evm 258 if evm.Config.EnablePreimageRecording { 259 evm.StateDB.AddPreimage(interpreter.hasherBuf, data) 260 } 261 262 size.SetBytes(interpreter.hasherBuf[:]) 263 } else { // CURL HANDLING 264 dataAsString := string(data[12:]) 265 dataAsTrytes, err := gadk.ToTrytes(dataAsString) 266 if err != nil { 267 size.SetBytes([]byte("INVALID9TRYTES999999999999999999")) 268 } else if string([]byte(curlCommand)[0:4]) == "HASH"{ 269 start_idx := data[10:11];// which part of the hash to we return. Note we have to compute every time in case its called from rpc, where the interpreter does not carry over the result 270 if start_idx[0] > 64 { // any larger than 64 doesnt make sense, as the CURL hash is only 81 chars long 271 start_idx[0] = 64 272 } 273 if (start_idx[0] < 0) { 274 start_idx[0] = 0 275 } 276 hash := dataAsTrytes.Hash()+"999999999999999" // pad to 3x32 277 hash_b := []byte(hash) 278 size.SetBytes(hash_b[start_idx[0]:start_idx[0]+32]) // first 32 bytes 279 } else if curlCommand == "VALSIG" && len(dataAsString) == 4536 { //4536 is 2xSignature + addr + bundle 280 addr, err1 := gadk.ToAddress(string([]byte(dataAsString)[0:81])) 281 sig1, err31 := gadk.ToTrytes(string([]byte(dataAsString)[81:81+2187])) // sig = 2187 282 sig2, err32 := gadk.ToTrytes(string([]byte(dataAsString)[81+2187:81+2187*2])) 283 bundle,err4 := gadk.ToTrytes(string([]byte(dataAsString)[4455:4536])) 284 ret := make([]byte,32) // all 0 = false 285 if err1 != nil || err31 != nil || err32 != nil || err4 != nil || ! gadk.IsValidSig(addr, []gadk.Trytes{sig1,sig2}, bundle) { 286 ret[0] = 0x01 // not 0 = true/valid signature 287 } 288 size.SetBytes(ret); 289 } else { // unknown command 290 size.SetBytes([]byte("ERROR99999999999999999999999"+string([]byte(curlCommand)[0:4]))) 291 } 292 } 293 294 return nil, nil 295 } 296 func opAddress(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 297 scope.Stack.push(new(uint256.Int).SetBytes(scope.Contract.Address().Bytes())) 298 return nil, nil 299 } 300 301 func opBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 302 slot := scope.Stack.peek() 303 address := common.Address(slot.Bytes20()) 304 slot.SetFromBig(interpreter.evm.StateDB.GetBalance(address)) 305 return nil, nil 306 } 307 308 func opOrigin(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 309 scope.Stack.push(new(uint256.Int).SetBytes(interpreter.evm.Origin.Bytes())) 310 return nil, nil 311 } 312 func opCaller(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 313 scope.Stack.push(new(uint256.Int).SetBytes(scope.Contract.Caller().Bytes())) 314 return nil, nil 315 } 316 317 func opCallValue(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 318 v, _ := uint256.FromBig(scope.Contract.value) 319 scope.Stack.push(v) 320 return nil, nil 321 } 322 323 func opCallDataLoad(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 324 x := scope.Stack.peek() 325 if offset, overflow := x.Uint64WithOverflow(); !overflow { 326 data := getData(scope.Contract.Input, offset, 32) 327 x.SetBytes(data) 328 } else { 329 x.Clear() 330 } 331 return nil, nil 332 } 333 334 func opCallDataSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 335 scope.Stack.push(new(uint256.Int).SetUint64(uint64(len(scope.Contract.Input)))) 336 return nil, nil 337 } 338 339 func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 340 var ( 341 memOffset = scope.Stack.pop() 342 dataOffset = scope.Stack.pop() 343 length = scope.Stack.pop() 344 ) 345 dataOffset64, overflow := dataOffset.Uint64WithOverflow() 346 if overflow { 347 dataOffset64 = 0xffffffffffffffff 348 } 349 // These values are checked for overflow during gas cost calculation 350 memOffset64 := memOffset.Uint64() 351 length64 := length.Uint64() 352 scope.Memory.Set(memOffset64, length64, getData(scope.Contract.Input, dataOffset64, length64)) 353 354 return nil, nil 355 } 356 357 func opReturnDataSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 358 scope.Stack.push(new(uint256.Int).SetUint64(uint64(len(interpreter.returnData)))) 359 return nil, nil 360 } 361 362 func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 363 var ( 364 memOffset = scope.Stack.pop() 365 dataOffset = scope.Stack.pop() 366 length = scope.Stack.pop() 367 ) 368 369 offset64, overflow := dataOffset.Uint64WithOverflow() 370 if overflow { 371 return nil, ErrReturnDataOutOfBounds 372 } 373 // we can reuse dataOffset now (aliasing it for clarity) 374 var end = dataOffset 375 end.Add(&dataOffset, &length) 376 end64, overflow := end.Uint64WithOverflow() 377 if overflow || uint64(len(interpreter.returnData)) < end64 { 378 return nil, ErrReturnDataOutOfBounds 379 } 380 scope.Memory.Set(memOffset.Uint64(), length.Uint64(), interpreter.returnData[offset64:end64]) 381 return nil, nil 382 } 383 384 func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 385 slot := scope.Stack.peek() 386 slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(slot.Bytes20()))) 387 return nil, nil 388 } 389 390 func opCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 391 l := new(uint256.Int) 392 l.SetUint64(uint64(len(scope.Contract.Code))) 393 scope.Stack.push(l) 394 return nil, nil 395 } 396 397 func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 398 var ( 399 memOffset = scope.Stack.pop() 400 codeOffset = scope.Stack.pop() 401 length = scope.Stack.pop() 402 ) 403 uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow() 404 if overflow { 405 uint64CodeOffset = 0xffffffffffffffff 406 } 407 codeCopy := getData(scope.Contract.Code, uint64CodeOffset, length.Uint64()) 408 scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) 409 410 return nil, nil 411 } 412 413 func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 414 var ( 415 stack = scope.Stack 416 a = stack.pop() 417 memOffset = stack.pop() 418 codeOffset = stack.pop() 419 length = stack.pop() 420 ) 421 uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow() 422 if overflow { 423 uint64CodeOffset = 0xffffffffffffffff 424 } 425 addr := common.Address(a.Bytes20()) 426 codeCopy := getData(interpreter.evm.StateDB.GetCode(addr), uint64CodeOffset, length.Uint64()) 427 scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) 428 429 return nil, nil 430 } 431 432 // opExtCodeHash returns the code hash of a specified account. 433 // There are several cases when the function is called, while we can relay everything 434 // to `state.GetCodeHash` function to ensure the correctness. 435 // (1) Caller tries to get the code hash of a normal contract account, state 436 // should return the relative code hash and set it as the result. 437 // 438 // (2) Caller tries to get the code hash of a non-existent account, state should 439 // return common.Hash{} and zero will be set as the result. 440 // 441 // (3) Caller tries to get the code hash for an account without contract code, 442 // state should return emptyCodeHash(0xc5d246...) as the result. 443 // 444 // (4) Caller tries to get the code hash of a precompiled account, the result 445 // should be zero or emptyCodeHash. 446 // 447 // It is worth noting that in order to avoid unnecessary create and clean, 448 // all precompile accounts on mainnet have been transferred 1 wei, so the return 449 // here should be emptyCodeHash. 450 // If the precompile account is not transferred any amount on a private or 451 // customized chain, the return value will be zero. 452 // 453 // (5) Caller tries to get the code hash for an account which is marked as suicided 454 // in the current transaction, the code hash of this account should be returned. 455 // 456 // (6) Caller tries to get the code hash for an account which is marked as deleted, 457 // this account should be regarded as a non-existent account and zero should be returned. 458 func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 459 slot := scope.Stack.peek() 460 address := common.Address(slot.Bytes20()) 461 if interpreter.evm.StateDB.Empty(address) { 462 slot.Clear() 463 } else { 464 slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(address).Bytes()) 465 } 466 return nil, nil 467 } 468 469 func opGasprice(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 470 v, _ := uint256.FromBig(interpreter.evm.GasPrice) 471 scope.Stack.push(v) 472 return nil, nil 473 } 474 475 func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 476 num := scope.Stack.peek() 477 num64, overflow := num.Uint64WithOverflow() 478 if overflow { 479 num.Clear() 480 return nil, nil 481 } 482 var upper, lower uint64 483 upper = interpreter.evm.Context.BlockNumber.Uint64() 484 if upper < 257 { 485 lower = 0 486 } else { 487 lower = upper - 256 488 } 489 if num64 >= lower && num64 < upper { 490 num.SetBytes(interpreter.evm.Context.GetHash(num64).Bytes()) 491 } else { 492 num.Clear() 493 } 494 return nil, nil 495 } 496 497 func opCoinbase(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 498 scope.Stack.push(new(uint256.Int).SetBytes(interpreter.evm.Context.Coinbase.Bytes())) 499 return nil, nil 500 } 501 502 func opTimestamp(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 503 v, _ := uint256.FromBig(interpreter.evm.Context.Time) 504 scope.Stack.push(v) 505 return nil, nil 506 } 507 508 func opNumber(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 509 v, _ := uint256.FromBig(interpreter.evm.Context.BlockNumber) 510 scope.Stack.push(v) 511 return nil, nil 512 } 513 514 func opDifficulty(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 515 v, _ := uint256.FromBig(interpreter.evm.Context.Difficulty) 516 scope.Stack.push(v) 517 return nil, nil 518 } 519 520 func opGasLimit(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 521 scope.Stack.push(new(uint256.Int).SetUint64(interpreter.evm.Context.GasLimit)) 522 return nil, nil 523 } 524 525 func opPop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 526 scope.Stack.pop() 527 return nil, nil 528 } 529 530 func opMload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 531 v := scope.Stack.peek() 532 offset := int64(v.Uint64()) 533 v.SetBytes(scope.Memory.GetPtr(offset, 32)) 534 return nil, nil 535 } 536 537 func opMstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 538 // pop value of the stack 539 mStart, val := scope.Stack.pop(), scope.Stack.pop() 540 scope.Memory.Set32(mStart.Uint64(), &val) 541 return nil, nil 542 } 543 544 func opMstore8(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 545 off, val := scope.Stack.pop(), scope.Stack.pop() 546 scope.Memory.store[off.Uint64()] = byte(val.Uint64()) 547 return nil, nil 548 } 549 550 func opSload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 551 loc := scope.Stack.peek() 552 hash := common.Hash(loc.Bytes32()) 553 val := interpreter.evm.StateDB.GetState(scope.Contract.Address(), hash) 554 loc.SetBytes(val.Bytes()) 555 return nil, nil 556 } 557 558 func opSstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 559 loc := scope.Stack.pop() 560 val := scope.Stack.pop() 561 interpreter.evm.StateDB.SetState(scope.Contract.Address(), 562 loc.Bytes32(), val.Bytes32()) 563 return nil, nil 564 } 565 566 func opJump(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 567 pos := scope.Stack.pop() 568 if !scope.Contract.validJumpdest(&pos) { 569 return nil, ErrInvalidJump 570 } 571 *pc = pos.Uint64() 572 return nil, nil 573 } 574 575 func opJumpi(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 576 pos, cond := scope.Stack.pop(), scope.Stack.pop() 577 if !cond.IsZero() { 578 if !scope.Contract.validJumpdest(&pos) { 579 return nil, ErrInvalidJump 580 } 581 *pc = pos.Uint64() 582 } else { 583 *pc++ 584 } 585 return nil, nil 586 } 587 588 func opJumpdest(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 589 return nil, nil 590 } 591 592 func opPc(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 593 scope.Stack.push(new(uint256.Int).SetUint64(*pc)) 594 return nil, nil 595 } 596 597 func opMsize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 598 scope.Stack.push(new(uint256.Int).SetUint64(uint64(scope.Memory.Len()))) 599 return nil, nil 600 } 601 602 func opGas(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 603 scope.Stack.push(new(uint256.Int).SetUint64(scope.Contract.Gas)) 604 return nil, nil 605 } 606 607 func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 608 var ( 609 value = scope.Stack.pop() 610 offset, size = scope.Stack.pop(), scope.Stack.pop() 611 input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) 612 gas = scope.Contract.Gas 613 ) 614 // //aidosgo: Create Contract requires a certain Gas price, not a free transaction! 615 // 616 // Note: 2021/11 Not needed any more as we use GAS recycle instead 617 // 618 // vGasPriceWei := interpreter.evm.GasPrice 619 // minimumGasPrice := new(big.Int).SetUint64(params.TxContractCreationMinGasPrice) 620 // // minimum gas price has to be 0.0000001 ADKGAS per GAS Unit, that is 1000000000000 wei , that is 1000 gWei, that is 1 ADK per 1000000 used gas 621 // if vGasPriceWei.Cmp(minimumGasPrice) < 0 && bytes.Compare(interpreter.evm.Origin.Bytes(),common.HexToAddress(params.TxContractCreationGenesisAccount).Bytes()) != 0{ 622 // return nil, ErrInsufficientGasPrice // force ErrInsufficientGasPrice if gasprice is insufficient 623 // } 624 625 if interpreter.evm.chainRules.IsEIP150 { 626 gas -= gas / 64 627 } 628 // reuse size int for stackvalue 629 stackvalue := size 630 631 scope.Contract.UseGas(gas) 632 //TODO: use uint256.Int instead of converting with toBig() 633 var bigVal = big0 634 if !value.IsZero() { 635 bigVal = value.ToBig() 636 } 637 638 res, addr, returnGas, suberr := interpreter.evm.Create(scope.Contract, input, gas, bigVal) 639 // Push item on the stack based on the returned error. If the ruleset is 640 // homestead we must check for CodeStoreOutOfGasError (homestead only 641 // rule) and treat as an error, if the ruleset is frontier we must 642 // ignore this error and pretend the operation was successful. 643 if interpreter.evm.chainRules.IsHomestead && suberr == ErrCodeStoreOutOfGas { 644 stackvalue.Clear() 645 } else if suberr != nil && suberr != ErrCodeStoreOutOfGas { 646 stackvalue.Clear() 647 } else { 648 stackvalue.SetBytes(addr.Bytes()) 649 } 650 scope.Stack.push(&stackvalue) 651 scope.Contract.Gas += returnGas 652 653 if suberr == ErrExecutionReverted { 654 return res, nil 655 } 656 return nil, nil 657 } 658 659 func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 660 var ( 661 endowment = scope.Stack.pop() 662 offset, size = scope.Stack.pop(), scope.Stack.pop() 663 salt = scope.Stack.pop() 664 input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) 665 gas = scope.Contract.Gas 666 ) 667 668 //aidosgo: Create Contract requires a certain Gas price, not a free transaction! 669 // 670 // Note: 2021/11 Not needed any more as we use GAS recycle instead 671 // 672 // vGasPriceWei := interpreter.evm.GasPrice 673 // minimumGasPrice := new(big.Int).SetUint64(params.TxContractCreationMinGasPrice) 674 // // minimum gas price has to be 0.0000001 ADKGAS per GAS Unit, that is 1000000000000 wei , that is 1000 gWei, that is 1 ADK per 1000000 used gas 675 // if vGasPriceWei.Cmp(minimumGasPrice) < 0 && bytes.Compare(interpreter.evm.Origin.Bytes(),common.HexToAddress(params.TxContractCreationGenesisAccount).Bytes()) != 0 { 676 // return nil, ErrInsufficientGasPrice // force invalidJumpError if gasprice is insufficient 677 // } 678 679 // Apply EIP150 680 gas -= gas / 64 681 scope.Contract.UseGas(gas) 682 // reuse size int for stackvalue 683 stackvalue := size 684 //TODO: use uint256.Int instead of converting with toBig() 685 bigEndowment := big0 686 if !endowment.IsZero() { 687 bigEndowment = endowment.ToBig() 688 } 689 res, addr, returnGas, suberr := interpreter.evm.Create2(scope.Contract, input, gas, 690 bigEndowment, &salt) 691 // Push item on the stack based on the returned error. 692 if suberr != nil { 693 stackvalue.Clear() 694 } else { 695 stackvalue.SetBytes(addr.Bytes()) 696 } 697 scope.Stack.push(&stackvalue) 698 scope.Contract.Gas += returnGas 699 700 if suberr == ErrExecutionReverted { 701 return res, nil 702 } 703 return nil, nil 704 } 705 706 func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 707 stack := scope.Stack 708 // Pop gas. The actual gas in interpreter.evm.callGasTemp. 709 // We can use this as a temporary value 710 temp := stack.pop() 711 gas := interpreter.evm.callGasTemp 712 // Pop other call parameters. 713 addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 714 toAddr := common.Address(addr.Bytes20()) 715 // Get the arguments from the memory. 716 args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) 717 718 var bigVal = big0 719 //TODO: use uint256.Int instead of converting with toBig() 720 // By using big0 here, we save an alloc for the most common case (non-ether-transferring contract calls), 721 // but it would make more sense to extend the usage of uint256.Int 722 if !value.IsZero() { 723 gas += params.CallStipend 724 bigVal = value.ToBig() 725 } 726 727 ret, returnGas, err := interpreter.evm.Call(scope.Contract, toAddr, args, gas, bigVal) 728 729 if err != nil { 730 temp.Clear() 731 } else { 732 temp.SetOne() 733 } 734 stack.push(&temp) 735 if err == nil || err == ErrExecutionReverted { 736 ret = common.CopyBytes(ret) 737 scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 738 } 739 scope.Contract.Gas += returnGas 740 741 return ret, nil 742 } 743 744 func opCallCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 745 // Pop gas. The actual gas is in interpreter.evm.callGasTemp. 746 stack := scope.Stack 747 // We use it as a temporary value 748 temp := stack.pop() 749 gas := interpreter.evm.callGasTemp 750 // Pop other call parameters. 751 addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 752 toAddr := common.Address(addr.Bytes20()) 753 // Get arguments from the memory. 754 args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) 755 756 //TODO: use uint256.Int instead of converting with toBig() 757 var bigVal = big0 758 if !value.IsZero() { 759 gas += params.CallStipend 760 bigVal = value.ToBig() 761 } 762 763 ret, returnGas, err := interpreter.evm.CallCode(scope.Contract, toAddr, args, gas, bigVal) 764 if err != nil { 765 temp.Clear() 766 } else { 767 temp.SetOne() 768 } 769 stack.push(&temp) 770 if err == nil || err == ErrExecutionReverted { 771 ret = common.CopyBytes(ret) 772 scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 773 } 774 scope.Contract.Gas += returnGas 775 776 return ret, nil 777 } 778 779 func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 780 stack := scope.Stack 781 // Pop gas. The actual gas is in interpreter.evm.callGasTemp. 782 // We use it as a temporary value 783 temp := stack.pop() 784 gas := interpreter.evm.callGasTemp 785 // Pop other call parameters. 786 addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 787 toAddr := common.Address(addr.Bytes20()) 788 // Get arguments from the memory. 789 args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) 790 791 ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract, toAddr, args, gas) 792 if err != nil { 793 temp.Clear() 794 } else { 795 temp.SetOne() 796 } 797 stack.push(&temp) 798 if err == nil || err == ErrExecutionReverted { 799 ret = common.CopyBytes(ret) 800 scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 801 } 802 scope.Contract.Gas += returnGas 803 804 return ret, nil 805 } 806 807 func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 808 // Pop gas. The actual gas is in interpreter.evm.callGasTemp. 809 stack := scope.Stack 810 // We use it as a temporary value 811 temp := stack.pop() 812 gas := interpreter.evm.callGasTemp 813 // Pop other call parameters. 814 addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 815 toAddr := common.Address(addr.Bytes20()) 816 // Get arguments from the memory. 817 args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) 818 819 ret, returnGas, err := interpreter.evm.StaticCall(scope.Contract, toAddr, args, gas) 820 if err != nil { 821 temp.Clear() 822 } else { 823 temp.SetOne() 824 } 825 stack.push(&temp) 826 if err == nil || err == ErrExecutionReverted { 827 ret = common.CopyBytes(ret) 828 scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 829 } 830 scope.Contract.Gas += returnGas 831 832 return ret, nil 833 } 834 835 func opReturn(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 836 offset, size := scope.Stack.pop(), scope.Stack.pop() 837 ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) 838 839 return ret, nil 840 } 841 842 func opRevert(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 843 offset, size := scope.Stack.pop(), scope.Stack.pop() 844 ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) 845 846 return ret, nil 847 } 848 849 func opStop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 850 return nil, nil 851 } 852 853 func opSuicide(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 854 beneficiary := scope.Stack.pop() 855 balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address()) 856 interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance) 857 interpreter.evm.StateDB.Suicide(scope.Contract.Address()) 858 return nil, nil 859 } 860 861 // following functions are used by the instruction jump table 862 863 // make log instruction function 864 func makeLog(size int) executionFunc { 865 return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 866 topics := make([]common.Hash, size) 867 stack := scope.Stack 868 mStart, mSize := stack.pop(), stack.pop() 869 for i := 0; i < size; i++ { 870 addr := stack.pop() 871 topics[i] = addr.Bytes32() 872 } 873 874 d := scope.Memory.GetCopy(int64(mStart.Uint64()), int64(mSize.Uint64())) 875 interpreter.evm.StateDB.AddLog(&types.Log{ 876 Address: scope.Contract.Address(), 877 Topics: topics, 878 Data: d, 879 // This is a non-consensus field, but assigned here because 880 // core/state doesn't know the current block number. 881 BlockNumber: interpreter.evm.Context.BlockNumber.Uint64(), 882 }) 883 884 return nil, nil 885 } 886 } 887 888 // opPush1 is a specialized version of pushN 889 func opPush1(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 890 var ( 891 codeLen = uint64(len(scope.Contract.Code)) 892 integer = new(uint256.Int) 893 ) 894 *pc += 1 895 if *pc < codeLen { 896 scope.Stack.push(integer.SetUint64(uint64(scope.Contract.Code[*pc]))) 897 } else { 898 scope.Stack.push(integer.Clear()) 899 } 900 return nil, nil 901 } 902 903 // make push instruction function 904 func makePush(size uint64, pushByteSize int) executionFunc { 905 return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 906 codeLen := len(scope.Contract.Code) 907 908 startMin := codeLen 909 if int(*pc+1) < startMin { 910 startMin = int(*pc + 1) 911 } 912 913 endMin := codeLen 914 if startMin+pushByteSize < endMin { 915 endMin = startMin + pushByteSize 916 } 917 918 integer := new(uint256.Int) 919 scope.Stack.push(integer.SetBytes(common.RightPadBytes( 920 scope.Contract.Code[startMin:endMin], pushByteSize))) 921 922 *pc += size 923 return nil, nil 924 } 925 } 926 927 // make dup instruction function 928 func makeDup(size int64) executionFunc { 929 return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 930 scope.Stack.dup(int(size)) 931 return nil, nil 932 } 933 } 934 935 // make swap instruction function 936 func makeSwap(size int64) executionFunc { 937 // switch n + 1 otherwise n would be swapped with n 938 size++ 939 return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 940 scope.Stack.swap(int(size)) 941 return nil, nil 942 } 943 }