Skip to content

Instantly share code, notes, and snippets.

@arnabghose997
Last active August 1, 2024 20:52
Show Gist options
  • Save arnabghose997/f2d33955d5359de255055d6ce8c619f7 to your computer and use it in GitHub Desktop.
Save arnabghose997/f2d33955d5359de255055d6ce8c619f7 to your computer and use it in GitHub Desktop.
Convert a secp256k1 compressed public key to Tendermint/Cosmos based blockchain address (Golang)
package main
import (
"fmt"
"crypto/sha256"
"golang.org/x/crypto/ripemd160"
"encoding/base64"
"github.com/cosmos/btcutil/bech32"
)
// PublicKeyToAddress converts secp256k1 public key to a bech32 Tendermint/Cosmos based address
func PublicKeyToAddress(addressPrefix, publicKeyString string) string {
// Decode public key string
pubKeyBytes := decodePublicKeyString(publicKeyString)
// Hash pubKeyBytes as: RIPEMD160(SHA256(public_key_bytes))
pubKeySha256Hash := sha256.Sum256(pubKeyBytes)
ripemd160hash := ripemd160.New()
ripemd160hash.Write(pubKeySha256Hash[:])
addressBytes := ripemd160hash.Sum(nil)
// Convert addressBytes into a bech32 string
address := toBech32("hid", addressBytes)
return address
}
// Code courtesy: https://github.com/cosmos/cosmos-sdk/blob/90c9c9a9eb4676d05d3f4b89d9a907bd3db8194f/types/bech32/bech32.go#L10
func toBech32(addrPrefix string, addrBytes []byte) string {
converted, err := bech32.ConvertBits(addrBytes, 8, 5, true)
if err != nil {
panic(err)
}
addr, err := bech32.Encode(addrPrefix, converted)
if err != nil {
panic(err)
}
return addr
}
// decodePublicKeyString decodes a base-64 encoded public key
// into a Byte Array. The logic will differ for other string encodings
func decodePublicKeyString(pubKey string) []byte {
pubKeyBytes, err := base64.StdEncoding.DecodeString(pubKey)
if err != nil {
panic(err)
}
return pubKeyBytes
}
func main() {
inputPublicKey := "At8sTdbKdkdyvxi8FjLe4Dl9PYc+u19VMqCpmA7PBrPz"
inputPrefix := "hid" // osmo - Osmosis | cosmos - Cosmos Hub | hid - Hypersign Identity Network
bech32address := PublicKeyToAddress(inputPrefix, inputPublicKey)
fmt.Println(bech32address) // hid18vux70nvs5ee0sfvqfjgt6rq5fd89asd7xaypj
}
@stuart-clark-45
Copy link

This was an absolute life saver thank you! I only wish google had gotten me to it sooner!

@technicallyty
Copy link

you may want to update L25: https://gist.github.com/arnabghose997/f2d33955d5359de255055d6ce8c619f7#file-publickeytoaddress-go-L25

you don't use the addressPrefix in the funtion arg

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment