C Execute Contratos Inteligentes de Solidez com o EVM no Oracle Blockchain Platform

Você pode executar contratos inteligentes da Solidity com uma Máquina Virtual Ethereum (EVM) implantada como um chaincode no Oracle Blockchain Platform.

A EVM executa contratos inteligentes Solidity em redes Ethereum. O EVM foi criado através do projeto Hyperledger Burrow e integrado ao Hyperledger Fabric. Este projeto permite que você use uma plataforma blockchain com permissão do Hyperledger Fabric para interagir com contratos inteligentes Ethereum escritos em uma linguagem compatível com EVM, como o Solidity.

As etapas a seguir descrevem o processo de execução de um contrato inteligente Solidity em um Oracle Blockchain Platform provisionado:
  1. Faça download do pacote de chaincode EVM na console do Oracle Blockchain Platform.
  2. Implante o chaincode EVM em um canal.
  3. Gere código de bytes para um contrato inteligente Solidity usando o IDE Remix.
  4. Implante o código de bytes de contrato inteligente no código de cadeia EVM implantado. Use o endereço retornado da implantação para enviar transações.
As etapas deste tópico foram testadas com o pacote de chaincode EVM que está disponível na console do Oracle Blockchain Platform e pode não funcionar com outras versões.

Observação:

Se seu chaincode tiver sido instalado anteriormente em uma instância do Hyperledger Fabric v1.4.7, ele deverá continuar funcionando conforme o esperado quando sua instância for submetida a upgrade para o Hyperledger Fabric v2.x.

Faça Download do Chaincode EVM e do Pacote Fab3

Na guia Ferramentas do Desenvolvedor da console do Oracle Blockchain Platform, abra o painel Desenvolvimento de Aplicativos e clique em Fazer download do pacote de chaincode EVM. Você deve ser um usuário administrador para fazer download do arquivo.

Implante o Chaincode EVM no Oracle Blockchain Platform

Depois de fazer download do pacote de chaincode EVM, implante-o no Oracle Blockchain Platform.

  1. Faça log-in na console do Oracle Blockchain Platform.
  2. Na guia Chaincodes, clique em Implantar um Novo Chaincode.
  3. Selecione Implantação Rápida e especifique as seguintes informações:
    • Rótulo do Pacote: informe uma descrição do pacote de chaincode.
    • Idioma do Código de Cadeia: GoLang.
    • Nome do Código de Cadeia: informe o nome do código de cadeia. Por exemplo, soliditycc.
    • Versão: v1.
    • Init-required: deixe essa opção desmarcada.
    • Canal: selecione os canais nos quais você deseja instalar o chaincode.
    • Chaincode Empacotado: deixe essa opção desmarcada.
    • Chaincode source: faça o upload do pacote evmcc.zip que você baixou anteriormente.
    Para obter mais detalhes sobre o assistente de Implantação Rápida e restrições em campos como Rótulo do Pacote e Nome do Código de Cadeia, consulte: Usar Implantação Rápida.

Depois que você enviar suas informações, o chaincode EVM ficará visível na guia Chaincodes e será listado como um chaincode implantado em cada canal selecionado para instalação.

Crie e Compile seu Contrato Inteligente de Solidez

  1. Abra o IDE Remix baseado em browser: https://remix.ethereum.org/.
  2. Se você já tem um contrato inteligente Solidity escrito, importe-o para Remix.
  3. Se você não tiver um contrato inteligente Solidity escrito, crie um arquivo Solidity (.sol) no Remix e execute um dos seguintes procedimentos:
    • Se você estiver familiarizado com o Solidity, poderá criar seu próprio arquivo de contrato inteligente.
    • Você pode usar o código de amostra de Armazenamento Simples fornecido na documentação do Solidity: Solididade: Introdução a Contratos Inteligentes
    • Você pode usar o código de amostra que está sendo usado para este exemplo, que usa string name como entrada e imprime o mesmo que a string de saída usando set(name) e get():
      pragma solidity ^0.4.0;
      contract Myname {
          string public yourName;
      
          function set(string name) public {
              yourName = name;
          }
          function get() public view returns (string) {
              return yourName;
          }
      }
      
    Talvez você veja uma mensagem de erro sobre a versão do compilador padrão que não corresponde à versão especificada em seu contrato inteligente.
  4. Compile seu contrato inteligente. Abra o painel Compilador Solidity no Remix, certifique-se de que sua guia de contrato inteligente esteja aberta para selecioná-la como o arquivo que está sendo compilado, defina a versão do compilador como a 4 mais recente. Versão X e clique em Compile.
    Captura de tela do contrato inteligente Solidity de teste na visualização Remix Compiler.

  5. Depois que o arquivo for compilado, clique no ícone Código de bytes para copiar o código de bytes como um documento JSON para sua área de transferência.
  6. Cole o código de bytes copiado em um editor de texto e salve-o.

Implantar o Contrato Inteligente

No código de bytes copiado, a seção necessária é o campo "object". Este é o código de bytes EVM de um contrato inteligente de amostra.
"object": "608060405234801561001057600080fd5b50610410806100206000396000f30060
8060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463
ffffffff1680634ed3885e1461005c5780636d4ce63c146100c5578063d97d663014610155575b600080fd5b34801561
006857600080fd5b506100c3600480360381019080803590602001908201803590602001908080601f01602080910402
602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506101
e5565b005b3480156100d157600080fd5b506100da6101ff565b60405180806020018281038252838181518152602001
91508051906020019080838360005b8381101561011a5780820151818401526020810190506100ff565b505050509050
90810190601f1680156101475780820380516001836020036101000a031916815260200191505b509250505060405180
910390f35b34801561016157600080fd5b5061016a6102a1565b60405180806020018281038252838181518152602001
91508051906020019080838360005b838110156101aa57808201518184015260208101905061018f565b505050509050
90810190601f1680156101d75780820380516001836020036101000a031916815260200191505b509250505060405180
910390f35b80600090805190602001906101fb92919061033f565b5050565b6060600080546001816001161561010002
03166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615
6101000203166002900480156102975780601f1061026c57610100808354040283529160200191610297565b82019190
6000526020600020905b81548152906001019060200180831161027a57829003601f168201915b505050505090509056
5b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190
818152602001828054600181600116156101000203166002900480156103375780601f1061030c576101008083540402
83529160200191610337565b820191906000526020600020905b81548152906001019060200180831161031a57829003
601f168201915b505050505081565b828054600181600116156101000203166002900490600052602060002090601f01
6020900481019282601f1061038057805160ff19168380011785556103ae565b828001600101855582156103ae579182
015b828111156103ad578251825591602001919060010190610392565b5b5090506103bb91906103bf565b5090565b61
03e191905b808211156103dd5760008160009055506001016103c5565b5090565b905600a165627a7a72305820a990d4
0b57c66329a32a18e847b3c18d6c911487ffadfed2098e71e8cafa0c980029",
Em geral, a EVM espera dois argumentos:
  • O endereço to.
  • O input que é necessário nas transações Ethereum.

Para implantar contratos inteligentes, o campo to é o endereço zero e o input é o código de bytes EVM compilado do contrato. Portanto, há dois argumentos fornecidos para o comando invoke. O primeiro, que tradicionalmente deveria ser um nome de função dentro do chaincode, agora é 0000000000000000000000000000000000000000, e o segundo argumento é o bytecode de contrato inteligente Solidity.

  1. Para implantar o contrato inteligente Solidity no Oracle Blockchain Platform, você pode fazer a seguinte chamada de proxy REST para enviar os dois argumentos ao EVM.
    {
        "chaincode": "<evmcc-ccid>",
        "args": [
            "0000000000000000000000000000000000000000",
            "<bytecode-of-the-smart-contract>"
        ],
        "timeout": 0,
        "sync": true
    }
    O exemplo a seguir usa o cURL para implantar o contrato inteligente Solidity no Oracle Blockchain Platform com o nome soliditycc:
    curl -L -X POST 'https://<hostname>:7443/restproxy/api/v2/channels/<channelname>/transactions' \
    -H 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=' \
    -H 'Content-Type: application/json' \
    --data-raw '{"chaincode":"<evmcc-ccid>","args":["0000000000000000000000000000000000000000","<bytecode-of-the-smart-contract>"],"timeout":0,"sync":true}'
  2. A resposta payload da transação é o endereço do contrato implantado. Copie este endereço e salve-o. O endereço do contrato é usado quando você executa funções de contrato inteligente.
    Captura de tela da chamada e resposta da API mostrando o endereço do contrato inteligente no campo de resposta de carga útil.
    Neste exemplo, o endereço do contrato inteligente é 66b92979bb66d645371b3247177e4b2513cb9834.
Há duas maneiras de interagir com um contrato inteligente implantado:
  1. Usando um valor de hash do método e parâmetros de entrada.
  2. Usando o nome do método e os parâmetros de entrada diretamente.

Interagindo com o Contrato Inteligente Usando Valores de Hash

Depois de ter o endereço do contrato inteligente, você pode usar as chamadas a seguir para interagir com o contrato inteligente implantado por meio do proxy REST.

Para executar funções, você usa transações de chamada e consulta, mas com parâmetros diferentes. O contrato de amostra contém duas funções: get e set.

Nessas transações, o campo to é o endereço do contrato e o campo input é o hash de execução da função concatenado com qualquer um dos argumentos necessários.

Você precisa adquirir o hash da execução da função para executar uma transação. Uma maneira simples de fazer isso é executar as funções no Remix IDE e, em seguida, copiar o hash dos logs de transação:

  1. No IDE Remix, abra o painel Implantar e Executar Transações. Certifique-se de que seu contrato esteja selecionado no campo Contrato e clique em Implantar.
    Captura de tela do contrato Solidity prestes a ser implantado.

    Depois que a implantação for concluída, o contrato deverá ser listado na lista Contratos Implantados.
  2. Expanda o contrato na lista Contratos Implantados. As funções de contrato inteligente são listadas.
  3. Executar uma transação. Para o exemplo fornecido, digite oracle e clique em set.
  4. A janela Terminal mostra os logs de transação. Se os logs de transação forem minimizados, expanda-os clicando no log. Copie o valor do campo input (que é o hash de execução da função) clicando no ícone ao lado dele. Salve esse valor no mesmo local do endereço do contrato, removendo o 0x à esquerda.
    Captura de tela da página Implantação mostrando os valores de transação e campo concluídos e apontando para o campo de entrada que contém o valor hash de execução da função.

  5. Depois de ter o hash de execução da função e o endereço do contrato, você poderá executar a transação definida no Oracle Blockchain Platform usando o hash e o endereço como argumentos de dados brutos.
    
    --data-raw '{"chaincode":"<chaincodename>","args":["<contractaddress>","<setfunctionexecutionhash>"]}'
    
    Por exemplo, usando cURL:
    curl -L -X POST 'https://<hostname>:7443/restproxy/api/v2/channels/<channelname>/transactions' \
    -H 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=' \
    -H 'Content-Type: application/json' \
    --data-raw '{"chaincode":"soliditycc","args":["66b92979bb66d645371b3247177e4b2513cb9834","4ed3885e000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000066f7261636c650000000000000000000000000000000000000000000000000000"]}'
    
  6. Abra a console do Oracle Blockchain Platform e verifique se a transação está listada no razão.

Para executar outra transação, como uma consulta, usando a função get do contrato inteligente, você pode gerar o hash de execução da função no Remix e combiná-lo com o endereço do contrato:

  1. Em Remix no painel Implantar e Executar Transações, certifique-se de que seu contrato ainda esteja listado em Contratos Implantados. Caso contrário, reimplante-o.
  2. Clique em obter. Recupere e salve a entrada da transação como você fez com a transação definida, removendo o 0x à esquerda.
    Captura de tela da transação get no Remix, esclarecendo que o campo de entrada contém o hash de execução da função necessária.

  3. Você pode usar esse hash de transação e o endereço do contrato para executar uma transação de consulta no chaincode implantado no Oracle Blockchain Platform.
    
    --data-raw '{"chaincode":"<chaincodename>","args":["<contractaddress>","<getfunctionexecutionhash>"]}'
    
    Por exemplo, em cURL:
    curl -L -X POST 'https://<hostname>:7443/restproxy/api/v2/channels/<channelname>/chaincode-queries' \
    -H 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=' \
    -H 'Content-Type: application/json' \
    --data-raw '{"chaincode":"soliditycc","args":["66b92979bb66d645371b3247177e4b2513cb9834","6d4ce63c"]}'
    
    O payload retornado conterá o ativo que está sendo consultado - no exemplo, a string oracle.

O payload de amostra a seguir ilustra outra maneira de enviar uma transação usando a entrada codificada em formato hexadecimal.

{
    "chaincode": "<evmcc-ccid>",
    "args": [
        "<smart-contract-address>",
        "<hexadecimal-encoded-method-and-input-parameters>"
    ],
    "sync": true
}

Interagindo com o Contrato Inteligente Usando Nomes de Métodos

Use o método setAbi opcional para definir uma especificação ABI (Application Binary Interface), que permite enviar entrada e obter saída em formato legível (não codificado em hexadecimal) em vez de código de bytes. Clique no ícone ABI (ao lado do ícone Bytecode) no painel Compilador de Solidez no IDE Remix para obter a especificação ABI. Os seguintes tipos de entrada são suportados para o formato de entrada legível: uint, string, address, bool, uint[], string[] e address[]. A execução de transações em contratos inteligentes que implementam a substituição do método e a sobrecarga do método não é suportada pelo proxy fab3, apenas pelo proxy REST. O payload de amostra a seguir usa o método setAbi para definir uma especificação de ABI.

{
    "chaincode": "<evmcc-ccid>",
    "args": [
        "setABI",
        "<smart-contract-address>",
        "<abi-spec-of-smart-contract>" --> use the string format of the abi specification
    ],
    "sync": true
}

Você também pode fazer chamadas usando o nome do método e os parâmetros de entrada diretamente, conforme mostrado no payload de amostra a seguir.

{
    "chaincode": "<evmcc-ccid>",
    "args": [
        "<smart-contract-address>",
        "<smart-contract-method-name>",
		"[<array-of-input-parameters>]", --> empty array if there are no input parameters.
		"[<string-array-of-input-types>]" --> this is optional and is needed when there is method overriding in the smart contract.
    ],
    "sync": true
}

Configurando Quantias de Gás

Você pode configurar o valor do gás usando os métodos setGasAmount e getGasAmount, conforme mostrado nos payloads de amostra a seguir.

{
    "chaincode": "<evmcc-ccid>",
    "args": [
        "setGasAmount",
        "<gas-amount>"
    ],
    "sync": true
}
{
    "chaincode": "<evmcc-ccid>",
    "args": [
        "getGasAmount"
    ],
    "sync": true
}