Tips

Validator Moniker-Address Mapping

One of the challenges we faced during the development of Coris was figuring out an elegant way to map a validator’s moniker to his/her address, all without messing with gaiadebug or go-amino. A big inspiration for us, whom we’d like to give credits to, was js-tendermint by Nomic, a JavaScript light client for the Tendermint consensus engine. After reading through their code base, specifically pubkey.js, we learned that a validator’s HEX address is simply the first 20 bytes of its corresponding Ed25519 pubkey. We hence made the plan to first decode a bech32-encoded validator consensus pubkey to Ed25519, strip out the first 20 bytes to get the actual HEX value, then pass in the HEX value to function getAddress(pubkey) in pubkey.js to derive a validator address.

Here is what the steps would look like:

  1. Decode a bech32-encoded key to Ed25519
    For example, cosmosvalconspub1zcjduepqu3srzgruamf6jaylwv20xq6s4snjhtn6t9razznmn2vn9sekslcsdscys3 would give you 1624DE6420E46031207CEED3A9749F7314F30350AC272BAE7A5947D10A7B9A9932C33687F1, where 1624DE64 indicates it is a Ed25519, 20 is length, E46031207CEED3A9749F7314F30350AC272BAE7A5947D10A7B9A9932C33687F1 is the actual HEX value.
  2. Pass in the HEX value from previous step to getAddress(pubkey), and derive its corresponding validator address
    function getAddress(pubkey) {
    var bytes = Buffer.from(pubkey, 'base64');
    return tmhash(bytes).slice(0, 20).toString('hex').toUpperCase(); //tmhash is just sha256
    }

    getAddress(hex.hexToBytes('E46031207CEED3A9749F7314F30350AC272BAE7A5947D10A7B9A9932C33687F1'));