Quickest: compare with the archive canister did file and translate in your head. The order of lines stays the same between what’s mentioned in the .did file and how it’s outputted.
Nicer solution: Download the .did file (linked above) and use the --candid <path/to/can.did> option with dfx canister call.
However, there is still 2 fields (“to” and “parent_hash”) of type “blob” and “opt blob” respectively that I don’t know how to decode. How can I decode them?
$ dfx canister --network ic call qjdve-lqaaa-aaaaa-aaaeq-cai get_blocks '(record {start = 1: nat64; length = 1:nat64})' --candid ./src/ledger_archive.did
dfx.json not found, using default.
(
variant {
Ok = record {
blocks = vec {
record {
transaction = record {
memo = 0 : nat64;
operation = opt variant {
Mint = record {
to = blob "t\ec\82\f5\e0\d8\05*\a1\1d\c7H$\9b\dd\0a\ec)\d6(\19\9e\ee\ef\ad\d0\13\8f\8b\1b\10Y";
amount = record { e8s = 311_585_714_285 : nat64 };
}
};
created_at_time = record {
timestamp_nanos = 1_620_328_630_192_468_691 : nat64;
};
};
timestamp = record {
timestamp_nanos = 1_620_328_630_192_468_691 : nat64;
};
parent_hash = opt blob "\ff\ca\0e\cf^\83uA\c7\ee[\e41\e43\ad\8e\97*\7f7\1e\86\fb\e4\f8\addl|\bc\ea";
};
};
}
},
)
In both cases I’d expect the data to be binary data - the to field is likely an account identifier and the parent_hash is just what it says: a hash. As for how that would be converted to actual bytes (or hex) I don’t know. I’ll ping the Candid specialists for that.
blob is a short hand for vec nat8, which represents binary data. If the byte is a printable ascii, we show that character directly. Otherwise, we use \xx to represent its hex byte. For example, blob “t\ec\82” would be 74ec82 in hex.
@chenyan@Vivienne, could you help me with these more detailed questions about the record format:
What is ‘memo’ for? it seems that it is always 0. If it always 0, why is it there?
Every record has information about the destination of the transaction (‘to’ field) but it has no information about the origin (there is no ‘from’ field). Without this information, it is not possible to trace the flow of transactions. Is this correct? How can I identify the origin of every transaction?
I’m only 99% sure, but I think the memo is for transaction (TX) deduplication. I have a canister that triggers multiple identical transfers in the same function and if I don’t change the memo between the TXs then it only executes one payment. Maybe there’s some more behind the memo, but that’s the use case I know about.
If you look at the .did file, you can see that there’s three TX types: Mint, Burn, and Transfer. It looks like you only found blocks with Mint operations in them, that’s why you haven’t seen a from field yet.
@Vivienne@chenyan, I have successfully decoded the principal_ids and confirmed that they exist, so the decoding works. However, when I apply the same decoding algorithm to the parent_hash field, I am not able to find the transaction (FYI, I use ICP Explorer<parent_hash_decoded> ). Is the parent_hash field using a different decoding algorithm?
I think that would be a different algorithm. I’m not familiar with ledger, but I would assume this is a good entry point to start searching: ic/lib.rs at master · dfinity/ic · GitHub
actually, before sending my question, I tried to reverse engineer the encoding strategy for parent_has unsuccessfully probably because my rust skills are quiet bad. I would appreciate ledger developer’s feedback
Please take a look at the specification for the ledger . In particular, there’s a section which describes how blocks are hashed. Hopefully that will help.