Saltar al contenido principal

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_depth de 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…0000 es correcto, no está averiado.

Qué contiene una prueba

CampoSignificado
merkle_proofhashes hermanos, [0] el más profundo (el más cercano a la hoja)
proof_depthnúmero de hermanos — debe coincidir con merkle_proof.length
proof_terminalqué hay al final del camino: Occupied, Vacant o Blocked
smt_rootla 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.