From e69b980ee74c943cbc2ccc492e295b476067f9b5 Mon Sep 17 00:00:00 2001 From: sandy <18382255942@163.com> Date: Thu, 22 Jul 2021 11:54:17 +0800 Subject: [PATCH] fix(): fix Ecrecover --- utils.go | 12 +++++++----- utils_test.go | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/utils.go b/utils.go index b5851f2..788a1ae 100644 --- a/utils.go +++ b/utils.go @@ -37,19 +37,21 @@ func EIP712Hash(typedData core.TypedData) (hash []byte, err error) { return } -func Ecrecover(hash, sigData []byte) (addr common.Address, err error) { - sig := make([]byte, len(sigData)) - copy(sig, sigData) +func Ecrecover(hash, signature []byte) (addr common.Address, err error) { + sig := make([]byte, len(signature)) + copy(sig, signature) if len(sig) != 65 { err = fmt.Errorf("invalid length of signture: %d", len(sig)) return } - if sig[64] != 27 && sig[64] != 28 { + if sig[64] != 27 && sig[64] != 28 && sig[64] != 1 && sig[64] != 0 { err = fmt.Errorf("invalid signature type") return } - sig[64] -= 27 + if sig[64] >= 27 { + sig[64] -= 27 + } recoverPub, err := crypto.Ecrecover(hash, sig) if err != nil { diff --git a/utils_test.go b/utils_test.go index 2d43487..07ee0f3 100644 --- a/utils_test.go +++ b/utils_test.go @@ -2,7 +2,9 @@ package goether import ( "encoding/json" + "github.com/ethereum/go-ethereum/core/types" "math/big" + "strings" "testing" "github.com/ethereum/go-ethereum/accounts" @@ -46,4 +48,42 @@ func TestEcrecover(t *testing.T) { addr, err = Ecrecover(hash, sig) assert.NoError(t, err) assert.Equal(t, "0xab6c371B6c466BcF14d4003601951e5873dF2AcA", addr.String()) + + tx := &types.Transaction{} + // eip1559 tx + data := []byte(`{ + "accessList": [], + "blockHash": "0xe936ee0e5a915b9c163a7a1ff67269dd5f1ccb981f91b269a2130711e6a62598", + "blockNumber": "0xa2f4f1", + "chainId": "0x3", + "from": "0xcba9f09e7e6b4a41a9d11f347416b75ee100344f", + "gas": "0x5208", + "gasPrice": "0x3b9aca0a", + "hash": "0x87f6d244a9f99b2fb173f3eece4beecabb88da46c90f558b4d57fd10d8cb247b", + "input": "0x", + "maxFeePerGas": "0x22ecb25c00", + "maxPriorityFeePerGas": "0x3b9aca00", + "nonce": "0x1", + "r": "0x6f741f168a787c708be5d7670de97b05c7e0a2e2f1959dd11fe5213508ea44a0", + "s": "0x2e409f1b92769885c45f87bbdb858740e0bf7b74c1cd8297bcefbccb6b35ac21", + "to": "0xc8d40bbc3ea2018ab8d76dbbee32f906207966d0", + "transactionIndex": "0x72", + "type": "0x2", + "v": "0x0", + "value": "0xaa87bee538000" + }`) + + err = tx.UnmarshalJSON(data) + assert.NoError(t, err) + sigHash := types.NewLondonSigner(tx.ChainId()).Hash(tx) + + // assemble london tx signature + sig = make([]byte, 0, 65) + v, r, s := tx.RawSignatureValues() + sig = append(r.Bytes(), s.Bytes()...) + sig = append(sig, byte(v.Uint64())) + // verify + addr, err = Ecrecover(sigHash.Bytes(), sig) + assert.NoError(t, err) + assert.Equal(t, "0xcba9f09e7e6b4a41a9d11f347416b75ee100344f", strings.ToLower(addr.String())) }