I'm trying to get a stake address from a Shelley address in Python using this library: https://pypi.org/project/bech32/

I can convert an address from bech32 to hex without issue, but I'm getting stuck grabbing the staking part (final 56 bytes) and converting that to Bech32. I keep getting a staking address that doesn't actually exist:

address_words = bech32.bech32_decode("addr1qxdvcswn0exwc2vjfr6u6f6qndfhmk94xjrt5tztpelyk4yg83zn9d4vrrtzs98lcl5u5q6mv7ngmg829xxvy3g5ydls7c76wu")

address_hexlist = bech32.convertbits(address_words[1], 5, 16)

account = ''.join([f'{c:04x}' for c in address_hexlist])[-58:-2]

btr = bytes.fromhex(account)

stake_words = bech32.convertbits(btr, 8, 5)

stakeaddr = bech32.bech32_encode("addr", stake_words)

Using the above, I get the correct account = 883c4532b6ac18d62814ffc7e9ca035b67a68da0ea298cc24514237f

However, I get the wrong staking address at the end: stake13q7y2v4k4svdv2q5llr7njsrtdn6drdqag5cesj9zs3h7xjwn42

The correct staking address should be: stake1uxyrc3fjk6kp343gznlu06w2qddk0f5d5r4znrxzg52zxlclk0hlq

The annoying thing is, the wrong address I get is the same as what you get trying to use https://slowli.github.io/bech32-buffer/ which makes me think I'm missing something specific that cardano does differently to the bech32 spec.

I can't use the provided bech32.exe binary because it refuses to work (even if it did work, I'd still like to get it working in python).

  • Great first post, welcome aboard.
    – gRebel
    Jul 17, 2021 at 11:35

2 Answers 2


Credit to someone on Reddit who helped me with this:

Deriving the staking address requires you to manually update the header byte before bech32 encoding the hex account. All I needed to do was add e1 to the start of the account (1110 0001)


Maybe it is a bit late, but hope it helps.

You can use this python library PyCardano to derive the stake key.

Here is the code example:

>>> from pycardano import Address, Network

>>> addr = Address.from_primitive("addr1qxdvcswn0exwc2vjfr6u6f6qndfhmk94xjrt5tztpelyk4yg83zn9d4vrrtzs98lcl5u5q6mv7ngmg829xxvy3g5ydls7c76wu")
>>> addr2 = Address(staking_part=addr.staking_part, network=Network.MAINNET)
>>> addr2

We first convert the address string to an Address object, addr. Then we use the staking part of the address to create a new stake address.

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.