github.com/palisadeinc/bor@v0.0.0-20230615125219-ab7196213d15/accounts/abi/bind/auth.go (about)

     1  // Copyright 2016 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum 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-ethereum 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-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package bind
    18  
    19  import (
    20  	"context"
    21  	"crypto/ecdsa"
    22  	"errors"
    23  	"io"
    24  	"math/big"
    25  
    26  	"github.com/ethereum/go-ethereum/accounts"
    27  	"github.com/ethereum/go-ethereum/accounts/external"
    28  	"github.com/ethereum/go-ethereum/accounts/keystore"
    29  	"github.com/ethereum/go-ethereum/common"
    30  	"github.com/ethereum/go-ethereum/core/types"
    31  	"github.com/ethereum/go-ethereum/crypto"
    32  	"github.com/ethereum/go-ethereum/log"
    33  )
    34  
    35  // ErrNoChainID is returned whenever the user failed to specify a chain id.
    36  var ErrNoChainID = errors.New("no chain id specified")
    37  
    38  // ErrNotAuthorized is returned when an account is not properly unlocked.
    39  var ErrNotAuthorized = errors.New("not authorized to sign this account")
    40  
    41  // NewTransactor is a utility method to easily create a transaction signer from
    42  // an encrypted json key stream and the associated passphrase.
    43  //
    44  // Deprecated: Use NewTransactorWithChainID instead.
    45  func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) {
    46  	log.Warn("WARNING: NewTransactor has been deprecated in favour of NewTransactorWithChainID")
    47  
    48  	json, err := io.ReadAll(keyin)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	key, err := keystore.DecryptKey(json, passphrase)
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  
    58  	return NewKeyedTransactor(key.PrivateKey), nil
    59  }
    60  
    61  // NewKeyStoreTransactor is a utility method to easily create a transaction signer from
    62  // an decrypted key from a keystore.
    63  //
    64  // Deprecated: Use NewKeyStoreTransactorWithChainID instead.
    65  func NewKeyStoreTransactor(keystore *keystore.KeyStore, account accounts.Account) (*TransactOpts, error) {
    66  	log.Warn("WARNING: NewKeyStoreTransactor has been deprecated in favour of NewTransactorWithChainID")
    67  	signer := types.HomesteadSigner{}
    68  	return &TransactOpts{
    69  		From: account.Address,
    70  		Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) {
    71  			if address != account.Address {
    72  				return nil, ErrNotAuthorized
    73  			}
    74  			signature, err := keystore.SignHash(account, signer.Hash(tx).Bytes())
    75  			if err != nil {
    76  				return nil, err
    77  			}
    78  			return tx.WithSignature(signer, signature)
    79  		},
    80  		Context: context.Background(),
    81  	}, nil
    82  }
    83  
    84  // NewKeyedTransactor is a utility method to easily create a transaction signer
    85  // from a single private key.
    86  //
    87  // Deprecated: Use NewKeyedTransactorWithChainID instead.
    88  func NewKeyedTransactor(key *ecdsa.PrivateKey) *TransactOpts {
    89  	log.Warn("WARNING: NewKeyedTransactor has been deprecated in favour of NewKeyedTransactorWithChainID")
    90  	keyAddr := crypto.PubkeyToAddress(key.PublicKey)
    91  	signer := types.HomesteadSigner{}
    92  	return &TransactOpts{
    93  		From: keyAddr,
    94  		Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) {
    95  			if address != keyAddr {
    96  				return nil, ErrNotAuthorized
    97  			}
    98  			signature, err := crypto.Sign(signer.Hash(tx).Bytes(), key)
    99  			if err != nil {
   100  				return nil, err
   101  			}
   102  			return tx.WithSignature(signer, signature)
   103  		},
   104  		Context: context.Background(),
   105  	}
   106  }
   107  
   108  // NewTransactorWithChainID is a utility method to easily create a transaction signer from
   109  // an encrypted json key stream and the associated passphrase.
   110  func NewTransactorWithChainID(keyin io.Reader, passphrase string, chainID *big.Int) (*TransactOpts, error) {
   111  	json, err := io.ReadAll(keyin)
   112  	if err != nil {
   113  		return nil, err
   114  	}
   115  	key, err := keystore.DecryptKey(json, passphrase)
   116  	if err != nil {
   117  		return nil, err
   118  	}
   119  	return NewKeyedTransactorWithChainID(key.PrivateKey, chainID)
   120  }
   121  
   122  // NewKeyStoreTransactorWithChainID is a utility method to easily create a transaction signer from
   123  // an decrypted key from a keystore.
   124  func NewKeyStoreTransactorWithChainID(keystore *keystore.KeyStore, account accounts.Account, chainID *big.Int) (*TransactOpts, error) {
   125  	if chainID == nil {
   126  		return nil, ErrNoChainID
   127  	}
   128  	signer := types.LatestSignerForChainID(chainID)
   129  	return &TransactOpts{
   130  		From: account.Address,
   131  		Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) {
   132  			if address != account.Address {
   133  				return nil, ErrNotAuthorized
   134  			}
   135  			signature, err := keystore.SignHash(account, signer.Hash(tx).Bytes())
   136  			if err != nil {
   137  				return nil, err
   138  			}
   139  			return tx.WithSignature(signer, signature)
   140  		},
   141  		Context: context.Background(),
   142  	}, nil
   143  }
   144  
   145  // NewKeyedTransactorWithChainID is a utility method to easily create a transaction signer
   146  // from a single private key.
   147  func NewKeyedTransactorWithChainID(key *ecdsa.PrivateKey, chainID *big.Int) (*TransactOpts, error) {
   148  	keyAddr := crypto.PubkeyToAddress(key.PublicKey)
   149  	if chainID == nil {
   150  		return nil, ErrNoChainID
   151  	}
   152  	signer := types.LatestSignerForChainID(chainID)
   153  	return &TransactOpts{
   154  		From: keyAddr,
   155  		Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) {
   156  			if address != keyAddr {
   157  				return nil, ErrNotAuthorized
   158  			}
   159  			signature, err := crypto.Sign(signer.Hash(tx).Bytes(), key)
   160  			if err != nil {
   161  				return nil, err
   162  			}
   163  			return tx.WithSignature(signer, signature)
   164  		},
   165  		Context: context.Background(),
   166  	}, nil
   167  }
   168  
   169  // NewClefTransactor is a utility method to easily create a transaction signer
   170  // with a clef backend.
   171  func NewClefTransactor(clef *external.ExternalSigner, account accounts.Account) *TransactOpts {
   172  	return &TransactOpts{
   173  		From: account.Address,
   174  		Signer: func(address common.Address, transaction *types.Transaction) (*types.Transaction, error) {
   175  			if address != account.Address {
   176  				return nil, ErrNotAuthorized
   177  			}
   178  			return clef.SignTx(account, transaction, nil) // Clef enforces its own chain id
   179  		},
   180  		Context: context.Background(),
   181  	}
   182  }