github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/internal/ethapi/api_main.go (about) 1 // Copyright 2015 The go-simplechain Authors 2 // This file is part of the go-simplechain library. 3 // 4 // The go-simplechain 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-simplechain 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-simplechain library. If not, see <http://www.gnu.org/licenses/>. 16 //go:build !sub 17 // +build !sub 18 19 package ethapi 20 21 import ( 22 "bytes" 23 "context" 24 "errors" 25 "github.com/bigzoro/my_simplechain/crypto" 26 "math/big" 27 28 "github.com/bigzoro/my_simplechain/common" 29 "github.com/bigzoro/my_simplechain/common/hexutil" 30 "github.com/bigzoro/my_simplechain/core/types" 31 "github.com/bigzoro/my_simplechain/log" 32 "github.com/bigzoro/my_simplechain/rpc" 33 ) 34 35 // SendTxArgs represents the arguments to sumbit a new transaction into the transaction pool. 36 type SendTxArgs struct { 37 From common.Address `json:"from"` 38 To *common.Address `json:"to"` 39 Gas *hexutil.Uint64 `json:"gas"` 40 GasPrice *hexutil.Big `json:"gasPrice"` 41 Value *hexutil.Big `json:"value"` 42 Nonce *hexutil.Uint64 `json:"nonce"` 43 // We accept "data" and "input" for backwards-compatibility reasons. "input" is the 44 // newer name and should be preferred by clients. 45 Data *hexutil.Bytes `json:"data"` 46 Input *hexutil.Bytes `json:"input"` 47 48 Endorsements []byte `json:"endorsements"` 49 } 50 51 // setDefaults is a helper function that fills in default values for unspecified tx fields. 52 func (args *SendTxArgs) setDefaults(ctx context.Context, b Backend) error { 53 if args.GasPrice == nil { 54 price, err := b.SuggestPrice(ctx) 55 if err != nil { 56 return err 57 } 58 args.GasPrice = (*hexutil.Big)(price) 59 } 60 if args.Value == nil { 61 args.Value = new(hexutil.Big) 62 } 63 if args.Nonce == nil { 64 nonce, err := b.GetPoolNonce(ctx, args.From) 65 if err != nil { 66 return err 67 } 68 args.Nonce = (*hexutil.Uint64)(&nonce) 69 } 70 if args.Data != nil && args.Input != nil && !bytes.Equal(*args.Data, *args.Input) { 71 return errors.New(`both "data" and "input" are set and not equal. Please use "input" to pass transaction call data`) 72 } 73 if args.To == nil { 74 // Contract creation 75 var input []byte 76 if args.Data != nil { 77 input = *args.Data 78 } else if args.Input != nil { 79 input = *args.Input 80 } 81 if len(input) == 0 { 82 return errors.New(`contract creation without any data provided`) 83 } 84 } 85 // Estimate the gas usage if necessary. 86 if args.Gas == nil { 87 // For backwards-compatibility reason, we try both input and data 88 // but input is preferred. 89 input := args.Input 90 if input == nil { 91 input = args.Data 92 } 93 callArgs := CallArgs{ 94 From: &args.From, // From shouldn't be nil 95 To: args.To, 96 GasPrice: args.GasPrice, 97 Value: args.Value, 98 Data: input, 99 } 100 pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) 101 estimated, err := DoEstimateGas(ctx, b, callArgs, pendingBlockNr, b.RPCGasCap()) 102 if err != nil { 103 return err 104 } 105 args.Gas = &estimated 106 log.Trace("Estimate gas usage automatically", "gas", args.Gas) 107 } 108 return nil 109 } 110 111 // SubmitTransaction is a helper function that submits tx to txPool and logs a message. 112 func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (common.Hash, error) { 113 if err := b.SendTx(ctx, tx); err != nil { 114 return common.Hash{}, err 115 } 116 if tx.To() == nil { 117 signer := types.MakeSigner(b.ChainConfig()) 118 from, err := types.Sender(signer, tx) 119 if err != nil { 120 return common.Hash{}, err 121 } 122 addr := crypto.CreateAddress(from, tx.Nonce()) 123 log.Info("Submitted contract creation", "fullHash", tx.Hash().Hex(), "contract", addr.Hex()) 124 } else { 125 log.Info("Submitted transaction", "fullHash", tx.Hash().Hex(), "recipient", tx.To()) 126 } 127 return tx.Hash(), nil 128 } 129 130 func (args *SendTxArgs) toTransaction() *types.Transaction { 131 var input []byte 132 if args.Input != nil { 133 input = *args.Input 134 } else if args.Data != nil { 135 input = *args.Data 136 } 137 if args.To == nil { 138 return types.NewContractCreation(uint64(*args.Nonce), (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input) 139 } 140 return types.NewTransaction(uint64(*args.Nonce), *args.To, (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input, args.Endorsements) 141 }