Skip to content

Commit

Permalink
feat: ✨ eth: RecoverSignerAddress
Browse files Browse the repository at this point in the history
Signed-off-by: thanhpp <[email protected]>
  • Loading branch information
thanhpp committed Mar 21, 2024
1 parent d28eca3 commit 65420b9
Showing 1 changed file with 44 additions and 0 deletions.
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
}

0 comments on commit 65420b9

Please sign in to comment.