Перейти до основного вмісту

Докази Меркла

Кожне розв'язання імені, яке повертає 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, описані в розділі Перевірка доказів.