Implementação do catálogo de ouvidorias utilizando smart contracts em Ethereum.
O blockchain armazenará os dados --
conta (account Ethereum),
nome,
ente e
endpoint (URL do site ou web service) -- das ouvidorias, que deverão atender aos requisitos
impostos pelo smart contract CatalogoOuvidorias
, resumidos como segue:
- O contrato exige uma ouvidoria inicial para ser criado no blockchain.
- Uma segunda ouvidoria poderá ser incluída, se previamente autorizada pela ouvidoria inicial.
- Uma terceira ouvidoria poderá ser incluída, se previamente autorizada pelas duas ouvidorias já cadastradas.
- Da quarta ouvidoria em diante, poderão ser incluídas indefinidas ouvidorias, desde que cada uma seja previamente autorizada por três quaisquer ouvidorias já cadastradas.
Desta maneira, o mais importante do contrato são o construtor e dois métodos:
- Construtor
function CatalogoOuvidorias(<dados da ouvidoria inicial>)
cria, com a ouvidoria inicial, o contrato para inserção no blockchain; - Método
function autorizar(<endereco da account da ouvidoria candidata>)
é chamado por uma ouvidoria cadastrada para manifestar sua autorização ao cadastro de uma ouvidoria candidata. Ao autorizar, o método emite o eventoouvidoriaAutorizada()
com os dados das ouvidorias autorizadora e autorizada. - Método
function cadastrar(<dados da ouvidoria candidata>)
é chamado por uma ouvidoria candidata que já tenha acumulado o número de autorizações exigidas para entrar no cadastro de ouvidorias. Quando executado com sucesso, este método emite o eventoouvidoriaCadastrada()
incluindo os dados da ouvidoria cadastrada.
Docker + Docker Compose. Todo o resto é executado dentro de containers.
/
- Pasta com arquivo
docker-compose.yml
que cria o ambiente de execução do projeto (que está na pastacatalogo-project
/).
- Pasta com arquivo
catalogo-project/
- Projeto principal, contendo código JavaScript e Solidity (utilizando o framework Truffle).
dockerfiles/
Dockerfile
s para containers (testrpc
etruffle
) usados no ambiente de execução do projeto.
ethereum-testnets/
Para testar o funcionamento do contrato, existem dois roteiros possíveis:
- rodar os testes automatizados (e comandos quaisquer) numa testnet local (em memória);
- explorar o contrato deployado na testnet "real" rinkeby, através das ferramentas que ela disponibiliza.
Siga abaixo os passos para executar qualquer um desses dois roteiros.
O docker-compose.yml
da raiz (isto eh, a pasta onde este README.md
se encontra) sobe dois containers:
- um com o
testrpc
, uma testnet Ethereum local para desenvolvimento; - outro com
truffle
, um framework para desenvolvimento de smart contracts. Este container abre direto no truffle console.
Para subi-los e se conectar ao truffle console, execute, na raiz deste projeto, os comandos abaixo:
# Subir compose com testrpc e truffle
$ docker-compose up --build -d
# Conectar-se ao container com truffle
# (Obs.: caso nenhum exista com esse nome, use `docker ps` para encontrar o correto. Além
# disso, o comando docker-compose up acima também imprime o nome do container criado.)
$ docker attach ouvidoriascatalogo_truffle_1
Neste momento você estará no truffle console (que está contectado à testnet/testrpc local chamada unbtest
) e deve ver isto:
truffle(unbtest)>
# Considerando que voce estah no console truffle do container iniciado no passo acima
# Executar testes
truffle(unbtest)> test
O resultado será algo como:
Using network 'unbtest'. Compiling ./contracts/CatalogoOuvidorias.sol... 0xad109c84c8f5d759beab921fc58e2493609959a2 Contract: CatalogoOuvidorias ✓ script de deploy padrao constroi corretamente o contrato inicial (642ms) criado em ambiente de testes ✓ construtor cria catalogo com uma ouvidoria cadastrada inicialmente (862ms) ✓ ouvidoria jah cadastrada pode chamar autorizar (90ms) ✓ ouvidoria nao cadastrada NAO pode chamar autorizar (58ms) ✓ ouvidoria jah cadastrada nao pode autorizar uma outra ouvidoria mais de uma vez (153ms) ✓ ouvidoria jah cadastrada NAO pode autorizar uma outra ouvidoria jah cadastrada (308ms) ✓ candidata sem autorizacoes nao consegue cadastrar-se (56ms) ✓ quando ha somente uma ouvidoria cadastrada, uma candidata consegue cadastrar-se tendo apenas uma autorizacao (810ms) ✓ quando ha somente duas ouvidorias cadastradas, uma candidata NAO consegue cadastrar-se tendo apenas uma autorizacao (380ms) ✓ quando ha somente duas ouvidorias cadastradas, uma candidata consegue cadastrar-se tendo apenas duas autorizacoes (1212ms) ✓ quando ha tres ou mais ouvidorias cadastradas, uma candidata NAO consegue cadastrar-se tendo apenas uma autorizacao (665ms) ✓ quando ha tres ou mais ouvidorias cadastradas, uma candidata NAO consegue cadastrar-se tendo apenas duas autorizacoes (817ms) ✓ quando ha tres ou mais ouvidorias cadastradas, uma candidata consegue cadastrar-se tendo apenas tres autorizacoes (1678ms)
O script de demonstração é só o que o nome diz, demonstração. O script de testes contém um uso muito mais avançado de todos os métodos do smart contract, explorando todas suas possibilidades. Ainda assim, o script de demonstração é um bom passo (exemplo) inicial caso deseje executar um código que exercite o contrato de outras maneiras quaisquer.
# Considerando que voce estah no console truffle do container iniciado no passo acima
# Faz o deploy dos contratos, caso nao tenha feito antes, ou refaz, caso jah tenha.
truffle(unbtest)> migrate --reset
...
# Executa script com varias demonstracoes
truffle(unbtest)> exec src/demonstracao.js
O resultado deste comando, naturalmente, variará de acordo com o conteúdo que você deixou/editou no src/demonstracao.js
.
A testnet rinkeby é uma rede ethereum em todos os sentidos (a única diferença é que ela tem faucets que te dão $$ grátis), e assim apresentamos duas possibilidades de interação com o contrato que deployamos na rinkeby:
- acessar os sites da rinkeby e apenas ver os dados (blocos, metadados) do contrato; ou
- utilizar a uma IDE in-browser de solidity, conectar-se a um nó rinkeby e chamar métodos do contrato.
Abaixo, detalhes dessas alternativas.
- Account usada para criar o contrato na rinkeby:
0x1750dd0f8cd22ee9d849ab11ebc62adb37ffc10a
- Caso queira utilizá-la em algum site/ferramenta:
- Arquivo UTC (private key):
UTC--...7ffc10a
- Senha:
unb
- Arquivo UTC (private key):
- Transação que criou o contrato:
0xa5da280ff47cf13945ef440ae81773017ff10379911ad1f49101dbbb3aa6aa4d
- Argumentos usados (construtor) durante a criação:
"CGU-OGU", 0, "Uniao", "http://cgu.gov.br/ogu"
- Endereço do contrato criado:
Ethereum Remix é uma IDE in-browser. Ela permite que você execute métodos de contratos, dentre outras coisas. Para utilizá-la, você precisa conectar-se a um nó rinkeby. Você pode subir seu próprio nó ou usar um da internet.
Usar um nó da internet é mais simples, mas (via remix IDE) somente permite executar métodos de leitura do contrato.
- Comece acessando a URL abaixo:
- https://remix.ethereum.org/#gist=d414cee109931d333e39fd5b5a8d4aa9&version=soljson-v0.4.11+commit.68ef5810.js
- Ela abre a IDE tendo como arquivo o contrato
CatalogoOuvidorias
(que foi copiado em um gist, por ser a única maneira de abrir a IDE com um arquivo pré-carregado).
- Aba
Contract
-> Na comboEnvironment
, selecioneWeb3 Provider
-> Na modal digitehttps://rinkeby.infura.io/
e aguarde. - Após o carregamento, note que nenhuma das accounts (combo
Account
) disponíveis é nossa, mas você conseguirá fazer consultas sem problema. - Acesse versão já deployada do contrato:
- Clique no botão
Address
(verde) e digite na modal o endereço do contrato já deployado:0xff5a6388151086d0186c741c3af426b7cc846c52
.
- Clique no botão
- Assim que aberto o contrato, aparecerão botões com os métodos.
- Para executar, basta preencher os argumentos e apertar o botão do nome do método.
- Lembre-se de utilizar aspas duplas em argumentos do tipo
address
:"0x1750dd0f8cd22ee9d849ab11ebc62adb37ffc10a"
- Experimente chamar alguns métodos passando como argumento o endereço da account da ouvidoria inicial (a usada para criar o contrato):
"0x1750dd0f8cd22ee9d849ab11ebc62adb37ffc10a"
- Lembre-se de utilizar aspas duplas em argumentos do tipo
Importante: como a Solidity e a EVM são pé duro, quando você executar métodos que por alguma lógica falham (ex.: você querer autorizar alguém a partir de uma account sem privilégio suficiente), a mensagem de erro que aparece é normalmente bem estranha, parecendo ser um erro interno ao invés de um comportamento normal. Só pra você saber :)
Usar um nó local é mais complexo, mas permite que você escolha qual account vai usar e, por consequência, conseguirá, mais facilmente, não só realizar leitura, mas também escrita no contrato.
Utilize esta opção quando quiser realizar transações a partir da account 0x1750dd0f8cd22ee9d849ab11ebc62adb37ffc10a
ou de outras accounts que você criar.
O principal ponto negativo é que você precisará esperar o nó sincronizar todo o blockchain rinkeby.
-
Suba o nó:
- Ir na pasta
ethereum-testnets/rinkeby
- Digitar:
docker-compose up --build
- Isso vai subir um nó que se conectará à rinkeby. Você precisa aguardar ele baixar todo o blockchain para poder interagir com a rede.
- Não se preocupe com as linhas
WARN [XX-XX|XX:XX:XX] Block sealing failed err=unauthorized
, elas não têm impacto no escopo em que estamos.
- Não se preocupe com as linhas
- Ir na pasta
-
Acesse a IDE
- Comece acessando a URL abaixo:
- (note o HTTP, não HTTPS) http://remix.ethereum.org/#gist=d414cee109931d333e39fd5b5a8d4aa9&version=soljson-v0.4.11+commit.68ef5810.js
- Ela abre a IDE tendo como arquivo o contrato
CatalogoOuvidorias
(que foi copiado em um gist, por ser a única maneira de abrir a IDE com um arquivo pré-carregado).
- Aba
Contract
-> Na comboEnvironment
, selecioneWeb3 Provider
-> Na modal digitehttp://localhost:8546
(note o SEIS ao final)- Se o erro
Invalid JSON RPC response: ""
acontecer, certifique-se de que você está via HTTP e não HTTPS.
- Se o erro
- Agora você pode ou deployar o contrato, ou acessar uma versão já deployada dele.
- Deployar:
- Quando fizemos o deploy pela primeira vez, digitamos
"CGU-OGU", 0, "Uniao", "http://cgu.gov.br/ogu"
no campo de texto próximo ao botãoCreate
(vermelho) e cliquei no botão.
- Quando fizemos o deploy pela primeira vez, digitamos
- Acessar a versão já deployada do contrato:
- Clique no botão
Address
(verde) e digite na modal o endereço do contrato já deployado:0xff5a6388151086d0186c741c3af426b7cc846c52
.
- Clique no botão
- Deployar:
- Assim que aberto o contrato, aparecerão botões com os métodos.
- Para executar, basta preencher os argumentos e apertar o botão do nome do método.
- Lembre-se de utilizar aspas duplas em argumentos do tipo
address
:"0x1750dd0f8cd22ee9d849ab11ebc62adb37ffc10a"
- Experimente chamar alguns métodos passando como argumento o endereço da account da ouvidoria inicial (a usada para criar o contrato):
"0x1750dd0f8cd22ee9d849ab11ebc62adb37ffc10a"
- Lembre-se de utilizar aspas duplas em argumentos do tipo
- Comece acessando a URL abaixo:
As mensagens de commit deste repo buscam seguir estas convencoes.