github.com/0chain/gosdk@v1.17.11/znft/ethereum_wallet.go (about)

     1  package znft
     2  
     3  import (
     4  	"context"
     5  	"math/big"
     6  	"path"
     7  	"time"
     8  
     9  	"github.com/ethereum/go-ethereum/accounts"
    10  	"github.com/ethereum/go-ethereum/accounts/abi/bind"
    11  	"github.com/ethereum/go-ethereum/accounts/keystore"
    12  	"github.com/ethereum/go-ethereum/common"
    13  	"github.com/ethereum/go-ethereum/ethclient"
    14  	"github.com/ethereum/go-ethereum/params"
    15  	"github.com/pkg/errors"
    16  )
    17  
    18  func CreateEthClient(ethereumNodeURL string) (*ethclient.Client, error) {
    19  	client, err := ethclient.Dial(ethereumNodeURL)
    20  	if err != nil {
    21  		Logger.Error(err)
    22  		return nil, err
    23  	}
    24  	return client, err
    25  }
    26  
    27  func (app *Znft) createSignedTransactionFromKeyStore(ctx context.Context) (*bind.TransactOpts, error) {
    28  	var (
    29  		signerAddress = common.HexToAddress(app.cfg.WalletAddress)
    30  		password      = app.cfg.VaultPassword
    31  		value         = app.cfg.Value
    32  	)
    33  
    34  	client, err := CreateEthClient(app.cfg.EthereumNodeURL)
    35  	if err != nil {
    36  		err := errors.Wrap(err, "failed to create ethereum client")
    37  		Logger.Fatal(err)
    38  		return nil, err
    39  	}
    40  
    41  	keyDir := path.Join(app.cfg.Homedir, WalletDir)
    42  	ks := keystore.NewKeyStore(keyDir, keystore.StandardScryptN, keystore.StandardScryptP)
    43  	signer := accounts.Account{
    44  		Address: signerAddress,
    45  	}
    46  	signerAcc, err := ks.Find(signer)
    47  	if err != nil {
    48  		err := errors.Wrapf(err, "signer: %s", signerAddress.Hex())
    49  		Logger.Fatal(err)
    50  		return nil, err
    51  	}
    52  
    53  	chainID, err := client.ChainID(ctx)
    54  	if err != nil {
    55  		err := errors.Wrap(err, "failed to get chain ID")
    56  		Logger.Fatal(err)
    57  		return nil, err
    58  	}
    59  
    60  	err = ks.TimedUnlock(signer, password, time.Second*2)
    61  	if err != nil {
    62  		Logger.Fatal(err)
    63  		return nil, err
    64  	}
    65  
    66  	opts, err := bind.NewKeyStoreTransactorWithChainID(ks, signerAcc, chainID)
    67  	if err != nil {
    68  		Logger.Fatal(err)
    69  		return nil, err
    70  	}
    71  
    72  	valueWei := new(big.Int).Mul(big.NewInt(value), big.NewInt(params.Wei))
    73  
    74  	opts.Value = valueWei // in wei (= no funds)
    75  
    76  	return opts, nil
    77  }
    78  
    79  func (app *Znft) createSignedTransactionFromKeyStoreWithGasPrice(ctx context.Context, gasLimitUnits uint64) (*bind.TransactOpts, error) { //nolint
    80  	client, err := CreateEthClient(app.cfg.EthereumNodeURL)
    81  	if err != nil {
    82  		err := errors.Wrap(err, "failed to create ethereum client")
    83  		Logger.Fatal(err)
    84  		return nil, err
    85  	}
    86  
    87  	nonce, err := client.PendingNonceAt(ctx, common.HexToAddress(app.cfg.WalletAddress))
    88  	if err != nil {
    89  		Logger.Fatal(err)
    90  		return nil, err
    91  	}
    92  
    93  	gasPriceWei, err := client.SuggestGasPrice(ctx)
    94  	if err != nil {
    95  		Logger.Fatal(err)
    96  		return nil, err
    97  	}
    98  
    99  	opts, err := app.createSignedTransactionFromKeyStore(ctx)
   100  	if err != nil {
   101  		Logger.Fatal(err)
   102  		return nil, err
   103  	}
   104  
   105  	opts.Nonce = big.NewInt(int64(nonce)) // (nil = use pending state), look at bind.CallOpts{Pending: true}
   106  	opts.GasLimit = gasLimitUnits         // in units  (0 = estimate)
   107  	opts.GasPrice = gasPriceWei           // wei (nil = gas price oracle)
   108  
   109  	return opts, nil
   110  }