BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Artigos Explorando o HyperLedger: Uma experiência em ser um desbravador neste Framework

Explorando o HyperLedger: Uma experiência em ser um desbravador neste Framework

Favoritos

Pontos Principais

  • Algum tempo atrás a equipe do OpenGift explorou o desenvolvimento de uma blockchain baseada no HyperLedger em um ambiente de produção. Este artigo apresenta a história de nossas tentativas de integrá-lo, os problemas que encontramos e tudo aquilo que nos ajudou a resolvê-los.
  • Nós acreditamos que o HyperLedger Fabric é a melhor opção para aplicações de negócio baseadas em blockchain do que uma rede privada com Ethereum.
  • Com HyperLedger é possível desenvolver um sistema onde os clientes não precisam confiar um nos outros e parceiros não precisam confiar em outros parceiros, mas clientes precisam confiar em parceiros.
  • A rede é fácil de expandir e pode existir sem uma organização pai.
  • O HyperLedger não está livre de desvantagens técnicas e, portanto, esteja preparado para escrever muitos scripts de suporte para manter o HyperLedger em produção.

Algum tempo atrás, nossa equipe explorou a implantação de um blockchain baseado em HyperLedger em um ambiente de produção. Este artigo apresenta a história de nossas tentativas de integrá-lo, os problemas que encontramos e tudo aquilo que nos ajudou a resolvê-los. Várias atualizações importantes foram introduzidas na estrutura do HyperLedger e, assim, alguns dos desafios foram superados, enquanto outros ainda aguardam uma solução.

Na primeira parte do artigo, explicamos por que decidimos usar um blockchain para resolver um problema de negócios e por que escolhemos o framework HyperLedger sobre o Ethereum. A segunda parte do artigo é dedicada à arquitetura blockchain baseada em HyperLedger e aos aspectos técnicos da implementação deste framework.

Por que usar blockchain?

Inicialmente acreditamos que o blockchain era desnecessário para o nosso negócio. Afinal, a maioria das empresas resolve seus problemas de confiança referindo-se a instalações centralizadas ou centros de arbitragem. Como resultado, levamos muito tempo para decidir se, no nosso caso, uma solução blockchain era necessária ou não.

Nossa plataforma é um tipo de "web resource" em que as empresas podem reduzir seu tempo de desenvolvimento e os custos de manutenção trabalhando diretamente com equipes de código aberto. Identificamos que, para alguns clientes, pode ser difícil estabelecer relações de trabalho com mantenedores de código aberto e colaboradores importantes. A prática padrão de recorrer a serviços de desenvolvedores internos ou freelancers para ajustar o código-fonte aberto parecia insatisfatória, devido ao aumento do tempo e do preço do projeto.

Com a nossa plataforma, procuramos resolver essa ineficiência fornecendo um "ponto de entrada" e uma interface simples para os clientes solicitarem e co-financiarem o desenvolvimento de novos recursos no OSS. Para que esse sistema fosse sustentável, precisávamos introduzir uma ferramenta que incentivasse os desenvolvedores a atender às solicitações dos clientes. Depois de alguma deliberação, chegamos a uma ideia de "propriedade digital".

A ideia era bastante simples: uma pessoa que registra um projeto em nossa plataforma recebe 'compartilhamentos' digitais, que podem ser transferidos para seus colegas colaboradores a seu próprio critério. Como o nome sugere, nossas ações permitem que os detentores recebam uma parte de uma receita do projeto proporcional à participação na propriedade.

Na parte superior dessa restrição, adicionamos uma regra de que qualquer desenvolvedor "externo" poderia criar uma peça solicitada de funcionalidade e, se essa solução for aceita pelos clientes, receberá uma parte dos compartilhamentos do projeto.

Queríamos que os desenvolvedores tratassem os compartilhamentos de nossos projetos como um recurso valioso de longo prazo, o que implica intrinsecamente que os desenvolvedores acreditem que ele não desaparecerá. Basicamente, nós tínhamos duas opções: poderíamos adiar a introdução dessa funcionalidade até ganharmos a confiança da comunidade ou poderíamos criar um sistema sem confiança. O último caminho exigiria a construção de uma plataforma de tal forma que deixasse os ativos intocados, mesmo se a organização pai saísse do negócio.

Também planejamos integrar a plataforma com várias organizações parceiras, que terceirizaram tarefas de desenvolvimento para nossa plataforma e receberiam automaticamente uma taxa quando fossem concluídas. Em um cenário ideal, apenas forneceríamos um ponto de acesso para as organizações em nossa rede por meio de um processo de registro simples, como a integração da API. Nosso objetivo era tornar o processo o mais fácil possível para evitar todas as complicações legais e burocracia. Depois de algumas dúvidas, decidimos que o blockchain nos ajudaria a concretizar essa visão.

Ethereum vs HyperLedger

  • O Ethereum foi a nossa primeira escolha, apesar de não termos uma experiência significativa com a plataforma. Nós não estudamos a documentação em detalhes. À primeira vista, parecia uma escolha fácil. Vários fatores nos levaram a tentar:
  • Está bastante maduro;
  • É estável;
  • É fácil de integrar;
  • É fácil de desenvolver;
  • Tem uma comunidade grande;
  • Está se desenvolvendo rapidamente;
  • Ele tem sido usado em vários projetos;
  • Dá uma oportunidade de implantação privada em nossa rede privada.

Por outro lado, houve alguns fatores que eventualmente nos convenceram de que Ethereum não era a escolha certa para nós:

  • Não-determinação do algoritmo de consenso.
  • Prova de trabalho (POW) é imprevisível.
  • Não existência de papéis.
  • Acesso incontrolável à rede.
  • Taxa de transação e alta carga de trabalho da CPU, mesmo em um modo de inatividade (menor).

Algumas dessas questões têm potenciais mitigações no desenvolvimento do mundo Ethereum.Por exemplo, a modificação do protocolo GHOST pode ajudar, mas mesmo neste caso, se os proprietários dos principais pools repentinamente decidirem que sua ramificação é mais longa, por exemplo, enquanto um petroleiro com atum está a caminho do seu destino… bem, o cancelamento da transação de pagamento pode surpreendê-lo, se a transação estiver sendo conduzida em uma rede Ethereum pública (ou de uso compartilhado). Como o atum não pode voltar ao mar, a "maré" do Ethereum "não estará para peixe".

Em um caso extremo, podemos até ter um parceiro cuja capacidade de nó permita que eles percam toda a rede, portanto, não faria sentido usar o blockchain.

Também foi muito importante para nós entender se um membro da rede é um cliente ou um parceiro. Temos que saber disso com certeza. A rede Ethereum não suporta esse recurso, então precisaríamos construir isso. Nós certamente poderíamos integrar nossa VPN ao blockchain.

Mas se fornecermos acesso a parceiros, naturalmente, deve haver uma maneira de abrir esse acesso. Ao mesmo tempo, gostaríamos de exercer controle sobre quem tem acesso à nossa rede e o que eles podem obter dela.

Uma descoberta principal que é importante lembrar, dentro de um caso de uso de negócios, é que as capacidades dos nós corporativos podem ser significativamente preponderantes aos nós privados. É por isso que optamos por um blockchain privado, usando o framework Hyperledger.

O HyperLedger também nos permitiu evitar os pequenos inconvenientes que observamos em relação aos custos de transações e uso da CPU que observamos com o Ethereum.

No momento, o HyperLedger Fabric era um dos mais avançados e maduros frameworks da família. Ele também tem alguns recursos que fazem com que ele se destaque. A arquitetura autorizada garante que, se alguém acessou seu blockchain, você saiba se eles têm um certificado emitido por uma autoridade de certificação (CA).

Também gostamos do seu algoritmo determinístico PBFT, com o qual é possível ter 100% de certeza de que uma transação é concluída assim que receber essa notificação. Teste em um container docker também é muito simples.

Tentamos descobrir se precisamos de tolerância a falhas bizantinas. Nós realmente confiamos em nossos parceiros e eles realmente confiam em nós? Podemos nos dar ao luxo de nos expor ao Problema dos Generais Bizantinos, sabendo que a qualquer momento qualquer nó poderia começar a enviar dados incorretos para a rede?

Nós finalmente decidimos que deveríamos ter essa proteção, e foi bastante fácil com o HyperLedger.

Ainda em dúvida, realizamos alguns testes para comparar o HyperLedger Fabric e o Ethereum em uma rede privada. Nós codificamos um contrato trivial que gera um array e depois o classifica. Os resultados são visíveis no gráfico abaixo. Adicionamos duas linhas para 1 milhão e 10 milhões de elementos à imagem apenas para mostrar que o HyperLedger está aqui também. Na verdade, a diferença é tão grande que as linhas são invisíveis.

Y axis: Milliseconds.  

Y axis: Megabytes 

Agora, vamos considerar o tempo necessário para chegar a um consenso. Nós pegamos uma simples transação vazia e a colocamos em um cluster de 8 máquinas. As máquinas tiveram que chegar a um acordo e retornar a confirmação: esperamos por seis confirmações na rede privada Ethereum e uma confirmação de cada nó na rede HyperLedger. A velocidade ainda era melhor no cluster do HyperLedger

Y axis:  seconds

Devemos observar que realizamos os testes na versão 0.6 do HyperLedger Fabric; a partir de março, a versão mais recente é a 1.2.0, que possui um nó separado responsável pela manutenção da ordem de transação. Naquela época, a rede ficaria congelada caso aumentasse o número de nós para 16 e a velocidade para 500 transações por segundo. Nesse ritmo, a rede não conseguiu chegar a um consenso antes de receber uma nova solicitação de transação.

Arquitetura HyperLedger

Antes de avançarmos, vamos considerar a arquitetura básica do HyperLedger.

Peer - o nó principal, que armazena informações sobre todas as transações (na versão 1.0 é dividido em "Endorser", um par que confirma transações e "Committer", um par que registra transações no registro.)

App - o cliente que inicia uma transação pode ser substituído por seu próprio aplicativo no Hyperledger SDK

CA - fornece aos usuários certificados que lhes permitem fazer transações e ler dados do registro

Orderer - organiza transações em block e transfere blocos para nós em registro no ledger

O HyperLedger pode separar nós por funções. Em particular, há um par que armazena o registro. Na versão 1.2, existem vários subtipos de pares, mas geralmente os pares são responsáveis ​​por armazenar registros e validar as transações de entrada. Eles armazenam todos os contratos inteligentes e códigos de cadeia e aprovam transações de entrada e as salvam no registro.

O aplicativo que construímos está no frontend. Ele pode enviar informações sobre transações para o blockchain e pode efetuar login no blockchain com um certificado de membro. Também é responsável pelo consenso.

A CA emite certificados. Por padrão, o HyperLedger pode distinguir nós por atributo organizacional; cada organização possui seu próprio certificado raiz. Com um certificado de associação, você pode atribuir direitos sobre a conclusão de contratos inteligentes, direitos sobre a alteração da configuração de rede e direitos para adicionar novos colegas - basicamente, o que quiser. Nas versões mais recentes da estrutura, também é possível adicionar quaisquer atributos que desejar aos certificados, para que possa ser ainda mais flexível ao fornecer diferentes conjuntos de direitos aos participantes do sistema

Um serviço de pedidos, ou o "orderer", é um conjunto de nós responsáveis ​​por uma ordem de transação em um bloco. O orderer recolhe as transações em um bloco e envia este bloco aos pares, para que possam enviá-lo para um registro. Ele não armazena contratos inteligentes, embora armazene dados contábeis em um arquivo binário, que é usado para inicializar o novo par. Perder este arquivo significa perder todos os dados do blockchain. O orderer também realiza alguma validação: verifica os hashes e as assinaturas.

Por exemplo, nosso sistema consiste nos seguintes elementos:

  • Uma aplicação web,
  • Um par,
  • Uma organização OpenGift,
  • Uma CA raiz da organização
  • Uma CA intermediária, que foi projetada com uma ideia de escalonar o sistema;
  • Um agrupamento de pedidos no Apache Kafka ao qual todos os parceiros se referem.

No presente momento, nosso blockchain é implantado em quatro pares reais e temos quatro clientes em Kafka. Finalmente, precisamos de cinco, já que é recomendado usar um número ímpar de nós para o serviço de pedidos nesse modo. Temos aproximadamente 100 aplicativos clientes, 1 CA raiz e 1 CA intermediária. Nos primeiros meses de nosso trabalho, realizamos mais de 1.000 transações, mas nosso sistema nos permite processar a mesma quantidade em 1 segundo.

Os parceiros têm seus próprios pares para que eles possam armazenar um registro e validar transações, e os clientes podem se referir a qualquer ponto que desejarem para interagir com o blockchain.

Os aplicativos cliente fazem "login" no blockchain fornecendo um certificado, que pode ser emitido por um servidor intermediário de Certificação de Autoridade confiável por blockchain, por exemplo, "organization one". Os servidores de CA intermediários são autorizados por um servidor CA raiz, que é mantido à parte da rede blockchain. Em seguida, o aplicativo cliente pode interagir com os pares dentro da estrutura de políticas disponíveis, em conformidade com restrições e permissões. Uma vez que qualquer par confirme uma transação enviada pelo aplicativo, e se ele usar qualquer algoritmo de consenso, ele envia a transação ao solicitante. O orderer confirma essas transações para os pares. Depois disso, o aplicativo pode esperar por qualquer número de confirmações dos pares para garantir que a transação foi registrada no ledger.

Como é implementar o HyperLedger Fabric em produção?

Talvez a primeira coisa que você perceba seja a ausência de qualquer painel de administração simples. É muito difícil manter tudo em modo de produção sem o Kubernetes ou o Swarm, então tivemos que escrever muitos scripts de suporte. Espero que, com o projeto Cello, isso mude para melhor.

Enfrentamos vários desafios técnicos ao tentar implementar essa arquitetura. Primeiro, o serviço de ordenação pode operar em dois modos: modo solo e modo Apache Kafka. Se usar o modo de solo, não será possível alternar para o modo escalável sem recriar toda a rede.

Segundo, se usar os serviços do comprador no Kafka, não poderá escalá-lo para outras organizações. Se outras organizações já tiverem seus próprios serviços de pedidos, você precisará chegar a um acordo sobre quem será responsável pela organização das transações em blocos. Isso significa que apenas uma organização pode ser responsável pela ordem das transações em um bloco, o que leva a alguma vulnerabilidade. No entanto, em geral, se as transações são válidas, sua ordem em um bloco não é de uma importância particular. Se alguém alterar a ordem das transações e elas se tornarem inválidas, elas serão marcadas como inválidas no bloco, e sua solicitação retornará uma falha.

Os CAs (certificação de autoridades) são facilmente escaláveis. Cada organização tem um CA raiz e pode emitir qualquer número de certificados intermediários para CAs. Isso é ótimo porque os CAs são responsáveis ​​por adicionar usuários à rede. No entanto, o modo de revogação de certificado não está bem configurado. Primeiro, para solicitar que várias partes assinem um certificado de revogação, é preciso escrever um código de cadeia adicional. Em segundo lugar, mesmo quando adiciona informações sobre um certificado revogado em um blockchain, o ex-titular do certificado ainda pode se conectar a pares. É preciso gerar os certificados manualmente e adicioná-los às pastas de pares e pedidos. Controlar esse tipo de processo pode ser desafiador em uma estrutura descentralizada.

Também é preciso ter em mente que até que o orderer tenha criado um novo bloco, todas as consultas ao registrador retornarão o estado anterior da rede, ou seja, o registrador tem uma semântica transacional (com versão). Isso significa que, caso tenha um processo de negócios que consista em várias consultas de leitura e uma consulta de gravação logo após elas, levando em consideração o resultado das consultas de leitura, é melhor torná-las assíncronas. Porque neste caso, sua expectativa de ler o registro não será consistente com seu estado real. Em geral, você precisa aguardar o solicitante para formar um bloco e enviá-lo para o ledger; somente depois disso você pode enviar consultas de leitura, supondo que o estado já tenha sido alterado.

Como os blocos não são criados de acordo com o protocolo POW, você pode definir qualquer frequência de criação de blocos para o serviço de pedidos. No modo solo, você não será capaz de criar mais de um bloco por segundo, e no modo Apache Kafka, mas pode configurar este parâmetro de forma bastante flexível. Tenha em mente que, se diminuir o tempo de espera para criar um novo bloco, sua rede aumentará de tamanho rapidamente. O espaço em disco também será consumido muito rapidamente e, portanto, sempre precisará encontrar um equilíbrio entre uma velocidade de confirmação de transações e sua capacidade.

O mecanismo de consenso é realizado no nível da transação, para que você possa especificar os requisitos que as transações precisarão cumprir para serem válidas no contrato inteligente. Por exemplo, quando introduz um novo contrato inteligente no código da cadeia, você define um procedimento de sua confirmação, quantos participantes precisam assinar a transação para que ela permaneça válida.

Contratos inteligentes podem ser escritos em várias línguas, sendo Golang e Java os principais. Um contrato inteligente típico tem a estrutura mais simples. Apenas dois métodos simples são necessários para serem usados ​​no contrato inteligente: um dos métodos é chamado quando um novo código de cadeia é configurado ou atualizado (init) e o outro quando é chamado (invoke). Políticas diferentes são configuradas para inicializar um novo contrato inteligente e chamá-lo. Um grupo de usuários pode ser responsável pela atualização de um contrato inteligente; outro grupo pode ser responsável por sua implementação. Aqui nós consideramos a chamada de função mais simples, que pega uma função e parâmetros desta função como um argumento de entrada e dependendo do nome da função chama o método necessário.

func (t *SimpleChaincode) add(stub shim.ChaincodeStubInterface, args []string) pb.Response {
    	var cs clientState;
	clienState.Name = args[0]
	clientState.Balance = 0
	strState, er := json.Marshal(clientState)
    
	err = stub.PutState(pName, []byte(strState))
    
	if err ~= nil {
    	return shim.Error("Failed to add Client state")
	}
    
	return shim.Success([]byte(“OK”))
}

O armazenamento de dados no HyperLedger pode ser considerado como um mapa de chave-valor, conhecido como armazenamento KV. Trabalhar com armazenamento KV é baixo nível. Com o método PutState(), é possível escrever em armazenamento KV e, com GetState(), ler a partir dele. Mas o mais interessante é que você pode trabalhar em um contrato inteligente com os atributos de certificados. Neste exemplo, pode ver como o hash da chave pública de um usuário autorizado é usado como um identificador para sua carteira. Neste obtemos um hash e o usamos como chave para o armazenamento KV.

func (t *SimpleChaincode) add(stub shim.ChaincodeStubInterface, args []string) pb.Response {
            pk, err := cid.GetX509CertificatePublicKey(stub)
    
	var cs clientState;
	clienState.Name = args[0]
	clientState.Balance = 0
	strState, er := json.Marshal(clientState)
    
	err = stub.PutState(pName, []byte(strState))
    
	if err ~= nil {
    	return shim.Error("Failed to add Client state")
	}
    
	return shim.Success([]byte(pk))
}

func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	pk, err := cid.GetX509CertificatePublicKey(stub)
    
	strState, err :- stub.GetState(pk)
	if strState == nil {
    	return shim.Error("Client not found")
	}
    
	var cs clientState
	err = json.Unmarshal(Avalbytes, &cs)
    
	return shim.Success([]byte(cs.Balance))
}

Apesar de ainda estarmos usando a versão 0.6 do framework, as versões mais novas contêm algumas melhorias importantes, que temos que mencionar:

  • Nas versões mais antigas, era preciso recriar todos os blockchain para incluir uma nova organização em um bloco de origem. Agora é bem simples e também pode alterar as políticas de trabalho com blockchain para cada organização.
  • Começando com 1.2. versão o sistema pode ter seus pares calculando a informação solicitada dinamicamente e apresentá-lo ao SDK de uma maneira consumível.
  • Aplicativos externos podem receber e processar informações sobre eventos de uma cadeia. Esse recurso pode ser útil em vários casos, por exemplo, para notificar uma organização controladora sobre atividades suspeitas.

Experiência HyperLedger em poucas palavras

Do ponto de vista técnico, o sistema ainda está se desenvolvendo (a cada dia mais firme). Existem alguns problemas técnicos, mas esperamos que a comunidade encontre soluções para eles. Ainda assim, acreditamos que o HyperLedger é uma das melhores opções para empresas que desejam implementar blockchain em negócios do mundo real.

No lado comercial, graças à estrutura, percebemos com êxito a funcionalidade pretendida de propriedade digital, o que nos ajuda a incentivar as equipes de desenvolvimento a trabalhar em projetos de código aberto. A rede é fácil de expandir e pode existir sem uma organização pai. Se desaparecermos, a comunidade define um novo serviço de pedidos, atualiza o canal e continua trabalhando.

Com base em um feedback que recebemos, esse recurso facilita a adoção da plataforma, pois nossos usuários não precisam confiar em nós e confiar em nossa capacidade de fazer negócios. Estamos ativamente procurando parceiros para entregar os nós e planejamos realizar as primeiras integrações técnicas para o nosso blockchain no início de 2019.

About the Authors

Yegor Maslov é o CEO da OpenGift Inc., plataforma para monetização de software de código aberto, chefe do projeto The Hive, reusabilidade de código de capacitação do sistema nas organizações. Yegor tem mais de 15 anos de experiência em desenvolvimento de software web e móveis combinados com uma extensa experiência em empreendedorismo técnico.

Konstantin Erokhin é um engenheiro de DevOps com mais de 10 anos de experiência profissional. Trabalhou em empresas como Kaspersky, Sberbank Technologies, Bolsa de Valores de Moscou.

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

BT