github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/rpc/api/eth_args.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package api 18 19 import ( 20 "encoding/json" 21 "fmt" 22 "math/big" 23 "strconv" 24 "strings" 25 26 "github.com/ethereum/go-ethereum/common" 27 "github.com/ethereum/go-ethereum/core/state" 28 "github.com/ethereum/go-ethereum/core/types" 29 "github.com/ethereum/go-ethereum/rpc/shared" 30 ) 31 32 const ( 33 defaultLogLimit = 100 34 defaultLogOffset = 0 35 ) 36 37 type GetBalanceArgs struct { 38 Address string 39 BlockNumber int64 40 } 41 42 func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) { 43 var obj []interface{} 44 if err := json.Unmarshal(b, &obj); err != nil { 45 return shared.NewDecodeParamError(err.Error()) 46 } 47 48 if len(obj) < 1 { 49 return shared.NewInsufficientParamsError(len(obj), 1) 50 } 51 52 addstr, ok := obj[0].(string) 53 if !ok { 54 return shared.NewInvalidTypeError("address", "not a string") 55 } 56 args.Address = addstr 57 58 if len(obj) > 1 { 59 if err := blockHeight(obj[1], &args.BlockNumber); err != nil { 60 return err 61 } 62 } else { 63 args.BlockNumber = -1 64 } 65 66 return nil 67 } 68 69 type GetStorageArgs struct { 70 Address string 71 BlockNumber int64 72 } 73 74 func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) { 75 var obj []interface{} 76 if err := json.Unmarshal(b, &obj); err != nil { 77 return shared.NewDecodeParamError(err.Error()) 78 } 79 80 if len(obj) < 1 { 81 return shared.NewInsufficientParamsError(len(obj), 1) 82 } 83 84 addstr, ok := obj[0].(string) 85 if !ok { 86 return shared.NewInvalidTypeError("address", "not a string") 87 } 88 args.Address = addstr 89 90 if len(obj) > 1 { 91 if err := blockHeight(obj[1], &args.BlockNumber); err != nil { 92 return err 93 } 94 } else { 95 args.BlockNumber = -1 96 } 97 98 return nil 99 } 100 101 type GetStorageAtArgs struct { 102 Address string 103 BlockNumber int64 104 Key string 105 } 106 107 func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) { 108 var obj []interface{} 109 if err := json.Unmarshal(b, &obj); err != nil { 110 return shared.NewDecodeParamError(err.Error()) 111 } 112 113 if len(obj) < 2 { 114 return shared.NewInsufficientParamsError(len(obj), 2) 115 } 116 117 addstr, ok := obj[0].(string) 118 if !ok { 119 return shared.NewInvalidTypeError("address", "not a string") 120 } 121 args.Address = addstr 122 123 keystr, ok := obj[1].(string) 124 if !ok { 125 return shared.NewInvalidTypeError("key", "not a string") 126 } 127 args.Key = keystr 128 129 if len(obj) > 2 { 130 if err := blockHeight(obj[2], &args.BlockNumber); err != nil { 131 return err 132 } 133 } else { 134 args.BlockNumber = -1 135 } 136 137 return nil 138 } 139 140 type GetTxCountArgs struct { 141 Address string 142 BlockNumber int64 143 } 144 145 func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) { 146 var obj []interface{} 147 if err := json.Unmarshal(b, &obj); err != nil { 148 return shared.NewDecodeParamError(err.Error()) 149 } 150 151 if len(obj) < 1 { 152 return shared.NewInsufficientParamsError(len(obj), 1) 153 } 154 155 addstr, ok := obj[0].(string) 156 if !ok { 157 return shared.NewInvalidTypeError("address", "not a string") 158 } 159 args.Address = addstr 160 161 if len(obj) > 1 { 162 if err := blockHeight(obj[1], &args.BlockNumber); err != nil { 163 return err 164 } 165 } else { 166 args.BlockNumber = -1 167 } 168 169 return nil 170 } 171 172 type SubmitHashRateArgs struct { 173 Id string 174 Rate uint64 175 } 176 177 func (args *SubmitHashRateArgs) UnmarshalJSON(b []byte) (err error) { 178 var obj []interface{} 179 if err := json.Unmarshal(b, &obj); err != nil { 180 return shared.NewDecodeParamError(err.Error()) 181 } 182 183 if len(obj) < 2 { 184 return shared.NewInsufficientParamsError(len(obj), 2) 185 } 186 187 arg0, ok := obj[0].(string) 188 if !ok { 189 return shared.NewInvalidTypeError("hash", "not a string") 190 } 191 args.Id = arg0 192 193 arg1, ok := obj[1].(string) 194 if !ok { 195 return shared.NewInvalidTypeError("rate", "not a string") 196 } 197 198 args.Rate = common.String2Big(arg1).Uint64() 199 200 return nil 201 } 202 203 type HashArgs struct { 204 Hash string 205 } 206 207 func (args *HashArgs) UnmarshalJSON(b []byte) (err error) { 208 var obj []interface{} 209 if err := json.Unmarshal(b, &obj); err != nil { 210 return shared.NewDecodeParamError(err.Error()) 211 } 212 213 if len(obj) < 1 { 214 return shared.NewInsufficientParamsError(len(obj), 1) 215 } 216 217 arg0, ok := obj[0].(string) 218 if !ok { 219 return shared.NewInvalidTypeError("hash", "not a string") 220 } 221 args.Hash = arg0 222 223 return nil 224 } 225 226 type BlockNumArg struct { 227 BlockNumber int64 228 } 229 230 func (args *BlockNumArg) UnmarshalJSON(b []byte) (err error) { 231 var obj []interface{} 232 if err := json.Unmarshal(b, &obj); err != nil { 233 return shared.NewDecodeParamError(err.Error()) 234 } 235 236 if len(obj) < 1 { 237 return shared.NewInsufficientParamsError(len(obj), 1) 238 } 239 240 if err := blockHeight(obj[0], &args.BlockNumber); err != nil { 241 return err 242 } 243 244 return nil 245 } 246 247 type GetDataArgs struct { 248 Address string 249 BlockNumber int64 250 } 251 252 func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) { 253 var obj []interface{} 254 if err := json.Unmarshal(b, &obj); err != nil { 255 return shared.NewDecodeParamError(err.Error()) 256 } 257 258 if len(obj) < 1 { 259 return shared.NewInsufficientParamsError(len(obj), 1) 260 } 261 262 addstr, ok := obj[0].(string) 263 if !ok { 264 return shared.NewInvalidTypeError("address", "not a string") 265 } 266 args.Address = addstr 267 268 if len(obj) > 1 { 269 if err := blockHeight(obj[1], &args.BlockNumber); err != nil { 270 return err 271 } 272 } else { 273 args.BlockNumber = -1 274 } 275 276 return nil 277 } 278 279 type NewDataArgs struct { 280 Data string 281 } 282 283 func (args *NewDataArgs) UnmarshalJSON(b []byte) (err error) { 284 var obj []interface{} 285 286 if err := json.Unmarshal(b, &obj); err != nil { 287 return shared.NewDecodeParamError(err.Error()) 288 } 289 290 // Check for sufficient params 291 if len(obj) < 1 { 292 return shared.NewInsufficientParamsError(len(obj), 1) 293 } 294 295 data, ok := obj[0].(string) 296 if !ok { 297 return shared.NewInvalidTypeError("data", "not a string") 298 } 299 args.Data = data 300 301 if len(args.Data) == 0 { 302 return shared.NewValidationError("data", "is required") 303 } 304 305 return nil 306 } 307 308 type NewSigArgs struct { 309 From string 310 Data string 311 } 312 313 func (args *NewSigArgs) UnmarshalJSON(b []byte) (err error) { 314 var obj []interface{} 315 316 if err := json.Unmarshal(b, &obj); err != nil { 317 return shared.NewDecodeParamError(err.Error()) 318 } 319 320 // Check for sufficient params 321 if len(obj) < 1 { 322 return shared.NewInsufficientParamsError(len(obj), 1) 323 } 324 325 from, ok := obj[0].(string) 326 if !ok { 327 return shared.NewInvalidTypeError("from", "not a string") 328 } 329 args.From = from 330 331 if len(args.From) == 0 { 332 return shared.NewValidationError("from", "is required") 333 } 334 335 data, ok := obj[1].(string) 336 if !ok { 337 return shared.NewInvalidTypeError("data", "not a string") 338 } 339 args.Data = data 340 341 if len(args.Data) == 0 { 342 return shared.NewValidationError("data", "is required") 343 } 344 345 return nil 346 } 347 348 type NewTxArgs struct { 349 From string 350 To string 351 Nonce *big.Int 352 Value *big.Int 353 Gas *big.Int 354 GasPrice *big.Int 355 Data string 356 357 BlockNumber int64 358 } 359 360 func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) { 361 var obj []json.RawMessage 362 var ext struct { 363 From string 364 To string 365 Nonce interface{} 366 Value interface{} 367 Gas interface{} 368 GasPrice interface{} 369 Data string 370 } 371 372 // Decode byte slice to array of RawMessages 373 if err := json.Unmarshal(b, &obj); err != nil { 374 return shared.NewDecodeParamError(err.Error()) 375 } 376 377 // Check for sufficient params 378 if len(obj) < 1 { 379 return shared.NewInsufficientParamsError(len(obj), 1) 380 } 381 382 // Decode 0th RawMessage to temporary struct 383 if err := json.Unmarshal(obj[0], &ext); err != nil { 384 return shared.NewDecodeParamError(err.Error()) 385 } 386 387 if len(ext.From) == 0 { 388 return shared.NewValidationError("from", "is required") 389 } 390 391 args.From = ext.From 392 args.To = ext.To 393 args.Data = ext.Data 394 395 var num *big.Int 396 if ext.Nonce != nil { 397 num, err = numString(ext.Nonce) 398 if err != nil { 399 return err 400 } 401 } 402 args.Nonce = num 403 404 if ext.Value == nil { 405 num = big.NewInt(0) 406 } else { 407 num, err = numString(ext.Value) 408 if err != nil { 409 return err 410 } 411 } 412 args.Value = num 413 414 num = nil 415 if ext.Gas != nil { 416 if num, err = numString(ext.Gas); err != nil { 417 return err 418 } 419 } 420 args.Gas = num 421 422 num = nil 423 if ext.GasPrice != nil { 424 if num, err = numString(ext.GasPrice); err != nil { 425 return err 426 } 427 } 428 args.GasPrice = num 429 430 // Check for optional BlockNumber param 431 if len(obj) > 1 { 432 if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil { 433 return err 434 } 435 } else { 436 args.BlockNumber = -1 437 } 438 439 return nil 440 } 441 442 type SourceArgs struct { 443 Source string 444 } 445 446 func (args *SourceArgs) UnmarshalJSON(b []byte) (err error) { 447 var obj []interface{} 448 if err := json.Unmarshal(b, &obj); err != nil { 449 return shared.NewDecodeParamError(err.Error()) 450 } 451 452 if len(obj) < 1 { 453 return shared.NewInsufficientParamsError(len(obj), 1) 454 } 455 456 arg0, ok := obj[0].(string) 457 if !ok { 458 return shared.NewInvalidTypeError("source code", "not a string") 459 } 460 args.Source = arg0 461 462 return nil 463 } 464 465 type CallArgs struct { 466 From string 467 To string 468 Value *big.Int 469 Gas *big.Int 470 GasPrice *big.Int 471 Data string 472 473 BlockNumber int64 474 } 475 476 func (args *CallArgs) UnmarshalJSON(b []byte) (err error) { 477 var obj []json.RawMessage 478 var ext struct { 479 From string 480 To string 481 Value interface{} 482 Gas interface{} 483 GasPrice interface{} 484 Data string 485 } 486 487 // Decode byte slice to array of RawMessages 488 if err := json.Unmarshal(b, &obj); err != nil { 489 return shared.NewDecodeParamError(err.Error()) 490 } 491 492 // Check for sufficient params 493 if len(obj) < 1 { 494 return shared.NewInsufficientParamsError(len(obj), 1) 495 } 496 497 // Decode 0th RawMessage to temporary struct 498 if err := json.Unmarshal(obj[0], &ext); err != nil { 499 return shared.NewDecodeParamError(err.Error()) 500 } 501 502 args.From = ext.From 503 args.To = ext.To 504 505 var num *big.Int 506 if ext.Value == nil { 507 num = big.NewInt(0) 508 } else { 509 if num, err = numString(ext.Value); err != nil { 510 return err 511 } 512 } 513 args.Value = num 514 515 if ext.Gas != nil { 516 if num, err = numString(ext.Gas); err != nil { 517 return err 518 } 519 } else { 520 num = nil 521 } 522 args.Gas = num 523 524 if ext.GasPrice != nil { 525 if num, err = numString(ext.GasPrice); err != nil { 526 return err 527 } 528 } else { 529 num = nil 530 } 531 args.GasPrice = num 532 533 args.Data = ext.Data 534 535 // Check for optional BlockNumber param 536 if len(obj) > 1 { 537 if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil { 538 return err 539 } 540 } else { 541 args.BlockNumber = -1 542 } 543 544 return nil 545 } 546 547 type HashIndexArgs struct { 548 Hash string 549 Index int64 550 } 551 552 func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) { 553 var obj []interface{} 554 if err := json.Unmarshal(b, &obj); err != nil { 555 return shared.NewDecodeParamError(err.Error()) 556 } 557 558 if len(obj) < 2 { 559 return shared.NewInsufficientParamsError(len(obj), 2) 560 } 561 562 arg0, ok := obj[0].(string) 563 if !ok { 564 return shared.NewInvalidTypeError("hash", "not a string") 565 } 566 args.Hash = arg0 567 568 arg1, ok := obj[1].(string) 569 if !ok { 570 return shared.NewInvalidTypeError("index", "not a string") 571 } 572 args.Index = common.Big(arg1).Int64() 573 574 return nil 575 } 576 577 type BlockNumIndexArgs struct { 578 BlockNumber int64 579 Index int64 580 } 581 582 func (args *BlockNumIndexArgs) UnmarshalJSON(b []byte) (err error) { 583 var obj []interface{} 584 if err := json.Unmarshal(b, &obj); err != nil { 585 return shared.NewDecodeParamError(err.Error()) 586 } 587 588 if len(obj) < 2 { 589 return shared.NewInsufficientParamsError(len(obj), 2) 590 } 591 592 if err := blockHeight(obj[0], &args.BlockNumber); err != nil { 593 return err 594 } 595 596 var arg1 *big.Int 597 if arg1, err = numString(obj[1]); err != nil { 598 return err 599 } 600 args.Index = arg1.Int64() 601 602 return nil 603 } 604 605 type GetBlockByHashArgs struct { 606 BlockHash string 607 IncludeTxs bool 608 } 609 610 func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) { 611 var obj []interface{} 612 613 if err := json.Unmarshal(b, &obj); err != nil { 614 return shared.NewDecodeParamError(err.Error()) 615 } 616 617 if len(obj) < 2 { 618 return shared.NewInsufficientParamsError(len(obj), 2) 619 } 620 621 argstr, ok := obj[0].(string) 622 if !ok { 623 return shared.NewInvalidTypeError("blockHash", "not a string") 624 } 625 args.BlockHash = argstr 626 627 args.IncludeTxs = obj[1].(bool) 628 629 return nil 630 } 631 632 type GetBlockByNumberArgs struct { 633 BlockNumber int64 634 IncludeTxs bool 635 } 636 637 func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) { 638 var obj []interface{} 639 if err := json.Unmarshal(b, &obj); err != nil { 640 return shared.NewDecodeParamError(err.Error()) 641 } 642 643 if len(obj) < 2 { 644 return shared.NewInsufficientParamsError(len(obj), 2) 645 } 646 647 if err := blockHeight(obj[0], &args.BlockNumber); err != nil { 648 return err 649 } 650 651 args.IncludeTxs = obj[1].(bool) 652 653 return nil 654 } 655 656 type BlockFilterArgs struct { 657 Earliest int64 658 Latest int64 659 Address []string 660 Topics [][]string 661 Skip int 662 Max int 663 } 664 665 func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) { 666 var obj []struct { 667 FromBlock interface{} `json:"fromBlock"` 668 ToBlock interface{} `json:"toBlock"` 669 Limit interface{} `json:"limit"` 670 Offset interface{} `json:"offset"` 671 Address interface{} `json:"address"` 672 Topics interface{} `json:"topics"` 673 } 674 675 if err = json.Unmarshal(b, &obj); err != nil { 676 return shared.NewDecodeParamError(err.Error()) 677 } 678 679 if len(obj) < 1 { 680 return shared.NewInsufficientParamsError(len(obj), 1) 681 } 682 683 // args.Earliest, err = toNumber(obj[0].ToBlock) 684 // if err != nil { 685 // return shared.NewDecodeParamError(fmt.Sprintf("FromBlock %v", err)) 686 // } 687 // args.Latest, err = toNumber(obj[0].FromBlock) 688 // if err != nil { 689 // return shared.NewDecodeParamError(fmt.Sprintf("ToBlock %v", err)) 690 691 var num int64 692 var numBig *big.Int 693 694 // if blank then latest 695 if obj[0].FromBlock == nil { 696 num = -1 697 } else { 698 if err := blockHeight(obj[0].FromBlock, &num); err != nil { 699 return err 700 } 701 } 702 // if -2 or other "silly" number, use latest 703 if num < 0 { 704 args.Earliest = -1 //latest block 705 } else { 706 args.Earliest = num 707 } 708 709 // if blank than latest 710 if obj[0].ToBlock == nil { 711 num = -1 712 } else { 713 if err := blockHeight(obj[0].ToBlock, &num); err != nil { 714 return err 715 } 716 } 717 args.Latest = num 718 719 if obj[0].Limit == nil { 720 numBig = big.NewInt(defaultLogLimit) 721 } else { 722 if numBig, err = numString(obj[0].Limit); err != nil { 723 return err 724 } 725 } 726 args.Max = int(numBig.Int64()) 727 728 if obj[0].Offset == nil { 729 numBig = big.NewInt(defaultLogOffset) 730 } else { 731 if numBig, err = numString(obj[0].Offset); err != nil { 732 return err 733 } 734 } 735 args.Skip = int(numBig.Int64()) 736 737 if obj[0].Address != nil { 738 marg, ok := obj[0].Address.([]interface{}) 739 if ok { 740 v := make([]string, len(marg)) 741 for i, arg := range marg { 742 argstr, ok := arg.(string) 743 if !ok { 744 return shared.NewInvalidTypeError(fmt.Sprintf("address[%d]", i), "is not a string") 745 } 746 v[i] = argstr 747 } 748 args.Address = v 749 } else { 750 argstr, ok := obj[0].Address.(string) 751 if ok { 752 v := make([]string, 1) 753 v[0] = argstr 754 args.Address = v 755 } else { 756 return shared.NewInvalidTypeError("address", "is not a string or array") 757 } 758 } 759 } 760 761 if obj[0].Topics != nil { 762 other, ok := obj[0].Topics.([]interface{}) 763 if ok { 764 topicdbl := make([][]string, len(other)) 765 for i, iv := range other { 766 if argstr, ok := iv.(string); ok { 767 // Found a string, push into first element of array 768 topicsgl := make([]string, 1) 769 topicsgl[0] = argstr 770 topicdbl[i] = topicsgl 771 } else if argarray, ok := iv.([]interface{}); ok { 772 // Found an array of other 773 topicdbl[i] = make([]string, len(argarray)) 774 for j, jv := range argarray { 775 if v, ok := jv.(string); ok { 776 topicdbl[i][j] = v 777 } else if jv == nil { 778 topicdbl[i][j] = "" 779 } else { 780 return shared.NewInvalidTypeError(fmt.Sprintf("topic[%d][%d]", i, j), "is not a string") 781 } 782 } 783 } else if iv == nil { 784 topicdbl[i] = []string{""} 785 } else { 786 return shared.NewInvalidTypeError(fmt.Sprintf("topic[%d]", i), "not a string or array") 787 } 788 } 789 args.Topics = topicdbl 790 return nil 791 } else { 792 return shared.NewInvalidTypeError("topic", "is not a string or array") 793 } 794 } 795 796 return nil 797 } 798 799 type FilterIdArgs struct { 800 Id int 801 } 802 803 func (args *FilterIdArgs) UnmarshalJSON(b []byte) (err error) { 804 var obj []interface{} 805 if err := json.Unmarshal(b, &obj); err != nil { 806 return shared.NewDecodeParamError(err.Error()) 807 } 808 809 if len(obj) < 1 { 810 return shared.NewInsufficientParamsError(len(obj), 1) 811 } 812 813 var num *big.Int 814 if num, err = numString(obj[0]); err != nil { 815 return err 816 } 817 args.Id = int(num.Int64()) 818 819 return nil 820 } 821 822 type LogRes struct { 823 Address *hexdata `json:"address"` 824 Topics []*hexdata `json:"topics"` 825 Data *hexdata `json:"data"` 826 BlockNumber *hexnum `json:"blockNumber"` 827 LogIndex *hexnum `json:"logIndex"` 828 BlockHash *hexdata `json:"blockHash"` 829 TransactionHash *hexdata `json:"transactionHash"` 830 TransactionIndex *hexnum `json:"transactionIndex"` 831 } 832 833 func NewLogRes(log *state.Log) LogRes { 834 var l LogRes 835 l.Topics = make([]*hexdata, len(log.Topics)) 836 for j, topic := range log.Topics { 837 l.Topics[j] = newHexData(topic) 838 } 839 l.Address = newHexData(log.Address) 840 l.Data = newHexData(log.Data) 841 l.BlockNumber = newHexNum(log.Number) 842 l.LogIndex = newHexNum(log.Index) 843 l.TransactionHash = newHexData(log.TxHash) 844 l.TransactionIndex = newHexNum(log.TxIndex) 845 l.BlockHash = newHexData(log.BlockHash) 846 847 return l 848 } 849 850 func NewLogsRes(logs state.Logs) (ls []LogRes) { 851 ls = make([]LogRes, len(logs)) 852 853 for i, log := range logs { 854 ls[i] = NewLogRes(log) 855 } 856 857 return 858 } 859 860 func NewHashesRes(hs []common.Hash) []string { 861 hashes := make([]string, len(hs)) 862 863 for i, hash := range hs { 864 hashes[i] = hash.Hex() 865 } 866 867 return hashes 868 } 869 870 type SubmitWorkArgs struct { 871 Nonce uint64 872 Header string 873 Digest string 874 } 875 876 func (args *SubmitWorkArgs) UnmarshalJSON(b []byte) (err error) { 877 var obj []interface{} 878 if err = json.Unmarshal(b, &obj); err != nil { 879 return shared.NewDecodeParamError(err.Error()) 880 } 881 882 if len(obj) < 3 { 883 return shared.NewInsufficientParamsError(len(obj), 3) 884 } 885 886 var objstr string 887 var ok bool 888 if objstr, ok = obj[0].(string); !ok { 889 return shared.NewInvalidTypeError("nonce", "not a string") 890 } 891 892 args.Nonce = common.String2Big(objstr).Uint64() 893 if objstr, ok = obj[1].(string); !ok { 894 return shared.NewInvalidTypeError("header", "not a string") 895 } 896 897 args.Header = objstr 898 899 if objstr, ok = obj[2].(string); !ok { 900 return shared.NewInvalidTypeError("digest", "not a string") 901 } 902 903 args.Digest = objstr 904 905 return nil 906 } 907 908 type tx struct { 909 tx *types.Transaction 910 911 To string `json:"to"` 912 From string `json:"from"` 913 Nonce string `json:"nonce"` 914 Value string `json:"value"` 915 Data string `json:"data"` 916 GasLimit string `json:"gas"` 917 GasPrice string `json:"gasPrice"` 918 Hash string `json:"hash"` 919 } 920 921 func newTx(t *types.Transaction) *tx { 922 from, _ := t.From() 923 var to string 924 if t := t.To(); t != nil { 925 to = t.Hex() 926 } 927 928 return &tx{ 929 tx: t, 930 To: to, 931 From: from.Hex(), 932 Value: t.Value().String(), 933 Nonce: strconv.Itoa(int(t.Nonce())), 934 Data: "0x" + common.Bytes2Hex(t.Data()), 935 GasLimit: t.Gas().String(), 936 GasPrice: t.GasPrice().String(), 937 Hash: t.Hash().Hex(), 938 } 939 } 940 941 type ResendArgs struct { 942 Tx *tx 943 GasPrice string 944 GasLimit string 945 } 946 947 func (tx *tx) UnmarshalJSON(b []byte) (err error) { 948 var fields map[string]interface{} 949 if err := json.Unmarshal(b, &fields); err != nil { 950 return shared.NewDecodeParamError(err.Error()) 951 } 952 953 var ( 954 nonce uint64 955 to common.Address 956 amount = new(big.Int).Set(common.Big0) 957 gasLimit = new(big.Int).Set(common.Big0) 958 gasPrice = new(big.Int).Set(common.Big0) 959 data []byte 960 contractCreation = true 961 ) 962 963 if val, found := fields["Hash"]; found { 964 if hashVal, ok := val.(string); ok { 965 tx.Hash = hashVal 966 } 967 } 968 969 if val, found := fields["To"]; found { 970 if strVal, ok := val.(string); ok && len(strVal) > 0 { 971 tx.To = strVal 972 to = common.HexToAddress(strVal) 973 contractCreation = false 974 } 975 } 976 977 if val, found := fields["From"]; found { 978 if strVal, ok := val.(string); ok { 979 tx.From = strVal 980 } 981 } 982 983 if val, found := fields["Nonce"]; found { 984 if strVal, ok := val.(string); ok { 985 tx.Nonce = strVal 986 if nonce, err = strconv.ParseUint(strVal, 10, 64); err != nil { 987 return shared.NewDecodeParamError(fmt.Sprintf("Unable to decode tx.Nonce - %v", err)) 988 } 989 } 990 } else { 991 return shared.NewDecodeParamError("tx.Nonce not found") 992 } 993 994 var parseOk bool 995 if val, found := fields["Value"]; found { 996 if strVal, ok := val.(string); ok { 997 tx.Value = strVal 998 if _, parseOk = amount.SetString(strVal, 0); !parseOk { 999 return shared.NewDecodeParamError(fmt.Sprintf("Unable to decode tx.Amount - %v", err)) 1000 } 1001 } 1002 } 1003 1004 if val, found := fields["Data"]; found { 1005 if strVal, ok := val.(string); ok { 1006 tx.Data = strVal 1007 if strings.HasPrefix(strVal, "0x") { 1008 data = common.Hex2Bytes(strVal[2:]) 1009 } else { 1010 data = common.Hex2Bytes(strVal) 1011 } 1012 } 1013 } 1014 1015 if val, found := fields["GasLimit"]; found { 1016 if strVal, ok := val.(string); ok { 1017 tx.GasLimit = strVal 1018 if _, parseOk = gasLimit.SetString(strVal, 0); !parseOk { 1019 return shared.NewDecodeParamError(fmt.Sprintf("Unable to decode tx.GasLimit - %v", err)) 1020 } 1021 } 1022 } 1023 1024 if val, found := fields["GasPrice"]; found { 1025 if strVal, ok := val.(string); ok { 1026 tx.GasPrice = strVal 1027 if _, parseOk = gasPrice.SetString(strVal, 0); !parseOk { 1028 return shared.NewDecodeParamError(fmt.Sprintf("Unable to decode tx.GasPrice - %v", err)) 1029 } 1030 } 1031 } 1032 1033 if contractCreation { 1034 tx.tx = types.NewContractCreation(nonce, amount, gasLimit, gasPrice, data) 1035 } else { 1036 tx.tx = types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, data) 1037 } 1038 1039 return nil 1040 } 1041 1042 func (args *ResendArgs) UnmarshalJSON(b []byte) (err error) { 1043 var obj []interface{} 1044 if err = json.Unmarshal(b, &obj); err != nil { 1045 return shared.NewDecodeParamError(err.Error()) 1046 } 1047 1048 if len(obj) < 1 { 1049 return shared.NewInsufficientParamsError(len(obj), 1) 1050 } 1051 1052 data, err := json.Marshal(obj[0]) 1053 if err != nil { 1054 return shared.NewDecodeParamError("Unable to parse transaction object") 1055 } 1056 1057 trans := new(tx) 1058 err = json.Unmarshal(data, trans) 1059 if err != nil { 1060 return shared.NewDecodeParamError("Unable to parse transaction object") 1061 } 1062 1063 if trans == nil || trans.tx == nil { 1064 return shared.NewDecodeParamError("Unable to parse transaction object") 1065 } 1066 1067 gasLimit, gasPrice := trans.GasLimit, trans.GasPrice 1068 1069 if len(obj) > 1 && obj[1] != nil { 1070 if gp, ok := obj[1].(string); ok { 1071 gasPrice = gp 1072 } else { 1073 return shared.NewInvalidTypeError("gasPrice", "not a string") 1074 } 1075 } 1076 if len(obj) > 2 && obj[2] != nil { 1077 if gl, ok := obj[2].(string); ok { 1078 gasLimit = gl 1079 } else { 1080 return shared.NewInvalidTypeError("gasLimit", "not a string") 1081 } 1082 } 1083 1084 args.Tx = trans 1085 args.GasPrice = gasPrice 1086 args.GasLimit = gasLimit 1087 1088 return nil 1089 }