I am trying to access big_map data for a specific key, but I found that I need to provide the hash of the key to retrieve the data. Is there a way to get the hash for a key? Knowing the algorithm used to generate the key should be good enough too.
2 Answers
Quick way (using Pytezos library):
>>> from pytezos.michelson.pack import get_key_hash
>>> get_key_hash({"string": "KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn"}, {"prim": "address"})
'exprvAHu1SyoiSzyh9w7GPfifvyrNiMb442y7Q2MA8tcPCGPajxRH6'
Where first argument is the key (Micheline JSON), and the second one is the expression type (Micheline JSON).
Here is the algorithm and intermediate results (for value/type used above):
- Pack key (e.g. using pack_data RPC endpoint)
050a0000001601a3d0f58d8964bd1b37fb0a0c197b38cf46608d4900
- Take Blake2b hash (digest size = 32)
d8a60c00b3c8f62cc2b3b8006b1858a621b5b74e06d3c82916659beaa24c8f67
- Prepend "0d2c401b"
0d2c401bd8a60c00b3c8f62cc2b3b8006b1858a621b5b74e06d3c82916659beaa24c8f67
- Base58 encode with checksum
exprvAHu1SyoiSzyh9w7GPfifvyrNiMb442y7Q2MA8tcPCGPajxRH6
I ended up using ConseilJS for this. I used the TezosMessageUtils.encodeBigMapKey
function in ConseilJS to create the hash key. Here's an example of how to convert the key to the hash :
const packedKey = TezosMessageUtils.encodeBigMapKey(Buffer.from(TezosMessageUtils.writePackedData(secretHash, "bytes"), "hex"));
You need to put the appropriate type of your key in the writePackedData
before encoding it.