Skip to main content

Hyperledger Fabric | Chaincode de sistema QSCC

1 estrella2 estrellas3 estrellas4 estrellas5 estrellas (2 votos, promedio: 5,00 de 5)
Cargando…

Hoy tuvimos un problemilla durante cierta implementación. Para solucionarlo tuve que confirmar la existencia de ciertas transacciones en la red Fabric de uno de nuestros clientes. Se trata de una instalación que funciona con LevelDB por temas de velocidad, por lo que no contaba con la interfaz web tan socorrida que nos proporciona CouchDB para realizar estas consultas de manera visual, así que decidí recurrir a los chaincodes del sistema. Utilizando este recurso pudimos resolver el problema en cuestión de minutos. Pero ¿qué son estos chaincodes de sistema? ¿qué hacen? ¿para qué sirven?.

Los chaincodes de sistema son exactamente lo que su nombre indica: “chaincodes”, es decir aplicaciones cuyo entorno de ejecución es nuestra blockchain fabric, y que además permiten realizar consultas y/o modificaciones  sobre el propio “sistema” sobre el que están corriendo.

Sin embargo hay diferencias importantes respecto a los chaincodes de usuario: Se trata de código que corre dentro del proceso del peer en vez de en contenedores docker separados. Por tanto, este tipo de chaincodes no se instalan e  instancian desde propuestas del SDK o de los CLIs, sino que se registran y despliegan en cada peer durante el arranque de los mismos. Debido a esta característica, tienen un nivel de acceso diferente a la información del peer y de la red, al contrario que los chaincodes de usuario que sólo tienen visibilidad del estado de su propio mundo (variables y funciones definidas sólo dentro del mismo chaincode).

Existen 5 chaincodes de sistema:

  • QSCC (Query System Chaincode), desde el que se puede hacer consultas sobre el mismo ledger, y es
    del que hablaremos en este artículo.
  • CSCC (Configuration System Chaincode), es el encargado de gestionar la configuración de los canales,
    así cómo de la creación y actualización de los mismos.
  • LSCC (Lifecycle System Chaincode), es el que permite gestionar el ciclo de vida de los chaincodes de
    usuario (instalación, consulta, upgrade, etc.)
  • ESCC (Endorsement System Chaincode), es el encargado de firmar las transacciones en la fase de
    endorsement.
  • VSCC (Validation System Chaincode), es el que valida las transacciones contra la política de
    endorsement.

QSCC

Dado que la documentación es escasa, vamos directamente a revisar el código fuente: Según el repositorio
de Fabric 1.4.8 (https://github.com/hyperledger/fabric/blob/v1.4.8/core/scc/qscc/query.go), dentro de este
chaincode de sistema tenemos 5 funciones disponibles:

  • GetTransactionByID
  • GetBlockByNumber
  • GetBlockByHash
  • GetBlockByTxID
  • GetChainInfo

Si nos fijamos bien, esto son básicamente 3 funciones, ya que las 3 GetBlockBy… hacen casi lo mismo como veremos.

Veamos una por una. Para ello nos ayudaremos de la red de ejemplo first-network que nos facilita Fabric dentro de su paquete fabric samples, que levantaré con los parámetros por defecto utilizando el comando byfn.sh up.

Una vez tenemos la red levantada nos conectamos al contenedor cli para lanzar las consultas:

El chaincode que despliega por defecto el script byfn.sh es el chaincode/chaincode_example02/go/ que define 2  valores, A y B, y 3 funciones: invoke (transferencia de A a B), delete (borra el estado de A o B) y query (consulta A o B).

GetTransactionByID

Vamos a ejecutar una transacción que transfiera 10 de A a B. Para que el código sea más legible definimos
antes algunas variables de entorno:

Estas variables de entorno también nos servirán para el resto de interacciones con la red que realicemos.
Una vez que las tenemos podemos realizar la transacción:

Es importante notar que lo hacemos con el flag –waitForEvent, de modo que el cli hace una espera síncrona a que los peers involucrados generen la transacción y devuelvan el identificador de la misma. En caso de no hacerlo con este flag obtendremos una respuesta asíncrona y nos perderemos el id de transacción. Nos fijamos en la línea:

Ahora que tenemos un hash de transacción, vamos a utilizarlo para hacer la consulta a QSCC. Esta consulta se realiza también utilizando el comando peer chaincode invoke, exactamente igual que si estuviéramos interactuando con un chaincode de usario:

Veremos una respuesta del estilo:

Lo que en sí no resulta muy útil, excepto porque nos permite saber:

  • Si el ID de transacción realmente existe o no (en el problema que tuvimos esta mañana eso era suficiente).
  • Los certificados involucrados en la transacción, que podemos decodificar en caso de estar haciendo debug de identidades.

El formato en el que el cli nos entrega el payload por pantalla es un protobuf codificado como string… es decir, prácticamente inútil de decodificar desde ese punto (invito una cerveza a quien me diga cómo decodificar eso sin pasar por un SDK). Fabric, como siempre, haciéndonos la vida fácil.

Por supuesto, en caso de preguntar por un hash inexistente la respuesta también lo reflejará claramente:

GetBlockBy…

Estas 3 funciones nos permiten obtener los bloques mismos del ledger. Una vez más, la respuesta viene codificada exactamente igual que antes, de modo que nos resulta muy poco útil excepto para los mismos usos anteriores: comprobar existencia, ver certificados, y si se afina el ojo, ver qué transacciones aparecen en cada bloque.

Por ejemplo:

Nos devuelve algo del estilo:

Donde aparece subrayado el ID de la única transacción que hay en ese bloque. Por supuesto en caso de que hubiera más transacciones dentro del bloque, también se mostrarían en el payload del resultado. Si en vez del bloque X preguntamos por los bloques 0, 1, 2 ó 3 podemos ver el bloque génesis, el bloque en el que se definen los anchor peers, el de la instalación del chaincode, etc., aunque como digo, hay que hacer mucho esfuerzo para intentar atisbar el contenido de dicha información debido al formato en que Fabric nos entrega la información. En caso de consultar un bloque inexistente la respuesta será del tipo:

La función GetBlockByHash funciona exactamente igual suponiendo que disponemos del hash del bloque en vez de su número.

La función GetBlockByTxID es más interesante ya que nos permite buscar el bloque que contiene la transacción que le indiquemos como parámetro. Es decir, no necesitamos saber el número de bloque ni su hash.

Finalmente, la función GetChainInfo… Veamos el resultado de su ejecución para intentar entender su función y utilidad:

Resultado:

¿Ideas?

Juan Capristán

Juan Capristán ha escrito 1 entradas


Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.