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

     1  package calls
     2  
     3  import (
     4  	"context"
     5  	"encoding/hex"
     6  	"math/big"
     7  
     8  	"github.com/ChainSafe/chainbridge-core/chains/evm/calls/evmclient"
     9  	"github.com/ethereum/go-ethereum"
    10  	"github.com/ethereum/go-ethereum/common"
    11  	"github.com/ethereum/go-ethereum/core/types"
    12  	"github.com/rs/zerolog/log"
    13  )
    14  
    15  type TxFabric func(nonce uint64, to *common.Address, amount *big.Int, gasLimit uint64, gasPrices []*big.Int, data []byte) (evmclient.CommonTransaction, error)
    16  
    17  type ContractChecker interface {
    18  	CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error)
    19  }
    20  
    21  type ContractCaller interface {
    22  	CallContract(ctx context.Context, callArgs map[string]interface{}, blockNumber *big.Int) ([]byte, error)
    23  }
    24  
    25  type GasPricer interface {
    26  	// make priority a pointer to uint8 to pass nil into all GasPrice functions (instead of magic numbers)
    27  	GasPrice(priority *uint8) ([]*big.Int, error)
    28  }
    29  
    30  type ClientDispatcher interface {
    31  	WaitAndReturnTxReceipt(h common.Hash) (*types.Receipt, error)
    32  	SignAndSendTransaction(ctx context.Context, tx evmclient.CommonTransaction) (common.Hash, error)
    33  	TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)
    34  	GetTransactionByHash(h common.Hash) (tx *types.Transaction, isPending bool, err error)
    35  	UnsafeNonce() (*big.Int, error)
    36  	LockNonce()
    37  	UnlockNonce()
    38  	UnsafeIncreaseNonce() error
    39  	From() common.Address
    40  }
    41  
    42  type ContractCallerDispatcher interface {
    43  	ContractCaller
    44  	ClientDispatcher
    45  	ContractChecker
    46  }
    47  
    48  type SimulateCaller interface {
    49  	ContractCaller
    50  	TransactionByHash(ctx context.Context, hash common.Hash) (tx *types.Transaction, isPending bool, err error)
    51  }
    52  
    53  // Simulate function gets transaction info by hash and then executes a message call transaction, which is directly executed in the VM
    54  // of the node, but never mined into the blockchain. Execution happens against provided block.
    55  func Simulate(c SimulateCaller, block *big.Int, txHash common.Hash, from common.Address) ([]byte, error) {
    56  	tx, _, err := c.TransactionByHash(context.TODO(), txHash)
    57  	if err != nil {
    58  		log.Debug().Msgf("[client] tx by hash error: %v", err)
    59  		return nil, err
    60  	}
    61  
    62  	log.Debug().Msgf("from: %v to: %v gas: %v gasPrice: %v value: %v data: %v", from, tx.To(), tx.Gas(), tx.GasPrice(), tx.Value(), tx.Data())
    63  
    64  	msg := ethereum.CallMsg{
    65  		From:     from,
    66  		To:       tx.To(),
    67  		Gas:      tx.Gas(),
    68  		GasPrice: tx.GasPrice(),
    69  		Value:    tx.Value(),
    70  		Data:     tx.Data(),
    71  	}
    72  	res, err := c.CallContract(context.TODO(), ToCallArg(msg), block)
    73  	if err != nil {
    74  		log.Debug().Msgf("[client] call contract error: %v", err)
    75  		return nil, err
    76  	}
    77  	bs, err := hex.DecodeString(common.Bytes2Hex(res))
    78  	if err != nil {
    79  		log.Debug().Msgf("[client] decode string error: %v", err)
    80  		return nil, err
    81  	}
    82  	log.Debug().Msg(string(bs))
    83  	return bs, nil
    84  }