1

I'm trying to get an Ethereum address public key from its previous transaction data. What I'm trying to achieve is to be able to get this data from a block explorer API like Etherscan API and then extract the public key from that data. I found this post which seems to be a good solution if works: https://scrapbox.io/piyopiyo/How_to_get_sender%E2%80%99s_Ethereum_address_and_public_key_from_signed_transaction

Here's the code:

(async () => {
const ethers = require('ethers')

const CHIAN_ID = 3  // Ropsten
const SIGNED_TX = '0xf86b808504a817c800825208942890228d4478e2c3b0ebf5a38479e3396c1d6074872386f26fc100008029a0520e5053c1b573d747f823a0b23d52e5a619298f46cd781d677d0e5e78fbc750a075be461137c2c2a5594beff76ecb11a215384c574a7e5b620dba5cc63b0a0f13'

const tx = ethers.utils.RLP.decode(ethers.utils.arrayify(SIGNED_TX))
const v = ethers.BigNumber.from(tx[6]).toNumber()
const r = ethers.utils.hexZeroPad(tx[7], 32)
const s = ethers.utils.hexZeroPad(tx[8], 32)
const rawTx = tx.slice(0, 6)

// EIP-155
if (CHIAN_ID !== 0) {
    rawTx.push(ethers.utils.hexlify(CHIAN_ID))
    rawTx.push('0x')
    rawTx.push('0x')
}

const digest = ethers.utils.keccak256(ethers.utils.RLP.encode(rawTx))
const signature = ethers.utils.joinSignature({v, r, s});

const publicKey = ethers.utils.recoverPublicKey(digest, signature)
console.log('publicKey:', publicKey)

const address = ethers.utils.recoverAddress(digest, signature)
console.log('address:', address)

})()

The problem is in the sample it has used a hash called signedTx, which is a hash with 220 characters length, And I couldn't find any similar hashes in the transaction data. I wanted to ask if you guys think the explained code works and if so where can I get that signedTx parameter to feed the functin.

6
  • 1
    try by replaceing the example 0xc....90 in browser with your transaction etherscan.io/…
    – Majd TL
    Jan 31, 2023 at 16:15
  • Could you confirm I understand you correctly: you with to take a tx and find the address responsible for the transaction?
    – immaxkent
    Jan 31, 2023 at 17:51
  • Thanks @MajdTL, It also works with the raw transaction in the link you sent. I've also tried other raw transactions and couldn't get the result and wanted to ask if there was something special with the transaction you sent. The other problem is how can I get the raw transaction data? I couldn't find any API endpoint from Etherscan (or other block explorers) that would bring raw transaction hex. Thanks again
    – m0j1
    Jan 31, 2023 at 18:30
  • Thanks @XaEk, No. what I want to achieve is to find the public key of a given Ethereum address.
    – m0j1
    Jan 31, 2023 at 18:31
  • this example is a legacy transaction, it does not use the eip1559. this one use it etherscan.io/…
    – Majd TL
    Feb 1, 2023 at 8:27

1 Answer 1

1

I think I understand you.

As per the docs:

The public key is generated from the private key using the Elliptic Curve Digital Signature Algorithm. You get a public address for your account by taking the last 20 bytes of the Keccak-256 hash of the public key and adding 0x to the beginning.

EDIT This information alone isn't enough to derive the full public key.

Here’s a process you could use for finding the public key from past transactions;

  1. Assuming you are starting with a transaction, you can take the tx.hash and use web3.eth.getTransactionReceipt(hash), as seen in the docs, to explore the blockchain and find the transaction object relating to your tx.hash.

  2. Here (as you have in your code) you'll have v, r, s values. v is the message hash, s is signature and r is the empirical 'pubKey'. In order to reverse engineer the public key (which by definition includes the address associated with that account), you can use something like ethereumjs-utils, along with the original tx.hash, to yield your public key (source)

Hope that helps and is more concise

2
  • Thanks, Could you explain a bit more about the second step? I think you have assumed that address is the same as public key, but unfortunately it isn't.
    – m0j1
    Jan 31, 2023 at 18:32
  • No, sorry. I have made edits for a better method
    – immaxkent
    Jan 31, 2023 at 23:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.