From 42a26000eacd23ca325623c6460a70f5c8d4a50f Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Thu, 25 Aug 2016 13:50:47 +0200 Subject: [PATCH] add personal_recover --- internal/ethapi/api.go | 29 +++++++++++++++++++++++++++++ internal/web3ext/web3ext.go | 5 +++++ 2 files changed, 34 insertions(+) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index ac78cd1362..c51558e4c6 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -312,6 +312,35 @@ func (s *PrivateAccountAPI) Sign(ctx context.Context, message string, addr commo return common.ToHex(signature), nil } +// recover returns the address for the account that was used to create the signature. +// +// https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_recover +func (s *PrivateAccountAPI) Recover(ctx context.Context, message string, signature string) (common.Address, error) { + var ( + sig = common.FromHex(signature) + hash = crypto.Keccak256(common.FromHex(message)) + ) + + if len(sig) != 65 { + return common.Address{}, fmt.Errorf("signature must be 65 bytes long") + } + + // see crypto.Ecrecover description + if sig[64] == 27 || sig[64] == 28 { + sig[64] -= 27 + } + + rpk, err := crypto.Ecrecover(hash, sig) + if err != nil { + return common.Address{}, err + } + + pubKey := crypto.ToECDSAPub(rpk) + recoveredAddr := crypto.PubkeyToAddress(*pubKey) + + return recoveredAddr, nil +} + // SignAndSendTransaction was renamed to SendTransaction. This method is deprecated // and will be removed in the future. It primary goal is to give clients time to update. func (s *PrivateAccountAPI) SignAndSendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) { diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index f7d5e67c66..e201d7c4ae 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -434,6 +434,11 @@ web3._extend({ call: 'personal_sign', params: 3, inputFormatter: [null, web3._extend.formatters.inputAddressFormatter, null] + }), + new web3._extend.Method({ + name: 'recover', + call: 'personal_recover', + params: 2 }) ] })