How to verify ICP transactions?


[via Motoko]
so I transferred some ICP using “transfer” call on NNS Ledger canister, and it returned me { Ok: nat64 }. Is there a way to verify this? on my canister, there will be a public shared({caller}) iHavePaid(to: Principal, transferResult: Nat64) function, how should I verify the transferResult?

[via browsing web]
I did check the transaction at and the transferResult is the block index(? pls correct me if i’m wrong), but the real identifier on the transaction history there was the Hash. If I search on the dashboard by using the block index, i get nothing, but when i use the hash, it will redirect me to the transaction detail.

[via Motoko]
How can i get the transaction details by using this block index so that i can verify it myself like so: (payer == caller and payee == to and total == amount)?

I did try dfx canister call nnsledger query_block and it gave me this

How am I supposed to make sense of this? I dont know what is what :frowning:

Thank you :slight_smile:


Have a look at the Ledger documentation. A lot of it is explained in these documents.

For Motoko interactions with the ledger, have a look at the defi and ledger-transfer examples. There you can see how to interact with the ledger, and from the full ledger interface (see link below or in the docs) you figure out what exact functions you want to call.

dfx canister call outputs encoded candid keys. If you want to see the decoded keys, download this file, can point to it using dfx canister call <...other args> --candid <path/to/ledger.did>


Hi Severin
Thanks for coming to my rescue

Got it, so the blockIndex will only get returned after a Successful or Completed token transfer, as below

One last question tho,
Can there be a block index with Failed or Incomplete transfer status? or will it ALWAYS 100% Successful?

I’m asking because, if the blockIndex can be Failed, then whats gonna happen when a user just pass a Failed blockIndex to my verifyTransfer(blockIndex: Nat64, memo: Nat64, sender: Principal, receiver: Principal, amount_e8s: Nat64)? What if this function queries the ledger canister for the block, then find all these properties to be matched? Won’t that be unfair? since the user failed to transfer, yet he will be treated as if his transfer was successful (since the status (Success/Fail) is not included the transaction detail).

Or am I looking too much into this?

Thank you again.

Where do you get the idea that there could be an incomplete transfer? If you look at TransferResult you can see that it is either Ok(blockIndex) or Err(transferError). There is no option for an incomplete transfer. If the transfer fails then no block is created.

1 Like

Thanks @Severin

If the transfer fails then no block is created.

200 IQ based and redpilled