Proofs verifying (low-level)
Overview
This section describes instructions and manuals for interacting with TON at a low level. it is assumed that you have already become familiar with exotic cells, TL-B language and understand the simple proof verifying example.
This article describes advanced examples of verifying proofs from Liteservers.
It's important to check any data you receive from a node for trustless interaction with the blockchain. However, the article covers only part of trustless communication with Liteserver, because its assumed that you verified the Block hash you received from a Liteserver (or from anyone else). Block hash verifying is more advanced, because you need to sync key blocks and (or) check block signatures, and will be described in the other article in the future. But anyway even using only these examples you're decreasing probability that Liteserver will send you the wrong data that you will believe.
Block Header
Let's say we know a Block ID:
<TL BlockIdExt [wc=-1, shard=-9223372036854775808, seqno=31220993, root_hash=51ed3b9e728e7c548b15a5e5ce988b4a74984c3f8374f3f1a52c7b1f46c26406, file_hash=d4fcdc692de1a252deb379cd25774842b733e6a96525adf82b8ffc41da667bf5] >
And we ask a Liteserver for a Header for this block. Liteserver response
contains a header_proof
boc.
Show boc
b5ee9c72010207010001470009460351ed3b9e728e7c548b15a5e5ce988b4a74984c3f8374f3f1a52c7b1f46c26406001601241011ef55aaffffff110204050601a09bc7a98700000000040101dc65010000000100ffffffff000000000000000064b6c356000023d38ba64000000023d38ba64004886d00960007028101dc64fd01dc42bec400000003000000000000002e030098000023d38b96fdc401dc650048a3971c46472b85c8d761060a6e7ae9f13a90cdda815915a89597cfecb393a6b568807adfb3c1c5efc920907225175db61ca384e4f8b313799e3cbb8b7b4085284801018c6053c1185700c0fe4311d5cf8fa533ea0382e361a7b76d0cf299b75ac0356c000328480101741100d622b0d5264bcdb86a14e36fc8c349b82ae49e037002eb07079ead8b060015284801015720b6aefcbf406209522895faa6c0d10cc3315d90bcaf09791b19f595e86f8f0007
After boc deserialization, we got Cell:
280[0351ED3B9E728E7C548B15A5E5CE988B4A74984C3F8374F3F1A52C7B1F46C264060016] -> {
64[11EF55AAFFFFFF11] -> {
640[9BC7A98700000000040101DC65010000000100FFFFFFFF000000000000000064B6C356000023D38BA64000000023D38BA64004886D00960007028101DC64FD01DC42BEC400000003000000000000002E] -> {
608[000023D38B96FDC401DC650048A3971C46472B85C8D761060A6E7AE9F13A90CDDA815915A89597CFECB393A6B568807ADFB3C1C5EFC920907225175DB61CA384E4F8B313799E3CBB8B7B4085]
},
288[01018C6053C1185700C0FE4311D5CF8FA533EA0382E361A7B76D0CF299B75AC0356C0003],
288[0101741100D622B0D5264BCDB86A14E36FC8C349B82AE49E037002EB07079EAD8B060015],
288[01015720B6AEFCBF406209522895FAA6C0D10CC3315D90BCAF09791B19F595E86F8F0007]
}
}
that we should deserialize according to the Block Tlb scheme:
{
'global_id': -239,
'info':
{
'version': 0,
'not_master': 0,
'after_merge': 0,
'before_split': 0,
'after_split': 0,
'want_split': False,
'want_merge': True,
'key_block': False,
'vert_seqno_incr': 0,
'flags': 1,
'seqno': 31220993,
'vert_seqno': 1,
'shard': {'shard_pfx_bits': 0, 'workchain_id': -1, 'shard_prefix': 0},
'gen_utime': 1689699158,
'start_lt': 39391488000000,
'end_lt': 39391488000004,
'gen_validator_list_hash_short': 2288844950,
'gen_catchain_seqno': 459393,
'min_ref_mc_seqno': 31220989,
'prev_key_block_seqno': 31212222,
'gen_software': {'version': 3, 'capabilities': 46},
'master_ref': None,
'prev_ref': {'type_': 'prev_blk_info', 'prev': {'end_lt': 39391487000004, 'seqno': 31220992, 'root_hash': b'H\xa3\x97\x1cFG+\x85\xc8\xd7a\x06\nnz\xe9\xf1:\x90\xcd\xda\x81Y\x15\xa8\x95\x97\xcf\xec\xb3\x93\xa6', 'file_hash': b'\xb5h\x80z\xdf\xb3\xc1\xc5\xef\xc9 \x90r%\x17]\xb6\x1c\xa3\x84\xe4\xf8\xb3\x13y\x9e<\xbb\x8b{@\x85'}},
'prev_vert_ref': None
},
'value_flow': None,
'state_update': None,
'extra': None
}
Now, we should check that seqno
in deserialized block matches to block seqno
we know, and then compute hash_1 of the only
Merkle Proof reference and compare it to block hash we know:
assert h_proof.refs[0].get_hash(0) == block_id.root_hash
Now, we can trust all other data, this Cell contains
Checking Proof Examples: Python, Kotlin, C++