cosmos / cosmjs

The Swiss Army knife to power JavaScript based client solutions ranging from Web apps/explorers over browser extensions to server-side clients like faucets/scrapers.
https://cosmos.github.io/cosmjs/
Apache License 2.0
648 stars 332 forks source link

How to convert cosmos public key to ethereum address? #1044

Closed chismo950 closed 2 years ago

chismo950 commented 2 years ago

use @cosmjs/crypto?

nooomski commented 2 years ago

What exactly do you mean @chismo950 ? Cosmos public keys aren't related to Ethereum addresses.

webmaster128 commented 2 years ago

⚠️ Warning: With great power comes great responsibility

This is very well possible. It is probably big hackery and should not be done, but it can be done.

Like Ethereum, Cosmos SDK uses secp256k1 keypairs. So you can (not should) use an Ethereum keypair for a Cosmos chain and vice versa. The biggest difference is that Ethereum uses uncompressed secp256k1 pubkeys and Cosmos uses compressed secp256k1 pubkeys.

The steps are as follows:

  1. Uncompress the secp256k1 pubkey (#1047)
  2. Create a Keccak256 hash of the 64 bytes after the leaxing 0x04 byte and cut the last 20 bytes (as done here)
  3. Hex encode the 20 byte result of 2. and prefix with 0x
  4. (optional) Implement the upper/lower case checksum from EIP-55 as implemented here.

Point 4 is out of scope for CosmJS but the rest can be done with the general purpose tooling you find here.

chismo950 commented 2 years ago

⚠️ Warning: With great power comes great responsibility

This is very well possible. It is probably big hackery and should not be done, but it can be done.

Like Ethereum, Cosmos SDK uses secp256k1 keypairs. So you can (not should) use an Ethereum keypair for a Cosmos chain and vice versa. The biggest difference is that Ethereum uses uncompressed secp256k1 pubkeys and Cosmos uses compressed secp256k1 pubkeys.

The steps are as follows:

  1. Uncompress the secp256k1 pubkey (Add Secp256k1.uncompressPubkey #1047)
  2. Create a Keccak256 hash of the 64 bytes after the leaxing 0x04 byte and cut the last 20 bytes (as done here)
  3. Hex encode the 20 byte result of 2. and prefix with 0x
  4. (optional) Implement the upper/lower case checksum from EIP-55 as implemented here.

Point 4 is out of scope for CosmJS but the rest can be done with the general purpose tooling you find here.

Thank you very much, I did it!

tungleanh0902 commented 6 months ago

Hi. Is there a way to convert from eth address to cosmos chain address in Go? I tried several ways but my imported wallet from eth not match with the one I convert on chains like osmosis, cosmos, nolus, and it match with evmos and dym. Do you know why? Is it because evmos and dym impl evm module?

baoskee commented 4 months ago

⚠️ Warning: With great power comes great responsibility

This is very well possible. It is probably big hackery and should not be done, but it can be done.

Like Ethereum, Cosmos SDK uses secp256k1 keypairs. So you can (not should) use an Ethereum keypair for a Cosmos chain and vice versa. The biggest difference is that Ethereum uses uncompressed secp256k1 pubkeys and Cosmos uses compressed secp256k1 pubkeys.

The steps are as follows:

  1. Uncompress the secp256k1 pubkey (Add Secp256k1.uncompressPubkey #1047)
  2. Create a Keccak256 hash of the 64 bytes after the leaxing 0x04 byte and cut the last 20 bytes (as done here)
  3. Hex encode the 20 byte result of 2. and prefix with 0x
  4. (optional) Implement the upper/lower case checksum from EIP-55 as implemented here.

Point 4 is out of scope for CosmJS but the rest can be done with the general purpose tooling you find here.

⚠️ THIS IS NOT TRUE!

Ethereum uses different HD path (m/44'/60'/0'/0/0) than Cosmos (m/44'/118'/0'/0/0). So the secp256k1 Cosmos pubkey you find in transactions will NOT CONVERT.

Please do not use this in production. ❌

webmaster128 commented 4 months ago

Ethereum uses different HD path (m/44'/60'/0'/0/0) than Cosmos (m/44'/118'/0'/0/0)

The chain itself does not care which derivation path you use. In fact it can't even know where the derived keypair is coming from. The problem you will have though is compatibility with other wallets.

codebycarson commented 4 months ago

@webmaster128 is correct, the chain itself doesn't care. You can generate a private key with any coin type and use it, chains just usually have a canonical coin type so that things don't interfere, but once you have the Private Key it doesn't matter, the chain just cares if things are signed with the right private keys.

You can see this in action on Sei. If you take your seed from Metamask and put it into a Sei Cosmos wallet like Compass it give a different wallet address than metamask due to it generating a coin type 118 private key from the mnemonic where Metamask generated a coin type 60 Private Key.

Now if instead of exporting the seed from Metamask, you export the private key, you will see the addresses do in fact match. This is because the Private Key was generated specifically for coin type 60 by Metamask and then Compass can pick it up and use it just fine.

codebycarson commented 4 months ago

You can derive addresses the "Ethereum way" and the "Cosmos way" because in both cases the addresses are just derived from the pubkey, which comes from the private key, which comes from the HD path of the mnemonic.

baoskee commented 4 months ago

You can derive addresses the "Ethereum way" and the "Cosmos way" because in both cases the addresses are just derived from the pubkey, which comes from the private key, which comes from the HD path of the mnemonic.

Thanks @webmaster128 @codebycarson for the clarification. I have a couple more questions:

webmaster128 commented 4 months ago

It's the same for both Ethereum and Cosmos. You don't need to use HD derivation at all and can just have a raw private and public secp256k1 key.

mnemonic + HD path  ----->  private key  ----->  public key  ------>  address
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
client-side only (invisible to the chain)

then I assume that would not be the same for two different HD paths from the same mnemonic

Two paths just give you two different private keys, two different public keys, two different addresses. So completely independent accounts from the perspective of the chain.