github.com/ChainSafe/chainbridge-core@v1.4.2/chains/evm/calls/transactor/signAndSend/signAndSend.go (about)

     1  package signAndSend
     2  
     3  import (
     4  	"context"
     5  	"math/big"
     6  
     7  	"github.com/ChainSafe/chainbridge-core/chains/evm/calls"
     8  	"github.com/ChainSafe/chainbridge-core/chains/evm/calls/transactor"
     9  	"github.com/ethereum/go-ethereum/common"
    10  	"github.com/rs/zerolog/log"
    11  )
    12  
    13  type signAndSendTransactor struct {
    14  	TxFabric       calls.TxFabric
    15  	gasPriceClient calls.GasPricer
    16  	client         calls.ClientDispatcher
    17  }
    18  
    19  func NewSignAndSendTransactor(txFabric calls.TxFabric, gasPriceClient calls.GasPricer, client calls.ClientDispatcher) transactor.Transactor {
    20  	return &signAndSendTransactor{
    21  		TxFabric:       txFabric,
    22  		gasPriceClient: gasPriceClient,
    23  		client:         client,
    24  	}
    25  }
    26  
    27  func (t *signAndSendTransactor) Transact(to *common.Address, data []byte, opts transactor.TransactOptions) (*common.Hash, error) {
    28  	t.client.LockNonce()
    29  	n, err := t.client.UnsafeNonce()
    30  	if err != nil {
    31  		t.client.UnlockNonce()
    32  		return &common.Hash{}, err
    33  	}
    34  
    35  	err = transactor.MergeTransactionOptions(&opts, &transactor.DefaultTransactionOptions)
    36  	if err != nil {
    37  		t.client.UnlockNonce()
    38  		return &common.Hash{}, err
    39  	}
    40  
    41  	gp := []*big.Int{opts.GasPrice}
    42  	if opts.GasPrice.Cmp(big.NewInt(0)) == 0 {
    43  		gp, err = t.gasPriceClient.GasPrice(&opts.Priority)
    44  		if err != nil {
    45  			t.client.UnlockNonce()
    46  			return &common.Hash{}, err
    47  		}
    48  	}
    49  
    50  	tx, err := t.TxFabric(n.Uint64(), to, opts.Value, opts.GasLimit, gp, data)
    51  	if err != nil {
    52  		t.client.UnlockNonce()
    53  		return &common.Hash{}, err
    54  	}
    55  
    56  	h, err := t.client.SignAndSendTransaction(context.TODO(), tx)
    57  	if err != nil {
    58  		t.client.UnlockNonce()
    59  		log.Error().Err(err)
    60  		return &common.Hash{}, err
    61  	}
    62  
    63  	err = t.client.UnsafeIncreaseNonce()
    64  	t.client.UnlockNonce()
    65  	if err != nil {
    66  		return &common.Hash{}, err
    67  	}
    68  
    69  	_, err = t.client.WaitAndReturnTxReceipt(h)
    70  	if err != nil {
    71  		return &common.Hash{}, err
    72  	}
    73  
    74  	return &h, nil
    75  }