Coinbase lanzo en junio Rosetta como una especificación de código abierto que hace que la integración con blockchains sea más simple, rápida y confiable.
Ahora hay más de 20 proyectos de blockchain trabajando en una implementación de Rosetta (Near, Cardano, Celo, Coda, Neo, Tron, Handshake, Oasis, Cosmos, Decred, Filecoin, Ontology, Sia, Zilliqa, Digibyte, Harmony, Kadena, Nervos y Blockstack), cinco SDK en progreso (Golang, JavaScript, TypeScript, Java y Rust) y ocho equipos han hecho contribuciones a al menos uno de los repositorios de Rosetta en GitHub ( rosetta-specificaciones , rosetta-sdk-go y rosetta -cli ).
Hoy, compartimos una contribución clave a esta creciente colección de implementaciones: rosetta-bitcoin .
¿Por qué Bitcoin?
Bitcoin es el referente de todas las criptomonedas, es la cadena de bloques más popular, tiene la mayor capitalización de mercado y la mayoría de los desarrolladores de cadenas de bloques saben cómo funciona (por lo que es más fácil entender cómo se puede implementar Rosetta para otras cadenas de bloques).
En otra nota, la implementación de referencia para Bitcoin (conocida como Bitcoin Core ) no proporciona soporte nativo para muchas de las características que desean los integradores.
No es posible consultar saldos de cuenta y / o UTXO para todas las cuentas, entregar bloques preprocesados a las personas que llaman para que no necesiten buscar todas las entradas para analizar una transacción, ni construir transacciones sin importar claves privadas en el nodo (que no es no es práctico para los usuarios que nunca traen claves privadas en línea).
A menudo, estas características faltantes impulsan a los integradores a ejecutar algún tipo de software de «indexación» adicional e implementar sus propias bibliotecas para manejar la construcción de transacciones .
rosetta-bitcoin proporciona acceso a todas estas funciones, no requiere configuración por defecto y se puede iniciar con un solo comando. Además, rosetta-bitcoin habilita estas funciones exclusivamente a través de la interacción RPC con Bitcoin Core, por lo que no necesitamos mantener una bifurcación de Bitcoin Core para habilitar esta nueva funcionalidad y configuración fácil.
Actualización de la API de Rosetta
Rosetta-bitcoin implementa los dos componentes principales de la API de Rosetta: la API de datos y la API de construcción .
Juntos, estos componentes proporcionan acceso universal de lectura y escritura a Bitcoin.
Hemos incluido varios diagramas a continuación que describen los puntos finales específicos que admite cualquier implementación de API de Rosetta.
Si está interesado en construir sobre una implementación, le recomendamos usar rosetta-sdk-go (que abstrae estos flujos detrás de las funciones de Golang).
La API de datos consta de todos los puntos finales utilizados para «obtener información» sobre una cadena de bloques. Podemos conseguir que las redes sean compatibles con una implementación (que puede ser> 1 si una cadena de bloques admite la fragmentación o si es una puerta de enlace a varias redes), los tipos de operación admitidos en cada red y el estado de cada red .
La API de datos también permite obtener el contenido de cualquier bloque , obtener una transacción particular en un bloque y obtener el saldo de cualquier cuenta presente en un bloque.
Las herramientas de validación de Rosetta aseguran que el saldo calculado para cualquier cuenta de las operaciones en bloques sea igual al saldo devuelto por el nodo (a menudo llamado «reconciliación»).
Por último, la API de datos permite obtener todas las transacciones de mempool y cualquier transacción de mempool en particular . Esto es útil para los integradores que desean monitorear el estado de sus transmisiones e inspeccionar los depósitos entrantes antes de que se confirmen en la cadena.
Mientras que la API de datos proporciona la capacidad de leer datos de una cadena de bloques en un formato estándar, la API de construcción permite a los desarrolladores escribir en una cadena de bloques (es decir, construir transacciones) en un formato estándar.
Para cumplir con estrictos estándares de seguridad, se espera que las implementaciones no tengan estado, funcionen completamente fuera de línea y admitan la generación y firma de claves independientes.
Podemos derivar una dirección de una clave pública (en blockchains que no requieren originación en cadena).
Cuando se construye una transacción de manera genérica, a menudo no es posible especificar completamente el resultado o lo que puede aparecer en la cadena (por ejemplo: construir una transacción que intenta utilizar un «préstamo flash»).
A la colección de operaciones la llamamos «intención» de la transacción (que suele ser un subconjunto de todas las operaciones en la transacción en cadena).
En un nivel alto, construir una transacción con la API de construcción implica crear una «intención», recopilar los metadatos necesarios para crear una transacción con la «intención», firmar cargas útiles de las cuentas responsables de la «intención» y transmitir la transacción creada.
Antes de intentar firmar o transmitir una transacción, confirmamos que la transacción que construimos tiene la misma «intención» que proporcionamos originalmente al iniciar el flujo de construcción. Puede ver todo este flujo de construcción en el siguiente diagrama:
Una vez que tenemos una transacción firmada (que realiza la «intención» de nuestra elección), podemos calcular su hash específico de red y transmitirlo .
Cómo funciona
En Coinbase optimizamos la reutilización de paquetes al desarrollar rosetta-bitcoin. Si podía hacerse con un paquete existente de rosetta-sdk-go , lo usamos. Esto ha llevado a incorporar algunas mejoras de rendimiento significativas a medida que evaluamos y optimizamos rosetta-bitcoin.
En Coinbase usamos Bitcoin Core para sincronizar bloques / transacciones de transmisión, ingerir esos bloques usando el paquete sincronizador , almacenar bloques procesados usando el paquete de almacenamiento y atender las solicitudes de la API de Rosetta usando el paquete del servidor de los datos almacenados en caché usando el paquete de almacenamiento . Puede encontrar una vista de alto nivel de esta arquitectura a continuación:
Para implementar el punto final de la API / cuenta / saldo de Rosetta , tuvimos que construir un indexador UTXO que proporciona búsquedas de saldo atómico. “Atómico” en este sentido significa que podemos obtener el saldo de una cuenta con el índice de bloque y el hash del bloque donde era válido en una sola llamada RPC. Con nuestra implementación de Rosetta Bitcoin, ¡ya no necesita ejecutar un indexador por separado!
Implementamos la ingesta simultánea de bloques para acelerar la sincronización de bloques y la poda automática para eliminar bloques de Bitcoin Core después de ingerir un bloque para ahorrar espacio.
La ingestión simultánea de bloques nos permite completar varios bloques antes del bloque de procesamiento actual mientras esperamos que se guarde el bloque poblado más recientemente (manteniendo ocupados nuestros recursos de almacenamiento).
Debido a que almacenamos todos los bloques ingeridos en nuestra propia caché de almacenamiento, no necesitamos mantener datos duplicados en la base de datos de Bitcoin Core.
Por último, pero no menos importante, implementamos la construcción de transacciones sin estado, fuera de línea y basada en curvas para enviar desde cualquier dirección SegWit-Bech32 . Optamos por admitir solo el envío desde direcciones SegWit-Bech32 para minimizar la complejidad en la primera versión (hay muchas piezas nuevas en movimiento aquí). Esperamos revisar las contribuciones de la comunidad que agregan MultiSig, Lightning y otro soporte de direcciones.
Pruébalo
¡Basta de charla, enséñame el código! Esta sección lo guiará a través de la construcción de rosetta-bitcoin, iniciar rosetta-bitcoin, interactuar con rosetta-bitcoin y probar rosetta-bitcoin. Para completar los siguientes pasos, debe estar en una computadora que cumpla con los requisitos del sistema rosetta-bitcoin y debe instalar Docker .
Primero, necesitamos descargar la imagen de Docker rosetta-bitcoin prediseñada (guardada con la etiqueta rosetta-bitcoin:latest
):
curl -sSfL https://raw.githubusercontent.com/coinbase/rosetta-bitcoin/master/install.sh | sh -s
A continuación, necesitamos iniciar un contenedor usando nuestra imagen descargada (el contenedor se inicia en modo separado ):
docker run -d --rm --ulimit "nofile = 100000: 100000" -v "$ (pwd) / bitcoin-data: / data" -e "MODO = ONLINE" -e "RED = TESTNET" -e "PUERTO = 8080 "-p 8080: 8080 -p 18333: 18333 rosetta-bitcoin: último
Después de iniciar el contenedor, verá un identificador impreso en su terminal (ese es el ID del contenedor de Docker). Para ver los registros de este contenedor en ejecución, debe ejecutar:
registros de Docker --tail 100 -f <container_id>
Para asegurarnos de que todo funcione, hagamos una solicitud cURL para el estado actual de la red (es posible que deba esperar unos minutos para que el nodo comience a sincronizarse):
curl --request POST 'http: // localhost: 8080 / network / status' \--header 'Aceptar: aplicación / json' \--header 'Content-Type: application / json' \--data-raw '{ "identificador_red": { "blockchain": "Bitcoin", "red": "Testnet3" }} '| jq
Ahora que rosetta-bitcoin se está ejecutando, ¡la diversión realmente puede comenzar! A continuación, instalamos rosetta-cli , nuestra herramienta CLI para interactuar y probar las implementaciones de la API de Rosetta (esto se instalará en ./bin/rosetta-cli
):
curl -sSfL https://raw.githubusercontent.com/coinbase/rosetta-cli/master/scripts/install.sh | sh -s
Recomendamos mover este rosetta-cli
binario descargado a su bin
carpeta para que pueda ejecutarse llamando en rosetta-cli
lugar de ./bin/rosetta-cli
). El resto de este tutorial asume que lo ha hecho.
También necesitamos descargar el archivo de configuración para interactuar con rosetta-bitcoin:
curl -sSfL https://raw.githubusercontent.com/coinbase/rosetta-bitcoin/master/rosetta-cli-conf/bitcoin_testnet.json -o bitcoin_testnet.json
Podemos buscar el estado de sincronización actual:
vista rosetta-cli: redes --archivo de configuración bitcoin_testnet.json
Podemos buscar el contenido de cualquier bloque sincronizado (asegúrese de que el índice que busca sea menor que el índice devuelto por el índice actual devuelto en estado de sincronización):
vista rosetta-cli: bloque <índice de bloque> - archivo de configuración bitcoin_testnet.json
Podemos validar los puntos finales de la API de datos usando el comando `check: data`:
comprobación de rosetta-cli: datos - archivo de configuración bitcoin_testnet.json
Esta prueba sincronizará todos los bloques y confirmará que el saldo de cada cuenta devuelto por el punto final `/ account / balance` coincide con el saldo calculado utilizando las operaciones de Rosetta .
Por último, podemos validar los puntos finales de la API de construcción usando el comando `check: construction`:
comprobación de rosetta-cli: construcción - archivo de configuración bitcoin_testnet.json
Esta prueba creará, difundirá y confirmará transacciones de testnet hasta que alcancemos nuestras condiciones de salida especificadas (número de transacciones exitosas de cada tipo). Esta prueba ajusta automáticamente las tarifas según el tamaño estimado de las transacciones que crea y devuelve todos los fondos a una dirección de grifo al final de la prueba.
Cuando haya terminado de jugar con rosetta-bitcoin, ejecute el siguiente comando para apagarlo:
docker kill --signal = 2 <container_id>
Trabajo futuro
- Publique puntos de referencia para la velocidad de sincronización, el uso del almacenamiento y las pruebas de carga en testnet y mainnet
- Implementar la API de Rosetta / mempool / punto final de transacción
- Agregue la prueba de CI al repositorio usando rosetta-cli (probablemente en una red de prueba)
- Admite transacciones Multi-Sig y construcción de transacciones multifase
- Escriba un paquete de billetera (usando primitivas rosetta-sdk-go) para orquestar la construcción de transacciones para cualquier implementación de Rosetta (puede encontrar algunos trabajos iniciales en este esfuerzo aquí )
Si está interesado en alguno de estos artículos, comuníquese con el sitio de la comunidad de Coinbase .
Trabajar en Coinbase
Estamos contratando activamente en Coinbase a desarrolladores apasionados para unirse al equipo de Crypto y un líder de relaciones con desarrolladores para trabajar en el proyecto Rosetta. Si está interesado en ayudar a construir este lenguaje común para interactuar con blockchains, Coinbase está contratando.
Este sitio web contiene enlaces a sitios web de terceros u otro contenido solo con fines informativos («Sitios de terceros»). Los sitios de terceros no están bajo el control de Coinbase, Inc. y sus afiliados («Coinbase»), y Coinbase no es responsable del contenido de ningún sitio de terceros, incluido, entre otros, cualquier enlace contenido en un tercero. Sitio de terceros, o cualquier cambio o actualización de un Sitio de terceros. Coinbase no es responsable de la transmisión por Internet o cualquier otra forma de transmisión recibida de cualquier sitio de terceros. Coinbase le proporciona estos enlaces solo para su conveniencia, y la inclusión de cualquier enlace no implica respaldo, aprobación o recomendación por parte de Coinbase del sitio o asociación con sus operadores.
Todas las imágenes proporcionadas en este documento son de Coinbase.