Skip to content

Commit

Permalink
Merge pull request #31 from KyberNetwork/feat/eth/recover-signer
Browse files Browse the repository at this point in the history
feat: ✨ eth: RecoverSignerAddress
  • Loading branch information
thanhpp authored Mar 21, 2024
2 parents d28eca3 + bb86072 commit f0ef619
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 0 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/shopspring/decimal v1.3.1
github.com/sourcegraph/conc v0.3.0
github.com/stretchr/testify v1.8.4
github.com/test-go/testify v1.1.4
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
)

Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbe
github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE=
github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU=
github.com/tidwall/gjson v1.8.1 h1:8j5EE9Hrh3l9Od1OIEDAb7IpezNA20UdRngNAj5N0WU=
github.com/tidwall/gjson v1.8.1/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk=
github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE=
Expand Down
44 changes: 44 additions & 0 deletions pkg/eth/recover.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package eth

import (
"fmt"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
)

const signatureLength = 65

func RecoverSignerAddress(hexEncodedHash string, hexEncodedSignature string) (common.Address, error) {
hash, err := hexutil.Decode(hexEncodedHash)
if err != nil {
return common.Address{}, fmt.Errorf("decode hash error: %w", err)
}

signature, err := hexutil.Decode(hexEncodedSignature)
if err != nil {
return common.Address{}, fmt.Errorf("decode signature error: %w", err)
}

// Signature in Ethereum consists of R, S, V; the V is at last byte, R and S are the rest.
// The standard Ethereum signature is 65 bytes (R: 32 bytes, S: 32 bytes, V: 1 byte).
// Ensure the signature is 65 bytes and split it into R, S, and V components.
if len(signature) != signatureLength {
return common.Address{}, fmt.Errorf("invalid signature length, expect: %d, got: %v", signatureLength, len(signature))
}

// Ethereum uses a 'recovery id' for V, but go-ethereum expects V to be 27 or 28.
signature[64] -= 27

// Recover the public key from the signature
pubKey, err := crypto.SigToPub(hash, signature)
if err != nil {
return common.Address{}, fmt.Errorf("signature to public key error: %w", err)
}

// Derive the Ethereum address from the public key
address := crypto.PubkeyToAddress(*pubKey)

return address, nil
}
18 changes: 18 additions & 0 deletions pkg/eth/recover_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package eth_test

import (
"testing"

"github.com/KyberNetwork/tradinglib/pkg/eth"
"github.com/test-go/testify/require"
)

func TestRecover(t *testing.T) {
hashHex := "0xef6777697377372751e5daa1772d3b2b03f6f50b85dd3d7a79b4f12381897ec8"
signatureHex := "0xf89e6165aa337b8ebf74effa1a2b0980cc54e3780af077337b12438f30c901ab69ad655518007bd15073c919780ac61d3a4d5918c8966ffdb07256776ca6223f1c" // nolint: lll

addr, err := eth.RecoverSignerAddress(hashHex, signatureHex)
require.NoError(t, err)

t.Log(addr.String())
}

0 comments on commit f0ef619

Please sign in to comment.