github.com/ethw3/go-ethereuma@v0.0.0-20221013053120-c14602a4c23c/core/types/transaction_signing.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 types 18 19 import ( 20 "crypto/ecdsa" 21 "errors" 22 "fmt" 23 "math/big" 24 25 "github.com/ethw3/go-ethereuma/common" 26 "github.com/ethw3/go-ethereuma/crypto" 27 "github.com/ethw3/go-ethereuma/params" 28 ) 29 30 var ErrInvalidChainId = errors.New("invalid chain id for signer") 31 32 // sigCache is used to cache the derived sender and contains 33 // the signer used to derive it. 34 type sigCache struct { 35 signer Signer 36 from common.Address 37 } 38 39 // MakeSigner returns a Signer based on the given chain config and block number. 40 func MakeSigner(config *params.ChainConfig, blockNumber *big.Int) Signer { 41 var signer Signer 42 switch { 43 case config.IsEthPoWFork(blockNumber): 44 signer = NewLondonSigner(config.ChainID_ALT) 45 case config.IsLondon(blockNumber): 46 signer = NewLondonSigner(config.ChainID) 47 case config.IsBerlin(blockNumber): 48 signer = NewEIP2930Signer(config.ChainID) 49 case config.IsEIP155(blockNumber): 50 signer = NewEIP155Signer(config.ChainID) 51 case config.IsHomestead(blockNumber): 52 signer = HomesteadSigner{} 53 default: 54 signer = FrontierSigner{} 55 } 56 return signer 57 } 58 59 // LatestSigner returns the 'most permissive' Signer available for the given chain 60 // configuration. Specifically, this enables support of EIP-155 replay protection and 61 // EIP-2930 access list transactions when their respective forks are scheduled to occur at 62 // any block number in the chain config. 63 // 64 // Use this in transaction-handling code where the current block number is unknown. If you 65 // have the current block number available, use MakeSigner instead. 66 func LatestSigner(config *params.ChainConfig) Signer { 67 68 if config.ChainID != nil { 69 if config.EthPoWForkBlock != nil { 70 return NewLondonSigner(config.ChainID_ALT) 71 } 72 if config.LondonBlock != nil { 73 return NewLondonSigner(config.ChainID) 74 } 75 if config.BerlinBlock != nil { 76 return NewEIP2930Signer(config.ChainID) 77 } 78 if config.EIP155Block != nil { 79 return NewEIP155Signer(config.ChainID) 80 } 81 } 82 return HomesteadSigner{} 83 } 84 85 // LatestSignerForChainID returns the 'most permissive' Signer available. Specifically, 86 // this enables support for EIP-155 replay protection and all implemented EIP-2718 87 // transaction types if chainID is non-nil. 88 // 89 // Use this in transaction-handling code where the current block number and fork 90 // configuration are unknown. If you have a ChainConfig, use LatestSigner instead. 91 // If you have a ChainConfig and know the current block number, use MakeSigner instead. 92 func LatestSignerForChainID(chainID *big.Int) Signer { 93 if chainID == nil { 94 return HomesteadSigner{} 95 } 96 return NewLondonSigner(chainID) 97 } 98 99 // SignTx signs the transaction using the given signer and private key. 100 func SignTx(tx *Transaction, s Signer, prv *ecdsa.PrivateKey) (*Transaction, error) { 101 h := s.Hash(tx) 102 sig, err := crypto.Sign(h[:], prv) 103 if err != nil { 104 return nil, err 105 } 106 return tx.WithSignature(s, sig) 107 } 108 109 // SignNewTx creates a transaction and signs it. 110 func SignNewTx(prv *ecdsa.PrivateKey, s Signer, txdata TxData) (*Transaction, error) { 111 tx := NewTx(txdata) 112 h := s.Hash(tx) 113 sig, err := crypto.Sign(h[:], prv) 114 if err != nil { 115 return nil, err 116 } 117 return tx.WithSignature(s, sig) 118 } 119 120 // MustSignNewTx creates a transaction and signs it. 121 // This panics if the transaction cannot be signed. 122 func MustSignNewTx(prv *ecdsa.PrivateKey, s Signer, txdata TxData) *Transaction { 123 tx, err := SignNewTx(prv, s, txdata) 124 if err != nil { 125 panic(err) 126 } 127 return tx 128 } 129 130 // Sender returns the address derived from the signature (V, R, S) using secp256k1 131 // elliptic curve and an error if it failed deriving or upon an incorrect 132 // signature. 133 // 134 // Sender may cache the address, allowing it to be used regardless of 135 // signing method. The cache is invalidated if the cached signer does 136 // not match the signer used in the current call. 137 func Sender(signer Signer, tx *Transaction) (common.Address, error) { 138 if sc := tx.from.Load(); sc != nil { 139 sigCache := sc.(sigCache) 140 // If the signer used to derive from in a previous 141 // call is not the same as used current, invalidate 142 // the cache. 143 if sigCache.signer.Equal(signer) { 144 return sigCache.from, nil 145 } 146 } 147 148 addr, err := signer.Sender(tx) 149 if err != nil { 150 return common.Address{}, err 151 } 152 tx.from.Store(sigCache{signer: signer, from: addr}) 153 return addr, nil 154 } 155 156 // Signer encapsulates transaction signature handling. The name of this type is slightly 157 // misleading because Signers don't actually sign, they're just for validating and 158 // processing of signatures. 159 // 160 // Note that this interface is not a stable API and may change at any time to accommodate 161 // new protocol rules. 162 type Signer interface { 163 // Sender returns the sender address of the transaction. 164 Sender(tx *Transaction) (common.Address, error) 165 166 // SignatureValues returns the raw R, S, V values corresponding to the 167 // given signature. 168 SignatureValues(tx *Transaction, sig []byte) (r, s, v *big.Int, err error) 169 ChainID() *big.Int 170 171 // Hash returns 'signature hash', i.e. the transaction hash that is signed by the 172 // private key. This hash does not uniquely identify the transaction. 173 Hash(tx *Transaction) common.Hash 174 175 // Equal returns true if the given signer is the same as the receiver. 176 Equal(Signer) bool 177 } 178 179 type londonSigner struct{ eip2930Signer } 180 181 // NewLondonSigner returns a signer that accepts 182 // - EIP-1559 dynamic fee transactions 183 // - EIP-2930 access list transactions, 184 // - EIP-155 replay protected transactions, and 185 // - legacy Homestead transactions. 186 func NewLondonSigner(chainId *big.Int) Signer { 187 return londonSigner{eip2930Signer{NewEIP155Signer(chainId)}} 188 } 189 190 func (s londonSigner) Sender(tx *Transaction) (common.Address, error) { 191 if tx.Type() != DynamicFeeTxType { 192 return s.eip2930Signer.Sender(tx) 193 } 194 V, R, S := tx.RawSignatureValues() 195 // DynamicFee txs are defined to use 0 and 1 as their recovery 196 // id, add 27 to become equivalent to unprotected Homestead signatures. 197 V = new(big.Int).Add(V, big.NewInt(27)) 198 if tx.ChainId().Cmp(s.chainId) != 0 { 199 return common.Address{}, ErrInvalidChainId 200 } 201 return recoverPlain(s.Hash(tx), R, S, V, true) 202 } 203 204 func (s londonSigner) Equal(s2 Signer) bool { 205 x, ok := s2.(londonSigner) 206 return ok && x.chainId.Cmp(s.chainId) == 0 207 } 208 209 func (s londonSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { 210 txdata, ok := tx.inner.(*DynamicFeeTx) 211 if !ok { 212 return s.eip2930Signer.SignatureValues(tx, sig) 213 } 214 // Check that chain ID of tx matches the signer. We also accept ID zero here, 215 // because it indicates that the chain ID was not specified in the tx. 216 if txdata.ChainID.Sign() != 0 && txdata.ChainID.Cmp(s.chainId) != 0 { 217 return nil, nil, nil, ErrInvalidChainId 218 } 219 R, S, _ = decodeSignature(sig) 220 V = big.NewInt(int64(sig[64])) 221 return R, S, V, nil 222 } 223 224 // Hash returns the hash to be signed by the sender. 225 // It does not uniquely identify the transaction. 226 func (s londonSigner) Hash(tx *Transaction) common.Hash { 227 if tx.Type() != DynamicFeeTxType { 228 return s.eip2930Signer.Hash(tx) 229 } 230 return prefixedRlpHash( 231 tx.Type(), 232 []interface{}{ 233 s.chainId, 234 tx.Nonce(), 235 tx.GasTipCap(), 236 tx.GasFeeCap(), 237 tx.Gas(), 238 tx.To(), 239 tx.Value(), 240 tx.Data(), 241 tx.AccessList(), 242 }) 243 } 244 245 type eip2930Signer struct{ EIP155Signer } 246 247 // NewEIP2930Signer returns a signer that accepts EIP-2930 access list transactions, 248 // EIP-155 replay protected transactions, and legacy Homestead transactions. 249 func NewEIP2930Signer(chainId *big.Int) Signer { 250 return eip2930Signer{NewEIP155Signer(chainId)} 251 } 252 253 func (s eip2930Signer) ChainID() *big.Int { 254 return s.chainId 255 } 256 257 func (s eip2930Signer) Equal(s2 Signer) bool { 258 x, ok := s2.(eip2930Signer) 259 return ok && x.chainId.Cmp(s.chainId) == 0 260 } 261 262 func (s eip2930Signer) Sender(tx *Transaction) (common.Address, error) { 263 V, R, S := tx.RawSignatureValues() 264 switch tx.Type() { 265 case LegacyTxType: 266 if !tx.Protected() { 267 return HomesteadSigner{}.Sender(tx) 268 } 269 V = new(big.Int).Sub(V, s.chainIdMul) 270 V.Sub(V, big8) 271 case AccessListTxType: 272 // AL txs are defined to use 0 and 1 as their recovery 273 // id, add 27 to become equivalent to unprotected Homestead signatures. 274 V = new(big.Int).Add(V, big.NewInt(27)) 275 default: 276 return common.Address{}, ErrTxTypeNotSupported 277 } 278 if tx.ChainId().Cmp(s.chainId) != 0 { 279 return common.Address{}, ErrInvalidChainId 280 } 281 return recoverPlain(s.Hash(tx), R, S, V, true) 282 } 283 284 func (s eip2930Signer) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { 285 switch txdata := tx.inner.(type) { 286 case *LegacyTx: 287 return s.EIP155Signer.SignatureValues(tx, sig) 288 case *AccessListTx: 289 // Check that chain ID of tx matches the signer. We also accept ID zero here, 290 // because it indicates that the chain ID was not specified in the tx. 291 if txdata.ChainID.Sign() != 0 && txdata.ChainID.Cmp(s.chainId) != 0 { 292 return nil, nil, nil, ErrInvalidChainId 293 } 294 R, S, _ = decodeSignature(sig) 295 V = big.NewInt(int64(sig[64])) 296 default: 297 return nil, nil, nil, ErrTxTypeNotSupported 298 } 299 return R, S, V, nil 300 } 301 302 // Hash returns the hash to be signed by the sender. 303 // It does not uniquely identify the transaction. 304 func (s eip2930Signer) Hash(tx *Transaction) common.Hash { 305 switch tx.Type() { 306 case LegacyTxType: 307 return rlpHash([]interface{}{ 308 tx.Nonce(), 309 tx.GasPrice(), 310 tx.Gas(), 311 tx.To(), 312 tx.Value(), 313 tx.Data(), 314 s.chainId, uint(0), uint(0), 315 }) 316 case AccessListTxType: 317 return prefixedRlpHash( 318 tx.Type(), 319 []interface{}{ 320 s.chainId, 321 tx.Nonce(), 322 tx.GasPrice(), 323 tx.Gas(), 324 tx.To(), 325 tx.Value(), 326 tx.Data(), 327 tx.AccessList(), 328 }) 329 default: 330 // This _should_ not happen, but in case someone sends in a bad 331 // json struct via RPC, it's probably more prudent to return an 332 // empty hash instead of killing the node with a panic 333 //panic("Unsupported transaction type: %d", tx.typ) 334 return common.Hash{} 335 } 336 } 337 338 // EIP155Signer implements Signer using the EIP-155 rules. This accepts transactions which 339 // are replay-protected as well as unprotected homestead transactions. 340 type EIP155Signer struct { 341 chainId, chainIdMul *big.Int 342 } 343 344 func NewEIP155Signer(chainId *big.Int) EIP155Signer { 345 if chainId == nil { 346 chainId = new(big.Int) 347 } 348 return EIP155Signer{ 349 chainId: chainId, 350 chainIdMul: new(big.Int).Mul(chainId, big.NewInt(2)), 351 } 352 } 353 354 func (s EIP155Signer) ChainID() *big.Int { 355 return s.chainId 356 } 357 358 func (s EIP155Signer) Equal(s2 Signer) bool { 359 eip155, ok := s2.(EIP155Signer) 360 return ok && eip155.chainId.Cmp(s.chainId) == 0 361 } 362 363 var big8 = big.NewInt(8) 364 365 func (s EIP155Signer) Sender(tx *Transaction) (common.Address, error) { 366 if tx.Type() != LegacyTxType { 367 return common.Address{}, ErrTxTypeNotSupported 368 } 369 if !tx.Protected() { 370 return HomesteadSigner{}.Sender(tx) 371 } 372 if tx.ChainId().Cmp(s.chainId) != 0 { 373 return common.Address{}, ErrInvalidChainId 374 } 375 V, R, S := tx.RawSignatureValues() 376 V = new(big.Int).Sub(V, s.chainIdMul) 377 V.Sub(V, big8) 378 return recoverPlain(s.Hash(tx), R, S, V, true) 379 } 380 381 // SignatureValues returns signature values. This signature 382 // needs to be in the [R || S || V] format where V is 0 or 1. 383 func (s EIP155Signer) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { 384 if tx.Type() != LegacyTxType { 385 return nil, nil, nil, ErrTxTypeNotSupported 386 } 387 R, S, V = decodeSignature(sig) 388 if s.chainId.Sign() != 0 { 389 V = big.NewInt(int64(sig[64] + 35)) 390 V.Add(V, s.chainIdMul) 391 } 392 return R, S, V, nil 393 } 394 395 // Hash returns the hash to be signed by the sender. 396 // It does not uniquely identify the transaction. 397 func (s EIP155Signer) Hash(tx *Transaction) common.Hash { 398 return rlpHash([]interface{}{ 399 tx.Nonce(), 400 tx.GasPrice(), 401 tx.Gas(), 402 tx.To(), 403 tx.Value(), 404 tx.Data(), 405 s.chainId, uint(0), uint(0), 406 }) 407 } 408 409 // HomesteadTransaction implements TransactionInterface using the 410 // homestead rules. 411 type HomesteadSigner struct{ FrontierSigner } 412 413 func (s HomesteadSigner) ChainID() *big.Int { 414 return nil 415 } 416 417 func (s HomesteadSigner) Equal(s2 Signer) bool { 418 _, ok := s2.(HomesteadSigner) 419 return ok 420 } 421 422 // SignatureValues returns signature values. This signature 423 // needs to be in the [R || S || V] format where V is 0 or 1. 424 func (hs HomesteadSigner) SignatureValues(tx *Transaction, sig []byte) (r, s, v *big.Int, err error) { 425 return hs.FrontierSigner.SignatureValues(tx, sig) 426 } 427 428 func (hs HomesteadSigner) Sender(tx *Transaction) (common.Address, error) { 429 if tx.Type() != LegacyTxType { 430 return common.Address{}, ErrTxTypeNotSupported 431 } 432 v, r, s := tx.RawSignatureValues() 433 return recoverPlain(hs.Hash(tx), r, s, v, true) 434 } 435 436 type FrontierSigner struct{} 437 438 func (s FrontierSigner) ChainID() *big.Int { 439 return nil 440 } 441 442 func (s FrontierSigner) Equal(s2 Signer) bool { 443 _, ok := s2.(FrontierSigner) 444 return ok 445 } 446 447 func (fs FrontierSigner) Sender(tx *Transaction) (common.Address, error) { 448 if tx.Type() != LegacyTxType { 449 return common.Address{}, ErrTxTypeNotSupported 450 } 451 v, r, s := tx.RawSignatureValues() 452 return recoverPlain(fs.Hash(tx), r, s, v, false) 453 } 454 455 // SignatureValues returns signature values. This signature 456 // needs to be in the [R || S || V] format where V is 0 or 1. 457 func (fs FrontierSigner) SignatureValues(tx *Transaction, sig []byte) (r, s, v *big.Int, err error) { 458 if tx.Type() != LegacyTxType { 459 return nil, nil, nil, ErrTxTypeNotSupported 460 } 461 r, s, v = decodeSignature(sig) 462 return r, s, v, nil 463 } 464 465 // Hash returns the hash to be signed by the sender. 466 // It does not uniquely identify the transaction. 467 func (fs FrontierSigner) Hash(tx *Transaction) common.Hash { 468 return rlpHash([]interface{}{ 469 tx.Nonce(), 470 tx.GasPrice(), 471 tx.Gas(), 472 tx.To(), 473 tx.Value(), 474 tx.Data(), 475 }) 476 } 477 478 func decodeSignature(sig []byte) (r, s, v *big.Int) { 479 if len(sig) != crypto.SignatureLength { 480 panic(fmt.Sprintf("wrong size for signature: got %d, want %d", len(sig), crypto.SignatureLength)) 481 } 482 r = new(big.Int).SetBytes(sig[:32]) 483 s = new(big.Int).SetBytes(sig[32:64]) 484 v = new(big.Int).SetBytes([]byte{sig[64] + 27}) 485 return r, s, v 486 } 487 488 func recoverPlain(sighash common.Hash, R, S, Vb *big.Int, homestead bool) (common.Address, error) { 489 if Vb.BitLen() > 8 { 490 return common.Address{}, ErrInvalidSig 491 } 492 V := byte(Vb.Uint64() - 27) 493 if !crypto.ValidateSignatureValues(V, R, S, homestead) { 494 return common.Address{}, ErrInvalidSig 495 } 496 // encode the signature in uncompressed format 497 r, s := R.Bytes(), S.Bytes() 498 sig := make([]byte, crypto.SignatureLength) 499 copy(sig[32-len(r):32], r) 500 copy(sig[64-len(s):64], s) 501 sig[64] = V 502 // recover the public key from the signature 503 pub, err := crypto.Ecrecover(sighash[:], sig) 504 if err != nil { 505 return common.Address{}, err 506 } 507 if len(pub) == 0 || pub[0] != 4 { 508 return common.Address{}, errors.New("invalid public key") 509 } 510 var addr common.Address 511 copy(addr[:], crypto.Keccak256(pub[1:])[12:]) 512 return addr, nil 513 } 514 515 // deriveChainId derives the chain id from the given v parameter 516 func deriveChainId(v *big.Int) *big.Int { 517 if v.BitLen() <= 64 { 518 v := v.Uint64() 519 if v == 27 || v == 28 { 520 return new(big.Int) 521 } 522 return new(big.Int).SetUint64((v - 35) / 2) 523 } 524 v = new(big.Int).Sub(v, big.NewInt(35)) 525 return v.Div(v, big.NewInt(2)) 526 }