Докази Меркла
Кожне розв'язання імені, яке повертає API, супроводжується доказом Меркла. Він дозволяє звірити відповідь із коренем стану, а не довіряти серверу, що її надіслав.
Дерево
PiNS зберігає всі імена в компактному розрідженому дереві Меркла над 128-бітовим простором
ключів. Ключ імені — це перші 16 байтів SHA-256(domain_name), тому імена розподіляються
рівномірно і ніхто не може обрати, куди потрапить його ім'я.
«Компактне» означає, що лист розміщується на мінімальній глибині, де префікс його ключа унікальний, а не на фіксованій глибині 128. У дереві з кількома тисячами імен більшість доказів складається лише з десятка з невеликим хешів — достатньо мало, щоб перевірити їх на телефоні, у розширенні браузера чи всередині гаманця.
Два наслідки, про які варто знати, перш ніж писати верифікатор:
- Довжина доказу непостійна. Читайте
proof_depthз відповіді й ніколи не розраховуйте на фіксований розмір. - Порожнє піддерево — це 32 нульові байти на будь-якій висоті. Тому корінь порожнього дерева
складається з самих нулів: щойно ініціалізований індексатор, який повідомляє
0000…0000, працює правильно, а не зламаний.
Що містить доказ
| Поле | Значення |
|---|---|
merkle_proof | сусідні хеші, [0] — найглибший (найближчий до листа) |
proof_depth | кількість сусідів — має збігатися з merkle_proof.length |
proof_terminal | що розташоване в кінці шляху: Occupied, Vacant або Blocked |
smt_root | корінь, який відновлюють ці сусіди |
Наявність і відсутність
Саме термінал дозволяє доказу стверджувати «це ім'я не зареєстроване» так само переконливо, як і «зареєстроване»:
Occupied— у кінці шляху стоїть власний лист цього ключа. Ім'я існує, і виданий вам запис — той самий, що лежить у дереві.Vacant— там порожнє піддерево. Ім'я не зареєстроване.Blocked— цю позицію займає лист іншого імені. Ім'я не зареєстроване; відповідь несе блокувальний запис, тож ви можете переконатися, що він хешується в знайдений там лист і що його ключ справді поділяє той самий префікс.
Без Blocked індексатор міг би приховати реєстрацію, заявивши, що слот порожній. Оскільки
блокувальний запис включено повністю, цю заяву можна перевірити, а не прийняти на віру.
Перевірка
Захешуйте запис у лист, потім згорніть сусідів назад до кореня, визначаючи на кожному кроці за
бітами ключа, іти ліворуч чи праворуч. Якщо ви прийшли до smt_root, запис — рівно те, що фіксує
дерево.
Залишається одне запитання: а smt_root — це справжній корінь? Відповідь дає якірний контракт у
BNB Smart Chain. Обидва кроки, з перевіреним кодом на Python, PHP і JavaScript, описані в розділі
Перевірка доказів.