Back-End

8 mai, 2017

Blockchain chaincode para desenvolvedores Java – parte 01

Publicidade

Você provavelmente já ouviu falar sobre blockchain, mas talvez você não tenha certeza de como ele se aplica a você enquanto um desenvolvedor Java. Este tutorial irá esclarecer qualquer confusão. Em uma abordagem passo a passo, vou mostrar como usar o Hyperledger Fabric v0.6 para criar, executar e realizar contratos inteligentes, ou chaincode, escritos na linguagem Java. Você instalará ferramentas, definirá sua rede de blockchain local e, finalmente, criará e executará um contrato inteligente de chaincode.

Pré-requisitos

Para este tutorial, presumo que você tem os seguintes pré-requisitos:

  • Você já ouviu falar de blockchain ou do framework Hyperledger Fabric
  • Você possui conhecimento e experiência intermediária em programação Java tanto com a linguagem quanto com a plataforma
  • Você está familiarizado com ou (idealmente) proficiente em usar:
  • Eclipse IDE
  • Docker e Docker Compose
  • Gradle
  • Linha de comando do Linux
  • SoapUI ou outro software de cliente HTTP, como o Postman

Você também deve estar confortável instalando software em seu computador com mínima orientação. No que concerne a espaço, eu não estou incluindo instruções detalhadas de instalação para todo o software que você precisa; os sites onde você pode obter o software fornecem instruções de instalação.

Antes de mergulhar neste tutorial, quero falar um pouco sobre blockchain.

Princípios do Blockchain

Blockchain está no hype, mas é bem merecido. Não é só a tecnologia em si que é legal, ela é perturbadora e tem o potencial de revolucionar a forma como negócios são feitos na Internet.

Como? Bem, vamos pensar sobre os atributos fundamentais de um acordo de negócio bem-sucedido:

  • Confiança: Temos um acordo, mas posso realmente confiar que você irá honrá-lo (ou me honrar)?
  • Transparência: Permite um olhar “por trás dos panos” (o que pode tanto construir a confiança como diminuir a necessidade dela).
  • Responsabilidade: Define critérios para determinar se todas as partes concordam que o negócio foi honrado ou não.

A saúde de qualquer relacionamento comercial entre duas ou mais partes significará níveis variáveis dos três atributos acima (por exemplo, mais confiança significa menos transparência exigida, e vice-versa), mas um pouco de todos eles deve estar presente, ou haverá problemas.

Como o blockchain ajuda? Em primeiro lugar, através da utilização de um framework comum, os parceiros de negócios podem estabelecer uma rede de confiança inicial. Em seguida, através do uso de um ledger que é visível para todas as partes empresariais, blockchain fornece transparência. Finalmente, através do uso do consenso de todas as partes na forma de contratos inteligentes (ou chaincode), há responsabilidade.

Então, o que isso significa para você enquanto um desenvolvedor Java?

O rápido crescimento da comunidade Hyperledger e da Hyperledger Fabric significa que a tecnologia blockchain está rapidamente chegando em um projeto de desenvolvimento de software perto de você. Você estará preparado?

O panorama da tecnologia blockchain

Às vezes, a tecnologia de desenvolvimento pode atrapalhar a solução do problema empresarial. Meu objetivo principal neste tutorial é mostrar-lhe como escrever chaincode em Java, então eu escolhi a pilha de desenvolvimento mais simples para esse fim.

Dito isto, existem outras opções para os componentes da pilha. Para este tutorial, usarei o Docker como o ambiente de contêiner de rede, mas outra opção é Vagrant com VirtualBox. Se você nunca usou Vagrant, você deveria pelo menos experimentá-lo.

Considerando que Docker é um ambiente de contêiner, Vagrant usa a virtualização. Quando combinado com VirtualBox, um ambiente de virtualização fornece um nível diferente de controle sobre o ambiente computacional que alguns desenvolvedores preferem (o que o torna uma escolha ideal para desenvolvedores do fabric).

Se você está com a impressão de que o panorama da tecnologia blockchain é muito fluida no momento, você está correto. No entanto, isso significa que você está entrando em blockchain e chaincode no momento certo: no piso térreo. Como esta tecnologia amadurece, o seu investimento em aprendê-la nesta fase inicial vai pagar belos dividendos no caminho.

Blockchain é uma dessas tecnologias disruptivas que tem o potencial de revolucionar a maneira como todos fazem negócios. Não apenas B2B, mas B2C e, eventualmente, C2C. Este é um momento muito emocionante, de fato.

Vamos começar!

Configure o seu ambiente de desenvolvimento

Para executar o chaincode, primeiro você precisa configurar o seu ambiente de desenvolvimento.

Depois de concluir esta seção, você estará pronto para executar um dos exemplos do chaincode do Hyperledger Java, onde você implantará e invocará transações no chaincode real. Depois disso, vou mostrar-lhe como escrever um novo programa chaincode do zero (bem, quase).

Nesta seção você irá:

  1. Configurar o ambiente de rede – para executar a sua rede blockchain local.
  2. Instalar o software de compilação – para fazer o build do seu chaincode.
  3. Instalar um cliente HTTP – para invocar transações no seu chaincode.
  4. Iniciar a rede blockchain.
  5. Construir o cliente JAR Java shim.

Não vou mentir para você; há um pouco de trabalho de configuração a ser feito para escrever chaincode. Mas se você seguir estas instruções e aplicar um pouco de diligência, valerá a pena.

1. Configure o ambiente de rede

Neste tutorial, você usará o Docker, junto com as imagens de componentes de rede blockchain pré-construídas do Docker Hub, para executar sua rede blockchain local. Você poderia construir o fabric a partir do zero se você quisesse (é código aberto, afinal), mas nesta fase, é mais fácil usar as imagens pré-construídas Hyperledger Fabric disponíveis no Docker Hub.

Como mencionei na introdução, outra opção (e você pode ver nos documentos do Hyperledger) é usar Vagrant e VirtualBox. Vagrant é uma ótima opção para os desenvolvedores de fabric, embora como desenvolvedores de chaincode, estarmos mais preocupados com a construção, execução e teste de nosso chaincode do que trabalhar com o fabric em si.

Se você já tem a versão 1.12 ou superior do Docker instalada, você pode pular para a próxima parte. Nas instruções que seguem, eu entenderei que você não tem o Docker instalado (isto é, você não está atualizando de uma versão anterior do Docker). A instalação do Docker também instalará o Docker Compose, uma ferramenta para definir e executar aplicativos que exigem vários contêineres, assim como a rede de blockchain Hyperledger local que você executará neste tutorial o faz.

Instale o Docker

Instruções de instalação para Mac, Windows e Linux podem ser encontradas aqui: Docker em Mac, Windows e Linux

Verifique a instalação do Docker

Para testar a sua instalação do Docker, abra uma janela de terminal (ou prompt de comando no Windows) e digite os seguintes comandos:

docker -v
docker-compose -v

Você deve obter um resultado como este:

$ docker -v
Docker version 1.13.1, build 092cba3
$ docker-compose -v
docker-compose version 1.11.1, build 7c5d5e4

Se você quiser ver Docker em ação, você pode executar a imagem de hello-world assim:

$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
78445dd45222: Pull complete 
Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
Status: Downloaded newer image for hello-world:latest
 
Hello from Docker!
This message shows that your installation appears to be working correctly.
 
To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.
 
To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash
 
Share images, automate workflows, and more with a free Docker ID:
 https://cloud.docker.com/
 
For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

2. Instale o software de compilação

Para o sistema de compilação, o Hyperledger Fabric utiliza Gradle, e você usará isso também para este tutorial. O Gradle é um sistema de automação de compilação que combina sintaxe simples para especificar componentes de compilação, juntamente com os melhores recursos do Apache Ant e do Apache Maven para criar um poderoso sistema de compilação fácil de usar. Não é de admirar que muitos desenvolvedores estejam mudando seus projetos para Gradle.

Leia mais sobre o Gradle (e alguns de seus usuários de alto perfil) na página principal do Gradle.

Instale o Gradle

Para instalar o Gradle, siga as instruções para Mac, Windows e Linux

Verifique a instalação do Gradle

Para verificar a sua instalação do Gradle, abra uma janela de terminal e execute este comando:

gradle -v

Você deve obter um resultado como este:

$ gradle -v
 
------------------------------------------------------------
Gradle 3.3
------------------------------------------------------------
 
Build time:   2017-01-03 15:31:04 UTC
Revision:     075893a3d0798c0c1f322899b41ceca82e4e134b
 
Groovy:       2.4.7
Ant:          Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM:          1.8.0_102 (Oracle Corporation 25.102-b14)
OS:           Mac OS X 10.12.3 x86_64

3. Instale um cliente HTTP

O próximo passo é o software de cliente HTTP, que permite que o seu chaincode se comunique com a interface REST do Hyperledger blockchain fabric. Seu navegador pode emitir um HTTP GET, mas para interagir com o fabric você precisa ser capaz de fazer POST nas mensagens. Isso significa que você precisa de um cliente HTTP.

O cliente HTTP que eu escolhi para este tutorial é SoapUI, que fornece uma edição comunitária livre que é poderosa, fácil de usar e contém muitos recursos.

Instale o SoapUI

Para instalar o SoapUI, siga as instruções de instalação para Mac OS, Windows e Linux

Verifique a instalação do SoapUI

Para verificar se o SoapUI está instalado, inicie o aplicativo em seu computador. No Mac OS, o SoapUI deve abrir para a Página Inicial do SoapUI, mostrada na Figura 1.

4. Inicie a rede de blockchain

Agora que você instalou o software necessário para desenvolver e testar o seu chaincode, é hora de iniciar sua rede de blockchain local. O primeiro passo é definir a configuração da rede.

Primeiro, crie um diretório que servirá como a raiz de todo o código fonte que você usará para o desenvolvimento do chaincode. Neste tutorial, usarei ~/home/mychaincode (ou C:\home\chaincode no Windows).

Em seguida, defina a variável de ambiente GOPATH para este caminho. Não estaremos compilando nenhum código Go, nem construindo pacotes Golang ou outros binários, mas a terminologia Golang é criada em Hyperledger. Então, é uma boa ideia ficar confortável com o pensar em termos da linguagem Go e do GOPATH.

O GOPATH

O Hyperledger Fabric é escrito em Go, e o GOPATH é um termo que você verá frequentemente nos documentos do Hyperledger. Então, se você planeja fazer muito desenvolvimento de chaincode usando o Hyperledger, você deve se sentir confortável com ele.

O GOPATH é a raiz do seu ambiente Go. Código fonte, binários e outros pacotes Golang são todos referenciados em relação a este caminho.

No Linux, você executaria este comando:

export GOPATH=~/home/mychaincode

Ou no Windows, você deve usar algo como:

SET GOPATH=C:\home\mychaincode

Em seguida, você deve informar ao Docker Compose como compor e executar a rede de blockchain. A definição da rede está em YAML, e você deve nomeá-la docker-compose.yml. Você pode chamar o arquivo de outra coisa, mas quando você inicia o Docker Compose, você deve especificar o sinalizador -f. Eu recomendo permanecer com o padrão, que é docker-compose.yml.

Crie o arquivo docker-compose.yml na raiz do seu GOPATH. Cole os seguintes conteúdos:

membersrvc:
  image: hyperledger/fabric-membersrvc
  ports:
    - "7054:7054"
  command: membersrvc
vp0:
  image: hyperledger/fabric-peer
  ports:
    - "7050:7050"
    - "7051:7051"
    - "7053:7053"
  environment:
    - CORE_PEER_ADDRESSAUTODETECT=true
    - CORE_VM_ENDPOINT=unix:///var/run/docker.sock
    - CORE_LOGGING_LEVEL=DEBUG
    - CORE_PEER_ID=vp0
    - CORE_PEER_PKI_ECA_PADDR=membersrvc:7054
    - CORE_PEER_PKI_TCA_PADDR=membersrvc:7054
    - CORE_PEER_PKI_TLSCA_PADDR=membersrvc:7054
    - CORE_SECURITY_ENABLED=false
    - CORE_SECURITY_ENROLLID=test_vp0
    - CORE_SECURITY_ENROLLSECRET=MwYpmSRjupbT
  links:
    - membersrvc
  command: sh -c "sleep 5; peer node start --peer-chaincodedev"

Há muita coisa acontecendo aqui, a maioria delas está além do escopo deste tutorial, mas eu quero explicar algumas coisas.

Esse arquivo diz ao Docker Compose para definir dois serviços:

  • membersrvc: O node de serviços integrantes que fornece serviços de associação, especificamente uma autoridade de certificação/certificate authority (CA), que é responsável pelo manuseio de toda a logística criptográfica (como emissão e revogação de certificados). A imagem Docker pré-construída que você usará para isso é chamada hyperledger/fabric-membersrvc.
  • vp0: O único node de pares de validação na rede. Para fins de desenvolvimento, não precisamos de uma rede de pares de validação extravagante; um único par será suficiente. A imagem Docker pré-construída que você usará para isso é chamada de hyperledger/fabric-peer.

Um grande número de variáveis de ambiente são definidas pelo par vp0. Repare que a variável CORE_LOGGING_LEVEL está definida como DEBUG. Isso produz uma grande quantidade de resultado, que pode ser útil às vezes. No entanto, se desejar menos resultado, altere o nível para INFO. Consulte “Controle de log” nos documentos de Configuração do Hyperledger para obter mais informações sobre os níveis de log.

Mais informações podem ser encontradas sobre a definição do arquivo Docker Compose YML no site do Docker.

Em seguida, repare que o valor CORE_SECURITY_ENABLED é false. Isso significa que o fabric não exigirá que você envie qualquer tipo de credenciais de usuário final. A segurança está além do escopo deste tutorial, mas se você estiver interessado em aprender mais, você pode verificar esta nota sobre a funcionalidade de segurança para suas solicitações chaincode.

Finalmente, uma palavra de cautela: alterar qualquer um desses valores de seus padrões (especialmente os valores de porta) pode fazer com que os exemplos neste tutorial não funcionem. Uma rede de blockchain é um conjunto de componentes de software distribuídos que requerem uma comunicação coordenada precisa. Eu recomendo que você não altere os valores de porta de seus valores padrão até que você entenda como todos os componentes do fabric interoperam.

Agora que a definição de rede blockchain está feita, você está pronto para iniciar sua rede blockchain local. Para fazer isso, execute Docker Compose. Navegue até o seu $GOPATH e execute este comando:

docker-compose up

Você deve obter resultado na janela do terminal como este:

$ docker-compose up
.
.
Pulling membersrvc (hyperledger/fabric-membersrvc:latest)...
latest: Pulling from hyperledger/fabric-membersrvc
.
.
Status: Downloaded newer image for hyperledger/fabric-membersrvc:latest
Pulling vp0 (hyperledger/fabric-peer:latest)...
latest: Pulling from hyperledger/fabric-peer
.
.
Status: Downloaded newer image for hyperledger/fabric-peer:latest
Creating mychaincode_membersrvc_1
Creating mychaincode_vp0_1
Attaching to mychaincode_membersrvc_1, mychaincode_vp0_1
vp0_1         | 19:30:03.773 [logging] LoggingInit -> DEBU 001 Setting default logging level to DEBUG for command 'node'
vp0_1         | 19:30:03.773 [nodeCmd] serve -> INFO 002 Running in chaincode development mode
.
.
.
vp0_1         | 19:30:04.146 [peer] chatWithSomePeers -> DEBU 07c Starting up the first peer of a new network
vp0_1         | 19:30:04.146 [consensus/statetransfer] verifyAndRecoverBlockchain -> DEBU 07d Validating existing blockchain, highest validated block is 0, valid through 0
vp0_1         | 19:30:04.146 [consensus/statetransfer] blockThread -> INFO 07e Validated blockchain to the genesis block
vp0_1         | 19:30:04.146 [consensus/handler] 1 -> DEBU 07f Starting up message thread for consenter
vp0_1         | 19:30:04.146 [nodeCmd] serve -> INFO 080 Starting peer with ID=name:"vp0" , network ID=dev, address=172.17.0.3:7051, rootnodes=, validator=true
vp0_1         | 19:30:04.146 [rest] StartOpenchainRESTServer -> INFO 081 Initializing the REST service on 0.0.0.0:7050, TLS is disabled.
vp0_1         | 19:30:04.147 [peer] ensureConnected -> DEBU 082 Starting Peer reconnect service (touch service), with period = 6s
.
.

Este resultado informa que a rede está funcionando e em execução, e pronta para aceitar solicitações de registro de chaincode.

Nota: as linhas realçadas só devem aparecer na primeira vez que você executar sua rede blockchain, porque Docker tem que baixar as imagens do Docker Hub. Uma vez que elas estão baixadas no seu computador, Docker só as puxará se as imagens do Docker Hub forem mais recentes do que as que você tem no seu computador.

Agora você está pronto para construir o cliente JAR Java shim, que permite que o seu chaincode de linguagem Java se comunique com o framework Hyperledger Fabric.

5. Crie o cliente JAR Java shim

Antes de poder executar os exemplos chaincode, você precisa obter o código-fonte mais recente do repositório GitHub da Hyperledger.

Primeiro, você precisará clonar o Hyperledger Fabric em sua máquina local para construir o seu chaincode (Nota: Esta é uma medida temporária; em algum momento, o cliente JAR Java shim deverá ser acessível a partir do repositório Maven central).

Nota: Lembre-se de que você configurou seu GOPATH para ~/home/mychaincode no Linux (ou Mac) ou C:\home\mychaincode no Windows.

Execute este comando para criar a estrutura de diretórios que os scripts de build de fabric esperados:

mkdir -p $GOPATH/src/github.com/hyperledger

Em seguida, navegue até a parte inferior da nova estrutura de diretórios que você criou:

cd $GOPATH/src/github.com/hyperledger

A partir daqui você precisa recuperar o código-fonte do Hyperledger para que você possa construir o cliente JAR Java shim.

Há duas maneiras de acessar a fonte Hyperledger.

  • Sem git: navegue até o espelho do Hyperledger no GitHub e clique no botão Clone ou download e depois Download ZIP (veja a Figura 2). Um arquivo ZIP chamado fabric-master.zip será baixado para o seu computador, que você pode extrair para $GOPATH/src/github.com/hyperledger. Nota: certifique-se de alterar o nome do diretório raiz do fabric-master para fabric quando você extrair o arquivo.
  • Com git: navegue até $GOPATH/src/github.com/hyperledger, copie o URL do campo de texto na caixa “Clone com HTTPS” (ver Figura 2) e execute este comando usando o URL copiado:
git clone https://github.com/hyperledger/fabric.git -b v0.6

Você deve ver o resultado da janela de terminal como este do comando git:

$ git clone https://github.com/hyperledger/fabric.git -b v0.6
Cloning into 'fabric'...
remote: Counting objects: 29272, done.
remote: Compressing objects: 100% (128/128), done.
remote: Total 29272 (delta 55), reused 0 (delta 0), pack-reused 29142
Receiving objects: 100% (29272/29272), 44.95 MiB | 5.67 MiB/s, done.
Resolving deltas: 100% (16671/16671), done.
Figura 2. Espelho Hyperledger no GitHub

Agora você está pronto para criar o cliente JAR shim do chaincode Java. Navegue até $GOPATH/src/github.com/hyperledger/fabric/core/chaincode/shim/java e execute estes dois comandos:

gradle -b build.gradle clean
gradle -b build.gradle build

O resultado de compilação Gradle deve ficar assim:

$ cd $GOPATH/src/github.com/hyperledger/fabric/core/chaincode/shim/java
$ gradle -b build.gradle clean
Starting a Gradle Daemon (subsequent builds will be faster)
:core:chaincode:shim:java:clean
 
BUILD SUCCESSFUL
 
Total time: 5.422 secs
$ gradle -b build.gradle build
:core:chaincode:shim:java:copyProtos UP-TO-DATE
:core:chaincode:shim:java:extractIncludeProto
:core:chaincode:shim:java:extractProto UP-TO-DATE
:core:chaincode:shim:java:generateProto UP-TO-DATE
:core:chaincode:shim:java:compileJava
:core:chaincode:shim:java:processResources
:core:chaincode:shim:java:classes
:core:chaincode:shim:java:jar
:core:chaincode:shim:java:assemble
:core:chaincode:shim:java:extractIncludeTestProto
:core:chaincode:shim:java:extractTestProto UP-TO-DATE
:core:chaincode:shim:java:generateTestProto UP-TO-DATE
:core:chaincode:shim:java:compileTestJava UP-TO-DATE
:core:chaincode:shim:java:processTestResources UP-TO-DATE
:core:chaincode:shim:java:testClasses UP-TO-DATE
:core:chaincode:shim:java:test UP-TO-DATE
:core:chaincode:shim:java:check UP-TO-DATE
:core:chaincode:shim:java:build
:core:chaincode:shim:java:copyToLib
:core:chaincode:shim:java:generatePomFileForMavenJavaPublication
:core:chaincode:shim:java:publishMavenJavaPublicationToMavenLocal
:core:chaincode:shim:java:publishToMavenLocal
 
BUILD SUCCESSFUL
 
Total time: 4.521 secs

A última coisa que a compilação faz é adicionar o cliente JAR shim ao seu repositório Maven local. Neste ponto, você está pronto para criar o seu chaincode. A menos que você atualize o código fonte do fabric em algum momento no futuro, ou apenas queira reconstruir o cliente JAR shim novamente por algum motivo, você não terá que executar o cliente JAR Java shim compilado novamente.

Fazer deploy e executar um exemplo de chaincode Java

Agora que definiu e iniciou a sua rede blockchain local e construiu e instalou o cliente JAR Java shim no seu repositório Maven local, está pronto para criar, registrar e invocar transações num dos exemplos de chaincode Java que é enviado com o Hyperledger Fabric que você baixou anteriormente.

Aqui estão os passos que você irá seguir:

  1. Crie o exemplo usando Gradle.
  2. Registre o exemplo com a rede de pares de validação, executando um script que é criado para você pela compilação Gradle.
  3. Implante o exemplo para a rede local blockchain usando SoapUI.
  4. Invoque transações no chaincode exemplo usando SoapUI.
  5. Crie o exemplo

1. Crie o exemplo usando Gradle

Navegue até o diretório $GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/java/Example.

Em seguida, inicie a compilação Gradle através da linha de comando utilizando este comando:

gradle -b build.gradle build

Você deve obter um resultado como este:

$ cd GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/java/Example
$ gradle -b build.gradle build
Starting a Gradle Daemon (subsequent builds will be faster)
:examples:chaincode:java:Example:compileJava
:examples:chaincode:java:Example:processResources UP-TO-DATE
:examples:chaincode:java:Example:classes
:examples:chaincode:java:Example:jar
:examples:chaincode:java:Example:startScripts
:examples:chaincode:java:Example:distTar
:examples:chaincode:java:Example:distZip
:examples:chaincode:java:Example:assemble
:examples:chaincode:java:Example:compileTestJava UP-TO-DATE
:examples:chaincode:java:Example:processTestResources UP-TO-DATE
:examples:chaincode:java:Example:testClasses UP-TO-DATE
:examples:chaincode:java:Example:test UP-TO-DATE
:examples:chaincode:java:Example:check UP-TO-DATE
:examples:chaincode:java:Example:build
:examples:chaincode:java:Example:copyToLib
 
BUILD SUCCESSFUL
 
Total time: 6.935 secs

A compilação cria uma distribuição autônoma que está localizada dentro do diretório compilar/distribuições em duas formas: um arquivo TAR e um arquivo ZIP e cada um desses arquivos contém tudo o que você precisa para executar o chaincode, incluindo um script para conduzi-lo chamado Example.

O chaincode Example agora está pronto para ser registrado com a rede blockchain local.

2. Registre o exemplo

Certifique-se de que a sua rede blockchain local está em execução. Se não estiver, você precisará iniciá-la. Consulte a seção “Inicie a rede blockchain” se precisar de uma atualização.

Se você ainda não estiver lá, navegue para $GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/java/Example.

Em seguida, extraia Example.zip (ou Example.tar) no diretório compilar/distribuições:

$ cd $GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/java/Example
$ cd build/distributions/
$ unzip Example.zip 
Archive:  Example.zip
  inflating: Example/lib/chaincode.jar  
  inflating: Example/lib/grpc-all-0.13.2.jar  
  inflating: Example/lib/commons-cli-1.3.1.jar  
  inflating: Example/lib/shim-client-1.0.jar  
  inflating: Example/lib/grpc-netty-0.13.2.jar  
  inflating: Example/lib/grpc-auth-0.13.2.jar  
  inflating: Example/lib/grpc-protobuf-nano-0.13.2.jar  
  inflating: Example/lib/grpc-core-0.13.2.jar  
  inflating: Example/lib/grpc-protobuf-0.13.2.jar  
  inflating: Example/lib/grpc-okhttp-0.13.2.jar  
  inflating: Example/lib/grpc-stub-0.13.2.jar  
  inflating: Example/lib/protobuf-java-3.0.0.jar  
  inflating: Example/lib/netty-tcnative-boringssl-static-1.1.33.Fork21-osx-x86_64.jar  
  inflating: Example/lib/netty-codec-http2-4.1.0.CR3.jar  
  inflating: Example/lib/google-auth-library-oauth2-http-0.3.0.jar  
  inflating: Example/lib/guava-18.0.jar  
  inflating: Example/lib/protobuf-javanano-3.0.0-alpha-5.jar  
  inflating: Example/lib/jsr305-3.0.0.jar  
  inflating: Example/lib/okio-1.6.0.jar  
  inflating: Example/lib/okhttp-2.5.0.jar  
  inflating: Example/lib/netty-codec-http-4.1.0.CR3.jar  
  inflating: Example/lib/netty-handler-4.1.0.CR3.jar  
  inflating: Example/lib/google-auth-library-credentials-0.3.0.jar  
  inflating: Example/lib/google-http-client-1.19.0.jar  
  inflating: Example/lib/google-http-client-jackson2-1.19.0.jar  
  inflating: Example/lib/netty-codec-4.1.0.CR3.jar  
  inflating: Example/lib/netty-buffer-4.1.0.CR3.jar  
  inflating: Example/lib/netty-transport-4.1.0.CR3.jar  
  inflating: Example/lib/httpclient-4.0.1.jar  
  inflating: Example/lib/jackson-core-2.1.3.jar  
  inflating: Example/lib/netty-common-4.1.0.CR3.jar  
  inflating: Example/lib/netty-resolver-4.1.0.CR3.jar  
  inflating: Example/lib/httpcore-4.0.1.jar  
  inflating: Example/lib/commons-logging-1.1.1.jar  
  inflating: Example/lib/commons-codec-1.3.jar  
  inflating: Example/bin/Example     
  inflating: Example/bin/Example.bat

“Por que tantos arquivos?”, você pode se perguntar. A distribuição contém tudo o que você precisa para executar o chaincode autonomamente (em seu próprio processo), juntamente com todos os JARs dependentes.

Para registrar o chaincode exemplo, dentro da pasta compilar/distribuições, execute o seguinte script:

./Example/bin/Example

Isso executa um processo autônomo que registra o chaincode exemplo com a rede local blockchain. Você deve ver o resultado da janela do terminal assim:

$ ./Example/bin/Example
Hello world! starting [Ljava.lang.String;@7ef20235
Feb 22, 2017 10:05:08 AM example.Example main
INFO: starting
Feb 22, 2017 10:05:08 AM org.hyperledger.java.shim.ChaincodeBase newPeerClientConnection
INFO: Inside newPeerCLientConnection
Feb 22, 2017 10:05:08 AM io.grpc.internal.TransportSet$1 call
INFO: Created transport io.grpc.netty.NettyClientTransport@3dd7b80b(/127.0.0.1:7051) for /127.0.0.1:7051
Feb 22, 2017 10:05:14 AM io.grpc.internal.TransportSet$TransportListener transportReady
INFO: Transport io.grpc.netty.NettyClientTransport@3dd7b80b(/127.0.0.1:7051) for /127.0.0.1:7051 is ready

Dê uma olhada no console para sua rede local blockchain e você deve ver linhas de resultado que se parecem com isso:

.
.
vp0_1         | 16:05:14.048 [chaincode] HandleChaincodeStream -> DEBU 06d Current context deadline = 0001-01-01 00:00:00 +0000 UTC, ok = false
vp0_1         | 16:05:14.065 [chaincode] processStream -> DEBU 06e []Received message REGISTER from shim
vp0_1         | 16:05:14.065 [chaincode] HandleMessage -> DEBU 06f []Handling ChaincodeMessage of type: REGISTER in state created
vp0_1         | 16:05:14.065 [chaincode] beforeRegisterEvent -> DEBU 070 Received REGISTER in state created
vp0_1         | 16:05:14.065 [chaincode] registerHandler -> DEBU 071 registered handler complete for chaincode hello
vp0_1         | 16:05:14.065 [chaincode] beforeRegisterEvent -> DEBU 072 Got REGISTER for chaincodeID = name:"hello" , sending back REGISTERED
.
.

Anote o nome do chaincodeID no resultado do log de registro (hello para o Example, veja a linha 8 no anterior). Você precisará disso mais tarde para a mensagem JSON ao implantar o chaincode Example através da interface REST do fabric.

O resultado anterior indica que o chaincode Example está em execução e foi registrado com a rede local de pares de validação de blockchain e está pronto para ser implantado.

3. Implante o exemplo

O Hyperledger Fabric fornece uma interface de serviço da web REST que você usa para interagir com o fabric. A primeira interação com o fabric é implantar o seu chaincode. Certifique-se de que sua rede local blockchain esteja em execução, então inicie o SoapUI e clique no botão REST para criar um novo projeto REST. Você deve ver uma caixa de diálogo como na Figura 3, onde você digita o URL baseado usado para todas as solicitações REST:

Figura 3. SoapUI Nova caixa de diálogo do projeto REST

Digite http://localhost:7050 como a URL e, em seguida, clique em OK. A porta 7050 é a porta REST padrão usada pelo fabric e, uma vez que sua rede blockchain está sendo executada no seu computador local, você usará o localhost como o nome do host.

Quando SoapUI surgir, você pode fazer um smoke test rápido para se certificar de que ele pode se comunicar com sua rede local blockchain. Expanda o novo recurso REST que você acabou de criar até ver Request 1. Em seguida, abra-o na janela Editor. Use GET para o método e em resource digite /chain. Certifique-se de clicar na opção JSON na guia de resultado e, em seguida, execute a solicitação (clicando no ícone de seta). Quando você executa esta requisi;áo, você simplesmente retorna o bloco hash atual na guia de resultado, localizada no lado direito da janela do editor, como você pode ver na Figura 4:

Figura 4. Smoke Test do Blockchain

Se você vir uma mensagem JSON semelhante à da Figura 4 (o valor currentBlockHash para sua rede será diferente, é claro), então você está pronto para implantar o chaincode Example.

Clique com o botão direito do mouse na extremidade de REST Project 1 (http://localhost:7050) e escolha New Resource; você deverá ver uma caixa de diálogo “Novo Recurso REST” (veja a Figura 5) com um campo Resource Path:

Figura 5. Caixa de Diálogo Novo Recurso SoapUI

Digite /chaincode como o resource path, em seguida, clique em OK e você deve ver o novo recurso aparecer no painel SoapUI Projects. Abra a solicitação para este recurso (por padrão, ele será chamado Request 1), mude o método para POST e cole este JSON na área de solicitação, localizada no canto inferior esquerdo da janela do editor de solicitações:

{
"jsonrpc": "2.0",
  "method": "deploy",
  "params": {
    "type": 1,
    "chaincodeID":{
        "name": "hello"
    },
    "CtorMsg": {
        "args": [""]
    }
  },
  "id": 1
}

Três coisas a observar:

  • Linha 3: O valor do método deve ser deploy.
  • Linhas 6-7: O chaincodeID.name na mensagem JSON deve corresponder ao chaincodeID quando você registrou o chaincode Example na seção anterior (hello para o chaincode Example).
  • Linha 13: O valor id é usado para coordenar solicitações. Você não precisa se preocupar tanto com isto para este tutorial, mas observe que ele sempre é enviado de volta na resposta (veja a próxima listagem).

Quando você envia essa solicitação, o resultado JSON deve se parecer com isto:

{
   "jsonrpc": "2.0",
   "result":    {
      "status": "OK",
      "message": "hello"
   },
   "id": 1
}

A Figura 6 mostra uma imagem de como isso se apresenta em SoapUI. A mensagem de resultado JSON aparecerá na guia de resultado, que está localizada no lado direito do editor de solicitação.

O resultado de log de rede na janela do terminal deve incluir linhas que se parecem com isso:

.
.
vp0_1         | 20:48:39.482 [rest] ProcessChaincode -> INFO 0c4 REST processing chaincode request...
vp0_1         | 20:48:39.482 [rest] processChaincodeDeploy -> INFO 0c5 REST deploying chaincode...
vp0_1         | 20:48:39.483 [devops] Deploy -> DEBU 0c6 Creating deployment transaction (hello)
vp0_1         | 20:48:39.483 [devops] Deploy -> DEBU 0c7 Sending deploy transaction (hello) to validator
vp0_1         | 20:48:39.483 [peer] sendTransactionsToLocalEngine -> DEBU 0c8 Marshalling transaction CHAINCODE_DEPLOY to send to local engine
vp0_1         | 20:48:39.483 [peer] sendTransactionsToLocalEngine -> DEBU 0c9 Sending message CHAIN_TRANSACTION with timestamp seconds:1487796519 nanos:483661510  to local engine
vp0_1         | 20:48:39.483 [consensus/noops] RecvMsg -> DEBU 0ca Handling Message of type: CHAIN_TRANSACTION 
vp0_1         | 20:48:39.483 [consensus/noops] broadcastConsensusMsg -> DEBU 0cb Broadcasting CONSENSUS
vp0_1         | 20:48:39.483 [peer] Broadcast -> DEBU 0cc Broadcast took 1.135s
vp0_1         | 20:48:39.483 [consensus/noops] RecvMsg -> DEBU 0cd Sending to channel tx uuid: hello
vp0_1         | 20:48:39.483 [rest] processChaincodeDeploy -> INFO 0ce Successfully deployed chainCode: hello
vp0_1         | 20:48:39.484 [rest] ProcessChaincode -> INFO 0cf REST successfully deploy chaincode: {"jsonrpc":"2.0","result":{"status":"OK","message":"hello"},"id":1}
.
.

As linhas 3-4 mostram o resultado indicando que a rede recebeu a mensagem de implantação e o fabric está implantando seu chaincode. As linhas 13-14 mostram que seu chaincode foi implantado com êxito.

Tome nota de resultado como este na janela do terminal executando o seu chaincode:

$ ./build/distributions/Example/bin/Example
Hello world! starting [Ljava.lang.String;@7ef20235
Feb 22, 2017 2:44:43 PM example.Example main
INFO: starting
Feb 22, 2017 2:44:43 PM org.hyperledger.java.shim.ChaincodeBase newPeerClientConnection
INFO: Inside newPeerCLientConnection
Feb 22, 2017 2:44:43 PM io.grpc.internal.TransportSet$1 call
INFO: Created transport io.grpc.netty.NettyClientTransport@46adccd3(/127.0.0.1:7051) for /127.0.0.1:7051
Feb 22, 2017 2:44:48 PM io.grpc.internal.TransportSet$TransportListener transportReady
INFO: Transport io.grpc.netty.NettyClientTransport@46adccd3(/127.0.0.1:7051) for /127.0.0.1:7051 is ready
Feb 22, 2017 2:48:40 PM example.Example run
INFO: In run, function:
Feb 22, 2017 2:48:40 PM example.Example run

Eu incluí todas os resultados para o contexto e você deve ver linhas como 11-13 quando você envia a mensagem de implantação para sua rede blockchain.

4. Invoque uma transação no exemplo

Finalmente, você irá invocar o método hello e vê-lo aparecer nas mensagens de log da janela do terminal executando o seu chaincode.

Sob o recurso chaincode em SoapUI, clique com o botão direito do mouse no Method 1 e escolha Clone Method. Chame o método Invoke e clique em OK. Abra Request 1 no seu novo método Invoke e cole nesta solicitação JSON:

{
"jsonrpc": "2.0",
  "method": "invoke",
  "params": {
    "type": 1,
    "chaincodeID":{
        "name": "hello"
    },
    "CtorMsg": {
        "args": ["hello"]
    }
  },
  "id": 2
}

Quando você executar a solicitação, você deve ver esta resposta JSON:

{
   "jsonrpc": "2.0",
   "result":    {
      "status": "OK",
      "message": "1c1811d0-a958-4c58-ab1d-e1df550c18a3"
   },
   "id": 2
}

A Figura 7 mostra uma imagem da tela de como isso se apresenta em SoapUI.

Figura 7. SoapUI – Solicitação de invocação do Chaincode

O resultado do log de rede deve incluir linhas que devem se apresentar assim:

.
.
vp0_1         | 21:44:35.143 [rest] ProcessChaincode -> INFO 555 REST processing chaincode request...
vp0_1         | 21:44:35.143 [rest] processChaincodeInvokeOrQuery -> INFO 556 REST invoke chaincode...
vp0_1         | 21:44:35.143 [devops] invokeOrQuery -> INFO 557 Transaction ID: 1c1811d0-a958-4c58-ab1d-e1df550c18a3
vp0_1         | 21:44:35.143 [devops] createExecTx -> DEBU 558 Creating invocation transaction (1c1811d0-a958-4c58-ab1d-e1df550c18a3)
vp0_1         | 21:44:35.143 [devops] invokeOrQuery -> DEBU 559 Sending invocation transaction (1c1811d0-a958-4c58-ab1d-e1df550c18a3) to validator
vp0_1         | 21:44:35.143 [peer] sendTransactionsToLocalEngine -> DEBU 55a Marshalling transaction CHAINCODE_INVOKE to send to local engine
vp0_1         | 21:44:35.143 [peer] sendTransactionsToLocalEngine -> DEBU 55b Sending message CHAIN_TRANSACTION with timestamp seconds:1487799875 nanos:143438691  to local engine
vp0_1         | 21:44:35.143 [consensus/noops] RecvMsg -> DEBU 55c Handling Message of type: CHAIN_TRANSACTION 
vp0_1         | 21:44:35.143 [consensus/noops] broadcastConsensusMsg -> DEBU 55d Broadcasting CONSENSUS
vp0_1         | 21:44:35.143 [peer] Broadcast -> DEBU 55e Broadcast took 1.249s
vp0_1         | 21:44:35.143 [consensus/noops] RecvMsg -> DEBU 55f Sending to channel tx uuid: 1c1811d0-a958-4c58-ab1d-e1df550c18a3
vp0_1         | 21:44:35.143 [rest] processChaincodeInvokeOrQuery -> INFO 560 Successfully submitted invoke transaction with txid (1c1811d0-a958-4c58-ab1d-e1df550c18a3)
vp0_1         | 21:44:35.143 [rest] ProcessChaincode -> INFO 561 REST successfully submitted invoke transaction: {"jsonrpc":"2.0","result":{"status":"OK","message":"1c1811d0-a958-4c58-ab1d-e1df550c18a3"},"id":2}
.
.

E o resultado do log do chaincode assim:

$ ./build/distributions/Example/bin/Example
Hello world! starting [Ljava.lang.String;@7ef20235
Feb 22, 2017 3:26:57 PM example.Example main
INFO: starting
Feb 22, 2017 3:26:57 PM org.hyperledger.java.shim.ChaincodeBase newPeerClientConnection
INFO: Inside newPeerCLientConnection
Feb 22, 2017 3:26:57 PM io.grpc.internal.TransportSet$1 call
INFO: Created transport io.grpc.netty.NettyClientTransport@765e4953(/127.0.0.1:7051) for /127.0.0.1:7051
Feb 22, 2017 3:27:02 PM io.grpc.internal.TransportSet$TransportListener transportReady
INFO: Transport io.grpc.netty.NettyClientTransport@765e4953(/127.0.0.1:7051) for /127.0.0.1:7051 is ready
Feb 22, 2017 3:27:24 PM example.Example run
INFO: In run, function:
Feb 22, 2017 3:27:24 PM example.Example run
SEVERE: No matching case for function:
Feb 22, 2017 3:30:55 PM example.Example run
INFO: In run, function:hello
hello invoked

Mais uma vez, mostrei todo o resultado do chaincode. Você pode ver onde a função hello foi invocada (linha 16).

Agora você já viu como construir, implantar e executar o chaincode Java em sua rede local blockchain. Na próxima parte deste artigo, você escreverá um programa chaincode (quase) a partir do zero usando o Eclipse IDE, criará o programa chaincode usando o Gradle e o exercitará isto usando SoapUI.

 

***

Steve Perry faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela Redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: https://www.ibm.com/developerworks/library/j-chaincode-for-java-developers/index.html

Salvar