Pruebas de Merkle
Cada resolución que devuelve la API viene con una prueba de Merkle. Le permite contrastar la respuesta con una raíz de estado en vez de confiar en el servidor que se la envió.
El árbol
PiNS guarda todos los nombres en un árbol de Merkle disperso compacto sobre un espacio de
claves de 128 bits. La clave de un nombre son los primeros 16 bytes de SHA-256(domain_name),
de modo que los nombres se distribuyen uniformemente y nadie puede elegir dónde cae el suyo.
«Compacto» significa que una hoja se sitúa a la menor profundidad en la que el prefijo de su clave es único, en lugar de a una profundidad fija de 128. En un árbol con unos pocos miles de nombres, la mayoría de las pruebas son solo una docena larga de hashes: lo bastante pequeñas para verificarlas en un teléfono, en una extensión del navegador o dentro de un monedero.
Dos consecuencias que conviene conocer antes de escribir un verificador:
- La longitud de la prueba varía. Lea
proof_depthde la respuesta; nunca dé por supuesto un tamaño fijo. - Un subárbol vacío son 32 bytes a cero a cualquier altura. Por eso la raíz de un árbol
vacío es toda ceros: un indexador recién inicializado que informe
0000…0000es correcto, no está averiado.
Qué contiene una prueba
| Campo | Significado |
|---|---|
merkle_proof | hashes hermanos, [0] el más profundo (el más cercano a la hoja) |
proof_depth | número de hermanos — debe coincidir con merkle_proof.length |
proof_terminal | qué hay al final del camino: Occupied, Vacant o Blocked |
smt_root | la raíz que reconstruyen esos hermanos |
Presencia y ausencia
El terminal es lo que permite a una prueba afirmar «este nombre no está registrado» con tanta solidez como «sí lo está»:
Occupied: al final del camino está la hoja propia de la clave. El nombre existe, y el registro que le han dado es el que hay en el árbol.Vacant: ahí hay un subárbol vacío. El nombre no está registrado.Blocked: esa posición la ocupa la hoja de un nombre distinto. El nombre no está registrado; la respuesta incluye el registro que bloquea para que pueda comprobar que su hash coincide con la hoja hallada allí y que su clave comparte realmente el prefijo.
Sin Blocked, un indexador podría ocultar un registro afirmando que un hueco estaba vacío. Como
el registro que bloquea se incluye completo, usted puede comprobar la afirmación en vez de
aceptarla.
Verificar
Convierta el registro en una hoja mediante hash y luego pliegue los hermanos de vuelta hasta la
raíz, usando los bits de la clave para decidir izquierda o derecha en cada paso. Si llega a
smt_root, el registro es exactamente aquello a lo que se compromete el árbol.
Queda una pregunta: ¿es smt_root la raíz auténtica? Respóndala preguntando al contrato ancla
en BNB Smart Chain. Ambos pasos, con código probado en Python, PHP y JavaScript, están en
Verificar pruebas.