package hmyapi import ( "bytes" "context" "errors" "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core/types" ) // SendTxArgs represents the arguments to sumbit a new transaction into the transaction pool. type SendTxArgs struct { From common.Address `json:"from"` To *common.Address `json:"to"` ShardID uint32 `json:"shardID` Gas *hexutil.Uint64 `json:"gas"` GasPrice *hexutil.Big `json:"gasPrice"` Value *hexutil.Big `json:"value"` Nonce *hexutil.Uint64 `json:"nonce"` // We accept "data" and "input" for backwards-compatibility reasons. "input" is the // newer name and should be preferred by clients. Data *hexutil.Bytes `json:"data"` Input *hexutil.Bytes `json:"input"` } // setDefaults is a helper function that fills in default values for unspecified tx fields. func (args *SendTxArgs) setDefaults(ctx context.Context, b *core.HmyAPIBackend) error { if args.Gas == nil { args.Gas = new(hexutil.Uint64) *(*uint64)(args.Gas) = 90000 } // TODO(ricl): add check for shardID if args.GasPrice == nil { // TODO(ricl): port // price, err := b.SuggestPrice(ctx) // if err != nil { // return err // } // args.GasPrice = (*hexutil.Big)(price) } if args.Value == nil { args.Value = new(hexutil.Big) } if args.Nonce == nil { nonce, err := b.GetPoolNonce(ctx, args.From) if err != nil { return err } args.Nonce = (*hexutil.Uint64)(&nonce) } if args.Data != nil && args.Input != nil && !bytes.Equal(*args.Data, *args.Input) { return errors.New(`both "data" and "input" are set and not equal. Please use "input" to pass transaction call data`) } if args.To == nil { // Contract creation var input []byte if args.Data != nil { input = *args.Data } else if args.Input != nil { input = *args.Input } if len(input) == 0 { return errors.New(`contract creation without any data provided`) } } return nil } func (args *SendTxArgs) toTransaction() *types.Transaction { var input []byte if args.Data != nil { input = *args.Data } else if args.Input != nil { input = *args.Input } if args.To == nil { return types.NewContractCreation(uint64(*args.Nonce), args.ShardID, (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input) } return types.NewTransaction(uint64(*args.Nonce), *args.To, args.ShardID, (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input) }