Meus olhos estão com medo, mas minhas mãos estão coçando!
Em artigos anteriores, analisamos as tecnologias em que as blockchains são construídas () e casos que podem ser implementados com a ajuda deles (Chegou a hora de colocar a mão na massa! Para projetos-piloto e provas de conceito (PoCs), prefiro usar a nuvem, pois ela é acessível de qualquer lugar do mundo e, muitas vezes, elimina a necessidade de configurações complexas de ambiente, já que configurações pré-configuradas estão disponíveis. Então, vamos construir algo simples, como uma rede para transferência de moedas entre participantes, e vamos chamá-la de Citcoin. Usaremos a nuvem da IBM e o blockchain universal Hyperledger Fabric. Primeiro, vamos entender por que o Hyperledger Fabric é chamado de blockchain universal.

Hyperledger Fabric — uma blockchain universal
De um modo geral, um sistema universal de informação é:
- Um conjunto de servidores e um núcleo de software que executa a lógica de negócios;
- Interfaces para interação com o sistema;
- Meios para registro, autenticação e autorização de dispositivos/pessoas;
- Um banco de dados que armazena dados operacionais e de arquivo:

A versão oficial do que é o Hyperledger Fabric pode ser lida em Em resumo, o Hyperledger Fabric é uma plataforma de código aberto que permite a construção de blockchains privadas e a execução de contratos inteligentes personalizados escritos em JavaScript e Go. Vamos analisar mais detalhadamente a arquitetura do Hyperledger Fabric e veremos que se trata de um sistema universal, com apenas requisitos específicos para armazenamento e registro de dados. Esses requisitos são que, como em todas as blockchains, os dados são armazenados em blocos, que só são adicionados à blockchain se os participantes chegarem a um consenso e, uma vez gravados, os dados não podem ser apagados ou excluídos.
Arquitetura Hyperledger Fabric
O diagrama mostra a arquitetura do Hyperledger Fabric:

Organizações — As organizações contêm pares, o que significa que a blockchain existe graças ao apoio das organizações. Diferentes organizações podem fazer parte de um mesmo canal.
Canal — uma estrutura lógica que une pares em grupos, definindo assim uma blockchain. O Hyperledger Fabric pode processar simultaneamente múltiplas blockchains com diferentes lógicas de negócio.
Provedor de Serviços de Associados (MSP) — é uma AC (Autoridade Certificadora) para emissão de identidades e atribuição de funções. Para criar um nó, você precisa interagir com o MSP.
Nós pares — verificar transações, armazenar o blockchain, executar contratos inteligentes e interagir com aplicativos. Os pares possuem uma identidade (certificado digital) emitida pelo MSP. Ao contrário das redes Bitcoin ou Ethereum, onde todos os nós são iguais, no Hyperledger Fabric os nós desempenham funções diferentes:
- O colega pode ser apoio de colegas (EP) e executar contratos inteligentes.
- Comprometendo-se com um colega (CP) - apenas armazenar dados no blockchain e atualizar o "Estado Mundial".
- Ponto de ancoragem (AP) - Se várias organizações participam de uma blockchain, nós âncora são usados para comunicação entre elas. Cada organização deve ter um ou mais nós âncora. Usando um AP, qualquer nó da organização pode obter informações sobre todos os nós de outras organizações. Para sincronizar informações entre os APs, utiliza-se uma rede ponto a ponto. .
- Líder entre pares Se uma organização possui vários pares, apenas o par líder receberá blocos do Serviço de Ordenação e os distribuirá aos demais pares. O líder pode ser atribuído estaticamente ou eleito dinamicamente pelos pares dentro da organização. O protocolo de fofoca também é usado para sincronizar informações sobre os líderes.
Ativos — entidades de valor armazenadas no blockchain. Mais especificamente, são dados chave-valor em formato JSON. Esses dados são registrados no "Blockchain". Eles possuem um histórico, armazenado no blockchain, e um estado atual, armazenado no banco de dados "Estado Mundial". As estruturas de dados são preenchidas arbitrariamente, dependendo das necessidades do negócio. Não há campos obrigatórios; a única recomendação é que os ativos tenham um proprietário e representem valor.
Ledger — consiste em uma blockchain e um banco de dados World State, que armazena o estado atual dos ativos. O World State utiliza LevelDB ou CouchDB.
Contrato inteligente — Os contratos inteligentes implementam a lógica de negócios do sistema. No Hyperledger Fabric, os contratos inteligentes são chamados de chaincode. O chaincode é usado para definir ativos e transações que os envolvem. Tecnicamente, os contratos inteligentes são módulos de software implementados em JS ou Go.
Política de endosso — Para cada chaincode, você pode definir políticas sobre quantas confirmações esperar para uma transação e de quem elas devem ser feitas. Se nenhuma política for definida, o padrão é "Uma transação deve ser confirmada por qualquer membro de qualquer organização no canal". Exemplos de políticas:
- A transação deve ser confirmada por um administrador da organização;
- Deve ser confirmado por qualquer membro ou cliente da organização;
- Deve ser verificado por qualquer organização equivalente.
Serviço de encomendas — Agrupa transações em blocos e as envia aos pares no canal. Garante a entrega da mensagem a todos os pares na rede. É utilizado em sistemas industriais. , para desenvolvimento e testes .
Fluxo de Chamadas

- O aplicativo interage com o Hyperledger Fabric usando os SDKs Go, Node.js ou Java;
- O cliente cria uma transação tx e a envia aos pares que a endossam;
- O nó verifica a assinatura do cliente, executa a transação e envia a assinatura de endosso de volta para o cliente. O chaincode é executado apenas no nó que endossa a transação, e o resultado é transmitido para todos os nós. Esse algoritmo é chamado de consenso PBFT (Practical Byzantine Fault Tolerant). Ele difere de o fato de a mensagem ser enviada e a confirmação ser esperada não de todos os participantes, mas apenas de um determinado grupo;
- Após o cliente receber o número de respostas correspondente à política de endosso, ele envia uma transação para o serviço de pedidos;
- O serviço de ordenação forma um bloco e o envia a todos os pares que o confirmam. O serviço de ordenação garante que os blocos sejam gravados sequencialmente, o que elimina a chamada bifurcação do livro-razão ();
- Os pares recebem o bloco, verificam novamente a política de endosso, gravam o bloco no blockchain e alteram o estado no banco de dados "Estado mundial".
Isso resulta em uma divisão de funções entre os nós. Isso garante a escalabilidade e a segurança do blockchain:
- Os contratos inteligentes (chaincode) são executados por nós que os endossam. Isso garante a confidencialidade dos contratos inteligentes, pois o código é armazenado apenas por nós que os endossam, e não por todos os participantes.
- O processo de ordenação deve ser rápido. Isso é garantido pelo fato de que a ordenação gera apenas um bloco e o envia para um conjunto fixo de nós líderes.
- Os nós de commit apenas armazenam a blockchain — podem ser muitos e não exigem muita energia nem operação instantânea.
Você pode aprender mais sobre as decisões arquitetônicas do Hyperledger Fabric e por que ele funciona da maneira que funciona aqui: ou aqui: .
Assim, o Hyperledger Fabric é um sistema verdadeiramente universal que permite:
- Implemente lógica de negócios personalizada usando o mecanismo de contrato inteligente;
- Escrever e recuperar dados do banco de dados blockchain em formato JSON;
- Conceda e verifique o acesso à API usando uma Autoridade Certificadora.
Agora que já abordamos alguns detalhes específicos do Hyperledger Fabric, vamos finalmente fazer algo útil!
Implantação da blockchain
Formulação do problema
O objetivo é implementar uma rede Citcoin com as seguintes funções: criar uma conta, obter um saldo, adicionar fundos a uma conta e transferir moedas de uma conta para outra. Vamos desenhar um modelo de objeto, que implementaremos em um contrato inteligente. Teremos, portanto, contas, identificadas por nomes e contendo um saldo, e uma lista de contas. As contas e a lista de contas são ativos em termos do Hyperledger Fabric. Consequentemente, elas possuem um histórico e um estado atual. Tentarei ilustrar isso visualmente:

Os valores superiores representam o estado atual armazenado no banco de dados "Estado Mundial". Abaixo deles, encontram-se os valores que mostram o histórico armazenado no blockchain. O estado atual dos ativos é alterado por transações. Um ativo só muda como um todo; portanto, a execução de uma transação cria um novo objeto, e o valor atual do ativo é perdido para o histórico.
IBM Cloud
Crie uma conta em Para usar a plataforma blockchain, você precisa atualizá-la para o modelo Pay-As-You-Go. Esse processo pode ser demorado, pois a IBM solicita informações adicionais e as verifica manualmente. Por outro lado, posso afirmar que a IBM oferece bons materiais de treinamento para a implementação do Hyperledger Fabric em sua nuvem. Gostei particularmente da seguinte série de artigos e exemplos:
Abaixo estão capturas de tela da plataforma IBM Blockchain. Este não é um guia para criar um blockchain, mas sim uma demonstração do escopo da tarefa. Para os nossos propósitos, criaremos uma única Organização:

Nele criamos nós: Orderer CA, Org1 CA, Orderer Peer:

Criamos usuários:

Vamos criar um canal e chamá-lo de citcoin:

O Channel é essencialmente uma blockchain, portanto, começa no bloco zero (bloco gênese):

Escrevendo um contrato inteligente
/*
* 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, tudo aqui deveria ser claro:
- Existem diversas funções (AddAccount, GetAccounts, SendFrom, GetBalance, RefillBalance) que o programa de demonstração chamará usando a API do Hyperledger Fabric.
- As funções SendFrom e RefillBalance geram eventos que o programa de demonstração receberá.
- A função `instantiate` é chamada uma vez quando o contrato inteligente é instanciado. Na verdade, ela não é chamada apenas uma vez, mas sempre que a versão do contrato inteligente muda. Portanto, inicializar a lista com um array vazio é uma má ideia, pois perderemos a lista atual sempre que a versão do contrato inteligente mudar. Mas tudo bem, estou apenas aprendendo.
- As contas e a lista de contas são estruturas de dados JSON. O JavaScript é usado para manipulação de dados.
- Você pode obter o valor atual de um ativo chamando a função getState e atualizá-lo usando putState.
- Quando uma conta é criada, a função AddAccount é chamada, a qual compara o número máximo de contas no blockchain (maxAccounts = 5). Existe um bug aqui (já notado?) que leva a um crescimento infinito do número de contas. Tais erros devem ser evitados.
Em seguida, carregamos o contrato inteligente no canal e o instanciamos:

Vamos analisar a transação para instalar o contrato inteligente:

Confira mais detalhes sobre o nosso canal:

O diagrama da rede blockchain resultante na nuvem da IBM é o seguinte. O diagrama também inclui um programa de demonstração em execução em um servidor virtual na nuvem da Amazon (mais detalhes na próxima seção):

Criando uma interface gráfica para chamadas de API do Hyperledger Fabric
O Hyperledger Fabric possui uma API que pode ser usada para:
- Criação de canal;
- Conexões ponto a ponto para canal;
- Instalar e instanciar contratos inteligentes em um canal;
- Transações por chamada;
- Solicitar informações na blockchain.
Desenvolvimento de aplicações
Em nosso programa de demonstração, usaremos a API apenas para iniciar transações e solicitar informações, pois já concluímos as demais etapas usando a plataforma blockchain da IBM. Desenvolveremos a interface gráfica usando uma pilha de tecnologias padrão: Express.js + Vue.js + Node.js. Um artigo à parte poderia ser escrito sobre como começar a criar aplicações web modernas. Aqui está o link para a série de palestras que mais gostei: O resultado é uma aplicação cliente-servidor com uma interface gráfica familiar no estilo do Material Design do Google. A API REST entre o cliente e o servidor consiste em diversas chamadas:
- HyperledgerDemo/v1/init — inicializar o blockchain;
- HyperledgerDemo/v1/accounts/list — obter uma lista de todas as contas;
- HyperledgerDemo/v1/account?name=Bob&balance=100 — criar conta Bob;
- HyperledgerDemo/v1/info?account=Bob — obter informações sobre a conta Bob;
- HyperledgerDemo/v1/transaction?from=Bob&to=Alice&volume=2 — transferir duas moedas de Bob para Alice;
- HyperledgerDemo/v1/disconnect — fechar a conexão com o blockchain.
A descrição da API com exemplos está publicada em — um programa amplamente conhecido para testar APIs HTTP.
Aplicação de demonstração na nuvem da Amazon
Enviei o aplicativo para a Amazon porque a IBM ainda não conseguiu atualizar minha conta e me permitir criar servidores virtuais. Para completar, adicionei um domínio. Vou manter o servidor funcionando por um tempo e depois desligá-lo, pois o aluguel está chegando aos poucos e o Citcoin ainda não está listado na corretora. Incluí capturas de tela da demonstração no artigo para que a lógica fique clara. O aplicativo de demonstração pode:
- Inicialize a blockchain;
- Criar uma conta (mas agora não é possível criar uma nova conta, visto que a blockchain atingiu o número máximo de contas especificado no contrato inteligente);
- Obtenha uma lista de contas;
- Transferir moedas Citcoin entre Alice, Bob e Alex;
- Receber eventos (mas atualmente não há como exibir eventos, então, por simplicidade, a interface indica que eventos não são suportados);
- Registrar ações.
Primeiro, vamos inicializar a blockchain:

Em seguida, crie sua conta e não perca tempo com o saldo:

Obtemos uma lista de todas as contas disponíveis:

Selecione o remetente e o destinatário e veja os respectivos saldos. Se o remetente e o destinatário forem a mesma pessoa, a conta de ambos será recarregada.

Monitoramos a execução das transações no registro de eventos:

Isso conclui o programa de demonstração. Em seguida, você poderá visualizar nossa transação no blockchain:

E a lista geral de transações:

Concluímos com sucesso a prova de conceito (PoC) da rede Citcoin. O que mais precisa ser feito para tornar a Citcoin uma rede completa para transferências de criptomoedas? Apenas um pouco:
- Na etapa de criação da conta, implemente a geração de chaves privada e pública. A chave privada deve ser armazenada pelo usuário da conta, e a chave pública deve ser armazenada no blockchain.
- Faça uma transferência de criptomoedas que utilize uma chave pública, em vez de um nome, para identificar o usuário.
- Criptografe as transações enviadas do usuário para o servidor com sua chave privada.
Conclusão
Implementamos a rede Citcoin com as seguintes funcionalidades: adicionar uma conta, consultar o saldo, recarregar a conta e transferir moedas de uma conta para outra. Então, qual foi o custo para construir a prova de conceito (PoC)?
- É necessário estudar blockchain em geral e Hyperledger Fabric em particular;
- Aprenda a usar as nuvens da IBM ou da Amazon;
- Aprenda a linguagem de programação JS e alguns frameworks web;
- Se alguns dados precisarem ser armazenados não no blockchain, mas em um banco de dados separado, aprenda a integrá-los, por exemplo, ao PostgreSQL;
- E por último, mas não menos importante, sem conhecimento Linux Em nenhum lugar do mundo moderno!
Não é nenhum bicho de sete cabeças, mas você vai ter que se esforçar bastante!
Исходники no GitHub
Coloquei as fontes em Breve descrição do repositório:
Catálogo «servidor— Servidor Node.js
Catálogo «cliente— Cliente Node.js
Catálogo «blockchain» (Os valores e chaves dos parâmetros, obviamente, não estão funcionando e são fornecidos apenas para fins de exemplo):
- contrato — código-fonte de contrato inteligente
- carteira — chaves de usuário para usar a API do Hyperledger Fabric.
- *.cds — versões compiladas de contratos inteligentes
- Arquivos *.json - arquivos de configuração de exemplo para usar a API do Hyperledger Fabric.
É só o começo!
Fonte: habr.com
