github.com/baptiste-b-pegasys/quorum/v22@v22.4.2/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 "crypto/ecdsa" 21 "errors" 22 "io" 23 "io/ioutil" 24 "math/big" 25 "reflect" 26 27 "github.com/ethereum/go-ethereum/accounts" 28 "github.com/ethereum/go-ethereum/accounts/external" 29 "github.com/ethereum/go-ethereum/accounts/keystore" 30 "github.com/ethereum/go-ethereum/common" 31 "github.com/ethereum/go-ethereum/core/types" 32 "github.com/ethereum/go-ethereum/crypto" 33 "github.com/ethereum/go-ethereum/log" 34 ) 35 36 // ErrNoChainID is returned whenever the user failed to specify a chain id. 37 var ErrNoChainID = errors.New("no chain id specified") 38 39 // ErrNotAuthorized is returned when an account is not properly unlocked. 40 var ErrNotAuthorized = errors.New("not authorized to sign this account") 41 42 // NewTransactor is a utility method to easily create a transaction signer from 43 // an encrypted json key stream and the associated passphrase. 44 // 45 // Deprecated: Use NewTransactorWithChainID instead. 46 func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) { 47 log.Warn("WARNING: NewTransactor has been deprecated in favour of NewTransactorWithChainID") 48 json, err := ioutil.ReadAll(keyin) 49 if err != nil { 50 return nil, err 51 } 52 key, err := keystore.DecryptKey(json, passphrase) 53 if err != nil { 54 return nil, err 55 } 56 return NewKeyedTransactor(key.PrivateKey), nil 57 } 58 59 // NewKeyStoreTransactor is a utility method to easily create a transaction signer from 60 // an decrypted key from a keystore. 61 // 62 // Deprecated: Use NewKeyStoreTransactorWithChainID instead. 63 func NewKeyStoreTransactor(keystore *keystore.KeyStore, account accounts.Account) (*TransactOpts, error) { 64 log.Warn("WARNING: NewKeyStoreTransactor has been deprecated in favour of NewTransactorWithChainID") 65 var homesteadSigner types.Signer = types.HomesteadSigner{} 66 return &TransactOpts{ 67 From: account.Address, 68 Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { 69 if address != account.Address { 70 return nil, ErrNotAuthorized 71 } 72 // Quorum 73 signer := homesteadSigner 74 if tx.IsPrivate() { 75 signer = types.QuorumPrivateTxSigner{} 76 } 77 // / Quorum 78 signature, err := keystore.SignHash(account, signer.Hash(tx).Bytes()) 79 if err != nil { 80 return nil, err 81 } 82 return tx.WithSignature(signer, signature) 83 }, 84 }, nil 85 } 86 87 // NewKeyedTransactor is a utility method to easily create a transaction signer 88 // from a single private key. 89 // 90 // Deprecated: Use NewKeyedTransactorWithChainID instead. 91 func NewKeyedTransactor(key *ecdsa.PrivateKey) *TransactOpts { 92 log.Warn("WARNING: NewKeyedTransactor has been deprecated in favour of NewKeyedTransactorWithChainID") 93 keyAddr := crypto.PubkeyToAddress(key.PublicKey) 94 var homesteadSigner types.Signer = types.HomesteadSigner{} 95 return &TransactOpts{ 96 From: keyAddr, 97 Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { 98 if address != keyAddr { 99 return nil, ErrNotAuthorized 100 } 101 // Quorum 102 signer := homesteadSigner 103 if tx.IsPrivate() { 104 signer = types.QuorumPrivateTxSigner{} 105 } 106 // / Quorum 107 signature, err := crypto.Sign(signer.Hash(tx).Bytes(), key) 108 if err != nil { 109 return nil, err 110 } 111 return tx.WithSignature(signer, signature) 112 }, 113 } 114 } 115 116 // NewTransactorWithChainID is a utility method to easily create a transaction signer from 117 // an encrypted json key stream and the associated passphrase. 118 func NewTransactorWithChainID(keyin io.Reader, passphrase string, chainID *big.Int) (*TransactOpts, error) { 119 json, err := ioutil.ReadAll(keyin) 120 if err != nil { 121 return nil, err 122 } 123 key, err := keystore.DecryptKey(json, passphrase) 124 if err != nil { 125 return nil, err 126 } 127 return NewKeyedTransactorWithChainID(key.PrivateKey, chainID) 128 } 129 130 // NewKeyStoreTransactorWithChainID is a utility method to easily create a transaction signer from 131 // an decrypted key from a keystore. 132 func NewKeyStoreTransactorWithChainID(keystore *keystore.KeyStore, account accounts.Account, chainID *big.Int) (*TransactOpts, error) { 133 if chainID == nil { 134 return nil, ErrNoChainID 135 } 136 latestSigner := types.LatestSignerForChainID(chainID) 137 log.Info("NewKeyStoreTransactorWithChainID", "latestSigner", reflect.TypeOf(latestSigner)) 138 return &TransactOpts{ 139 From: account.Address, 140 Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { 141 if address != account.Address { 142 return nil, ErrNotAuthorized 143 } 144 // Quorum 145 signer := latestSigner 146 if tx.IsPrivate() { 147 signer = types.QuorumPrivateTxSigner{} 148 } 149 // / Quorum 150 signature, err := keystore.SignHash(account, signer.Hash(tx).Bytes()) 151 if err != nil { 152 return nil, err 153 } 154 return tx.WithSignature(signer, signature) 155 }, 156 }, nil 157 } 158 159 // NewKeyedTransactorWithChainID is a utility method to easily create a transaction signer 160 // from a single private key. 161 func NewKeyedTransactorWithChainID(key *ecdsa.PrivateKey, chainID *big.Int) (*TransactOpts, error) { 162 keyAddr := crypto.PubkeyToAddress(key.PublicKey) 163 if chainID == nil { 164 return nil, ErrNoChainID 165 } 166 latestSigner := types.LatestSignerForChainID(chainID) 167 return &TransactOpts{ 168 From: keyAddr, 169 Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { 170 if address != keyAddr { 171 return nil, ErrNotAuthorized 172 } 173 // Quorum 174 signer := latestSigner 175 if tx.IsPrivate() { 176 signer = types.QuorumPrivateTxSigner{} 177 } 178 // / Quorum 179 signature, err := crypto.Sign(signer.Hash(tx).Bytes(), key) 180 if err != nil { 181 return nil, err 182 } 183 return tx.WithSignature(signer, signature) 184 }, 185 }, nil 186 } 187 188 // NewClefTransactor is a utility method to easily create a transaction signer 189 // with a clef backend. 190 func NewClefTransactor(clef *external.ExternalSigner, account accounts.Account) *TransactOpts { 191 return &TransactOpts{ 192 From: account.Address, 193 Signer: func(address common.Address, transaction *types.Transaction) (*types.Transaction, error) { 194 if address != account.Address { 195 return nil, ErrNotAuthorized 196 } 197 log.Info("Signing with NewClefTransactor") 198 return clef.SignTx(account, transaction, transaction.ChainId()) // Clef enforces its own chain id 199 }, 200 } 201 } 202 203 // Quorum 204 // 205 // NewWalletTransactor is a utility method to easily create a transaction signer 206 // from a wallet account 207 func NewWalletTransactor(w accounts.Wallet, account accounts.Account, chainId *big.Int) *TransactOpts { 208 return &TransactOpts{ 209 From: account.Address, 210 Signer: func(address common.Address, transaction *types.Transaction) (*types.Transaction, error) { 211 if address != account.Address { 212 return nil, errors.New("not authorized to sign this account") 213 } 214 if transaction.ChainId() == nil { 215 chainId = transaction.ChainId() 216 } 217 218 return w.SignTx(account, transaction, chainId) 219 }, 220 } 221 }