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  }