#StackBounty: #web3js #public-key #ecrecover Extracting Public key from signed Ethereum message or transaction in JavaScript

Bounty: 50

I’m trying to find out how to derive a public key (not the address) of an Ethereum account by using ethereumjs-util’s ecrecover method.

Basically I get a transaction by hash using Web3, convert r, s and v like in this answer, and pass them to ecrecover. It does yield a public key, but that key does not correspond to the address of the sender of the transaction.

What am I doing wrong?

Code below:

const ethJsUtil = require('ethereumjs-util');

class EthPubKeyReg {

    constructor(web3, chainId) {
        this.chainId = chainId;
        this.web3 = web3;

    async extractPubKey(txHash, chainId) {
        chainId = (chainId || this.chainId);
        let tx = await this.web3.eth.getTransaction(txHash);

        let v = parseInt(tx.v);

        let msgHash = ethJsUtil.toBuffer(tx.hash);
        let r = ethJsUtil.toBuffer(tx.r);
        let s = ethJsUtil.toBuffer(tx.s);

        let pubKey = ethJsUtil.ecrecover(msgHash, v, r, s);

        console.log("address", ethJsUtil.bufferToHex(ethJsUtil.pubToAddress(pubKey)));
        return pubKey;

    async extractPubKeyString(txHash, chainId) {
        return ethJsUtil.bufferToHex(await this.extractPubKey(txHash, chainId));

Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.