cosmjs icon indicating copy to clipboard operation
cosmjs copied to clipboard

Q: How to convert proposerAddress back to bech32

Open npow opened this issue 3 years ago • 2 comments

I am trying to convert the proposerAddress back to bech32 format, but when I do so it doesn't match the validator address showing up on mintscan.

  const tendermintClient = await StargateClient.connect('https://osmosis-1.technofractal.com/');
  const res = await tendermintClient.tmClient.block(2956000);
  const string = Bech32.encode("osmo", res.block.header.proposerAddress);
  console.log(string);

This outputs: osmo1arm6ztth2njxndd2cwpg6gt6q79wdfyf26rnjx, while on mintscan it shows the proposer as Nascent which has address osmo1gxlsy3jmt5aevkmlfh7rnnxrtqzqe4a6wmtafa. The address I encoded has no tokens either, so I must be doing something wrong.

npow avatar Jan 26 '22 17:01 npow

The proposer address you get from the Tendermint client is derived from an ed25519 Tendermint consensus keypair. Those are the addresses that have "cons" in their bech32 prefix.

You cannot interact with this address on the application level directly. This is why fancy browsers map it to the Cosmos SDK app level addresses for the users because they know both addresses of a validator.

I think you can do the mapping through the /staking/validators list (e.g. https://lcd-osmosis.blockapsis.com/staking/validators) by deriving the Tendermint address from consensus_pubkey using pubkeyToAddress from @cosmjs/tendermint-rpc. You might find a better query API for doing the mapping in packages/stargate/src/queries/staking.ts.

webmaster128 avatar Jan 26 '22 18:01 webmaster128

this also worked Since cosmosvaloper address has a consensus pubkey, the consensus address could be gotten from the consensus pubkey this way

import { sha256 } from "@cosmjs/crypto";
import { Bech32, fromBase64 } from "@cosmjs/encoding";
import { encodeBech32Pubkey } from "@cosmjs/launchpad";

const pubkey = {
  type: "tendermint/PubKeyEd25519",
  value: "w3rKE+tQoLK8G+XPmjn+NszCk07iQ0sWaBbN5hQZcBY=",
};

const ed25519PubkeyRaw = fromBase64(pubkey.value);
const addressData = sha256(ed25519PubkeyRaw).slice(0, 20);
const bech32Address = Bech32.encode(“cosmosvalcons", addressData);
console.log(bech32Address);

The address matches with the proposer hex address when encoded to bech32

Another solution

import { fromBase64, toHex } from "@cosmjs/encoding";
import { decodeBech32Pubkey } from "@cosmjs/launchpad"

Convert the consensus pubkey  to valconspub like this
const bech32Pubkey = encodeBech32Pubkey(pubkey, “cosmosvalconspub");
console.log(bech32Pubkey)
Then decode like this 
const pubkey = decodeBech32Pubkey(
"cosmosvalconspub1zcjduepqcdav5ylt2zst90qmuh8e5w07xmxv9y6wufp5k9ngzmx7v9qewqtqkcq4z8",
);
const addressData = sha256(fromBase64(pubkey.value)).slice(0, 20);
const address = toHex(addressData).toUpperCase();
console.log(address)

This address here matches the hex proposer address

uwezukwechibuzor avatar Jun 23 '22 10:06 uwezukwechibuzor

Here is a full example how to do the mapping via the staking.validators query: https://github.com/noislabs/proposers/blob/f552cf24724f8ab719168a149c7e3109b7606d37/index.ts. The core to produce the mapping from proposer address to operator are those lines: https://github.com/noislabs/proposers/blob/f552cf24724f8ab719168a149c7e3109b7606d37/index.ts#L34-L48

webmaster128 avatar Oct 15 '22 09:10 webmaster128