github.com/ebakus/go-ebakus@v1.0.5-0.20200520105415-dbccef9ec421/core/vm/contracts.go (about) 1 // Copyright 2019 The ebakus/go-ebakus Authors 2 // This file is part of the ebakus/go-ebakus library. 3 // 4 // The ebakus/go-ebakus 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 ebakus/go-ebakus 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 ebakus/go-ebakus library. If not, see <http://www.gnu.org/licenses/>. 16 17 package vm 18 19 import ( 20 "bytes" 21 "crypto/sha256" 22 "encoding/binary" 23 "errors" 24 "math/big" 25 "strings" 26 "sync" 27 "unsafe" 28 29 "github.com/ebakus/ebakusdb" 30 "github.com/ebakus/go-ebakus/accounts/abi" 31 "github.com/ebakus/go-ebakus/common" 32 "github.com/ebakus/go-ebakus/common/math" 33 "github.com/ebakus/go-ebakus/core/ebkdb" 34 "github.com/ebakus/go-ebakus/core/types" 35 "github.com/ebakus/go-ebakus/crypto" 36 "github.com/ebakus/go-ebakus/crypto/blake2b" 37 "github.com/ebakus/go-ebakus/crypto/bn256" 38 "github.com/ebakus/go-ebakus/log" 39 "github.com/ebakus/go-ebakus/params" 40 "golang.org/x/crypto/ripemd160" 41 ) 42 43 // PrecompiledContract is the basic interface for native Go contracts. The implementation 44 // requires a deterministic gas count based on the input size of the Run method of the 45 // contract. 46 type PrecompiledContract interface { 47 RequiredGas(input []byte) uint64 // RequiredPrice calculates the contract gas use 48 Run(evm *EVM, contract *Contract, input []byte) ([]byte, error) // Run runs the precompiled contract 49 } 50 51 // PrecompiledContractsEbakus contains the default set of pre-compiled Ebakus 52 // contracts used in the Ebakus blockchain. 53 var PrecompiledContractsEbakus = map[common.Address]PrecompiledContract{ 54 common.BytesToAddress([]byte{1}): &ecrecover{}, 55 common.BytesToAddress([]byte{2}): &sha256hash{}, 56 common.BytesToAddress([]byte{3}): &ripemd160hash{}, 57 common.BytesToAddress([]byte{4}): &dataCopy{}, 58 common.BytesToAddress([]byte{5}): &bigModExp{}, 59 common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, 60 common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, 61 common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, 62 common.BytesToAddress([]byte{9}): &blake2F{}, 63 types.PrecompliledSystemContract: &systemContract{}, 64 types.PrecompliledDBContract: &dbContract{}, 65 } 66 67 var systemContractMux sync.Mutex 68 69 // RunPrecompiledContract runs and evaluates the output of a precompiled contract. 70 func RunPrecompiledContract(evm *EVM, p PrecompiledContract, input []byte, contract *Contract) (ret []byte, err error) { 71 systemContractMux.Lock() 72 defer systemContractMux.Unlock() 73 74 db := evm.EbakusState 75 preUsedMemory := db.GetObjAllocated() 76 77 minimumGas := p.RequiredGas(input) 78 if contract.Gas < minimumGas { 79 return nil, ErrOutOfGas 80 } 81 ret, err = p.Run(evm, contract, input) 82 83 postUsedMemory := db.GetObjAllocated() 84 usedMemoryGas := minimumGas 85 usedMemory := int64(postUsedMemory - preUsedMemory) 86 87 if usedMemory < 0 { 88 usedMemory = 0 89 } 90 91 usedMemoryGas += (uint64(usedMemory) * params.EbakusDBMemoryUsageGas) 92 93 if !contract.UseGas(usedMemoryGas) { 94 return nil, ErrOutOfGas 95 } 96 97 return 98 } 99 100 const ( 101 SystemContractStakeCmd = "stake" 102 SystemContractGetStakedCmd = "getStaked" 103 SystemContractUnstakeCmd = "unstake" 104 SystemContractClaimCmd = "claim" 105 106 SystemContractVoteCmd = "vote" 107 SystemContractUnvoteCmd = "unvote" 108 SystemContractElectEnableCmd = "electEnable" 109 110 SystemContractStoreAbiCmd = "storeAbiForAddress" 111 SystemContractGetAbiCmd = "getAbiForAddress" 112 113 DBContractCreateTableCmd = "createTable" 114 DBContractInsertObjCmd = "insertObj" 115 DBContractDeleteObjCmd = "deleteObj" 116 DBContractGetCmd = "get" 117 DBContractSelectCmd = "select" 118 DBContractNextCmd = "next" 119 ) 120 121 const ( 122 maxClaimableEntries = 5 123 unstakeVestingPeriod = 60 * 60 * 24 * 3 // (3 days) Number of seconds taken for tokens to become claimable 124 ) 125 126 var ( 127 valueDecimalPoints = int64(4) 128 precisionFactor = new(big.Int).Exp(big.NewInt(10), big.NewInt(18-valueDecimalPoints), nil) 129 ) 130 131 var ( 132 errSystemContractError = errors.New("system contract error") 133 errSystemContractAbiError = errors.New("system contract ABI error") 134 errSystemContractQueryError = errors.New("system contract query parsing error") 135 136 errStakeMalformed = errors.New("staking transaction malformed") 137 errStakeNotEnoughBalance = errors.New("not enough balance for staking") 138 139 errUnstakeMalformed = errors.New("unstaking transaction malformed") 140 errUnstakeTooManyClaimable = errors.New("unstaking failure because of too many claimable entries") 141 errUnstakeNotEnoughStakedAmount = errors.New("not enough staked tokens for amount requested to unstake") 142 143 errVoteMalformed = errors.New("voting transaction malformed") 144 errVoteAddressIsNotWitness = errors.New("a voted address is not valid") 145 errVoteNothingStaked = errors.New("nothing staked") 146 errVoteMaxWitnessesReached = errors.New("not allowed to vote more than 20 witnesses") 147 errElectEnableMalformed = errors.New("elect enable transaction malformed") 148 errContractAbiMalformed = errors.New("contract abi transaction malformed") 149 errContractAbiNotFound = errors.New("contract abi not found") 150 errContractAbiExists = errors.New("contract abi exists") 151 152 errDBContractError = errors.New("db contract error") 153 errNoEntryFound = errors.New("no entry found in db") 154 errEmptyTableNameError = errors.New("table name is empty or invalid") 155 errTableAbiMalformed = errors.New("abi is empty or invalid") 156 errCreateTableMalformed = errors.New("create table transaction malformed") 157 errCreateTableExists = errors.New("create table failed as table exists") 158 errInsertObjMalformed = errors.New("insert object transaction malformed") 159 errDeleteObjMalformed = errors.New("delete object transaction malformed") 160 errSelectMalformed = errors.New("db select transaction malformed") 161 errIteratorMalformed = errors.New("next iterator transaction malformed") 162 ) 163 164 const ( 165 // The account wants to be witness and will be considered for block producer 166 // by stake delegation 167 ElectEnabledFlag uint64 = 1 168 ) 169 170 type systemContract struct{} 171 172 func (c *systemContract) RequiredGas(input []byte) uint64 { 173 if len(input) == 0 { 174 return params.SystemContractBaseGas 175 } 176 177 evmABI, err := abi.JSON(strings.NewReader(SystemContractABI)) 178 if err != nil { 179 return params.SystemContractBaseGas 180 } 181 182 cmdData, inputData := input[:4], input[4:] 183 method, err := evmABI.MethodById(cmdData) 184 if err != nil { 185 return params.SystemContractBaseGas 186 } 187 188 cmd := method.Name 189 190 switch cmd { 191 case SystemContractStakeCmd: 192 return params.SystemContractStakeGas 193 case SystemContractGetStakedCmd: 194 return params.SystemContractGetStakedGas 195 case SystemContractUnstakeCmd: 196 return params.SystemContractUnstakeGas 197 case SystemContractClaimCmd: 198 return params.SystemContractClaimGas 199 case SystemContractVoteCmd: 200 var addresses []common.Address 201 if err = evmABI.UnpackWithArguments(&addresses, cmd, inputData, abi.InputsArgumentsType); err != nil { 202 return params.SystemContractBaseGas 203 } 204 return params.SystemContractVoteGas * uint64(len(addresses)) 205 case SystemContractUnvoteCmd: 206 return params.SystemContractUnvoteGas 207 case SystemContractElectEnableCmd: 208 return params.SystemContractElectEnableGas 209 case SystemContractStoreAbiCmd: 210 return params.SystemContractStoreAbiGas 211 case SystemContractGetAbiCmd: 212 return params.SystemContractGetAbiGas 213 default: 214 return params.SystemContractBaseGas 215 } 216 } 217 218 type Witness struct { 219 Id common.Address 220 Stake uint64 221 Flags uint64 222 } 223 224 type WitnessArray []Witness 225 226 func (s WitnessArray) Diff(b WitnessArray) types.DelegateDiff { 227 r := make(types.DelegateDiff, 0) 228 229 for i, d := range b { 230 found := false 231 for j, from := range s { 232 if from.Id == d.Id { 233 if i != j { 234 r = append(r, types.DelegateItem{Pos: byte(i), DelegateAddress: common.Address{}, DelegateNumber: byte(j)}) 235 } 236 found = true 237 break 238 } 239 } 240 if !found { 241 r = append(r, types.DelegateItem{Pos: byte(i), DelegateAddress: d.Id, DelegateNumber: 0}) 242 } 243 } 244 245 return r 246 } 247 248 var WitnessesTable = ebkdb.GetDBTableName(types.PrecompliledSystemContract, "Witnesses") 249 250 type ClaimableId [common.AddressLength + unsafe.Sizeof(uint64(0))]byte // address + timestamp 251 252 type Claimable struct { 253 Id ClaimableId 254 Amount uint64 255 Timestamp uint64 256 } 257 258 var ClaimableTable = ebkdb.GetDBTableName(types.PrecompliledSystemContract, "Claimable") 259 260 func GetClaimableId(from common.Address, timestamp uint64) ClaimableId { 261 timestampBytes := make([]byte, 8) 262 binary.LittleEndian.PutUint64(timestampBytes, timestamp) 263 264 var id ClaimableId 265 b := bytes.Join([][]byte{from.Bytes(), timestampBytes}, []byte("")) 266 copy(id[:], b) 267 return id 268 } 269 270 // DelegationId represents the 40 byte of two 20 bytes addresses combined. 271 type DelegationId [common.AddressLength * 2]byte 272 273 type Delegation struct { 274 Id DelegationId // <from><witness> 275 } 276 277 var DelegationTable = ebkdb.GetDBTableName(types.PrecompliledSystemContract, "Delegations") 278 279 // AddressesToDelegationId returns bytes of both from address and target address. 280 func AddressesToDelegationId(from common.Address, witness common.Address) DelegationId { 281 var id DelegationId 282 283 copy(id[:], from[:]) 284 copy(id[common.AddressLength:], witness[:]) 285 286 return id 287 } 288 289 // Content gets from and witness addresses. 290 func (id DelegationId) Content() (from common.Address, witness common.Address) { 291 from = common.BytesToAddress(id[:common.AddressLength]) 292 witness = common.BytesToAddress(id[common.AddressLength:]) 293 return 294 } 295 296 type ContractAbiId []byte 297 298 type ContractAbi struct { 299 Id ContractAbiId 300 Abi string 301 } 302 303 // GetContractAbiId returns bytes of both from address type and name. 304 func GetContractAbiId(address common.Address, abiType string, name string) ContractAbiId { 305 var id ContractAbiId 306 307 if abiType == "" { 308 abiType = "abi" 309 } 310 311 b := bytes.Join([][]byte{address.Bytes(), []byte(abiType), []byte(name)}, []byte("")) 312 id = b[:] 313 314 return id 315 } 316 317 var ContractAbiTable = ebkdb.GetDBTableName(types.PrecompliledSystemContract, "ContractAbi") 318 319 func SystemContractSetupDB(db *ebakusdb.Snapshot, address common.Address) error { 320 321 if db.HasTable(WitnessesTable) { 322 panic("Witnesses table existed in genesis") 323 } 324 325 if db.HasTable(types.StakedTable) { 326 panic("Staked table existed in genesis") 327 } 328 329 if db.HasTable(ClaimableTable) { 330 panic("Claimable table existed in genesis") 331 } 332 333 if db.HasTable(DelegationTable) { 334 panic("Delegation table existed in genesis") 335 } 336 337 if db.HasTable(ContractAbiTable) { 338 panic("ContractAbi table existed in genesis") 339 } 340 341 db.CreateTable(WitnessesTable, &Witness{}) 342 db.CreateIndex(ebakusdb.IndexField{ 343 Table: WitnessesTable, 344 Field: "Stake", 345 }) 346 347 if err := db.InsertObj(WitnessesTable, &Witness{Id: address, Stake: 0, Flags: ElectEnabledFlag}); err != nil { 348 return err 349 } 350 351 db.CreateTable(types.StakedTable, &types.Staked{}) 352 db.CreateTable(ClaimableTable, &Claimable{}) 353 db.CreateTable(DelegationTable, &Delegation{}) 354 355 db.CreateTable(ContractAbiTable, &ContractAbi{}) 356 357 // it's not trully needed to store the ABIs, though we do this just for occuping the address of the system contracts 358 if _, err := storeAbiAtAddress(db, types.PrecompliledSystemContract, SystemContractABI); err != nil { 359 return err 360 } 361 362 if _, err := storeAbiAtAddress(db, types.PrecompliledDBContract, DBABI); err != nil { 363 return err 364 } 365 366 return nil 367 } 368 369 func DelegateVotingGetDelegates(snap *ebakusdb.Snapshot, maxWitnesses uint64) WitnessArray { 370 res := make(WitnessArray, 0) 371 372 orderClause, err := snap.OrderParser([]byte("Stake DESC")) 373 if err != nil { 374 log.Error("DelegateVotingGetDelegates load witnesses", "err", err) 375 return res 376 } 377 378 iter, err := snap.Select(WitnessesTable, nil, orderClause) 379 if err != nil { 380 log.Error("DelegateVotingGetDelegates load witnesses", "err", err) 381 return res 382 } 383 384 var w Witness 385 i := uint64(0) 386 for iter.Next(&w) && i < maxWitnesses { 387 if (w.Flags & ElectEnabledFlag) == 0 { 388 continue 389 } 390 res = append(res, w) 391 w = Witness{} 392 i++ 393 } 394 395 return res 396 } 397 398 func makeIDLikeWhereClause(db *ebakusdb.Snapshot, from common.Address) (*ebakusdb.WhereField, error) { 399 where := []byte("Id LIKE ") 400 whereClause, err := db.WhereParser(append(where, from.Bytes()...)) 401 if err != nil { 402 return nil, errSystemContractQueryError 403 } 404 return whereClause, nil 405 } 406 407 func vote(db *ebakusdb.Snapshot, from common.Address, addresses []common.Address, amount uint64) error { 408 for _, address := range addresses { 409 var witness Witness 410 411 whereClause, err := makeIDLikeWhereClause(db, address) 412 if err != nil { 413 return err 414 } 415 416 iter, err := db.Select(WitnessesTable, whereClause) 417 if err != nil { 418 return errSystemContractError 419 } 420 421 if iter.Next(&witness) == false { 422 return errVoteAddressIsNotWitness 423 } 424 425 witness.Stake = witness.Stake + amount 426 427 if err := db.InsertObj(WitnessesTable, &witness); err != nil { 428 return errSystemContractError 429 } 430 431 delegation := Delegation{ 432 Id: AddressesToDelegationId(from, address), 433 } 434 435 if err := db.InsertObj(DelegationTable, &delegation); err != nil { 436 return errSystemContractError 437 } 438 } 439 440 return nil 441 } 442 443 func unvote(db *ebakusdb.Snapshot, from common.Address, amount uint64) ([]common.Address, error) { 444 445 whereClause, err := makeIDLikeWhereClause(db, from) 446 if err != nil { 447 return nil, err 448 } 449 450 delIter, err := db.Select(DelegationTable, whereClause) 451 if err != nil { 452 return nil, errSystemContractError 453 } 454 455 var delegation Delegation 456 delegationsAddresses := make([]common.Address, 0) 457 delegationsToBeDeleted := make([]Delegation, 0) 458 459 for delIter.Next(&delegation) { 460 _, witnessAddress := delegation.Id.Content() 461 462 delegationsToBeDeleted = append(delegationsToBeDeleted, delegation) 463 delegationsAddresses = append(delegationsAddresses, witnessAddress) 464 465 var witness Witness 466 467 whereClause, err := makeIDLikeWhereClause(db, witnessAddress) 468 if err != nil { 469 return nil, err 470 } 471 472 iter, err := db.Select(WitnessesTable, whereClause) 473 if err != nil { 474 return nil, errSystemContractError 475 } 476 477 if iter.Next(&witness) == false { 478 return nil, errSystemContractError 479 } 480 481 if witness.Stake < amount { 482 return nil, errSystemContractError 483 } 484 485 witness.Stake = witness.Stake - amount 486 487 if witness.Stake < 0 { 488 return nil, errSystemContractError 489 } 490 491 if err := db.InsertObj(WitnessesTable, &witness); err != nil { 492 return nil, errSystemContractError 493 } 494 } 495 496 for _, delegation := range delegationsToBeDeleted { 497 if err := db.DeleteObj(DelegationTable, delegation.Id); err != nil { 498 return nil, errSystemContractError 499 } 500 } 501 502 return delegationsAddresses, nil 503 } 504 505 const SystemContractABI = `[ 506 { 507 "type": "function", 508 "name": "stake", 509 "inputs": [ 510 { 511 "name": "amount", 512 "type": "uint64" 513 } 514 ], 515 "outputs": [], 516 "stateMutability": "nonpayable" 517 },{ 518 "type": "function", 519 "name": "getStaked", 520 "inputs": [], 521 "outputs": [ 522 { 523 "name": "staked", 524 "type": "uint64" 525 } 526 ], 527 "constant": true, 528 "payable": false, 529 "stateMutability": "view" 530 },{ 531 "type": "function", 532 "name": "unstake", 533 "inputs": [ 534 { 535 "name": "amount", 536 "type": "uint64" 537 } 538 ], 539 "outputs": [], 540 "stateMutability": "nonpayable" 541 },{ 542 "type": "function", 543 "name": "claim", 544 "inputs": [], 545 "outputs": [], 546 "stateMutability": "nonpayable" 547 },{ 548 "type": "function", 549 "name": "vote", 550 "inputs": [ 551 { 552 "name": "addresses", 553 "type": "address[]" 554 } 555 ], 556 "outputs": [], 557 "stateMutability": "nonpayable" 558 },{ 559 "type": "function", 560 "name": "unvote", 561 "inputs": [], 562 "outputs": [], 563 "stateMutability": "nonpayable" 564 },{ 565 "type": "function", 566 "name": "electEnable", 567 "inputs": [ 568 { 569 "name": "enable", 570 "type": "bool" 571 } 572 ], 573 "outputs": [], 574 "stateMutability": "nonpayable" 575 },{ 576 "type": "function", 577 "name": "storeAbiForAddress", 578 "inputs": [ 579 { 580 "name": "address", 581 "type": "address" 582 }, 583 { 584 "name": "abi", 585 "type": "string" 586 } 587 ], 588 "outputs": [], 589 "stateMutability": "nonpayable" 590 },{ 591 "type": "function", 592 "name": "getAbiForAddress", 593 "inputs": [ 594 { 595 "name": "address", 596 "type": "address" 597 } 598 ], 599 "outputs": [ 600 { 601 "name": "abi", 602 "type": "string" 603 } 604 ], 605 "constant": true, 606 "payable": false, 607 "stateMutability": "view" 608 }]` 609 610 const SystemContractTablesABI = `[ 611 { 612 "type": "table", 613 "name": "Witnesses", 614 "inputs": [ 615 { 616 "name": "Id", 617 "type": "address" 618 }, 619 { 620 "name": "Stake", 621 "type": "uint64" 622 }, 623 { 624 "name": "Flags", 625 "type": "uint64" 626 } 627 ] 628 },{ 629 "type": "table", 630 "name": "Claimable", 631 "inputs": [ 632 { 633 "name": "Id", 634 "type": "bytes28" 635 }, 636 { 637 "name": "Amount", 638 "type": "uint64" 639 }, 640 { 641 "name": "Timestamp", 642 "type": "uint64" 643 } 644 ] 645 },{ 646 "type": "table", 647 "name": "Delegations", 648 "inputs": [ 649 { 650 "name": "Id", 651 "type": "bytes40" 652 } 653 ] 654 },{ 655 "type": "table", 656 "name": "ContractAbi", 657 "inputs": [ 658 { 659 "name": "Id", 660 "type": "bytes" 661 }, 662 { 663 "name": "Abi", 664 "type": "string" 665 } 666 ] 667 }]` 668 669 func (c *systemContract) stakeCmd(evm *EVM, from common.Address, amount uint64) ([]byte, error) { 670 if amount <= 0 { 671 log.Trace("Can't stake negative or zero amounts") 672 return nil, errSystemContractError 673 } 674 675 db := evm.EbakusState 676 677 hasEnoughBalance := false 678 amountToBeTransfered := amount 679 680 // Check if user has claimable entries that can be used for staking 681 whereClauseClaimable, err := makeIDLikeWhereClause(db, from) 682 if err != nil { 683 return nil, err 684 } 685 686 orderClauseClaimable, err := db.OrderParser([]byte("Id DESC")) 687 if err != nil { 688 return nil, errSystemContractError 689 } 690 691 iterClaimable, err := db.Select(ClaimableTable, whereClauseClaimable, orderClauseClaimable) 692 if err != nil { 693 return nil, errSystemContractError 694 } 695 696 claimableAmount := uint64(0) 697 claimablesToBeDeleted := make([]Claimable, 0) 698 var claimable Claimable 699 700 for iterClaimable.Next(&claimable) { 701 if amount-claimableAmount >= claimable.Amount { 702 claimableAmount = claimableAmount + claimable.Amount 703 704 claimablesToBeDeleted = append(claimablesToBeDeleted, claimable) 705 } else { 706 claimable.Amount = claimable.Amount - (amount - claimableAmount) 707 claimableAmount = claimableAmount + (amount - claimableAmount) 708 709 if err := db.InsertObj(ClaimableTable, &claimable); err != nil { 710 log.Trace("Claimable entry failed to be updated with new claimable amount", "err", err) 711 return nil, errSystemContractError 712 } 713 } 714 715 claimable = Claimable{} 716 717 if claimableAmount == amount { 718 hasEnoughBalance = true 719 break 720 } 721 } 722 723 amountToBeTransfered = amount - claimableAmount 724 725 // Check account has balance (amount <= balance) 726 balanceWei := evm.StateDB.GetBalance(from) 727 balance := new(big.Int).Div(balanceWei, precisionFactor).Uint64() 728 729 hasEnoughBalance = amountToBeTransfered <= balance 730 731 if !hasEnoughBalance { 732 log.Trace("Account doesn't have sufficient balance") 733 return nil, errStakeNotEnoughBalance 734 } 735 736 for _, claimableEntry := range claimablesToBeDeleted { 737 if err := db.DeleteObj(ClaimableTable, claimableEntry.Id); err != nil { 738 log.Trace("Claimable tokens failed to delete (staked)", "err", err) 739 return nil, errSystemContractError 740 } 741 } 742 743 // Update whole system staked amount 744 systemStaked := amount 745 746 if systemStakedBytesOut, found := db.Get([]byte(types.SystemStakeDBKey)); found { 747 systemStaked += binary.BigEndian.Uint64(*systemStakedBytesOut) 748 } 749 750 systemStakedBytesIn := make([]byte, 8) 751 binary.BigEndian.PutUint64(systemStakedBytesIn[:], systemStaked) 752 db.Insert([]byte(types.SystemStakeDBKey), systemStakedBytesIn) 753 754 staked, err := GetStaked(db, from) 755 if err != nil { 756 return nil, err 757 } 758 759 if staked != nil { 760 delegatedAddresses, err := unvote(db, from, staked.Amount) 761 if err != nil { 762 return nil, errSystemContractError 763 } 764 765 staked.Amount = staked.Amount + amount 766 767 if err := vote(db, from, delegatedAddresses, staked.Amount); err != nil { 768 return nil, errSystemContractError 769 } 770 } else { 771 delegatedAddresses, err := unvote(db, from, uint64(0)) 772 if err != nil { 773 return nil, errSystemContractError 774 } 775 776 staked = &types.Staked{ 777 Id: from, 778 Amount: amount, 779 } 780 781 if err := vote(db, from, delegatedAddresses, staked.Amount); err != nil { 782 return nil, errSystemContractError 783 } 784 } 785 786 if err := db.InsertObj(types.StakedTable, staked); err != nil { 787 return nil, errSystemContractError 788 } 789 790 amountToBeTransferedWei := new(big.Int).Mul(new(big.Int).SetUint64(amountToBeTransfered), precisionFactor) 791 // Fail if we're trying to transfer more than the available balance 792 if !evm.CanTransfer(evm.StateDB, from, amountToBeTransferedWei) { 793 log.Trace("Failed to stake amount because of insufficient balance", "err", err) 794 return nil, ErrInsufficientBalance 795 } 796 evm.Transfer(evm.StateDB, from, types.PrecompliledSystemContract, amountToBeTransferedWei) 797 798 return nil, nil 799 } 800 801 func (c *systemContract) getStakedCmd(evm *EVM, from common.Address) ([]byte, error) { 802 db := evm.EbakusState 803 804 staked, err := GetStaked(db, from) 805 if err != nil { 806 return nil, err 807 } 808 809 amount := uint64(0) 810 811 if staked != nil { 812 amount = staked.Amount 813 } 814 815 stakeAmount := make([]byte, 32) 816 binary.BigEndian.PutUint64(stakeAmount[24:], amount) 817 return stakeAmount, nil 818 } 819 820 func (c *systemContract) unstakeCmd(evm *EVM, from common.Address, amount uint64) ([]byte, error) { 821 db := evm.EbakusState 822 823 timestamp := evm.Time.Uint64() + unstakeVestingPeriod 824 newClaimableEntryId := GetClaimableId(from, timestamp) 825 826 // get all claimable tokens 827 whereClause, err := makeIDLikeWhereClause(db, from) 828 if err != nil { 829 return nil, err 830 } 831 832 iter, err := db.Select(ClaimableTable, whereClause) 833 if err != nil { 834 return nil, errSystemContractError 835 } 836 837 // Disallow more than maxClaimableEntries, to protect system abuse 838 var claimable Claimable 839 countClaimableEntries := 0 840 for iter.Next(&claimable) { 841 countClaimableEntries++ 842 843 if newClaimableEntryId == claimable.Id { 844 log.Trace("Unstake request failed because of existing entry for same block, please try again.") 845 return nil, errSystemContractError 846 } 847 848 if countClaimableEntries >= maxClaimableEntries { 849 log.Trace("Unstake failed as maxClaimableEntries reached", "maxClaimableEntries", maxClaimableEntries) 850 return nil, errUnstakeTooManyClaimable 851 } 852 } 853 854 var staked types.Staked 855 iter, err = db.Select(types.StakedTable, whereClause) 856 if err != nil { 857 return nil, errSystemContractError 858 } 859 860 if iter.Next(&staked) == false { 861 return nil, errSystemContractError 862 } 863 864 oldStake := staked.Amount 865 newStake := uint64(0) 866 867 if amount > staked.Amount { 868 return nil, errUnstakeNotEnoughStakedAmount 869 870 } else if amount == staked.Amount { 871 if err := db.DeleteObj(types.StakedTable, staked.Id); err != nil { 872 return nil, errSystemContractError 873 } 874 } else { 875 staked.Amount = staked.Amount - amount 876 newStake = staked.Amount 877 878 if err := db.InsertObj(types.StakedTable, &staked); err != nil { 879 return nil, errSystemContractError 880 } 881 } 882 883 newClaimableEntry := Claimable{ 884 Id: newClaimableEntryId, 885 Amount: amount, 886 Timestamp: timestamp, 887 } 888 889 if err := db.InsertObj(ClaimableTable, &newClaimableEntry); err != nil { 890 return nil, errSystemContractError 891 } 892 893 delegatedAddresses, err := unvote(db, from, oldStake) 894 if err != nil { 895 return nil, errSystemContractError 896 } 897 898 if err := vote(db, from, delegatedAddresses, newStake); err != nil { 899 return nil, errSystemContractError 900 } 901 902 // Update whole system staked amount 903 systemStakedBytesOut, found := db.Get([]byte(types.SystemStakeDBKey)) 904 if !found { 905 return nil, errSystemContractError 906 } 907 908 systemStakedOut := binary.BigEndian.Uint64(*systemStakedBytesOut) 909 if systemStakedOut < amount { 910 return nil, errSystemContractError 911 } 912 913 systemStaked := systemStakedOut - amount 914 systemStakedBytesIn := make([]byte, 8) 915 binary.BigEndian.PutUint64(systemStakedBytesIn[:], systemStaked) 916 db.Insert([]byte(types.SystemStakeDBKey), systemStakedBytesIn) 917 918 return nil, nil 919 } 920 921 func (c *systemContract) claimCmd(evm *EVM, from common.Address) ([]byte, error) { 922 db := evm.EbakusState 923 924 // check if user has claimable tokens 925 whereClause, err := makeIDLikeWhereClause(db, from) 926 if err != nil { 927 return nil, err 928 } 929 930 iter, err := db.Select(ClaimableTable, whereClause) 931 if err != nil { 932 return nil, errSystemContractError 933 } 934 935 claimableAmount := uint64(0) 936 var claimable Claimable 937 claimablesToBeDeleted := make([]Claimable, 0) 938 939 for iter.Next(&claimable) { 940 if claimable.Timestamp <= evm.Time.Uint64() { 941 claimableAmount = claimableAmount + claimable.Amount 942 943 claimablesToBeDeleted = append(claimablesToBeDeleted, claimable) 944 } 945 claimable = Claimable{} 946 } 947 948 for _, claimableEntry := range claimablesToBeDeleted { 949 if err := db.DeleteObj(ClaimableTable, claimableEntry.Id); err != nil { 950 return nil, errSystemContractError 951 } 952 } 953 954 if claimableAmount <= 0 { 955 log.Trace("No amount to be claimed") 956 return nil, nil 957 } 958 959 claimableAmountWei := new(big.Int).Mul(new(big.Int).SetUint64(claimableAmount), precisionFactor) 960 // Fail if we're trying to transfer more than the available balance 961 if !evm.CanTransfer(evm.StateDB, types.PrecompliledSystemContract, claimableAmountWei) { 962 log.Trace("Failed to claim amount because of insufficient balance", "err", err) 963 return nil, ErrInsufficientBalance 964 } 965 evm.Transfer(evm.StateDB, types.PrecompliledSystemContract, from, claimableAmountWei) 966 967 return nil, nil 968 } 969 970 func GetStaked(db *ebakusdb.Snapshot, from common.Address) (*types.Staked, error) { 971 var staked types.Staked 972 973 whereClause, err := makeIDLikeWhereClause(db, from) 974 if err != nil { 975 return nil, err 976 } 977 978 iter, err := db.Select(types.StakedTable, whereClause) 979 if err != nil { 980 return nil, errSystemContractError 981 } 982 983 if iter.Next(&staked) == false { 984 return nil, nil 985 } 986 987 return &staked, nil 988 } 989 990 func unique(addresses []common.Address) []common.Address { 991 used := make(map[common.Address]bool) 992 res := []common.Address{} 993 for _, entry := range addresses { 994 if _, value := used[entry]; !value { 995 used[entry] = true 996 res = append(res, entry) 997 } 998 } 999 return res 1000 } 1001 1002 func (c *systemContract) voteCmd(evm *EVM, from common.Address, addresses []common.Address) ([]byte, error) { 1003 db := evm.EbakusState 1004 1005 addresses = unique(addresses) 1006 1007 if len(addresses) > int(evm.chainConfig.DPOS.MaxWitnessesVotes) { 1008 return nil, errVoteMaxWitnessesReached 1009 } 1010 1011 staked, err := GetStaked(db, from) 1012 if err != nil { 1013 return nil, err 1014 } 1015 1016 if staked == nil { 1017 return nil, errVoteNothingStaked 1018 } 1019 1020 if _, err := unvote(db, from, staked.Amount); err != nil { 1021 return nil, err 1022 } 1023 1024 if err := vote(db, from, addresses, staked.Amount); err != nil { 1025 return nil, err 1026 } 1027 1028 return nil, nil 1029 } 1030 1031 func (c *systemContract) unvoteCmd(evm *EVM, from common.Address) ([]byte, error) { 1032 db := evm.EbakusState 1033 1034 staked, err := GetStaked(db, from) 1035 if err != nil { 1036 return nil, err 1037 } 1038 1039 if staked == nil { 1040 return nil, errVoteNothingStaked 1041 } 1042 1043 if _, err := unvote(db, from, staked.Amount); err != nil { 1044 return nil, errSystemContractError 1045 } 1046 1047 return nil, nil 1048 } 1049 1050 func (c *systemContract) electEnableCmd(evm *EVM, from common.Address, enable bool) ([]byte, error) { 1051 db := evm.EbakusState 1052 1053 var witness Witness 1054 1055 whereClause, err := makeIDLikeWhereClause(db, from) 1056 if err != nil { 1057 return nil, err 1058 } 1059 1060 iter, err := db.Select(WitnessesTable, whereClause) 1061 if err != nil { 1062 return nil, errSystemContractError 1063 } 1064 1065 if iter.Next(&witness) == false { 1066 witness = Witness{ 1067 Id: from, 1068 Stake: 0, 1069 Flags: 0, 1070 } 1071 } 1072 1073 if enable { 1074 witness.Flags |= ElectEnabledFlag 1075 } else { 1076 witness.Flags &= ^ElectEnabledFlag 1077 } 1078 1079 if err := db.InsertObj(WitnessesTable, &witness); err != nil { 1080 return nil, errSystemContractError 1081 } 1082 1083 return nil, nil 1084 } 1085 1086 func (c *systemContract) storeAbiAtAddress(evm *EVM, contractAddress common.Address, abi string) ([]byte, error) { 1087 return storeAbiAtAddress(evm.EbakusState, contractAddress, abi) 1088 } 1089 1090 func storeAbiAtAddress(db *ebakusdb.Snapshot, contractAddress common.Address, abi string) ([]byte, error) { 1091 id := GetContractAbiId(contractAddress, "abi", "") 1092 1093 where := []byte("Id LIKE ") 1094 whereClause, err := db.WhereParser(append(where, id[:]...)) 1095 if err != nil { 1096 return nil, errSystemContractError 1097 } 1098 1099 iter, err := db.Select(ContractAbiTable, whereClause) 1100 if err != nil { 1101 return nil, errSystemContractError 1102 } 1103 1104 var contractAbi ContractAbi 1105 1106 if iter.Next(&contractAbi) == true { 1107 return nil, errContractAbiExists 1108 } 1109 1110 contractAbi = ContractAbi{ 1111 Id: id, 1112 Abi: abi, 1113 } 1114 1115 if err := db.InsertObj(ContractAbiTable, &contractAbi); err != nil { 1116 return nil, errSystemContractError 1117 } 1118 1119 return nil, nil 1120 } 1121 1122 func (c *systemContract) getAbiAtAddress(evm *EVM, contractAddress common.Address) (string, error) { 1123 return GetAbiAtAddress(evm.EbakusState, contractAddress) 1124 } 1125 1126 func GetAbiAtAddress(db *ebakusdb.Snapshot, contractAddress common.Address) (string, error) { 1127 1128 if contractAddress == types.PrecompliledSystemContract { 1129 return SystemContractABI, nil 1130 } else if contractAddress == types.PrecompliledDBContract { 1131 return DBABI, nil 1132 } 1133 1134 idPrefix := GetContractAbiId(contractAddress, "abi", "") 1135 1136 where := []byte("Id LIKE ") 1137 whereClause, err := db.WhereParser(append(where, idPrefix[:]...)) 1138 if err != nil { 1139 return "", errSystemContractError 1140 } 1141 1142 iter, err := db.Select(ContractAbiTable, whereClause) 1143 if err != nil { 1144 return "", errSystemContractError 1145 } 1146 1147 var contractAbi ContractAbi 1148 if iter.Next(&contractAbi) == false { 1149 return "", errContractAbiNotFound 1150 } 1151 1152 contractAbiID := common.BytesToAddress(contractAbi.Id[:common.AddressLength]) 1153 if contractAbiID != contractAddress { 1154 return "", errSystemContractError 1155 } 1156 1157 return contractAbi.Abi, nil 1158 } 1159 1160 func (c *systemContract) Run(evm *EVM, contract *Contract, input []byte) ([]byte, error) { 1161 from := contract.Caller() 1162 1163 if len(input) == 0 { 1164 return nil, errSystemContractError 1165 } 1166 1167 evmABI, err := abi.JSON(strings.NewReader(SystemContractABI)) 1168 if err != nil { 1169 return nil, errSystemContractAbiError 1170 } 1171 1172 cmdData, inputData := input[:4], input[4:] 1173 method, err := evmABI.MethodById(cmdData) 1174 if err != nil { 1175 return nil, errSystemContractAbiError 1176 } 1177 1178 cmd := method.Name 1179 1180 switch cmd { 1181 case SystemContractStakeCmd: 1182 var amount uint64 1183 err = evmABI.UnpackWithArguments(&amount, cmd, inputData, abi.InputsArgumentsType) 1184 if err != nil { 1185 log.Trace("SystemContractABI failed to unpack input", "cmd", cmd, "err", err) 1186 return nil, errStakeMalformed 1187 } 1188 1189 _, err := c.claimCmd(evm, from) 1190 if err != nil { 1191 return nil, err 1192 } 1193 1194 return c.stakeCmd(evm, from, amount) 1195 case SystemContractGetStakedCmd: 1196 return c.getStakedCmd(evm, from) 1197 case SystemContractUnstakeCmd: 1198 var amount uint64 1199 err = evmABI.UnpackWithArguments(&amount, cmd, inputData, abi.InputsArgumentsType) 1200 if err != nil { 1201 log.Trace("SystemContractABI failed to unpack input", "cmd", cmd, "err", err) 1202 return nil, errUnstakeMalformed 1203 } 1204 1205 return c.unstakeCmd(evm, from, amount) 1206 case SystemContractClaimCmd: 1207 return c.claimCmd(evm, from) 1208 case SystemContractVoteCmd: 1209 var addresses []common.Address 1210 err = evmABI.UnpackWithArguments(&addresses, cmd, inputData, abi.InputsArgumentsType) 1211 if err != nil { 1212 log.Trace("SystemContractABI failed to unpack input", "cmd", cmd, "err", err) 1213 return nil, errVoteMalformed 1214 } 1215 1216 return c.voteCmd(evm, from, addresses) 1217 case SystemContractUnvoteCmd: 1218 return c.unvoteCmd(evm, from) 1219 case SystemContractElectEnableCmd: 1220 var enable bool 1221 err = evmABI.UnpackWithArguments(&enable, cmd, inputData, abi.InputsArgumentsType) 1222 if err != nil { 1223 return nil, errElectEnableMalformed 1224 } 1225 1226 return c.electEnableCmd(evm, from, enable) 1227 case SystemContractStoreAbiCmd: 1228 type contractAbiInput struct { 1229 Address common.Address 1230 Abi string 1231 } 1232 1233 var input contractAbiInput 1234 err = evmABI.UnpackWithArguments(&input, cmd, inputData, abi.InputsArgumentsType) 1235 if err != nil { 1236 log.Trace("SystemContractABI failed to unpack input", "cmd", cmd, "err", err) 1237 return nil, errContractAbiMalformed 1238 } 1239 1240 return c.storeAbiAtAddress(evm, input.Address, input.Abi) 1241 case SystemContractGetAbiCmd: 1242 var contractAddress common.Address 1243 err = evmABI.UnpackWithArguments(&contractAddress, cmd, inputData, abi.InputsArgumentsType) 1244 if err != nil { 1245 log.Trace("SystemContractABI failed to unpack input", "cmd", cmd, "err", err) 1246 return nil, errContractAbiMalformed 1247 } 1248 1249 contractAbi, err := c.getAbiAtAddress(evm, contractAddress) 1250 if err != nil { 1251 return nil, errSystemContractError 1252 } 1253 1254 res, err := evmABI.PackWithArguments(cmd, abi.OutputsArgumentsType, contractAbi) 1255 if err != nil { 1256 log.Trace("ContractAbi failed to pack response", "err", err) 1257 return nil, errSystemContractError 1258 } 1259 1260 return res[4:], nil 1261 default: 1262 return nil, errSystemContractError 1263 } 1264 1265 return nil, nil 1266 } 1267 1268 // ECRECOVER implemented as a native contract. 1269 type ecrecover struct{} 1270 1271 func (c *ecrecover) RequiredGas(input []byte) uint64 { 1272 return params.EcrecoverGas 1273 } 1274 1275 func (c *ecrecover) Run(evm *EVM, contract *Contract, input []byte) ([]byte, error) { 1276 const ecRecoverInputLength = 128 1277 1278 input = common.RightPadBytes(input, ecRecoverInputLength) 1279 // "input" is (hash, v, r, s), each 32 bytes 1280 // but for ecrecover we want (r, s, v) 1281 1282 r := new(big.Int).SetBytes(input[64:96]) 1283 s := new(big.Int).SetBytes(input[96:128]) 1284 v := input[63] - 27 1285 1286 // tighter sig s values input homestead only apply to tx sigs 1287 if !allZero(input[32:63]) || !crypto.ValidateSignatureValues(v, r, s, false) { 1288 return nil, nil 1289 } 1290 // We must make sure not to modify the 'input', so placing the 'v' along with 1291 // the signature needs to be done on a new allocation 1292 sig := make([]byte, 65) 1293 copy(sig, input[64:128]) 1294 sig[64] = v 1295 // v needs to be at the end for libsecp256k1 1296 pubKey, err := crypto.Ecrecover(input[:32], sig) 1297 // make sure the public key is a valid one 1298 if err != nil { 1299 return nil, nil 1300 } 1301 1302 // the first byte of pubkey is bitcoin heritage 1303 return common.LeftPadBytes(crypto.Keccak256(pubKey[1:])[12:], 32), nil 1304 } 1305 1306 // SHA256 implemented as a native contract. 1307 type sha256hash struct{} 1308 1309 // RequiredGas returns the gas required to execute the pre-compiled contract. 1310 // 1311 // This method does not require any overflow checking as the input size gas costs 1312 // required for anything significant is so high it's impossible to pay for. 1313 func (c *sha256hash) RequiredGas(input []byte) uint64 { 1314 return uint64(len(input)+31)/32*params.Sha256PerWordGas + params.Sha256BaseGas 1315 } 1316 func (c *sha256hash) Run(evm *EVM, contract *Contract, input []byte) ([]byte, error) { 1317 h := sha256.Sum256(input) 1318 return h[:], nil 1319 } 1320 1321 // RIPEMD160 implemented as a native contract. 1322 type ripemd160hash struct{} 1323 1324 // RequiredGas returns the gas required to execute the pre-compiled contract. 1325 // 1326 // This method does not require any overflow checking as the input size gas costs 1327 // required for anything significant is so high it's impossible to pay for. 1328 func (c *ripemd160hash) RequiredGas(input []byte) uint64 { 1329 return uint64(len(input)+31)/32*params.Ripemd160PerWordGas + params.Ripemd160BaseGas 1330 } 1331 func (c *ripemd160hash) Run(evm *EVM, contract *Contract, input []byte) ([]byte, error) { 1332 ripemd := ripemd160.New() 1333 ripemd.Write(input) 1334 return common.LeftPadBytes(ripemd.Sum(nil), 32), nil 1335 } 1336 1337 // data copy implemented as a native contract. 1338 type dataCopy struct{} 1339 1340 // RequiredGas returns the gas required to execute the pre-compiled contract. 1341 // 1342 // This method does not require any overflow checking as the input size gas costs 1343 // required for anything significant is so high it's impossible to pay for. 1344 func (c *dataCopy) RequiredGas(input []byte) uint64 { 1345 return uint64(len(input)+31)/32*params.IdentityPerWordGas + params.IdentityBaseGas 1346 } 1347 func (c *dataCopy) Run(evm *EVM, contract *Contract, in []byte) ([]byte, error) { 1348 return in, nil 1349 } 1350 1351 // bigModExp implements a native big integer exponential modular operation. 1352 type bigModExp struct{} 1353 1354 var ( 1355 big1 = big.NewInt(1) 1356 big4 = big.NewInt(4) 1357 big8 = big.NewInt(8) 1358 big16 = big.NewInt(16) 1359 big32 = big.NewInt(32) 1360 big64 = big.NewInt(64) 1361 big96 = big.NewInt(96) 1362 big480 = big.NewInt(480) 1363 big1024 = big.NewInt(1024) 1364 big3072 = big.NewInt(3072) 1365 big199680 = big.NewInt(199680) 1366 ) 1367 1368 // RequiredGas returns the gas required to execute the pre-compiled contract. 1369 func (c *bigModExp) RequiredGas(input []byte) uint64 { 1370 var ( 1371 baseLen = new(big.Int).SetBytes(getData(input, 0, 32)) 1372 expLen = new(big.Int).SetBytes(getData(input, 32, 32)) 1373 modLen = new(big.Int).SetBytes(getData(input, 64, 32)) 1374 ) 1375 if len(input) > 96 { 1376 input = input[96:] 1377 } else { 1378 input = input[:0] 1379 } 1380 // Retrieve the head 32 bytes of exp for the adjusted exponent length 1381 var expHead *big.Int 1382 if big.NewInt(int64(len(input))).Cmp(baseLen) <= 0 { 1383 expHead = new(big.Int) 1384 } else { 1385 if expLen.Cmp(big32) > 0 { 1386 expHead = new(big.Int).SetBytes(getData(input, baseLen.Uint64(), 32)) 1387 } else { 1388 expHead = new(big.Int).SetBytes(getData(input, baseLen.Uint64(), expLen.Uint64())) 1389 } 1390 } 1391 // Calculate the adjusted exponent length 1392 var msb int 1393 if bitlen := expHead.BitLen(); bitlen > 0 { 1394 msb = bitlen - 1 1395 } 1396 adjExpLen := new(big.Int) 1397 if expLen.Cmp(big32) > 0 { 1398 adjExpLen.Sub(expLen, big32) 1399 adjExpLen.Mul(big8, adjExpLen) 1400 } 1401 adjExpLen.Add(adjExpLen, big.NewInt(int64(msb))) 1402 1403 // Calculate the gas cost of the operation 1404 gas := new(big.Int).Set(math.BigMax(modLen, baseLen)) 1405 switch { 1406 case gas.Cmp(big64) <= 0: 1407 gas.Mul(gas, gas) 1408 case gas.Cmp(big1024) <= 0: 1409 gas = new(big.Int).Add( 1410 new(big.Int).Div(new(big.Int).Mul(gas, gas), big4), 1411 new(big.Int).Sub(new(big.Int).Mul(big96, gas), big3072), 1412 ) 1413 default: 1414 gas = new(big.Int).Add( 1415 new(big.Int).Div(new(big.Int).Mul(gas, gas), big16), 1416 new(big.Int).Sub(new(big.Int).Mul(big480, gas), big199680), 1417 ) 1418 } 1419 gas.Mul(gas, math.BigMax(adjExpLen, big1)) 1420 gas.Div(gas, new(big.Int).SetUint64(params.ModExpQuadCoeffDiv)) 1421 1422 if gas.BitLen() > 64 { 1423 return math.MaxUint64 1424 } 1425 return gas.Uint64() 1426 } 1427 1428 func (c *bigModExp) Run(evm *EVM, contract *Contract, input []byte) ([]byte, error) { 1429 var ( 1430 baseLen = new(big.Int).SetBytes(getData(input, 0, 32)).Uint64() 1431 expLen = new(big.Int).SetBytes(getData(input, 32, 32)).Uint64() 1432 modLen = new(big.Int).SetBytes(getData(input, 64, 32)).Uint64() 1433 ) 1434 if len(input) > 96 { 1435 input = input[96:] 1436 } else { 1437 input = input[:0] 1438 } 1439 // Handle a special case when both the base and mod length is zero 1440 if baseLen == 0 && modLen == 0 { 1441 return []byte{}, nil 1442 } 1443 // Retrieve the operands and execute the exponentiation 1444 var ( 1445 base = new(big.Int).SetBytes(getData(input, 0, baseLen)) 1446 exp = new(big.Int).SetBytes(getData(input, baseLen, expLen)) 1447 mod = new(big.Int).SetBytes(getData(input, baseLen+expLen, modLen)) 1448 ) 1449 if mod.BitLen() == 0 { 1450 // Modulo 0 is undefined, return zero 1451 return common.LeftPadBytes([]byte{}, int(modLen)), nil 1452 } 1453 return common.LeftPadBytes(base.Exp(base, exp, mod).Bytes(), int(modLen)), nil 1454 } 1455 1456 // newCurvePoint unmarshals a binary blob into a bn256 elliptic curve point, 1457 // returning it, or an error if the point is invalid. 1458 func newCurvePoint(blob []byte) (*bn256.G1, error) { 1459 p := new(bn256.G1) 1460 if _, err := p.Unmarshal(blob); err != nil { 1461 return nil, err 1462 } 1463 return p, nil 1464 } 1465 1466 // newTwistPoint unmarshals a binary blob into a bn256 elliptic curve point, 1467 // returning it, or an error if the point is invalid. 1468 func newTwistPoint(blob []byte) (*bn256.G2, error) { 1469 p := new(bn256.G2) 1470 if _, err := p.Unmarshal(blob); err != nil { 1471 return nil, err 1472 } 1473 return p, nil 1474 } 1475 1476 // runBn256Add implements the Bn256Add precompile, referenced by both 1477 // Byzantium and Istanbul operations. 1478 func runBn256Add(input []byte) ([]byte, error) { 1479 x, err := newCurvePoint(getData(input, 0, 64)) 1480 if err != nil { 1481 return nil, err 1482 } 1483 y, err := newCurvePoint(getData(input, 64, 64)) 1484 if err != nil { 1485 return nil, err 1486 } 1487 res := new(bn256.G1) 1488 res.Add(x, y) 1489 return res.Marshal(), nil 1490 } 1491 1492 // bn256Add implements a native elliptic curve point addition conforming to 1493 // Istanbul consensus rules. 1494 type bn256AddIstanbul struct{} 1495 1496 // RequiredGas returns the gas required to execute the pre-compiled contract. 1497 func (c *bn256AddIstanbul) RequiredGas(input []byte) uint64 { 1498 return params.Bn256AddGasIstanbul 1499 } 1500 1501 func (c *bn256AddIstanbul) Run(evm *EVM, contract *Contract, input []byte) ([]byte, error) { 1502 return runBn256Add(input) 1503 } 1504 1505 // runBn256ScalarMul implements the Bn256ScalarMul precompile, referenced by 1506 // both Byzantium and Istanbul operations. 1507 func runBn256ScalarMul(input []byte) ([]byte, error) { 1508 p, err := newCurvePoint(getData(input, 0, 64)) 1509 if err != nil { 1510 return nil, err 1511 } 1512 res := new(bn256.G1) 1513 res.ScalarMult(p, new(big.Int).SetBytes(getData(input, 64, 32))) 1514 return res.Marshal(), nil 1515 } 1516 1517 // bn256ScalarMulIstanbul implements a native elliptic curve scalar 1518 // multiplication conforming to Istanbul consensus rules. 1519 type bn256ScalarMulIstanbul struct{} 1520 1521 // RequiredGas returns the gas required to execute the pre-compiled contract. 1522 func (c *bn256ScalarMulIstanbul) RequiredGas(input []byte) uint64 { 1523 return params.Bn256ScalarMulGasIstanbul 1524 } 1525 1526 func (c *bn256ScalarMulIstanbul) Run(evm *EVM, contract *Contract, input []byte) ([]byte, error) { 1527 return runBn256ScalarMul(input) 1528 } 1529 1530 var ( 1531 // true32Byte is returned if the bn256 pairing check succeeds. 1532 true32Byte = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} 1533 1534 // false32Byte is returned if the bn256 pairing check fails. 1535 false32Byte = make([]byte, 32) 1536 1537 // errBadPairingInput is returned if the bn256 pairing input is invalid. 1538 errBadPairingInput = errors.New("bad elliptic curve pairing size") 1539 ) 1540 1541 // runBn256Pairing implements the Bn256Pairing precompile, referenced by both 1542 // Byzantium and Istanbul operations. 1543 func runBn256Pairing(input []byte) ([]byte, error) { 1544 // Handle some corner cases cheaply 1545 if len(input)%192 > 0 { 1546 return nil, errBadPairingInput 1547 } 1548 // Convert the input into a set of coordinates 1549 var ( 1550 cs []*bn256.G1 1551 ts []*bn256.G2 1552 ) 1553 for i := 0; i < len(input); i += 192 { 1554 c, err := newCurvePoint(input[i : i+64]) 1555 if err != nil { 1556 return nil, err 1557 } 1558 t, err := newTwistPoint(input[i+64 : i+192]) 1559 if err != nil { 1560 return nil, err 1561 } 1562 cs = append(cs, c) 1563 ts = append(ts, t) 1564 } 1565 // Execute the pairing checks and return the results 1566 if bn256.PairingCheck(cs, ts) { 1567 return true32Byte, nil 1568 } 1569 return false32Byte, nil 1570 } 1571 1572 // bn256PairingIstanbul implements a pairing pre-compile for the bn256 curve 1573 // conforming to Istanbul consensus rules. 1574 type bn256PairingIstanbul struct{} 1575 1576 // RequiredGas returns the gas required to execute the pre-compiled contract. 1577 func (c *bn256PairingIstanbul) RequiredGas(input []byte) uint64 { 1578 return params.Bn256PairingBaseGasIstanbul + uint64(len(input)/192)*params.Bn256PairingPerPointGasIstanbul 1579 } 1580 1581 func (c *bn256PairingIstanbul) Run(evm *EVM, contract *Contract, input []byte) ([]byte, error) { 1582 return runBn256Pairing(input) 1583 } 1584 1585 type blake2F struct{} 1586 1587 func (c *blake2F) RequiredGas(input []byte) uint64 { 1588 // If the input is malformed, we can't calculate the gas, return 0 and let the 1589 // actual call choke and fault. 1590 if len(input) != blake2FInputLength { 1591 return 0 1592 } 1593 return uint64(binary.BigEndian.Uint32(input[0:4])) 1594 } 1595 1596 const ( 1597 blake2FInputLength = 213 1598 blake2FFinalBlockBytes = byte(1) 1599 blake2FNonFinalBlockBytes = byte(0) 1600 ) 1601 1602 var ( 1603 errBlake2FInvalidInputLength = errors.New("invalid input length") 1604 errBlake2FInvalidFinalFlag = errors.New("invalid final flag") 1605 ) 1606 1607 func (c *blake2F) Run(evm *EVM, contract *Contract, input []byte) ([]byte, error) { 1608 // Make sure the input is valid (correct lenth and final flag) 1609 if len(input) != blake2FInputLength { 1610 return nil, errBlake2FInvalidInputLength 1611 } 1612 if input[212] != blake2FNonFinalBlockBytes && input[212] != blake2FFinalBlockBytes { 1613 return nil, errBlake2FInvalidFinalFlag 1614 } 1615 // Parse the input into the Blake2b call parameters 1616 var ( 1617 rounds = binary.BigEndian.Uint32(input[0:4]) 1618 final = (input[212] == blake2FFinalBlockBytes) 1619 1620 h [8]uint64 1621 m [16]uint64 1622 t [2]uint64 1623 ) 1624 for i := 0; i < 8; i++ { 1625 offset := 4 + i*8 1626 h[i] = binary.LittleEndian.Uint64(input[offset : offset+8]) 1627 } 1628 for i := 0; i < 16; i++ { 1629 offset := 68 + i*8 1630 m[i] = binary.LittleEndian.Uint64(input[offset : offset+8]) 1631 } 1632 t[0] = binary.LittleEndian.Uint64(input[196:204]) 1633 t[1] = binary.LittleEndian.Uint64(input[204:212]) 1634 1635 // Execute the compression function, extract and return the result 1636 blake2b.F(&h, m, t, final, rounds) 1637 1638 output := make([]byte, 64) 1639 for i := 0; i < 8; i++ { 1640 offset := i * 8 1641 binary.LittleEndian.PutUint64(output[offset:offset+8], h[i]) 1642 } 1643 return output, nil 1644 } 1645 1646 const DBABI = `[ 1647 { 1648 "type": "function", 1649 "name": "createTable", 1650 "inputs": [ 1651 { 1652 "name": "tableName", 1653 "type": "string" 1654 }, 1655 { 1656 "name": "indexes", 1657 "type": "string" 1658 }, 1659 { 1660 "name": "abi", 1661 "type": "string" 1662 } 1663 ], 1664 "outputs": [], 1665 "stateMutability": "nonpayable" 1666 },{ 1667 "type": "function", 1668 "name": "insertObj", 1669 "inputs": [ 1670 { 1671 "name": "tableName", 1672 "type": "string" 1673 }, 1674 { 1675 "name": "data", 1676 "type": "bytes" 1677 } 1678 ], 1679 "outputs": [ 1680 { 1681 "type": "bool" 1682 } 1683 ], 1684 "stateMutability": "nonpayable" 1685 },{ 1686 "type": "function", 1687 "name": "deleteObj", 1688 "inputs": [ 1689 { 1690 "name": "tableName", 1691 "type": "string" 1692 }, 1693 { 1694 "name": "id", 1695 "type": "bytes" 1696 } 1697 ], 1698 "outputs": [ 1699 { 1700 "type": "bool" 1701 } 1702 ], 1703 "stateMutability": "nonpayable" 1704 },{ 1705 "type": "function", 1706 "name": "get", 1707 "inputs": [ 1708 { 1709 "name": "tableName", 1710 "type": "string" 1711 }, 1712 { 1713 "name": "whereClause", 1714 "type": "string" 1715 }, 1716 { 1717 "name": "orderClause", 1718 "type": "string" 1719 } 1720 ], 1721 "outputs": [ 1722 { 1723 "type": "bytes" 1724 } 1725 ], 1726 "stateMutability": "nonpayable" 1727 },{ 1728 "type": "function", 1729 "name": "select", 1730 "inputs": [ 1731 { 1732 "name": "tableName", 1733 "type": "string" 1734 }, 1735 { 1736 "name": "whereClause", 1737 "type": "string" 1738 }, 1739 { 1740 "name": "orderClause", 1741 "type": "string" 1742 } 1743 ], 1744 "outputs": [ 1745 { 1746 "type": "bytes32" 1747 } 1748 ], 1749 "stateMutability": "nonpayable" 1750 },{ 1751 "type": "function", 1752 "name": "next", 1753 "inputs": [ 1754 { 1755 "type": "bytes32" 1756 } 1757 ], 1758 "outputs": [ 1759 { 1760 "type": "bytes" 1761 } 1762 ], 1763 "stateMutability": "nonpayable" 1764 }]` 1765 1766 // dbContract exposes ebakusdb to solidity 1767 type dbContract struct{} 1768 1769 // RequiredGas returns the gas required to execute the pre-compiled contract. 1770 func (c *dbContract) RequiredGas(input []byte) uint64 { 1771 if len(input) == 0 { 1772 return params.DBContractBaseGas 1773 } 1774 1775 evmABI, err := abi.JSON(strings.NewReader(DBABI)) 1776 if err != nil { 1777 return params.DBContractBaseGas 1778 } 1779 1780 cmdData, _ := input[:4], input[4:] 1781 method, err := evmABI.MethodById(cmdData) 1782 if err != nil { 1783 return params.DBContractBaseGas 1784 } 1785 1786 cmd := method.Name 1787 1788 switch cmd { 1789 case DBContractCreateTableCmd: 1790 return params.DBContractCreateTableGas 1791 case DBContractInsertObjCmd: 1792 return params.DBContractInsertObjGas 1793 case DBContractDeleteObjCmd: 1794 return params.DBContractDeleteObjGas 1795 case DBContractGetCmd: 1796 return params.DBContractGetGas 1797 case DBContractSelectCmd: 1798 return params.DBContractSelectGas 1799 case DBContractNextCmd: 1800 return params.DBContractNextGas 1801 default: 1802 return params.DBContractBaseGas 1803 } 1804 } 1805 1806 type tableDef struct { 1807 TableName string 1808 Indexes string 1809 Abi string 1810 } 1811 1812 type insertObjDef struct { 1813 TableName string 1814 Data []byte 1815 } 1816 type deleteObjDef struct { 1817 TableName string 1818 Id []byte 1819 } 1820 1821 type selectDef struct { 1822 TableName string 1823 WhereClause string 1824 OrderClause string 1825 } 1826 1827 func GetAbiForTable(db *ebakusdb.Snapshot, contractAddress common.Address, name string) (*abi.ABI, error) { 1828 var abiString string 1829 1830 if contractAddress == types.PrecompliledSystemContract { 1831 abiString = SystemContractTablesABI 1832 } else { 1833 id := GetContractAbiId(contractAddress, "table", name) 1834 1835 where := []byte("Id LIKE ") 1836 whereClause, err := db.WhereParser(append(where, id...)) 1837 if err != nil { 1838 return nil, errSystemContractError 1839 } 1840 1841 iter, err := db.Select(ContractAbiTable, whereClause) 1842 if err != nil { 1843 return nil, errContractAbiNotFound 1844 } 1845 1846 var contractAbi ContractAbi 1847 if iter.Next(&contractAbi) == false { 1848 return nil, errContractAbiNotFound 1849 } 1850 1851 abiString = contractAbi.Abi 1852 } 1853 1854 tableABI, err := abi.JSON(strings.NewReader(abiString)) 1855 if err != nil { 1856 return nil, errDBContractError 1857 } 1858 1859 return &tableABI, nil 1860 } 1861 1862 func (c *dbContract) prependByteSize(data []byte) []byte { 1863 size := make([]byte, 32) 1864 binary.BigEndian.PutUint32(size[28:], uint32(len(data))) 1865 return append(size, data...) 1866 } 1867 1868 func (c *dbContract) createTable(evm *EVM, contractAddress common.Address, table tableDef) ([]byte, error) { 1869 db := evm.EbakusState 1870 1871 if table.TableName == "" { 1872 return nil, errEmptyTableNameError 1873 } 1874 dbTableName := ebkdb.GetDBTableName(contractAddress, table.TableName) 1875 1876 if table.Abi == "" { 1877 return nil, errTableAbiMalformed 1878 } 1879 1880 tableABI, err := abi.JSON(strings.NewReader(table.Abi)) 1881 if err != nil { 1882 return nil, errTableAbiMalformed 1883 } 1884 1885 obj, err := tableABI.GetTableInstance(table.TableName) 1886 if err != nil { 1887 return nil, err 1888 } 1889 1890 id := GetContractAbiId(contractAddress, "table", table.TableName) 1891 1892 where := []byte("Id = ") 1893 whereClause, err := db.WhereParser(append(where, id...)) 1894 if err != nil { 1895 return nil, errDBContractError 1896 } 1897 1898 iter, err := db.Select(ContractAbiTable, whereClause) 1899 if err != nil { 1900 return nil, errDBContractError 1901 } 1902 1903 var contractAbi ContractAbi 1904 if iter.Next(&contractAbi) == true { 1905 return nil, errCreateTableExists 1906 } 1907 1908 contractAbi = ContractAbi{ 1909 Id: id, 1910 Abi: table.Abi, 1911 } 1912 1913 db.CreateTable(dbTableName, obj) 1914 1915 if table.Indexes != "" { 1916 indexes := strings.Split(table.Indexes, ",") 1917 for _, index := range indexes { 1918 db.CreateIndex(ebakusdb.IndexField{ 1919 Table: dbTableName, 1920 Field: index, 1921 }) 1922 } 1923 } 1924 1925 if err := db.InsertObj(ContractAbiTable, &contractAbi); err != nil { 1926 return nil, errDBContractError 1927 } 1928 1929 return common.LeftPadBytes([]byte{1}, 32), nil 1930 } 1931 1932 func (c *dbContract) insertObj(evm *EVM, contractAddress common.Address, insertObj insertObjDef) ([]byte, error) { 1933 db := evm.EbakusState 1934 1935 if insertObj.TableName == "" { 1936 return nil, errEmptyTableNameError 1937 } 1938 dbTableName := ebkdb.GetDBTableName(contractAddress, insertObj.TableName) 1939 1940 tableABI, err := GetAbiForTable(db, contractAddress, insertObj.TableName) 1941 if err != nil { 1942 return nil, err 1943 } 1944 1945 obj, err := tableABI.GetTableInstance(insertObj.TableName) 1946 if err != nil { 1947 return nil, err 1948 } 1949 1950 if err = tableABI.Unpack(obj, insertObj.TableName, insertObj.Data); err != nil { 1951 return nil, err 1952 } 1953 1954 if err := db.InsertObj(dbTableName, obj); err != nil { 1955 return common.LeftPadBytes([]byte{0}, 32), nil 1956 } 1957 1958 return common.LeftPadBytes([]byte{1}, 32), nil 1959 } 1960 1961 func (c *dbContract) deleteObj(evm *EVM, contractAddress common.Address, deleteObj deleteObjDef) ([]byte, error) { 1962 db := evm.EbakusState 1963 1964 if deleteObj.TableName == "" { 1965 return nil, errEmptyTableNameError 1966 } 1967 dbTableName := ebkdb.GetDBTableName(contractAddress, deleteObj.TableName) 1968 1969 tableABI, err := GetAbiForTable(db, contractAddress, deleteObj.TableName) 1970 if err != nil { 1971 return nil, err 1972 } 1973 1974 obj, err := tableABI.GetTableInstance(deleteObj.TableName) 1975 if err != nil { 1976 return nil, err 1977 } 1978 1979 id, err := tableABI.UnpackSingle(obj, deleteObj.TableName, "Id", deleteObj.Id) 1980 if err != nil { 1981 return nil, err 1982 } 1983 1984 if err := db.DeleteObj(dbTableName, id); err != nil { 1985 return common.LeftPadBytes([]byte{0}, 32), nil 1986 } 1987 1988 return common.LeftPadBytes([]byte{1}, 32), nil 1989 } 1990 1991 func EbakusDBGet(db *ebakusdb.Snapshot, contractAddress common.Address, tableName string, whereClause string, orderClause string) (interface{}, error) { 1992 if tableName == "" { 1993 return nil, errEmptyTableNameError 1994 } 1995 1996 dbTableName := ebkdb.GetDBTableName(contractAddress, tableName) 1997 1998 tableABI, err := GetAbiForTable(db, contractAddress, tableName) 1999 if err != nil { 2000 return nil, err 2001 } 2002 2003 obj, err := tableABI.GetTableInstance(tableName) 2004 if err != nil { 2005 return nil, err 2006 } 2007 2008 whereQuery, err := db.WhereParser([]byte(whereClause)) 2009 if err != nil { 2010 return nil, errDBContractError 2011 } 2012 2013 orderQuery, err := db.OrderParser([]byte(orderClause)) 2014 if err != nil { 2015 return nil, errDBContractError 2016 } 2017 2018 iter, err := db.Select(dbTableName, whereQuery, orderQuery) 2019 if err != nil { 2020 return nil, errDBContractError 2021 } 2022 2023 if iter.Next(obj) == false { 2024 return nil, errNoEntryFound 2025 } 2026 2027 return obj, nil 2028 } 2029 2030 func (c *dbContract) get(evm *EVM, contractAddress common.Address, selectObj selectDef) ([]byte, error) { 2031 db := evm.EbakusState 2032 2033 obj, err := EbakusDBGet(db, contractAddress, selectObj.TableName, selectObj.WhereClause, selectObj.OrderClause) 2034 if err != nil { 2035 return nil, err 2036 } 2037 2038 tableABI, err := GetAbiForTable(db, contractAddress, selectObj.TableName) 2039 if err != nil { 2040 return nil, err 2041 } 2042 2043 data, err := tableABI.Pack(selectObj.TableName, obj) 2044 if err != nil { 2045 return nil, err 2046 } 2047 2048 return c.prependByteSize(data), nil 2049 } 2050 2051 func EbakusDBSelect(db *ebakusdb.Snapshot, contractAddress common.Address, tableName string, whereClause string, orderClause string) (*ebakusdb.ResultIterator, error) { 2052 if tableName == "" { 2053 return nil, errEmptyTableNameError 2054 } 2055 dbTableName := ebkdb.GetDBTableName(contractAddress, tableName) 2056 2057 whereQuery, err := db.WhereParser([]byte(whereClause)) 2058 if err != nil { 2059 return nil, errDBContractError 2060 } 2061 2062 orderQuery, err := db.OrderParser([]byte(orderClause)) 2063 if err != nil { 2064 return nil, errDBContractError 2065 } 2066 2067 iter, err := db.Select(dbTableName, whereQuery, orderQuery) 2068 if err != nil { 2069 return nil, errDBContractError 2070 } 2071 2072 return iter, err 2073 } 2074 2075 func (c *dbContract) selectIter(evm *EVM, contractAddress common.Address, obj selectDef) ([]byte, error) { 2076 db := evm.EbakusState 2077 2078 iter, err := EbakusDBSelect(db, contractAddress, obj.TableName, obj.WhereClause, obj.OrderClause) 2079 if err != nil { 2080 return nil, err 2081 } 2082 2083 iterPointer := evm.addEbakusStateIterator(obj.TableName, iter) 2084 2085 var b bytes.Buffer 2086 binary.Write(&b, binary.BigEndian, iterPointer) 2087 2088 return common.RightPadBytes(b.Bytes(), 32), nil 2089 } 2090 2091 func EbakusDBNext(db *ebakusdb.Snapshot, contractAddress common.Address, tableName string, iter *ebakusdb.ResultIterator) (interface{}, error) { 2092 tableABI, err := GetAbiForTable(db, contractAddress, tableName) 2093 if err != nil { 2094 return nil, err 2095 } 2096 2097 obj, err := tableABI.GetTableInstance(tableName) 2098 if err != nil { 2099 return nil, err 2100 } 2101 2102 if iter.Next(obj) == false { 2103 // don't return an error as the contract doesn't have to stop execution 2104 // developer will check that no object found 2105 return nil, nil 2106 } 2107 2108 return obj, nil 2109 } 2110 2111 func (c *dbContract) next(evm *EVM, contractAddress common.Address, input []byte) ([]byte, error) { 2112 db := evm.EbakusState 2113 2114 tableIter := evm.getEbakusStateIterator(binary.BigEndian.Uint64(input)) 2115 2116 obj, err := EbakusDBNext(db, contractAddress, tableIter.TableName, tableIter.Iter) 2117 if err != nil { 2118 return nil, err 2119 } 2120 if obj == nil { 2121 return c.prependByteSize([]byte{}), nil 2122 } 2123 2124 tableABI, err := GetAbiForTable(db, contractAddress, tableIter.TableName) 2125 if err != nil { 2126 return nil, err 2127 } 2128 2129 data, err := tableABI.Pack(tableIter.TableName, obj) 2130 if err != nil { 2131 return nil, err 2132 } 2133 2134 return c.prependByteSize(data), nil 2135 } 2136 2137 func (c *dbContract) Run(evm *EVM, contract *Contract, input []byte) ([]byte, error) { 2138 from := contract.Caller() 2139 2140 if len(input) == 0 { 2141 return nil, errDBContractError 2142 } 2143 2144 evmABI, err := abi.JSON(strings.NewReader(DBABI)) 2145 if err != nil { 2146 return nil, errDBContractError 2147 } 2148 2149 cmdData, inputData := input[:4], input[4:] 2150 method, err := evmABI.MethodById(cmdData) 2151 if err != nil { 2152 return nil, errDBContractError 2153 } 2154 2155 cmd := method.Name 2156 2157 switch cmd { 2158 case DBContractCreateTableCmd: 2159 var tableObj tableDef 2160 err = evmABI.UnpackWithArguments(&tableObj, cmd, inputData, abi.InputsArgumentsType) 2161 if err != nil { 2162 return nil, errCreateTableMalformed 2163 } 2164 2165 return c.createTable(evm, from, tableObj) 2166 case DBContractInsertObjCmd: 2167 var insertObj insertObjDef 2168 err = evmABI.UnpackWithArguments(&insertObj, cmd, inputData, abi.InputsArgumentsType) 2169 if err != nil { 2170 return nil, errInsertObjMalformed 2171 } 2172 2173 return c.insertObj(evm, from, insertObj) 2174 case DBContractDeleteObjCmd: 2175 var deleteObj deleteObjDef 2176 err = evmABI.UnpackWithArguments(&deleteObj, cmd, inputData, abi.InputsArgumentsType) 2177 if err != nil { 2178 return nil, errDeleteObjMalformed 2179 } 2180 2181 return c.deleteObj(evm, from, deleteObj) 2182 case DBContractGetCmd: 2183 var selectData selectDef 2184 err = evmABI.UnpackWithArguments(&selectData, cmd, inputData, abi.InputsArgumentsType) 2185 if err != nil { 2186 return nil, errSelectMalformed 2187 } 2188 2189 return c.get(evm, from, selectData) 2190 case DBContractSelectCmd: 2191 var selectData selectDef 2192 err = evmABI.UnpackWithArguments(&selectData, cmd, inputData, abi.InputsArgumentsType) 2193 if err != nil { 2194 return nil, errSelectMalformed 2195 } 2196 2197 return c.selectIter(evm, from, selectData) 2198 case DBContractNextCmd: 2199 var iterData [32]byte 2200 err = evmABI.UnpackWithArguments(&iterData, cmd, inputData, abi.InputsArgumentsType) 2201 if err != nil { 2202 return nil, errIteratorMalformed 2203 } 2204 2205 return c.next(evm, from, iterData[:]) 2206 } 2207 2208 return nil, nil 2209 }