Parceros
  • 👽Recursos
    • 💻Nodos validadores
      • Buenas prácticas y seguridad de un validador
      • Montaje de nodo validador de Stargaze
      • Montaje de nodo validador de Tgrade
      • Montaje de nodo validador de Juno
      • Instalacion del Cosmovisor
      • Instalación de AutoCompound
      • Guía de instalación Prometheus y Grafana para un Validador
    • 🎓Desarrollo
      • Fundamentos en Gnu/Linux
      • Fundamentos en Blockchain
      • Billeteras
      • Introducción a Cosmos Hub
      • Guia de Inicio en Rust
      • Clases de CosmWasm
        • Introducción a CosmWasm
        • Puntos de entrada de un contrato vacio
        • Consultas - Query
      • Clases de Rust
        • Introducción a Rust
        • Ciclos
        • Funciones
        • Manejo de la memoria
        • Tipos de datos avanzados
        • Macros
        • Manejo de paquetes
        • Manejo de errores
      • Guia Archway
        • Instalación de requisitos
        • Configuración del proyecto
        • Solicitud de tokens Testnet
        • Mi primera app
          • Configuracion
          • Produciendo ejecutables wasm
          • Despliegue e instanciación de contratos en la cadena
          • Interactuar con su contrato
          • Construir el frontend de la dApp
        • Proyecto NFT
          • Creando un proyecto NFT
          • Despliegue del contrato de tokens
          • Acuñación y envío de tokens
          • Construye la Dapp NFT
        • Fee Grant
          • Comprendiendo los Fee grant
          • Grant asignación
          • Utilizando asignaciones grant
        • Multifirmas
          • Archway multi firma hub
          • Navegar por la interfaz multi firmas
      • Cosmwasm Documentacion
        • Introducción
        • Primeros pasos
          • Introducción
          • Configuración del entorno
          • Elaborar un contrato
          • Test Unitarios
          • Despliegue e interacción
          • Integración con contratos inteligentes
          • Próximos pasos
        • Arquitectura
          • ¿Qué son los contratos multicadena?
          • Modelo de actor para las convocatorias de contratos
          • Nombres y direcciones
          • Consulta del estado del contrato
          • Formatos de serialización
          • Composición del contrato
          • Comparación con los contratos de solidity
        • Contratos inteligentes
          • Semántica contractual
          • Message
            • Messages
            • Submensajes
          • State
            • Simple state
            • Complex state y maps
          • Result y option
          • Entry points
          • Query
          • Events
          • Math
          • Verificación de contratos inteligentes
          • Migration
          • Migrar una dapp a una red diferente
          • Testing
          • Ejecución Sudo
          • CosmWasm y CIB
        • Tutoriales
          • Opcion simple
            • Testing
          • Storage
            • ¿Cómo funciona el almacenamiento de valores clave?
            • Índices
            • Modelización avanzada de estados
          • Cosmwasm con ejemplos
            • Operaciones matemáticas de Cosmowasm
            • Crear una instancia de un contrato CosmWasm
            • Timelock
            • Contrato Crowdfunding
            • Respuestas y atributos en Cosmwasm
            • Lee y escribe
            • Envío de tokens
            • Token Vaults
            • Creador de mercado automático de productos constantes (AMM)
      • Guia Celestia
        • Descripcion general de celestia
          • Introduccion
          • Blockchains monolíticos vs modulares
          • Capa de disponibilidad de datos
            • La capa de disponibilidad de datos de Celestia
            • El ciclo de vida de una transacción celestia-app
            • Recuperabilidad de datos y poda
            • Disponibilidad de datos FAQ
          • Recursos adicionales
            • Aprende modular
            • Glosario de Celestia
            • Especificaciones de aplicación de celestes
            • Documentación API de nodo celestial
        • Ejecutar un nodo
          • Descripción general de los nodos en ejecución en Celestia
          • Guía de inicio rápido
            • Decidir qué nodo ejecutar
            • Entorno de desarrollo
            • Instalar celestia-node
            • Instalar celestia-app
            • 🐳 Configuración de Docker
          • Redes
            • Resumen de redes
            • Mainnet Beta
            • Mocha testnet
            • Arábica devnet
          • Tipos de nodos
            • Disponibilidad de datos
              • Nodo ligero
              • Nodo completo
              • Nodo puente
            • Consenso
            • Relay de IBC
              • Guía de retransmisión IBC
              • Relays de IBC
          • Recursos
            • nodo-celestia
              • Metricas
              • guía config.toml
              • Redes y valores personalizados
              • Solución de problemas
            • celestia-app
              • Especificaciones
              • Métricas, visualización y alertas
              • Mecánica de corte
              • Crear un testnet Celestia
              • Comandos CLI útiles
              • Monitor de Actualización
              • Carteras en celestia-app
              • Multisig
              • Crea una cuenta de adquisición
            • SystemD
            • Proceso de hardfork
        • Desarrolladores
          • Construir modular
          • Envío de blobs de datos a Celestia
          • Directrices de reenvío de transacciones
          • API de nodo
            • Celestia-node RPC CLI tutorial
            • Documentación de la API RPC de Celestia-Node
            • Rápido Scavenger
            • Page
          • Integrar con Blobstream
            • Descripción general de Blobstream
            • Integrarse con contratos de Blobstream
            • Integrar con el cliente Blobstream
            • Consultando las pruebas de Blobstream
            • Operadores locales de Blobstream X
              • Solicitar rangos de compromiso de datos
              • Nuevas implementaciones de Blobstream X
          • Implementar un rollup
            • L2s Ethereum
              • Ethereum fallback
              • Arbitro
                • Introducción a los rollups de Arbitrum con Celestia como DA
                • Implementar un arbitrum rollup devnet
                • Testnet de nitrógeno
                • Implementar un contrato inteligente sobre la implementación de Arbitrum
                • Implemente un dapp en su devnet Arbitrum rollup
                • Optimismo
                  • Introducción a la integración de OP Stack
                  • Bubs testnet
                  • Implemente un contrato inteligente en Bubs testnet
                  • Implemente un dapp en Bubs testnet
                  • Implemente un devnet OP Stack
                  • Implemente un devnet OP Stack en Celestia
                  • Auditoría
                  • Implemente un dapp con thirdweb
                  • Rollups-as-a-Servicio
                    • Caldera
            • Rollkit
            • Astria
              • Documentación
              • Implementar a Dusknet
            • SDK Soberano
            • Vistara
            • Dimensión
          • Carteras
            • Crea una billetera con celestia-node
            • Integraciones de billeteras con Celestia
          • Integre Celestia para proveedores de servicios
      • Unión
        • Arquitectura
          • CometBLS
          • Galois
          • Voyager
        • Conceptos
          • BLS Firmas
          • Clientes de Luz Condicional
          • Verificación de Consenso
          • Tecnología de validador distribuido
          • IBC
          • Sin permiso versus sin confianza
        • Infraestructura
          • Operador de nodo
            • Empezando
            • Docker Compose
            • Kubernetes
            • NixOS
            • Configuración del Nodo
        • Integracion
          • IBC Enabled Solidity
        • Demostrar
          • Dirigiendo el Union Devnet
          • PingPong
        • Unirse al testnet
          • Empezando
          • Ejecutar el binario cliente
          • Ejecución de Unionvisor
          • Obteniendo Tokens Testnet
          • Crear un Validador
          • Endpoints publicos
          • Sincronización de estado
          • Liberar un validador
          • Preguntas frecuentes
          • Historial de actualizaciones
        • Guia de estilo
          • Lista de palabras
      • Avail
        • Introducción a Avail
          • Aprovechar DA
          • Aprovechar Nexus
          • Aprovechar la fusión
        • Informacion de red
        • Más información sobre disponibilidad
          • El conseso
            • BABE
            • GRANDPA
            • NPoS
          • EIP-4844 y disponible
        • Guia de nuevo usuario
          • Cómo crear y administrar una cuenta disponible
          • Cómo utilizar el Explorador Goldberg Testnet
          • Cómo utilizar el faucet Testnet
          • Cómo establecer una identidad en cadena
          • Cómo generar una identificación de aplicación disponible
          • Cómo realizar transferencias de saldo disponibles
          • Cómo crear grupos de nominaciones disponibles
        • Construir con disponibilidad
          • Cree un paquete acumulativo con Avail
          • Comience con Avail
          • Optimium
            • OP Stack
            • Aprovechando la pila OP con Avail
            • Cómo utilizar la pila OP con Avail
            • Adaptador de pila OP 🔗
          • Validium
            • Polygon zkEVM
              • Construyendo sobre Polygon zkEVM con Avail
              • Cómo utilizar Polygon zkEVM con Avail
              • Nodo Validium 🔗
              • Contratos de Validium 🔗
              • Puente Validium 🔗
            • Madara Starknet
              • Construyendo sobre Madara Stack con Avail
              • Cómo utilizar Madara con Avail
              • Madara Starknet🔗
            • Referencia
          • Sovereign Rollups
            • Sovereign SDK 🔗
            • Rollkit 🔗
            • OpEVM 🔗
        • Glosario
        • Preguntas generales frecuentes
      • Dymension
        • Aprender
          • ELI5
          • RollApps
            • RollApps
            • Tokens
            • Gobernancia
            • Puente
            • En profundidad
              • Dymension RDK
                • Dymint
              • Gobernanza
                • Gobernador
                  • Descripción general
                  • Crear gobernador
                  • Otros comandos
                • Votación
                  • Parámetros ajustables
                  • Gasto comunitario
                  • Registro de tokens ERC-20
              • IBC Puente
                • Visión general
                • Seguridad
                • Retransmisores
          • Dymension
            • Visión general
            • DYM
              • Supply
              • Demanda
              • Crecimiento
              • Distribución
            • Seguridad
              • Estándares
              • Actualizable
              • Disponibilidad de datos
              • Pruebas de fraude
              • Resistencia a la censura
              • Page 1
            • Puentes
              • IBC
              • eIBC
            • Liquidez
              • Descripción general
              • Depositar tokens
              • Vinculación de tokens LP
              • Incentivos
              • Comisiones
            • Gobernanza
              • Descripción general
              • Preparando una propuesta
              • Proponiendo a la dimocracia
        • Construir
          • Descripción general
          • Testnet
            • EVM
              • Descripción general
            • CosmWasm
              • Descripción general
              • Información
              • Ejemplo de cosmoWasm
          • Roller CLI
            • Descripción general
            • Comenzar
              • Instalar
              • Inicializar RollApp
              • Registro
              • Correr
                • Simple
                • Avanzado
                  • Cliente ligero DA
                  • Secuenciador
                  • Retransmisor
            • Nodo en ejecución
              • Ejecutando en producción
              • Supervisión
              • Información de RollApp
              • Exportar claves
              • Mejora
              • Editar la configuración de RollApp
              • Sincronización de estado
            • Solución de problemas
              • Descripción general
              • Saldos
              • Hardware
              • Rollapp de importación/exportación
              • Acceso externo
              • Estado
              • Archivos de registro
            • RollApp local
              • Ejecute la aplicación EVM RollApp
              • Ejecute la aplicación CosmWasm RollApp
        • Validar
          • Preguntas frecuentes sobre nodos
          • Construir dimensión
          • Configuración de nodo
          • Únase a una red
          • Nodo de sincronización
          • Validador
          • Actualizaciones
          • Solución de problemas
          • Programa de delegación
            • objetivos del programa
            • Parámetros de evaluación
            • Solicitud
      • Movement
        • Desarrolladores
          • Inicio rápido
          • Configuración
            • Usando contenedores
            • Usando el instalador
          • Tutoriales
            • Desplegar
              • Módulo Aptos
              • Módulo Sui
              • Contratos EVM
                • Implementación de contratos de solidez en movimiento utilizando Foundry y Fractal
                • Implementación de contratos de solidez en M1 usando Hardhat y Fractal
                • Implementación de contratos inteligentes de Solidity en M1 utilizando el tiempo de ejecución Fractal
            • Ejecute MoveVM
              • Ejecutando M1 usted mismo
            • Construir dApp
              • Aptos Move dApp
              • Aplicación Sui Move
              • DApp de solidity
            • Interoperar
              • AptosVM<>MEVM
          • Herramientas de desarrollo
            • Movement CLI
              • Movement aptos
                • cuenta
                  • crear
                  • crear-cuenta-de-recursos
                    • derivar-dirección-de-cuenta-de-recursos
                  • fondo-con-grifo
                  • lista
                  • dirección de búsqueda
                  • rotar llave
                  • transferir
                • configuración
                  • generar-compleciones-de-shell
                  • configurar-global-config
                  • show-global-config
                  • mostrar-perfiles
                • génesis
                  • generar-admin-escritura-conjunto
                  • generar-génesis
                  • obtener direcciones de grupo
                  • generar-claves
                  • generar-plantilla-de-diseño
                  • configuración-git
                  • configuración-del-validador-de-conjuntos
                • gobernancia
                  • proponer
                  • votar
                  • propuesta de show
                  • lista-propuestas
                  • verificar-propuesta
                  • ejecutar propuesta
                  • generar-propuesta-de-actualización
                  • aprobar-ejecución-hash
                • información
                • init
                • llave
                  • generar
                  • extraer-peer
                • mover
                  • construir-publicar-carga útil
                  • limpio
                  • compilar
                  • script de compilación
                  • cobertura
                    • resumen
                    • fuente
                    • código de bytes
                  • crear-cuenta-de-recursos-y-publicar-paquete
                  • desmontar
                  • documento
                  • descargar
                  • init
                  • list
                  • probar
                  • publicar
                  • correr
                  • ejecutar guión
                  • prueba
                  • prueba transaccional
                  • verificar-paquete
                  • vista
                • multifirma
                  • aprobar
                  • crear
                  • crear-transacción
                  • ejecutar
                  • ejecutar-rechazar
                  • ejecutar con carga útil
                  • rechazar
                  • verificar-propuesta
                • nodo
                  • analizar-validador-rendimiento
                  • arranque-db
                  • verificar-conectividad-de-red
                  • conseguir-participación-pool
                  • inicializar-validador
                  • conjunto de validadores de unión
                  • conjunto de validadores de licencia
                  • mostrar-información-de-época
                  • mostrar-validador-config
                  • mostrar-conjunto-validador
                  • mostrar-validador-participación
                  • ejecutar-testnet-local
                  • actualización-clave-de-consenso
                  • actualizar-validador-direcciones-de-red
                • apostar
                  • agregar apuesta
                  • crear-contrato-de-participación
                  • distribuir-monedas-adquiridas
                  • aumentar-bloqueo
                  • inicializar-propietario de la participación
                  • solicitud-comisión
                  • establecer-votante-delegado
                  • operador de conjunto
                  • desbloquear-apuesta
                  • desbloquear-monedas-adquiridas
                  • retirar-apuesta
                • actualizar
              • movement sui
                • comenzar
                • génesis
                • ceremonia-genesis
                  • init
                  • estado de validación
                  • agregar-validador
                  • validadores de lista
                  • punto de control de compilación sin firmar
                  • examinar-punto-de-control-génesis
                  • verificar y firmar
                  • finalizar
                • herramienta clave
                  • convertir
                  • decodificar-tx-bytes
                  • decodificar-multi-sig
                  • generar
                  • importar
                  • lista
                  • par de claves de carga
                  • dirección multifirma
                  • multi-sig-combinar-sig-parcial
                  • herencia-sig-parcial-combinada-multi-sig
                  • espectáculo
                  • firmar
                  • señal-kms
                  • deshacer
                  • zk-login-firmar-y-ejecutar-tx
                  • zk-login-ingresar-token
                  • zk-login-sig-verificar
                  • zk-login-signo-inseguro-mensaje-personal
                • consola
                • cliente
                  • dirección activa
                  • entorno-activo
                  • direcciones
                  • llamar
                  • identificador de cadena
                  • campo dinámico
                  • env
                  • ejecutar-tx firmado
                  • gas
                  • fusionar moneda
                  • nueva direccion
                  • nuevo-ambiente
                  • objeto
                  • objetos
                  • pagar
                  • pago todo-sui
                  • pay-sui
                  • publicar
                  • moneda dividida
                  • cambiar
                  • bloque tx
                  • transferir
                  • transferencia-sui
                  • mejora
                  • verificar-bytecode-metro
                  • verificar-fuente
                  • transacción-repetición
                  • lote de repetición
                  • punto de control de repetición
                • validador
                  • hacer-información-validador
                  • convertirse en candidato
                  • comité conjunto
                  • comité de licencia
                  • metadatos de visualización
                  • actualizar-metadatos
                    • nombre
                    • descripción
                    • URL de la imagen
                    • URL del proyecto
                    • dirección de red
                    • dirección primaria
                    • dirección-trabajador
                    • dirección-p2p
                    • clave-pub-de-red
                    • clave-pub-trabajador
                    • protocolo-pub-clave
                  • actualizar-precio-de-gas
                  • validador de informes
                  • serializar-carga útil-pop
                  • mostrar-actualización-del-precio-del-gas-raw-txn
                • move
                  • construir
                  • cobertura
                    • resumen
                    • fuente
                    • código de bytes
                  • desmontar
                  • nuevo
                  • probar
                  • prueba
                • simulacro de incendio
                  • rotación de metadatos
              • movement ctl
              • movement manage
            • fractales
              • marco evm
          • Desarrolladores Aptos
            • Configurar la CLI de Aptos
            • Usando la CLI de Aptos
          • Desarrolladores Sui
            • Configurar Sui CLI
            • Usando Sui CLI
          • Preguntas más frecuentes
        • Ecosistema
          • Wallets
          • Tokens
          • Faucet
          • Move idioma
            • Módulos y scripts
            • Tipos primitivos
              • Enteros
              • booleano
              • DIRECCIÓN
              • Vector
              • Firmante
              • Referencias
              • Tuplas y unidad
          • Recursos de aprendizaje
          • Techpedia
            • Paralelización
            • Mover recursos
            • SDK de movement
      • Initia
        • ACERCA DE
          • Bienvenido a Inicia
          • Arquitectura Omnitia
            • Inicia (Capa 1)
            • Minitia (Capa 2)
          • Ciclo de vida de la transacción
          • Liquidez y apuestas consagradas
            • IniciaDEX
          • Programa de intereses adquiridos
        • CONSTRUIR SOBRE LA INICIATIVA
          • iniciado
          • inicia.js
          • Creando cuenta
          • Tutoriales específicos de VM
            • MoverVM
              • Implementación de módulos de movimiento
              • Creando moneda de movimiento
              • Envío de moneda de movimiento
              • Creando movimiento NFT
              • Módulos relacionados con el replanteo
              • Interactuar con Oracle en MoveVM
              • Mover ganchos IBC
            • WASMVM
              • Implementación del contrato CosmWasm
              • Interactuando con Oracle en WasmVM
              • Ganchos Wasm IBC
              • Fábrica de fichas
            • EVM
              • Implementación del contrato de solidez
              • Crear un token ERC-20 personalizado
              • Consultar estados del cosmos
              • Ejecutando mensajes de Cosmos
              • Conversión de direcciones entre EVM y Cosmos
              • Conversión entre direcciones Denom y ERC-20
              • Interactuar con Oracle en EVM
              • Ganchos EVM IBC
              • Ethereum JSON-RPC
          • Tutoriales generales
            • Oráculo: Furtivo
            • Mensajes entre cadenas
            • Saltar API
            • Miniswap
              • Interactuando con Minitswap
            • Conversión entre nombres de usuario y direcciones
            • Usando el Explorador local de Initia
            • Interactuando con InitiaDEX
            • Usando el widget de billetera Initia
        • IMPLEMENTAR MINITIA
          • Empezando
            • Implementación de su propia Minitia (Capa 2)
          • Configuración
          • Implementación de una Minitia independiente
          • Implementación completa de Minitia
            • Dirigiendo la Minitia
            • Pila de OPinit
              • Módulo OPinit: OPhost y OPchild
              • Configurar robots OPinit
                • Ejecutor del puente
                • Remitente de salida
                • Desafiador
                • Envío por lotes
                  • Envío de lotes a Inicia L1
                  • Envío de lotes a Celestia
            • Relé Hermes (IBC)
            • Habilitando oráculos
          • Retroceder
          • Agregar tokens a Initia Wallet
          • Personalizando Minitia
        • EJECUTAR EL NODO DE INICIO
          • Ejecutando el nodo de inicio
          • Arrancar un nodo de inicio
          • Conéctese a la red Inicial
          • Oráculo
          • Automatización de actualizaciones de software con Cosmovisor
          • Convertirse en un validador
        • RECURSOS
          • Registro de Iniciación
          • Información de la cadena Testnet
          • Parámetros de cadena
          • Documentación de la API
          • Documentos API (MiniMove)
          • Documentos API (MiniWasm)
          • Documentos API (MiniEVM)
      • Internet Computer
        • ¡Hola, mundo!
        • Descripción general del ICP
Powered by GitBook
On this page
  • Requisitos previos​
  • Descripción general de las consultas de prueba​
  • Demostración práctica​
  • Convertir las pruebas para ser utilizables en el DAVerifier biblioteca​
  • Conclusión​
  1. Recursos
  2. Desarrollo
  3. Guia Celestia
  4. Desarrolladores
  5. Integrar con Blobstream

Consultando las pruebas de Blobstream

PreviousIntegrar con el cliente BlobstreamNextOperadores locales de Blobstream X

Last updated 1 year ago

Requisitos previos

  • Acceso a una Celestia Punto final de RPC (o nodo completo). El nodo no necesita ser un nodo de validación para que se consulten las pruebas. Un nodo completo es suficiente.

Descripción general de las consultas de prueba

Para probar la inclusión de transacciones, blobs o acciones de PayForBlobs (PFB), comprometidas en un bloque de Celestia, utilizamos el RPC del nodo de consenso de Celestia para buscar pruebas que puedan verificarse en un contrato de liquidación nominal a través de Blobstream. De hecho, cuando una transacción PFB se incluye en un bloque, se separa en una transacción PFB (sin el blob) y el blob de datos real que lleva. Estos dos se dividen en acciones, que son las construcciones de bajo nivel de un bloque Celestia, y se guardan en el bloque Celestia correspondiente. Obtenga más información sobre las acciones en el .

Los dos diagramas a continuación resumen cómo se compromete una sola acción, que puede contener una transacción PFB, o una parte de los datos de despliegue que se publicaron utilizando un PFB, en Blobstream.

La parte se destaca en verde. R0, R1 etc., representan las respectivas raíces de fila y columna, los gradientes azul y rosa son datos codificados de borrado. Se pueden encontrar más detalles sobre el diseño cuadrado y parte de las especificaciones.

La plaza Celestia

Plaza
  • 0: esas son las acciones, que cuando están unificadas, contienen el PFB o el blob de datos de rollup.

  • 2: las raíces de datos: que son el compromiso binario del árbol de merkle sobre las raíces de fila y columna. Esto significa que si puede probar que una acción es parte de una fila, use una prueba de merkle de espacio de nombres. Luego pruebe que esta fila está comprometida con la raíz de datos. Entonces puede estar seguro de que esa acción se publicó en el bloque correspondiente.

  • 3: para agrupar varios bloques en el mismo compromiso, creamos un compromiso sobre el (dataRoot, height) tupla para un lote de bloques, lo que da como resultado una raíz de tupla de raíz de datos. Es este compromiso el que se almacena en el contrato inteligente de Blobstream X.

Entonces, si podemos demostrar que una acción es parte de una fila, entonces esa fila está comprometida por una raíz de datos. Luego, demuestre que esa raíz de datos junto con su altura está comprometida con la raíz de tupla de raíz de datos, que se guarda en el contrato de Blobstream X, podemos estar seguros de que esa participación se comprometió en el bloque Celestia correspondiente.

En este documento, proporcionaremos detalles sobre cómo consultar las pruebas anteriores y cómo adaptarlas para enviarlas a un contrato de rollup para su verificación.

Esta parte proporcionará los detalles de la generación de pruebas y la forma de hacer que los resultados de las consultas de pruebas estén listos para ser consumidos por el contrato de implementación objetivo.

NOTA

Para los fragmentos de cliente de go, asegúrese de tener los siguientes reemplazos en su go.mod:

ir

// go.mod
    github.com/cosmos/cosmos-sdk => github.com/celestiaorg/cosmos-sdk v1.18.3-sdk-v0.46.14
    github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
    github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
    github.com/tendermint/tendermint => github.com/celestiaorg/celestia-core v1.32.0-tm-v0.34.29

)

Además, asegúrese de actualizar las versiones para que coincidan con las últimas github.com/celestiaorg/cosmos-sdk y github.com/celestiaorg/celestia-core versiones.

El punto final se puede consultar utilizando el cliente golang:

ir

package main

import (
	"context"
	"fmt"
	"github.com/tendermint/tendermint/rpc/client/http"
	"os"
)

func main() {
	ctx := context.Background()
	trpc, err := http.New("tcp://localhost:26657", "/websocket")
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	err = trpc.Start()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	dcProof, err := trpc.DataRootInclusionProof(ctx, 15, 10, 20)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	fmt.Println(dcProof.Proof.String())
}

ir

package main

import (
	"context"
	"fmt"
	"github.com/celestiaorg/celestia-app/pkg/square"
	"github.com/ethereum/go-ethereum/accounts/abi/bind"
	ethcmn "github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/ethclient"
	blobstreamxwrapper "github.com/succinctlabs/blobstreamx/bindings"
	"github.com/tendermint/tendermint/crypto/merkle"
	"github.com/tendermint/tendermint/rpc/client/http"
	"math/big"
	"os"
)

func main() {
	err := verify()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

func verify() error {
	ctx := context.Background()

	// start the tendermint RPC client
	trpc, err := http.New("tcp://localhost:26657", "/websocket")
	if err != nil {
		return err
	}
	err = trpc.Start()
	if err != nil {
		return err
	}

	// get the PayForBlob transaction that contains the published blob
	tx, err := trpc.Tx(ctx, []byte("tx_hash"), true)
	if err != nil {
		return err
	}

	// get the block containing the PayForBlob transaction
	blockRes, err := trpc.Block(ctx, &tx.Height)
	if err != nil {
		return err
	}

	// get the nonce corresponding to the block height that contains
	// the PayForBlob transaction
	// since BlobstreamX emits events when new batches are submitted,
	// we will query the events
	// and look for the range committing to the blob
	// first, connect to an EVM RPC endpoint
	ethClient, err := ethclient.Dial("evm_rpc_endpoint")
	if err != nil {
		return err
	}
	defer ethClient.Close()

	// use the BlobstreamX contract binding
	wrapper, err := blobstreamxwrapper.NewBlobstreamX(ethcmn.HexToAddress("contract_Address"), ethClient)
	if err != nil {
		return err
	}

	LatestBlockNumber, err := ethClient.BlockNumber(context.Background())
	if err != nil {
		return err
	}

	eventsIterator, err := wrapper.FilterDataCommitmentStored(
		&bind.FilterOpts{
			Context: ctx,
			Start: LatestBlockNumber - 90000,
			End: &LatestBlockNumber,
		},
		nil,
		nil,
		nil,
	)
	if err != nil {
		return err
	}

	var event *blobstreamxwrapper.BlobstreamXDataCommitmentStored
	for eventsIterator.Next() {
		e := eventsIterator.Event
		if int64(e.StartBlock) <= tx.Height && tx.Height < int64(e.EndBlock) {
			event = &blobstreamxwrapper.BlobstreamXDataCommitmentStored{
				ProofNonce:     e.ProofNonce,
				StartBlock:     e.StartBlock,
				EndBlock:       e.EndBlock,
				DataCommitment: e.DataCommitment,
			}
			break
		}
	}
	if err := eventsIterator.Error(); err != nil {
		return err
	}
	err = eventsIterator.Close()
	if err != nil {
		return err
	}
	if event == nil {
		return fmt.Errorf("couldn't find range containing the transaction height")
	}

	// get the block data root inclusion proof to the data root tuple root
	dcProof, err := trpc.DataRootInclusionProof(ctx, uint64(tx.Height), event.StartBlock, event.EndBlock)
	if err != nil {
		return err
	}

	// verify that the data root was committed to by the BlobstreamX contract
	committed, err := VerifyDataRootInclusion(ctx, wrapper, event.ProofNonce.Uint64(), uint64(tx.Height), blockRes.Block.DataHash, dcProof.Proof)
	if err != nil {
		return err
	}
	if committed {
		fmt.Println("data root was committed to by the BlobstreamX contract")
	} else {
		fmt.Println("data root was not committed to by the BlobstreamX contract")
		return nil
	}
    return nil
}

func VerifyDataRootInclusion(
	_ context.Context,
	blobstreamXwrapper *blobstreamxwrapper.BlobstreamX,
	nonce uint64,
	height uint64,
	dataRoot []byte,
	proof merkle.Proof,
) (bool, error) {
	tuple := blobstreamxwrapper.DataRootTuple{
		Height:   big.NewInt(int64(height)),
		DataRoot: *(*[32]byte)(dataRoot),
	}

	sideNodes := make([][32]byte, len(proof.Aunts))
	for i, aunt := range proof.Aunts {
		sideNodes[i] = *(*[32]byte)(aunt)
	}
	wrappedProof := blobstreamxwrapper.BinaryMerkleProof{
		SideNodes: sideNodes,
		Key:       big.NewInt(proof.Index),
		NumLeaves: big.NewInt(proof.Total),
	}

	valid, err := blobstreamXwrapper.VerifyAttestation(
		&bind.CallOpts{},
		big.NewInt(int64(nonce)),
		tuple,
		wrappedProof,
	)
	if err != nil {
		return false, err
	}
	return valid, nil
}

Para demostrar que una transacción de rollup es parte de la raíz de datos, tendremos que proporcionar dos pruebas: (1) una prueba Merkle de espacio de nombres de la transacción a una raíz de fila. Esto podría hacerse probando las acciones que contienen la transacción en la raíz de la fila utilizando una prueba Merkle de espacio de nombres. (2) Y, una prueba Merkle binaria de la raíz de fila a la raíz de datos.

  • Una prueba NMT de las acciones a las raíces de las filas

  • Una prueba binaria de Merkle de la raíz de fila a la raíz de datos

NOTA

Si el rango de acciones abarca varias filas, entonces la prueba puede contener múltiples pruebas NMT y binarias.

El punto final se puede consultar utilizando el cliente golang:

ir

	sharesProof, err := trpc.ProveShares(ctx, 15, 0, 1)
	if err != nil {
		...
	}

Contratos inteligentes que utilizan el DAVerifier la biblioteca toma el siguiente formato de prueba:

solidez

/// @notice Contains the necessary parameters to prove that some shares, which were posted to
/// the Celestia network, were committed to by the BlobstreamX smart contract.
struct SharesProof {
    // The shares that were committed to.
    bytes[] data;
    // The shares proof to the row roots. If the shares span multiple rows, we will have multiple nmt proofs.
    NamespaceMerkleMultiproof[] shareProofs;
    // The namespace of the shares.
    Namespace namespace;
    // The rows where the shares belong. If the shares span multiple rows, we will have multiple rows.
    NamespaceNode[] rowRoots;
    // The proofs of the rowRoots to the data root.
    BinaryMerkleProof[] rowProofs;
    // The proof of the data root tuple to the data root tuple root that was posted to the BlobstreamX contract.
    AttestationProof attestationProof;
}

/// @notice Contains the necessary parameters needed to verify that a data root tuple
/// was committed to, by the BlobstreamX smart contract, at some specif nonce.
struct AttestationProof {
    // the attestation nonce that commits to the data root tuple.
    uint256 tupleRootNonce;
    // the data root tuple that was committed to.
    DataRootTuple tuple;
    // the binary Merkle proof of the tuple to the commitment.
    BinaryMerkleProof proof;
}

Para construir el SharesProof, necesitaremos la prueba que consultamos anteriormente, y es la siguiente:

Mientras que el NamespaceMerkleMultiproof ser:

solidez

/// @notice Namespace Merkle Tree Multiproof structure. Proves multiple leaves.
struct NamespaceMerkleMultiproof {
    // The beginning key of the leaves to verify.
    uint256 beginKey;
    // The ending key of the leaves to verify.
    uint256 endKey;
    // List of side nodes to verify and calculate tree.
    NamespaceNode[] sideNodes;
}

Entonces, podemos construir el NamespaceMerkleMultiproof con el siguiente mapeo:

  • beginKey en la estructura de Solidez == start en la respuesta de la consulta

  • endKey en la estructura de Solidez == end en la respuesta de la consulta

  • sideNodes en la estructura de Solidez == nodes en la respuesta de la consulta

  • El NamespaceNode, que es el tipo de sideNodes, se define de la siguiente manera:

solidez

/// @notice Namespace Merkle Tree node.
struct NamespaceNode {
    // Minimum namespace.
    Namespace min;
    // Maximum namespace.
    Namespace max;
    // Node value.
    bytes32 digest;
}

Entonces, construimos un NamespaceNode tomando los valores de la nodes campo en la respuesta de consulta, los convertimos de base64 a hex, luego usamos el siguiente mapeo:

  • min== los primeros 29 bytes en el valor decodificado

  • max== los segundos 29 bytes en el valor decodificado

  • digest== los 32 bytes restantes en el valor decodificado

El min y max son Namespace tipo que es:

solidez

/// @notice A representation of the Celestia-app namespace ID and its version.
/// See: https://celestiaorg.github.io/celestia-app/specs/namespace.html
struct Namespace {
    // The namespace version.
    bytes1 version;
    // The namespace ID.
    bytes28 id;
}

Entonces, para construirlos, separamos los 29 bytes en el valor decodificado para:

  • primer byte: version

  • 28 Bytes restantes: id

Un ayudante golang que se puede utilizar para hacer esta conversión es el siguiente:

ir

func toNamespaceMerkleMultiProofs(proofs []*tmproto.NMTProof) []client.NamespaceMerkleMultiproof {
	shareProofs := make([]client.NamespaceMerkleMultiproof, len(proofs))
	for i, proof := range proofs {
		sideNodes := make([]client.NamespaceNode, len(proof.Nodes))
		for j, node := range proof.Nodes {
			sideNodes[j] = *toNamespaceNode(node)
		}
		shareProofs[i] = client.NamespaceMerkleMultiproof{
			BeginKey:  big.NewInt(int64(proof.Start)),
			EndKey:    big.NewInt(int64(proof.End)),
			SideNodes: sideNodes,
		}
	}
	return shareProofs
}

func minNamespace(innerNode []byte) *client.Namespace {
	version := innerNode[0]
	var id [28]byte
	for i, b := range innerNode[1:28] {
		id[i] = b
	}
	return &client.Namespace{
		Version: [1]byte{version},
		Id:      id,
	}
}

func maxNamespace(innerNode []byte) *client.Namespace {
	version := innerNode[29]
	var id [28]byte
	for i, b := range innerNode[30:57] {
		id[i] = b
	}
	return &client.Namespace{
		Version: [1]byte{version},
		Id:      id,
	}
}

func toNamespaceNode(node []byte) *client.NamespaceNode {
	minNs := minNamespace(node)
	maxNs := maxNamespace(node)
	var digest [32]byte
	for i, b := range node[58:] {
		digest[i] = b
	}
	return &client.NamespaceNode{
		Min:    *minNs,
		Max:    *maxNs,
		Digest: digest,
	}
}

con proofs ser sharesProof.ShareProofs.

Cuál es el espacio de nombres utilizado por el rollup al enviar datos a Celestia. Como se ha descrito anteriormente, se puede construir de la siguiente manera:

solidez

/// @notice A representation of the Celestia-app namespace ID and its version.
/// See: https://celestiaorg.github.io/celestia-app/specs/namespace.html
struct Namespace {
    // The namespace version.
    bytes1 version;
    // The namespace ID.
    bytes28 id;
}

A través de tomar el namespace valor de la prove_shares respuesta de consulta, decodificándola de base64 a hex, luego:

  • primer byte: version

  • 28 Bytes restantes: id

Un método para convertir a espacio de nombres, siempre que el tamaño del espacio de nombres sea 29, es el siguiente:

ir

func namespace(namespaceID []byte) *client.Namespace {
	version := namespaceID[0]
	var id [28]byte
	for i, b := range namespaceID[1:] {
		id[i] = b
	}
	return &client.Namespace{
		Version: [1]byte{version},
		Id:      id,
	}
}

con namespace ser sharesProof.NamespaceID.

Cuáles son las raíces de las filas donde se localizan las acciones que contienen los datos de Rollup.

En golang, la prueba se puede convertir de la siguiente manera:

ir

func toRowRoots(roots []bytes.HexBytes) []client.NamespaceNode {
	rowRoots := make([]client.NamespaceNode, len(roots))
	for i, root := range roots {
		rowRoots[i] = *toNamespaceNode(root.Bytes())
	}
	return rowRoots
}

con roots ser sharesProof.RowProof.RowRoots.

Estas son las pruebas de las filas a la raíz de datos. Son de tipo BinaryMerkleProof:

solidez

/// @notice Merkle Tree Proof structure.
struct BinaryMerkleProof {
    // List of side nodes to verify and calculate tree.
    bytes32[] sideNodes;
    // The key of the leaf to verify.
    uint256 key;
    // The number of leaves in the tree
    uint256 numLeaves;
}

Para construirlos, tomamos la respuesta de la prove_shares consulta y realiza el siguiente mapeo:

  • key en la estructura de Solidez == index en la respuesta de la consulta

  • numLeaves en la estructura de Solidez == total en la respuesta de la consulta

  • sideNodes en la estructura de Solidez == aunts en la respuesta de la consulta

El tipo de la sideNodes es a bytes32.

Un ayudante golang para convertir las pruebas de fila es el siguiente:

ir

func toRowProofs(proofs []*merkle.Proof) []client.BinaryMerkleProof {
	rowProofs := make([]client.BinaryMerkleProof, len(proofs))
	for i, proof := range proofs {
		sideNodes := make( [][32]byte, len(proof.Aunts))
		for j, sideNode :=  range proof.Aunts {
			var bzSideNode [32]byte
			for k, b := range sideNode {
				bzSideNode[k] = b
			}
			sideNodes[j] = bzSideNode
		}
 		rowProofs[i] = client.BinaryMerkleProof{
			SideNodes: sideNodes,
			Key:       big.NewInt(proof.Index),
			NumLeaves: big.NewInt(proof.Total),
		}
	}
}

con proofs ser sharesProof.RowProof.Proofs.

Esta es la prueba de la raíz de datos a la raíz de tupla de raíz de datos, que se compromete en el contrato de Blobstream X:

solidez

/// @notice Contains the necessary parameters needed to verify that a data root tuple
/// was committed to, by the BlobstreamX smart contract, at some specif nonce.
struct AttestationProof {
    // the attestation nonce that commits to the data root tuple.
    uint256 tupleRootNonce;
    // the data root tuple that was committed to.
    DataRootTuple tuple;
    // the binary Merkle proof of the tuple to the commitment.
    BinaryMerkleProof proof;
}
  • tupleRootNonce: el nonce en el que Blobstream X se comprometió con el lote que contiene el bloque que contiene los datos.

  • tuple: el DataRootTuple del bloque:

solidez

/// @notice A tuple of data root with metadata. Each data root is associated
///  with a Celestia block height.
/// @dev `availableDataRoot` in
///  https://github.com/celestiaorg/celestia-specs/blob/master/src/specs/data_structures.md#header
struct DataRootTuple {
    // Celestia block height the data root was included in.
    // Genesis block is height = 0.
    // First queryable block is height = 1.
    uint256 height;
    // Data root.
    bytes32 dataRoot;
}

que comprende a dataRoot, es decir, el bloque que contiene la raíz de datos de datos de Rollup, y el height que es el height de ese bloque.

Un ayudante golang para crear una prueba de certificación:

ir

func toAttestationProof(
	nonce uint64,
	height uint64,
	blockDataRoot [32]byte,
	dataRootInclusionProof merkle.Proof,
) client.AttestationProof {
	sideNodes := make( [][32]byte, len(dataRootInclusionProof.Aunts))
	for i, sideNode :=  range dataRootInclusionProof.Aunts {
		var bzSideNode [32]byte
		for k, b := range sideNode {
			bzSideNode[k] = b
		}
		sideNodes[i] = bzSideNode
	}

	return client.AttestationProof{
		TupleRootNonce: big.NewInt(int64(nonce)),
		Tuple:          client.DataRootTuple{
			Height:   big.NewInt(int64(height)),
			DataRoot: blockDataRoot,
		},
		Proof:          client.BinaryMerkleProof{
			SideNodes: sideNodes,
			Key:       big.NewInt(dataRootInclusionProof.Index),
			NumLeaves: big.NewInt(dataRootInclusionProof.Total),
		},
	}
}

con el nonce siendo la certificación nonce, que se puede recuperar usando BlobstreamX eventos contractuales. Consulte a continuación un ejemplo. Y height siendo la altura del bloque Celestia que contiene los datos de despliegue, junto con el blockDataRoot siendo la raíz de datos de la altura del bloque. Finalmente, dataRootInclusionProof es la prueba de inclusión de raíz de datos de bloque Celestia a la raíz de tupla de raíz de datos que se consultó al comienzo de esta página.

Si el dataRoot o el tupleRootNonce se desconoce durante la verificación:

  • dataRoot: se puede consultar usando el /block?height=15 consulta (15 en este punto final de ejemplo), y tomando el data_hash campo de la respuesta.

  • tupleRootNonce: se puede volver a intentar consultando el BlobstreamXDataCommitmentStored eventos del contrato de BlobstreamX y buscando el nonce que acredite los datos correspondientes. Un ejemplo:

ir

	// get the nonce corresponding to the block height that contains the PayForBlob transaction
	// since BlobstreamX emits events when new batches are submitted, we will query the events
	// and look for the range committing to the blob
	// first, connect to an EVM RPC endpoint
	ethClient, err := ethclient.Dial("evm_rpc_endpoint")
	if err != nil {
		return err
	}
	defer ethClient.Close()

	// use the BlobstreamX contract binding
	wrapper, err := blobstreamxwrapper.NewBlobstreamX(ethcmn.HexToAddress("contract_Address"), ethClient)
	if err != nil {
		return err
	}

	LatestBlockNumber, err := ethClient.BlockNumber(ctx)
	if err != nil {
		return err
	}

	eventsIterator, err := wrapper.FilterDataCommitmentStored(
		&bind.FilterOpts{
			Context: ctx,
			Start: LatestBlockNumber - 90000, // 90000 can be replaced with the range of EVM blocks to look for the events in
			End: &LatestBlockNumber,
		},
		nil,
		nil,
		nil,
	)
	if err != nil {
		return err
	}

	var event *blobstreamxwrapper.BlobstreamXDataCommitmentStored
	for eventsIterator.Next() {
		e := eventsIterator.Event
		if int64(e.StartBlock) <= tx.Height && tx.Height < int64(e.EndBlock) {
			event = &blobstreamxwrapper.BlobstreamXDataCommitmentStored{
				ProofNonce:     e.ProofNonce,
				StartBlock:     e.StartBlock,
				EndBlock:       e.EndBlock,
				DataCommitment: e.DataCommitment,
			}
			break
		}
	}
	if err := eventsIterator.Error(); err != nil {
		return err
	}
	err = eventsIterator.Close()
	if err != nil {
		return err
	}
	if event == nil {
		return fmt.Errorf("couldn't find range containing the block height")
	}

Para escuchar nuevo BlobstreamXDataCommitmentStored eventos, secuenciadores pueden usar el WatchDataCommitmentStored como sigue:

ir

    ethClient, err := ethclient.Dial("evm_rpc")
    if err != nil {
	    return err
    }
    defer ethClient.Close()
    blobstreamWrapper, err := blobstreamxwrapper.NewBlobstreamXFilterer(ethcmn.HexToAddress("contract_address"), ethClient)
    if err != nil {
	    return err
    }

    eventsChan := make(chan *blobstreamxwrapper.BlobstreamXDataCommitmentStored, 100)
    subscription, err := blobstreamWrapper.WatchDataCommitmentStored(
	    &bind.WatchOpts{
			Context: ctx,
        },
	    eventsChan,
	    nil,
	    nil,
	    nil,
	)
    if err != nil {
	    return err
    }
    defer subscription.Unsubscribe()

    for {
	    select {
	    case <-ctx.Done():
		    return ctx.Err()
		case err := <-subscription.Err():
			return err
		case event := <-eventsChan:
			// process the event
		    fmt.Println(event)
	    }
    }

Luego, se pueden crear nuevas pruebas como se documentó anteriormente utilizando los nuevos compromisos de datos contenidos en los eventos recibidos.

Un ejemplo de rollup que utiliza el DAVerifier puede ser tan simple como:

solidez

pragma solidity ^0.8.22;

import {DAVerifier} from "@blobstream/lib/verifier/DAVerifier.sol";
import {IDAOracle} from "@blobstream/IDAOracle.sol";

contract SimpleRollup {
    IDAOracle bridge;
    ...
    function submitFraudProof(SharesProof memory _sharesProof, bytes32 _root) public {
        // (1) verify that the data is committed to by BlobstreamX contract
        (bool committedTo, DAVerifier.ErrorCodes err) = DAVerifier.verifySharesToDataRootTupleRoot(bridge, _sharesProof, _root);
        if (!committedTo) {
            revert("the data was not committed to by Blobstream");
        }
        // (2) verify that the data is part of the rollup block
        // (3) parse the data
        // (4) verify invalid state transition
        // (5) effects
    }
}

Luego, puede enviar la prueba de fraude usando golang de la siguiente manera:

ir

package main

import (
	"context"
	"fmt"
	"github.com/celestiaorg/celestia-app/pkg/square"
	"github.com/celestiaorg/celestia-app/x/qgb/client"
	"github.com/ethereum/go-ethereum/accounts/abi/bind"
	ethcmn "github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/ethclient"
	blobstreamxwrapper "github.com/succinctlabs/blobstreamx/bindings"
	"github.com/tendermint/tendermint/crypto/merkle"
	"github.com/tendermint/tendermint/libs/bytes"
	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
	"github.com/tendermint/tendermint/rpc/client/http"
	"github.com/tendermint/tendermint/types"
	"math/big"
	"os"
)

func main() {
	err := verify()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

func verify() error {
	ctx := context.Background()


	// ...
	// check the first section for this part of the implementation

	// get the nonce corresponding to the block height that contains the PayForBlob transaction
	// since Blobstream X emits events when new batches are submitted, we will query the events
	// and look for the range committing to the blob
	// first, connect to an EVM RPC endpoint
	ethClient, err := ethclient.Dial("evm_rpc_endpoint")
	if err != nil {
		return err
	}
	defer ethClient.Close()

	// ...
	// check the first section for this part of the implementation

	// now we will create the shares proof to be verified by the SimpleRollup
	// contract that uses the DAVerifier library

	// get the proof of the shares containing the blob to the data root
	sharesProof, err := trpc.ProveShares(ctx, 16, uint64(blobShareRange.Start), uint64(blobShareRange.End))
	if err != nil {
		return err
	}

	// use the SimpleRollup contract binding to submit to it a fraud proof
	simpleRollupWrapper, err := client.NewWrappers(ethcmn.HexToAddress("contract_Address"), ethClient)
	if err != nil {
		return err
	}

	// submit the fraud proof containing the share data that had the invalid state transition for example
	// along with its proof
	err = submitFraudProof(
		ctx,
		simpleRollupWrapper,
		sharesProof,
		event.ProofNonce.Uint64(),
		uint64(tx.Height),
		dcProof.Proof,
		blockRes.Block.DataHash,
	)

	return nil
}

func submitFraudProof(
	ctx context.Context,
	simpleRollup *client.Wrappers,
	sharesProof types.ShareProof,
	nonce uint64,
	height uint64,
	dataRootInclusionProof merkle.Proof,
	dataRoot []byte,
) error {
	var blockDataRoot [32]byte
	for i, b := range dataRoot[58:] {
		blockDataRoot[i] = b
	}
	tx, err := simpleRollup.SubmitFraudProof(
		&bind.TransactOpts{
			Context: ctx,
		},
		client.SharesProof{
			Data:             sharesProof.Data,
			ShareProofs:      toNamespaceMerkleMultiProofs(sharesProof.ShareProofs),
			Namespace:        *namespace(sharesProof.NamespaceID),
			RowRoots:         toRowRoots(sharesProof.RowProof.RowRoots),
			RowProofs:        toRowProofs(sharesProof.RowProof.Proofs),
			AttestationProof: toAttestationProof(nonce, height, blockDataRoot, dataRootInclusionProof),
		},
		blockDataRoot,
	)
	if err != nil {
		return err
	}
	// wait for transaction
}

func toAttestationProof(
	nonce uint64,
	height uint64,
	blockDataRoot [32]byte,
	dataRootInclusionProof merkle.Proof,
) client.AttestationProof {
	sideNodes := make( [][32]byte, len(dataRootInclusionProof.Aunts))
	for i, sideNode :=  range dataRootInclusionProof.Aunts {
		var bzSideNode [32]byte
		for k, b := range sideNode {
			bzSideNode[k] = b
		}
		sideNodes[i] = bzSideNode
	}

	return client.AttestationProof{
		TupleRootNonce: big.NewInt(int64(nonce)),
		Tuple:          client.DataRootTuple{
			Height:   big.NewInt(int64(height)),
			DataRoot: blockDataRoot,
		},
		Proof:          client.BinaryMerkleProof{
			SideNodes: sideNodes,
			Key:       big.NewInt(dataRootInclusionProof.Index),
			NumLeaves: big.NewInt(dataRootInclusionProof.Total),
		},
	}
}

func toRowRoots(roots []bytes.HexBytes) []client.NamespaceNode {
	rowRoots := make([]client.NamespaceNode, len(roots))
	for i, root := range roots {
		rowRoots[i] = *toNamespaceNode(root.Bytes())
	}
	return rowRoots
}

func toRowProofs(proofs []*merkle.Proof) []client.BinaryMerkleProof {
	rowProofs := make([]client.BinaryMerkleProof, len(proofs))
	for i, proof := range proofs {
		sideNodes := make( [][32]byte, len(proof.Aunts))
		for j, sideNode :=  range proof.Aunts {
			var bzSideNode [32]byte
			for k, b := range sideNode {
				bzSideNode[k] = b
			}
			sideNodes[j] = bzSideNode
		}
 		rowProofs[i] = client.BinaryMerkleProof{
			SideNodes: sideNodes,
			Key:       big.NewInt(proof.Index),
			NumLeaves: big.NewInt(proof.Total),
		}
	}
}

func toNamespaceMerkleMultiProofs(proofs []*tmproto.NMTProof) []client.NamespaceMerkleMultiproof {
	shareProofs := make([]client.NamespaceMerkleMultiproof, len(proofs))
	for i, proof := range proofs {
		sideNodes := make([]client.NamespaceNode, len(proof.Nodes))
		for j, node := range proof.Nodes {
			sideNodes[j] = *toNamespaceNode(node)
		}
		shareProofs[i] = client.NamespaceMerkleMultiproof{
			BeginKey:  big.NewInt(int64(proof.Start)),
			EndKey:    big.NewInt(int64(proof.End)),
			SideNodes: sideNodes,
		}
	}
	return shareProofs
}

func minNamespace(innerNode []byte) *client.Namespace {
	version := innerNode[0]
	var id [28]byte
	for i, b := range innerNode[1:28] {
		id[i] = b
	}
	return &client.Namespace{
		Version: [1]byte{version},
		Id:      id,
	}
}

func maxNamespace(innerNode []byte) *client.Namespace {
	version := innerNode[29]
	var id [28]byte
	for i, b := range innerNode[30:57] {
		id[i] = b
	}
	return &client.Namespace{
		Version: [1]byte{version},
		Id:      id,
	}
}

func toNamespaceNode(node []byte) *client.NamespaceNode {
	minNs := minNamespace(node)
	maxNs := maxNamespace(node)
	var digest [32]byte
	for i, b := range node[58:] {
		digest[i] = b
	}
	return &client.NamespaceNode{
		Min:    *minNs,
		Max:    *maxNs,
		Digest: digest,
	}
}

func namespace(namespaceID []byte) *client.Namespace {
	version := namespaceID[0]
	var id [28]byte
	for i, b := range namespaceID[1:] {
		id[i] = b
	}
	return &client.Namespace{
		Version: [1]byte{version},
		Id:      id,
	}
}

Después de crear todas las pruebas y verificarlas:

  1. Verifique la prueba de inclusión de la transacción a la raíz de datos de Celestia

  2. Demuestre que la tupla raíz de datos está comprometida con el contrato inteligente Blobstream X

Podemos estar seguros de que los datos se publicaron en Celestia, y luego las implementaciones pueden continuar con su mecanismo normal de prueba de fraude.

NOTA

Las construcciones de prueba anteriores se implementan en Solidity y pueden requerir diferentes enfoques en otros lenguajes de programación.

El esquema de compromiso

Diagrama de compromiso de Blobstream

Entonces, para demostrar la inclusión de una acción en un bloque de Celestia, usamos Blobstream como fuente de verdad. Actualmente, utilizaremos la implementación de Blobstream X de Blobstream, se puede encontrar más información sobre Blobstream X en . En pocas palabras, Blobstream X atestigua los datos publicados en Celestia en el contrato de Blobstream X mediante la verificación de una prueba zk de los encabezados de un lote de bloques de Celestia. Luego, mantiene referencia de ese lote de bloques utilizando el compromiso merkleizado de sus (dataRoot, height) resultando en a data root tuple root. Compruebe el diagrama anterior que muestra:

1: las raíces de fila y columna son las raíces del árbol merkle del espacio de nombres sobre las acciones. Más información sobre el NMT en el . Estos se comprometen con las filas y columnas que contienen las acciones anteriores.

Demostración práctica

1. Prueba de inclusión de raíz de datos

Para demostrar que la raíz de datos está comprometida con el contrato inteligente Blobstream X, tendremos que proporcionar una prueba Merkle de la tupla raíz de datos a una raíz de tupla raíz de datos. Esto se puede crear usando el consulta.

Esto permite consultar una raíz de datos a prueba de raíz de tupla de raíz de datos. Se necesita un bloque height, un bloque de inicio y un bloque final, luego genera la prueba binaria Merkle del DataRootTuple, correspondiente a eso height, a la DataRootTupleRoot que está comprometido en el contrato de Blobstream X.

Ejemplo completo de prueba de que un bloque Celestia fue comprometido por el contrato Blobstream X

2. Prueba de inclusión de transacciones

Estas pruebas se pueden generar utilizando el consulta.

Esto permite consultar una prueba de acciones a raíces de fila, luego una raíz de fila a pruebas de raíz de datos. Se necesita un bloque height, un índice de acción inicial y un índice de acción final que definen un rango de acciones. Luego, se generan dos pruebas:

Convertir las pruebas para ser utilizables en el DAVerifier biblioteca

data

Estas son las acciones en bruto que se presentaron a Celestia en el bytes formato. Si tomamos el ejemplo blob que se presentó en el , podemos convertirlo en bytes usando el abi.encode(...) como hecho para . Esto se puede obtener del resultado anterior de la consulta en el campo data.

shareProofs

Esta es la prueba de acciones a las raíces de las filas. Estos pueden contener múltiples pruebas si las acciones que contienen el blob se extienden a través de varias filas. Para construirlos, utilizaremos el resultado de la sección.

Un ejemplo de hacer esto se puede encontrar en el prueba.

namespace

Un ejemplo se puede encontrar en el prueba.

rowRoots

rowProofs

Un ejemplo se puede encontrar en el prueba.

attestationProof

proof: el BinaryMerkleProof de la tupla raíz de datos a la raíz de tupla raíz de datos. Construirlo es similar a construir las raíces de fila a prueba de raíz de datos en el sección.

Un ejemplo se puede encontrar en el prueba.

Escuchar nuevos compromisos de datos

Ejemplo de rollup que utiliza el DAVerifier

Para el paso (2), verifique el para más información.

Conclusión

👽
🎓
​
la visión general
especificaciones NMT
​
​
data_root_inclusion_proof
punto final
​
​
ProveShares
punto final
​
​
RollupInclusionProofs.t.sol
esta variable
prueba de inclusión de transacciones
​
prueba de inclusión de transacciones
RollupInclusiónProofs.t.sol
​
RollupInclusiónProofs.t.sol
​
​
RollupInclusiónProofs.t.sol
​
rowProof
RollupInclusiónProofs.t.sol
​
​
documentación de pruebas de inclusión de rollup
​
​
nodo completo de consenso
​
especificaciones de acciones
en el diseño del cuadrado de datos
estructuras de datos
​