Demostrar la existencia de registros en la cadena de bloques

Para prologar esto: no estoy completamente seguro de que esta pregunta tenga sentido. Sólo un pensamiento que tuve que quería comprobar la viabilidad de.

Estoy bastante seguro de que es posible usar una prueba de Merkle para mostrar que una transacción se incluyó en algún bloque, y me pregunto si esto también es posible con los registros.

Esencialmente, ¿sería posible probar que se generó un registro al incluir una prueba de Merkle de 1) la transacción que generó el registro o 2) el registro (sé que los registros se almacenan de manera diferente a las transacciones, por lo que no estoy seguro de que esto es posible en absoluto).

Esencialmente, ¿podría haber una prueba proporcionada a un contrato de que alguna transacción en algún bloque generó algún registro?

Respuestas (4)

Actualización: https://github.com/PISAresearch/event-proofs tiene algo de código. De su archivo Léame:

Pruebas de eventos

Un POC para explorar cómo se pueden verificar los registros de Ethereum en un contrato inteligente. Las pruebas se generan usando eth-proof y se verifican usando la implementación Merkle Patricia Tree de Peace Relay. Si ejecuta las pruebas contra Infura, tenga paciencia con ellas, ya que la generación de pruebas requiere muchas llamadas de rpc.


Respuesta original:

, se puede usar una prueba de Merkle de un recibo de transacción para verificar la existencia de registros.

Un encabezado de bloque Ethereum tiene la raíz de Merkle del trie de recibos (transacción).

Un recibo de transacción tiene todos los registros .

Al codificar el recibo de la transacción y los hash que componen la prueba de Merkle, el hash resultante se puede comparar con la raíz de Merkle en el encabezado. Una coincidencia indicaría que el registro existe.

Descripción del Libro Amarillo:

Cada recibo, denominado BR[i] para la i-ésima transacción, se coloca en un trie indexado y la raíz se registra en el encabezado como He. El recibo de la transacción es una tupla de cuatro elementos que comprende el estado posterior a la transacción, Rσ, el gas acumulativo utilizado en el bloque que contiene el recibo de la transacción inmediatamente después de que se realizó la transacción, Ru, el conjunto de registros creados mediante la ejecución de la transacción , Rl y el filtro Bloom compuesto a partir de la información de esos registros...:

En https://blog.ethereum.org/2015/11/15/merkling-in-ethereum Vitalik Buterin dio un ejemplo del uso de recibos, así como otros ejemplos que se pueden responder con pruebas de Merkle:

  • ¿Se ha incluido esta transacción en un bloque en particular?
  • Dime todas las instancias de un evento de tipo X (por ejemplo, un contrato de crowdfunding que alcanza su objetivo) emitido por esta dirección en los últimos 30 días
  • ¿Cuál es el saldo actual de mi cuenta?
  • ¿Existe esta cuenta?
  • Pretenda ejecutar esta transacción en este contrato. ¿Cuál sería la salida?

La primera es manejada por el árbol de transacciones; el tercero y cuarto son manejados por el árbol de estados, y el segundo por el árbol de recibos . Los primeros cuatro son bastante sencillos de calcular; el servidor simplemente encuentra el objeto, busca la rama de Merkle (la lista de hashes que van desde el objeto hasta la raíz del árbol) y responde al cliente ligero con la rama.

El quinto también es manejado por el árbol de estado, pero la forma en que se calcula es más compleja. Aquí, necesitamos construir lo que se puede llamar una prueba de transición de estado de Merkle...

Vitalik también hizo una presentación en DevCon1 y una sección sobre registros:

https://www.youtube.com/watch?v=gjwr-7PgpN8&t=2106

Estaba tratando de resolver este problema exacto y escribí una prueba de concepto que puede hacer esto:

https://github.com/figs999/Ethereum/blob/master/EventStorage.sol

Básicamente, necesita dos componentes: 1: una forma de leer y confirmar la validez de un encabezado de bloque 2: una forma de verificar el filtro de floración para detectar la presencia de una entrada de registro

En mi prueba de concepto, para ingerir una entrada de registro y confirmar su validez, un cliente llama a un método y pasa tanto el encabezado del bloque codificado en RLP del que proviene el registro como el contenido del registro en sí.

El encabezado codificado RLP se decodifica en el contrato. Una vez decodificado, el hash de bloque correcto para ese bloque se puede recuperar a través de block.blockhash. Luego, solo compara el hash keccak256 de los bytes del encabezado codificados en rlp y el hash real, si coinciden, el encabezado es válido.

Una vez que tenga un encabezado válido, puede leer los registros que aparecen en él. El florecimiento de los registros es un número de 256 bytes que se puede verificar para confirmar la existencia de un registro, siempre que sepa la dirección del contrato que escribió el registro, la firma del evento del registro y cualquier tema incluido en el registro.

El truco para validar un blob específico de datos de registro a partir de esto es incluir el blob de datos registrados como el valor de registro Y como un tema indexado. Cuando lo incluye como un tema indexado, el hash keccak256 del blob estará presente en la floración de registros.

Verificar la presencia de un registro específico en la floración de registros es relativamente simple, pero requiere un poco de matemática original que es un poco difícil de hacer de manera eficiente en solidez. Mi ejemplo se vio obligado a recurrir al ensamblaje para esta parte.

El proceso es el siguiente:

  1. Obtenga los tres valores hash que deberían estar en la floración de registros: el valor hash de la dirección del contrato, el valor hash del valor hash de la firma del evento [keccak256(keccak256("DataStored(bytes,bytes)"] y el valor hash del valor hash de los datos registrados.
  2. Para cada uno de los hashes, extraiga los primeros tres pares de bytes. Llamemos a estos [B1, B2, B3]
  3. Para cada par de bytes B, verifique la presencia del bit marcador (m) en la floración de registros, donde m = 1<<(B%2048).
  4. Si los registros florecen contienen los 9 bits que verifica, el registro es (lo más probable) válido.

Con este método, puede ingerir registros históricos en un contrato inteligente para validar datos o actuar como un espacio de almacenamiento de menor costo de gas. La contrapartida es que el costo de gas de la recuperación/validación de datos es significativamente mayor.

Recomendaría no usar el filtro de floración como evidencia de que sucedió un evento. Los filtros Bloom son propensos a falsos positivos. Son útiles para evitar escanear transacciones en un bloque si no tendrá el evento que está buscando, pero es posible que el filtro Bloom indique que ocurrió un evento cuando no lo tuvo. Para el escaneo de eventos, eso significa que escanea las transacciones y no encuentra nada, perdiendo el tiempo. Si lo usa como prueba de que algo sucedió, podría estar equivocado. Alguien podría crear algunos registros para hacer que el filtro Bloom produzca un falso positivo, comprometiendo su seguridad deliberadamente.
Es cierto que los filtros de floración pueden tener falsos positivos, pero creo que la tasa de colisión para este caso de uso en particular será lo suficientemente baja. Los filtros de floración utilizados para los registros de Ethereum son relativamente grandes, mientras que la cantidad de transacciones que se procesarán en un solo bloque será relativamente baja. Agregue a esto los requisitos de formato del contrato para el mensaje registrado, y el hecho de que está verificando la presencia del hash dicho registro en flor, y la probabilidad de que alguien encuentre una colisión significativa se vuelve casi nula.
Dicho esto, AusIV tiene razón en que esto no puede proporcionar PRUEBA criptográfica de que el registro está presente, por lo que debe sopesar la posibilidad de que se encuentre una colisión frente a la misión crítica de su caso de uso. Hay algunas técnicas que se pueden usar para protegerse aún más contra las colisiones, como asegurarse de que no haya ningún campo en el formato de registro que pueda usarse como un nonce (lo que permitiría que un atacante verifique las variaciones en un registro falso en busca de colisiones). ) o bien, exigir que el tamaño hash del registro también se incluya en los temas.
Si está utilizando el filtro de floración de bloques, no importa si los eventos en el filtro de floración provienen de su contrato. Alguien podría construir un contrato que emita eventos arbitrarios que se agreguen al filtro de floración. Dado que hay 9 bits para verificar, podrían crear 9 eventos, cada uno de los cuales establecerá un bit pertinente (y 8 bits irrelevantes). Las entradas a los eventos podrían calcularse fuera de la cadena de manera bastante económica, y luego el filtro de floración daría un falso positivo de que el evento del contrato estaba presente. Probablemente esté bastante a salvo de colisiones probabilísticas, pero sería fácil crear colisiones.

Puede lograr esto fácilmente usando ProvenDB . Aquí hay un código de ejemplo escrito en Go para probar continuamente la existencia y propiedad de sus registros en Blockchain: https://github.com/SouthbankSoftware/provenlogs . Espero que ayude :P

Las transacciones contienen referencias a cualquier registro emitido durante su ejecución, por lo que creo que probar la existencia o ubicación de la transacción en sí sería suficiente.