question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Recover public key from contract deployment transaction

See original GitHub issue

I’m trying to get the public key of a user during the contract deployment but I’m not sure if it’s possible with ethers.js. I’d like to solve it using only this package as I don’t want to bloat my react builds with web3.js. I’m using ethers 4.0.42.

I took a deep dive into your source code, ECDSA and looked at a related issue and came up with the following code.

I think my biggest issue is to get the signing hash. So here’s my attempt:

// before: contract = await factory.deploy(...);

// get the signing hash
const deployTx = contract.deployTransaction;
const txData = {
  gasPrice: deployTx.gasPrice,
  gasLimit: deployTx.gasLimit,
  value: deployTx.value,
  nonce: deployTx.nonce,
  data: deployTx.data,
  chainId: deployTx.chainId
};
const tx = await ethers.utils.resolveProperties(txData);
const rawTx = ethers.utils.serializeTransaction(tx); // returns RLP encoded tx
const msgHash = ethers.utils.keccak256(rawTx); // as specified by ECDSA

Note that msgHash is the signing hash.

// get flat signature for recovery
const expandedSig = {
  r: deployTx.r,
  s: deployTx.s,
  recoveryParam: 0, // not really sure what this does
  v: deployTx.v // i think this value is only needed because of EIP155 (CHAIN_ID * 2 + 35 or 36)
};
const signature = ethers.utils.joinSignature(expandedSig);


const msgBytes = ethers.utils.arrayify(msgHash); // create binary hash
const recoveredPubKey = ethers.utils.recoverPublicKey(
  msgBytes,
  signature
);
const recoveredAddress = ethers.utils.recoverAddress(msgBytes, signature);

Unfortunately both the recoveredPubKey and the recoveredAddress are false.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:11 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
lastmjscommented, Jun 12, 2020

I’m having a hard time getting the public key from a transaction response on ropsten. Would anyone mind giving me an example of how to do this with a simple transaction response, just a normal transaction from an external account?

Here’s the function from my application:

async function deriveEthereumPublicKeyFromEthereumAddress(ethereumAddress: string): Promise<string> {

    console.log('ethereumAddress', ethereumAddress);

    const etherscanProvider = new ethers.providers.EtherscanProvider('ropsten');

    const transactionResponses: ReadonlyArray<ethers.providers.TransactionResponse> = await etherscanProvider.getHistory(ethereumAddress);

    const aSignedTransaction: Readonly<ethers.providers.TransactionResponse> | undefined = transactionResponses.find((transactionResponse: Readonly<ethers.providers.TransactionResponse>) => {
        return transactionResponse.from === ethereumAddress;
    });

    if (aSignedTransaction === undefined) {
        throw new Error(`The Ethereum address has no signed transactions`);
    }

    const provider = ethers.getDefaultProvider('ropsten');

    const transactionResponse = await provider.getTransaction(aSignedTransaction.hash);

    console.log('transactionResponse', transactionResponse);

    const signature: string = ethers.utils.joinSignature({
        r: transactionResponse.r,
        s: transactionResponse.s,
        v: transactionResponse.v
    });

    console.log('signature', signature);

    const txData = {
        gasPrice: transactionResponse.gasPrice,
        gasLimit: transactionResponse.gasLimit,
        value: transactionResponse.value,
        nonce: transactionResponse.nonce,
        data: transactionResponse.data,
        chainId: transactionResponse.chainId
    };

    const transaction = await ethers.utils.resolveProperties(txData);
    const rawTransaction = ethers.utils.serializeTransaction(transaction);
    const hashedTransaction = ethers.utils.keccak256(rawTransaction);
    const hashedTransactionBytes = ethers.utils.arrayify(hashedTransaction);
    
    console.log('hashedTransactionBytes', hashedTransactionBytes);

    const publicKey: string = ethers.utils.recoverPublicKey(hashedTransactionBytes, signature)

    console.log('publicKey', publicKey);

    const originalAddress: string = ethers.utils.recoverAddress(hashedTransactionBytes, signature);

    console.log('originalAddress', originalAddress);

    return publicKey;
}

It doesn’t come out correctly, and I’m not sure why

1reaction
protortypcommented, Jan 12, 2020

Perfect! Thanks for helping out 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

ethers.js Recover public key from contract deployment via v,r,s ...
I wrote a gist that correctly recovers the public key given the transaction. In short: const tx = await provider.getTransaction(.
Read more >
How to extract public key for a signed transaction in Solidity ...
I want an user to: sign a message in a different blockchain (non-EVM) and retrieve the public key from a Solidity smart contract...
Read more >
The Lost Key Recovery System has been proposed ... - Medium
The Lost Key Recovery System smart contract has been proposed for deployment to the EOS Mainnet. This is the final step of the...
Read more >
Accounts in Nethereum
If using the TransactionManager, deploying a contract or using a contract function, the transaction will either be signed offline using the private key...
Read more >
Chapter 6: Transactions · GitBook
You can send to an address that has no corresponding private key or contract, thereby "burning" the ether, rendering it forever unspendable. Validation...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found