Blockchain: que PoC debemos construír?

Os teus ollos teñen medo e as mans che pican!

En artigos anteriores, tratamos as tecnoloxías nas que se constrúen as cadeas de bloques (Que debemos construír unha cadea de bloques?) e casos que se poden implementar coa súa axuda (Por que debemos construír un caso?). É hora de traballar coas mans! Para implementar pilotos e PoC (Proof of Concept), prefiro usar as nubes, porque... pódese acceder a eles desde calquera parte do mundo e, moitas veces, non hai que perder o tempo nunha tediosa instalación do medio ambiente, porque Hai configuracións predefinidas. Entón, fagamos algo sinxelo, por exemplo, unha rede para transferir moedas entre participantes e chamémoslle modestamente Bitcoin. Para iso empregaremos a nube de IBM e a cadea de bloques universal Hyperledger Fabric. En primeiro lugar, imos descubrir por que Hyperledger Fabric se chama unha cadea de bloques universal?

Blockchain: que PoC debemos construír?

Hyperledger Fabric - unha cadea de bloques universal

En xeral, un sistema de información universal é:

  • Un conxunto de servidores e un núcleo de software que realiza a lóxica empresarial;
  • Interfaces para a interacción co sistema;
  • Ferramentas de rexistro, autenticación e autorización de dispositivos/persoas;
  • Base de datos que almacena datos operativos e de arquivo:

Blockchain: que PoC debemos construír?

A versión oficial do que é Hyperledger Fabric pódese ler en On-line, e en resumo, Hyperledger Fabric é unha plataforma de código aberto que permite construír cadeas de bloques privadas e executar contratos intelixentes arbitrarios escritos nas linguaxes de programación JS e Go. Vexamos en detalle a arquitectura de Hyperledger Fabric e asegúrese de que este é un sistema universal que só ten características específicas para almacenar e gravar datos. A especificidade é que os datos, como en todas as cadeas de bloques, almacénanse en bloques que se colocan na cadea de bloques só se os participantes chegan a un consenso e despois de gravar os datos non se poden corrixir ou eliminar silenciosamente.

Hyperledger Fabric Architecture

O diagrama mostra a arquitectura Hyperledger Fabric:

Blockchain: que PoC debemos construír?

Organizacións - as organizacións conteñen pares, é dicir. blockchain existe debido ao apoio das organizacións. Diferentes organizacións poden formar parte da mesma canle.

Canle — unha estrutura lóxica que une os compañeiros en grupos, é dicir. especifícase a cadea de bloques. Hyperledger Fabric pode procesar simultáneamente varias cadeas de bloques con diferentes lóxicas de negocio.

Provedor de servizos de adhesión (MSP) é unha CA (Autoridade de Certificación) para emitir identidade e asignar roles. Para crear un nodo, cómpre interactuar co MSP.

Nodos pares — verificar transaccións, almacenar a cadea de bloques, executar contratos intelixentes e interactuar coas aplicacións. Os compañeiros teñen unha identidade (certificado dixital), que é emitida polo MSP. A diferenza da rede Bitcoin ou Etherium, onde todos os nodos teñen iguais dereitos, en Hyperledger Fabric os nodos xogan diferentes funcións:

  • Peer quizais pare avalando (EP) e executar contratos intelixentes.
  • Iguais comprometidos (CP): só garda datos na cadea de bloques e actualiza o "Estado mundial".
  • Anchor Peer (AP) - se varias organizacións participan na cadea de bloques, entón utilízanse os compañeiros de referencia para a comunicación entre elas. Toda organización debe ter un ou máis compañeiros de referencia. Usando AP, calquera compañeiro dunha organización pode obter información sobre todos os compañeiros doutras organizacións. Usado para sincronizar información entre AP protocolo de fofocas.
  • Líder Peer — se unha organización ten varios compañeiros, só o líder do mesmo recibirá bloques do servizo de Pedidos e entregalos ao resto dos compañeiros. O líder pode ser especificado de forma estática ou seleccionado dinámicamente polos compañeiros da organización. O protocolo de fofocas tamén se usa para sincronizar información sobre líderes.

Activos — entidades que teñen valor e están almacenadas na cadea de bloques. Máis concretamente, estes son datos clave-valor en formato JSON. Son estes datos os que se rexistran na Blockchain. Teñen un historial, que se almacena na cadea de bloques, e un estado actual, que se almacena na base de datos "Estado mundial". As estruturas de datos énchense de forma arbitraria dependendo das tarefas empresariais. Non hai campos obrigatorios, a única recomendación é que os activos deben ter un propietario e ser valiosos.

libro-razón — consiste na base de datos Blockchain e Word, que almacena o estado actual dos activos. O estado mundial usa LevelDB ou CouchDB.

Contrato intelixente — mediante contratos intelixentes, implícase a lóxica empresarial do sistema. En Hyperledger Fabric, os contratos intelixentes chámanse chaincode. Usando código en cadea, especifícanse os activos e as transaccións sobre eles. En termos técnicos, os contratos intelixentes son módulos de software implementados nas linguaxes de programación JS ou Go.

Política de aval — para cada código de cadea, pode establecer unha política sobre cantas confirmacións para unha transacción se deben esperar e de quen. Se a política non está definida, a opción predeterminada é: "a transacción debe ser confirmada por calquera membro de calquera organización da canle". Exemplos de políticas:

  • A transacción debe ser aprobada por calquera administrador da organización;
  • Debe ser confirmado por calquera membro ou cliente da organización;
  • Debe ser confirmado por calquera organización pares.

Servizo de pedidos — empaqueta transaccións en bloques e envíaas a pares da canle. Garante a entrega de mensaxes a todos os compañeiros da rede. Usado para sistemas industriais Corretor de mensaxes Kafka, para o desenvolvemento e probas Solo.

CallFlow

Blockchain: que PoC debemos construír?

  • A aplicación comunícase con Hyperledger Fabric mediante Go, Node.js ou Java SDK;
  • O cliente crea unha transacción tx e envíaa aos compañeiros de apoio;
  • O Peer verifica a sinatura do cliente, completa a transacción e envía a sinatura de endoso de volta ao cliente. O código en cadea execútase só no par de apoio e o resultado da súa execución envíase a todos os pares. Este algoritmo de traballo chámase consenso PBFT (Practical Byzantine Fault Tolerant). Difire de BFT clásico o feito de que a mensaxe se envíe e se espera a confirmación non de todos os participantes, senón só dun determinado conxunto;
  • Despois de que o cliente reciba o número de respostas correspondente á política de aval, envía a transacción ao servizo de Pedidos;
  • O servizo de pedidos xera un bloque e envíao a todos os compañeiros comprometidos. O servizo de pedidos garante a gravación secuencial dos bloques, o que elimina o chamado garfo do libro maior (ver sección "Gafos");
  • Os compañeiros reciben un bloque, verifican de novo a política de aprobación, escriben o bloque na cadea de bloques e cambian o estado na base de datos "Estado mundial".

Eses. Isto resulta nunha división de roles entre os nodos. Isto garante que a cadea de bloques sexa escalable e segura:

  • Os contratos intelixentes (chaincode) realizan o apoio de pares. Isto garante a confidencialidade dos contratos intelixentes, porque non o almacenan todos os participantes, senón só os compañeiros de apoio.
  • O pedido debería funcionar rapidamente. Isto está garantido polo feito de que Ordering só forma un bloque e envíao a un conxunto fixo de compañeiros líderes.
  • Os compañeiros comprometidos só almacenan a cadea de bloques: pode haber moitos deles e non requiren moita potencia e operación instantánea.

Máis detalles sobre as solucións arquitectónicas de Hyperledger Fabric e por que funciona deste xeito e non doutro xeito pódense atopar aquí: Orixes da Arquitectura ou aquí: Hyperledger Fabric: un sistema operativo distribuído para blockchains autorizados.

Entón, Hyperledger Fabric é un sistema verdadeiramente universal co que podes:

  • Implementar lóxica comercial arbitraria mediante o mecanismo de contrato intelixente;
  • Gravar e recibir datos da base de datos blockchain en formato JSON;
  • Conceda e verifique o acceso á API mediante a autoridade de certificación.

Agora que entendemos un pouco os detalles de Hyperledger Fabric, por fin fagamos algo útil!

Implantación de blockchain

Declaración de problemas

A tarefa é implementar a rede Citcoin coas seguintes funcións: crear unha conta, obter un saldo, recargar a túa conta, transferir moedas dunha conta a outra. Debuxemos un modelo de obxectos, que implementaremos nun contrato intelixente. Entón, teremos contas que se identifican por nomes e conteñen un saldo e unha lista de contas. As contas e unha lista de contas son, en termos de activos de Hyperledger Fabric. En consecuencia, teñen unha historia e un estado actual. Intentarei debuxar isto claramente:

Blockchain: que PoC debemos construír?

As cifras superiores son o estado actual, que se almacena na base de datos "Estado mundial". Debaixo deles hai figuras que mostran o historial que se almacena na cadea de bloques. O estado actual dos activos é modificado polas transaccións. O Activo cambia só no seu conxunto, polo que, como resultado da transacción, créase un novo obxecto e o valor actual do activo pasa ao historial.

IBM Cloud

Creamos unha conta en IBM cloud. Para usar a plataforma blockchain, debe actualizarse a Pay-As-You-Go. Este proceso pode non ser rápido, porque... IBM solicita información adicional e verifícaa manualmente. Como nota positiva, podo dicir que IBM ten bos materiais de formación que che permiten implantar Hyperledger Fabric na súa nube. Gustoume a seguinte serie de artigos e exemplos:

As seguintes son capturas de pantalla da plataforma IBM Blockchain. Esta non é unha instrución sobre como crear unha cadea de bloques, senón simplemente unha demostración do alcance da tarefa. Polo tanto, para os nosos propósitos, creamos unha organización:

Blockchain: que PoC debemos construír?

Creamos nodos nel: Orderer CA, Org1 CA, Orderer Peer:

Blockchain: que PoC debemos construír?

Creamos usuarios:

Blockchain: que PoC debemos construír?

Crea unha canle e chámaa citcoin:

Blockchain: que PoC debemos construír?

Esencialmente Channel é unha cadea de bloques, polo que comeza co bloque cero (bloque Genesis):

Blockchain: que PoC debemos construír?

Redacción dun contrato intelixente

/*
 * Citcoin smart-contract v1.5 for Hyperledger Fabric
 * (c) Alexey Sushkov, 2019
 */
 
'use strict';
 
const { Contract } = require('fabric-contract-api');
const maxAccounts = 5;
 
class CitcoinEvents extends Contract {
 
    async instantiate(ctx) {
        console.info('instantiate');
        let emptyList = [];
        await ctx.stub.putState('accounts', Buffer.from(JSON.stringify(emptyList)));
    }
    // Get all accounts
    async GetAccounts(ctx) {
        // Get account list:
        let accounts = '{}'
        let accountsData = await ctx.stub.getState('accounts');
        if (accountsData) {
            accounts = JSON.parse(accountsData.toString());
        } else {
            throw new Error('accounts not found');
        }
        return accountsData.toString()
    }
     // add a account object to the blockchain state identifited by their name
    async AddAccount(ctx, name, balance) {
        // this is account data:
        let account = {
            name: name,
            balance: Number(balance),       
            type: 'account',
        };
        // create account:
        await ctx.stub.putState(name, Buffer.from(JSON.stringify(account)));
 
        // Add account to list:
        let accountsData = await ctx.stub.getState('accounts');
        if (accountsData) {
            let accounts = JSON.parse(accountsData.toString());
            if (accounts.length < maxAccounts)
            {
                accounts.push(name);
                await ctx.stub.putState('accounts', Buffer.from(JSON.stringify(accounts)));
            } else {
                throw new Error('Max accounts number reached');
            }
        } else {
            throw new Error('accounts not found');
        }
        // return  object
        return JSON.stringify(account);
    }
    // Sends money from Account to Account
    async SendFrom(ctx, fromAccount, toAccount, value) {
        // get Account from
        let fromData = await ctx.stub.getState(fromAccount);
        let from;
        if (fromData) {
            from = JSON.parse(fromData.toString());
            if (from.type !== 'account') {
                throw new Error('wrong from type');
            }   
        } else {
            throw new Error('Accout from not found');
        }
        // get Account to
        let toData = await ctx.stub.getState(toAccount);
        let to;
        if (toData) {
            to = JSON.parse(toData.toString());
            if (to.type !== 'account') {
                throw new Error('wrong to type');
            }  
        } else {
            throw new Error('Accout to not found');
        }
 
        // update the balances
        if ((from.balance - Number(value)) >= 0 ) {
            from.balance -= Number(value);
            to.balance += Number(value);
        } else {
            throw new Error('From Account: not enought balance');          
        }
 
        await ctx.stub.putState(from.name, Buffer.from(JSON.stringify(from)));
        await ctx.stub.putState(to.name, Buffer.from(JSON.stringify(to)));
                 
        // define and set Event
        let Event = {
            type: "SendFrom",
            from: from.name,
            to: to.name,
            balanceFrom: from.balance,
            balanceTo: to.balance,
            value: value
        };
        await ctx.stub.setEvent('SendFrom', Buffer.from(JSON.stringify(Event)));
 
        // return to object
        return JSON.stringify(from);
    }
 
    // get the state from key
    async GetState(ctx, key) {
        let data = await ctx.stub.getState(key);
        let jsonData = JSON.parse(data.toString());
        return JSON.stringify(jsonData);
    }
    // GetBalance   
    async GetBalance(ctx, accountName) {
        let data = await ctx.stub.getState(accountName);
        let jsonData = JSON.parse(data.toString());
        return JSON.stringify(jsonData);
    }
     
    // Refill own balance
    async RefillBalance(ctx, toAccount, value) {
        // get Account to
        let toData = await ctx.stub.getState(toAccount);
        let to;
        if (toData) {
            to = JSON.parse(toData.toString());
            if (to.type !== 'account') {
                throw new Error('wrong to type');
            }  
        } else {
            throw new Error('Accout to not found');
        }
 
        // update the balance
        to.balance += Number(value);
        await ctx.stub.putState(to.name, Buffer.from(JSON.stringify(to)));
                 
        // define and set Event
        let Event = {
            type: "RefillBalance",
            to: to.name,
            balanceTo: to.balance,
            value: value
        };
        await ctx.stub.setEvent('RefillBalance', Buffer.from(JSON.stringify(Event)));
 
        // return to object
        return JSON.stringify(from);
    }
}
module.exports = CitcoinEvents;

Intuitivamente, todo debería quedar claro aquí:

  • Hai varias funcións (AddAccount, GetAccounts, SendFrom, GetBalance, RefillBalance) que o programa de demostración chamará mediante a API de Hyperledger Fabric.
  • As funcións SendFrom e RefillBalance xeran eventos que recibirá o programa de demostración.
  • A función de instanciación chámase unha vez cando se crea unha instancia dun contrato intelixente. De feito, chámase non só unha vez, senón cada vez que cambia a versión do contrato intelixente. Polo tanto, inicializar unha lista cunha matriz baleira é unha mala idea, porque Agora, cando cambiemos a versión do contrato intelixente, perderemos a lista actual. Pero está ben, só estou aprendendo).
  • As contas e unha lista de contas son estruturas de datos JSON. JS úsase para a manipulación de datos.
  • Podes obter o valor actual dun activo usando a chamada á función getState e actualizalo usando putState.
  • Ao crear unha conta, chámase a función AddAccount, na que se fai unha comparación para o número máximo de contas na cadea de bloques (maxAccounts = 5). E aquí hai unha xamba (xa notaches?), que leva a un aumento infinito do número de contas. Tales erros deben evitarse)

A continuación, cargamos o contrato intelixente na Canle e instanciámolo:

Blockchain: que PoC debemos construír?

Vexamos a transacción para instalar Smart Contract:

Blockchain: que PoC debemos construír?

Vexamos os detalles da nosa canle:

Blockchain: que PoC debemos construír?

Como resultado, obtemos o seguinte diagrama dunha rede blockchain na nube de IBM. O diagrama tamén mostra un programa de demostración que se executa na nube de Amazon nun servidor virtual (máis sobre iso na seguinte sección):

Blockchain: que PoC debemos construír?

Creando unha GUI para chamadas de API de Hyperledger Fabric

Hyperledger Fabric ten unha API que se pode usar para:

  • Crear canle;
  • Conexións peer to channel;
  • Instalación e instanciación de contratos intelixentes na canle;
  • Transaccións de chamadas;
  • Solicita información sobre a cadea de bloques.

Desenvolvemento de aplicacións

No noso programa de demostración usaremos a API só para chamar a transaccións e solicitar información, porque Xa completamos os pasos restantes usando a plataforma blockchain de IBM. Escribimos unha GUI usando unha pila de tecnoloxía estándar: Express.js + Vue.js + Node.js. Podes escribir un artigo separado sobre como comezar a crear aplicacións web modernas. Aquí vos deixo un enlace á serie de conferencias que máis me gustaron: Aplicación web Full Stack usando Vue.js e Express.js. O resultado é unha aplicación cliente-servidor cunha interface gráfica familiar ao estilo Material Design de Google. A API REST entre o cliente e o servidor consta de varias chamadas:

  • HyperledgerDemo/v1/init: inicializa a cadea de bloques;
  • HyperledgerDemo/v1/accounts/list — obtén unha lista de todas as contas;
  • HyperledgerDemo/v1/account?name=Bob&balance=100 — crear unha conta de Bob;
  • HyperledgerDemo/v1/info?account=Bob — obter información sobre a conta de Bob;
  • HyperledgerDemo/v1/transaction?from=Bob&to=Alice&volume=2: transfire dúas moedas de Bob a Alice;
  • HyperledgerDemo/v1/disconnect: pecha a conexión coa cadea de bloques.

Descrición da API con exemplos incluídos en Sitio web do carteiro - un programa ben coñecido para probar a API HTTP.

Aplicación de demostración na nube de Amazon

Carguei a aplicación a Amazon porque... IBM aínda non puido actualizar a miña conta e permitirme crear servidores virtuais. Como engadir unha cereixa ao dominio: www.citcoin.info. Vou manter o servidor acendido por un tempo e despois apagalo, porque... os céntimos de aluguer están a gotear e as moedas de citcoin aínda non cotizan na bolsa) Estou incluíndo capturas de pantalla da demostración no artigo para que a lóxica do traballo estea clara. A aplicación de demostración pode:

  • Inicializa a cadea de bloques;
  • Crea unha conta (pero agora non podes crear unha nova conta, porque o número máximo de contas especificado no contrato intelixente alcanzouse na cadea de bloques);
  • Recibir unha lista de Contas;
  • Transferir moedas de citcoin entre Alice, Bob e Alex;
  • Recibir eventos (pero agora non hai forma de mostrar eventos, polo que para simplificar a interface di que os eventos non son compatibles);
  • Rexistrar accións.

Primeiro iniciamos a cadea de bloques:

Blockchain: que PoC debemos construír?

A continuación, creamos a nosa conta, non perdas o tempo co saldo:

Blockchain: que PoC debemos construír?

Temos unha lista de todas as contas dispoñibles:

Blockchain: que PoC debemos construír?

Seleccionamos o remitente e o destinatario, e obtemos os seus saldos. Se o remitente e o destinatario son o mesmo, a súa conta será reabastecida:

Blockchain: que PoC debemos construír?

No rexistro monitorizamos a execución das transaccións:

Blockchain: que PoC debemos construír?

En realidade, iso é todo co programa de demostración. A continuación podes ver a nosa transacción na cadea de bloques:

Blockchain: que PoC debemos construír?

E a lista xeral de transaccións:

Blockchain: que PoC debemos construír?

Con isto, completamos con éxito a implementación do PoC para crear a rede Citcoin. Que máis hai que facer para que Citcoin se converta nunha rede completa para transferir moedas? Moi pequeno:

  • Na fase de creación da conta, implementa a xeración dunha chave privada/pública. A clave privada debe almacenarse co usuario da conta, a clave pública debe almacenarse na cadea de bloques.
  • Fai unha transferencia de moedas na que se utilice unha chave pública, máis que un nome, para identificar ao usuario.
  • Cifra transaccións que van do usuario ao servidor coa súa clave privada.

Conclusión

Implementamos a rede Citcoin coas seguintes funcións: engadir unha conta, obter un saldo, recargar a súa conta, transferir moedas dunha conta a outra. Entón, que nos custou construír un PoC?

  • Debes estudar blockchain en xeral e Hyperledger Fabric en particular;
  • Aprende a usar as nubes de IBM ou Amazon;
  • Aprende a linguaxe de programación JS e algún framework web;
  • Se hai que almacenar algúns datos non na cadea de bloques, senón nunha base de datos separada, aprende a integrar, por exemplo, con PostgreSQL;
  • E, por último, pero non menos importante: non se pode vivir no mundo moderno sen coñecementos de Linux!)

Por suposto, non é ciencia espacial, pero terás que traballar duro!

Fontes en GitHub

Fontes postas GitHub. Breve descrición do repositorio:
Catálogo «servidor» — Servidor Node.js
Catálogo «cliente» — Cliente Node.js
Catálogo «blockchain"(Os valores dos parámetros e as claves, por suposto, non funcionan e só se dan como exemplo):

  • contract — código fonte do contrato intelixente
  • wallet: claves de usuario para usar a API de Hyperledger Fabric.
  • *.cds - versións compiladas de contratos intelixentes
  • Ficheiros *.json: exemplos de ficheiros de configuración para usar a API de Hyperledger Fabric

É só o comezo!

Fonte: www.habr.com

Engadir un comentario