WEB3DEV

Cover image for Transferência de Ethers entre contas - Ledger
Adriano P. Araujo
Adriano P. Araujo

Posted on • Atualizado em

Transferência de Ethers entre contas - Ledger

Introdução

Nesta seção, vamos guiá-lo através da criação de um aplicativo. Este aplicativo criará uma transação que será assinada com a Ledger Nano antes de enviá-la para a blockchain. O objetivo da aplicação é transferir ethers de sua conta ethereum em sua Ledger para outra conta.


Sumário

1 . O que é necessário

2 . Rede Ropsten Ethereum

3 . Rede de Dimensões

4 . Implementação do tutorial

5 . Inicialização do projeto

6 . Implementação do código
..... . Página index em HTML
..... . Recurso index em JS
..... . Estilização style em CSS

7 . Modificar package em JSON

8 . Teste do tutorial

9 . Inicie o servidor de desenvolvimento

10 . Conecte sua Ledger ao aplicativo

11 . Crie uma transação para transferir ethereum


O que é necessário

Antes de começar, certifique-se de ter cumprido os  pré-requisitos.

Envie o token Ether para sua conta ethereum da Ledger Nano

Para enviar alguns ethers na rede Ropsten, acesse um dos sites da ropsten faucet:

A rede Ropsten não é visível na Ledger Live, então você pode verificar a execução da transação no ropsten.etherscan.io.

Se as faucet Ropsten e Dimension não funcionarem ou a fila for muito longa, use outra torneira de sua escolha para receber o testnet Ether.

Rede Ropsten Ethereum

Vá para o site Ropsten Ethereum Faucet, coloque sua chave pública da carteira no campo e clique em “Send me test Ether”

Fig. 1: Ropsten Ethereum Faucet

Rede de Dimensões

Acesse o site da Dimensions Network coloque sua Chave Pública da Carteira na entrada, faça o captcha e clique em ““Send me test Ether”

Fig. 2: Ropsten Ethereum Faucet

Implementação do tutorial

Nesta implementação, estaremos construindo uma aplicação web com javascript vanilla que usa o protocolo HID de um pacote Ledger  para se comunicar com a ledger. 

Inicialização do projeto

É hora de implementar a aplicação e testá-la. Primeiro, abra um terminal e crie uma nova pasta. Para este tutorial, a pasta será nomeada “e2e-eth-tutorial”. Rode:

mkdir e2e-eth-tutorial
cd e2e-eth-tutorial
Enter fullscreen mode Exit fullscreen mode

Inicialize o projeto executando o seguinte:

npm init
Enter fullscreen mode Exit fullscreen mode

Responda às perguntas exibidas ou, por padrão, pressione enter. Não há incidência na execução.

Rode:

touch index.html
touch index.js
touch style.css
mkdir assets
Enter fullscreen mode Exit fullscreen mode

Coloque este logotipo na pasta de ativos.

Sua pasta de trabalho deve ficar assim.

Fig. 3: Pasta da Aplicação

Implementação do código

Página index em HTML

Em index.html, copie e cole o seguinte código:

<!DOCTYPE html>

<html>

  <head>

    <title>Parcel Sandbox</title>

    <meta charset="UTF-8" />

    <link rel="stylesheet" href="style.css">

    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>

    <script src="[https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js](https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js)"></script>

    <script type="module" src="index.js"></script>

  </head>

  <body class="m-5">

    <div class="d-flex flex-column justify-content-center m-5 align-items-center">

      <p>Click on the bellow button to connect your Ledger Wallet</p>

      <button class="btn btn-primary w-25" data-bs-toggle="modal" data-bs-target="#WalletModal">Connect your Wallet</button>

    </div>

    <div class="d-flex flex-row">

      <div id="app" class="w-50">

        <form class="row g-3">

          <div class="col-md-12">

            <label for="wallet" class="form-label">Wallet Public Key</label>

            <input type="text" class="form-control" id="wallet" disabled>

          </div>

          <div class="col-md-12">

            <label for="recipient" class="form-label">Recipient</label>

            <input type="text" class="form-control" id="recipient">

          </div>

          <div class="col-md-6">

            <label for="gasPrice" class="form-label">Gas Price in wei</label>

            <input type="text" class="form-control" id="gasPrice" disabled>

          </div>

          <div class="col-md-6">

            <label for="gasLimit" class="form-label">Gas Limit in wei</label>

            <input type="text" class="form-control" id="gasLimit">

          </div>

          <div class="col-md-6">

            <label for="chainId" class="form-label">Chain ID</label>

            <input type="text" class="form-control" id="chainId" disabled>

          </div>

          <div class="col-md-6">

            <label for="value" class="form-label">Value</label>

            <input type="text" class="form-control" id="value" >

          </div>

          <div class="col-12">

            <button type="button" id="tx-transfer" class="btn btn-primary">Create Transaction</button>

          </div>

        </form>

      </div>

      <div class="w-50 d-flex flex-column">

            <p class="url">Ropsten etherscan: </p>

            <p  id="url"></p>

      </div>

    </div>

    <!-- Modal -->

    <div class="modal fade" id="WalletModal" tabindex="-1" aria-labelledby="WalletModalLabel" aria-hidden="true">

      <div class="modal-dialog">

        <div class="modal-content">

          <div class="modal-header">

            <h5 class="modal-title" id="WalletModalLabel">Choose your Wallet</h5>

            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>

          </div>

          <div class="modal-body d-flex justify-content-center">

            <button id="connect-ledger" class="rounded-3 align-self-center" data-bs-dismiss="modal">

              <img src="./assets/ledger-logo.jpg" class="card-img-top" alt="Ledger">

            </button>

          </div>

        </div>

      </div>

    </div>

  </body>

</html>
Enter fullscreen mode Exit fullscreen mode

Recurso index em JS

Em index.js, copie e cole o seguinte código:

import { ethers } from "ethers";

import TransportWebHID from "@ledgerhq/hw-transport-webhid";

import Eth from "@ledgerhq/hw-app-eth";

//Provedor Infuria para a rede Ropsten 

const provider = new ethers.providers.JsonRpcProvider("https://ropsten.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161");

const chainId = 3;

let gasPrice;

let addressWallet;

let recipient = "0x920f19c7F7Ce5b3170AdB94fDcC4570Da95D286b";

let value = 0.1;

let gasLimit = 1000000;

let nonce;

let _eth;

document.getElementById("connect-ledger").onclick = async function () {

    //Conectando-se a Ledger Nano com o protocolo HID

    const transport = await TransportWebHID.create();

//Definindo uma instância Ethereum e obtendo a chave pública da conta Ledger Nano ethereum

    _eth = new Eth(transport);

    const { address } = await _eth.getAddress("44'/60'/0'/0/0", false);

    //Obtendo algumas propriedades do provedor

    addressWallet = address;

    gasPrice = (await provider.getGasPrice())._hex;

    gasPrice = parseInt(gasPrice,16) * 1.15;

    //Preenchendo as entradas com o valor padrão

    document.getElementById("wallet").value = address;

    document.getElementById("gasPrice").value = parseInt(gasPrice) + " wei";

    document.getElementById("chainId").value = chainId;

    document.getElementById("value").value = value;

    document.getElementById("recipient").value = recipient;

    document.getElementById("gasLimit").value = gasLimit;

}
document.getElementById("tx-transfer").onclick = async function () {

    //Obtendo informações das entradas

    addressWallet = document.getElementById("wallet").value;

    recipient =  document.getElementById("recipient").value;

    value =  document.getElementById("value").value;

    gasLimit =  parseInt(document.getElementById("gasLimit").value);

    nonce =  await provider.getTransactionCount(addressWallet, "latest");

    //Construindo a transação com as informações coletadas

    const transaction = {

        to: recipient,

        gasPrice: "0x" + parseInt(gasPrice).toString(16),

        gasLimit: ethers.utils.hexlify(gasLimit),

        nonce: nonce,

        chainId: chainId,

        data: "0x00",

        value: ethers.utils.parseUnits(value, "ether")._hex,

    }

    //Serializando a transação para passá-la a Ledger Nano para a assinatura

    let unsignedTx = ethers.utils.serializeTransaction(transaction).substring(2);

    //Assinando com a Ledger Nano (Assine o que você vê)

    const signature = await _eth.signTransaction("44'/60'/0'/0/0",unsignedTx);

    //Analisando a assinatura

    signature.r = "0x"+signature.r;

    signature.s = "0x"+signature.s;

    signature.v = parseInt(signature.v);

    signature.from = addressWallet;

    //dispondo em séria a mesma transação de antes, mas adicionando a assinatura nela

    let signedTx = ethers.utils.serializeTransaction(transaction, signature);

    //Enviando a transação para a blockchain

    const hash = (await provider.sendTransaction(signedTx)).hash;

    //Exibindo o Ropsten etherscan na tela

    const url = "https://ropsten.etherscan.io/tx/" + hash;

    document.getElementById("url").innerHTML
Enter fullscreen mode Exit fullscreen mode

Estilização style em CSS

Em style.css copie e cole o seguinte código:

.modal-content{

    width: 300px;

    height: 400px;

}

#connect-ledger{

    width: 17rem;

    height: 9rem;

    background-color: white;

    border: none;

}

#connect-ledger:hover{

    background-color: #EDEFF3;

}

.modal-body{

    background-color: #F7F9FD;

}

#url,.url{

    text-align: center;

    margin-top: 160px;

    color: green;

}
Enter fullscreen mode Exit fullscreen mode

Instalação de dependências

Instale os pacotes

Rode:

npm install --save-dev parcel

npm install --save @ledgerhq/hw-app-eth

npm install --save @ledgerhq/hw-transport-webhid

npm install --save ethers
Enter fullscreen mode Exit fullscreen mode
Pacotes O que isso faz?
parcel É uma ferramenta de compilação que o ajudará a empacotar seu aplicativo para executá-lo no navegador.
@ledgerhq/hw-app-eth Isso ajudará você a pedir a seu Ledger Nano para acessar o endereço ethereum..
@ledgerhq/hw-transport-webhid Ele fornece todos os métodos para interagir com sua Ledger com uma conexão HID.
ethers Ele fornece todos os métodos para interagir com a blockchain ethereum.

Modificar Package em JSON

Modifique a 5ª linha:

"main": "index.js"

=>

"source": "index.html"

E certifique-se de ter esta linha nos scripts:

 "scripts": {
    "start": "parcel"
  },
Enter fullscreen mode Exit fullscreen mode

Adicione isso no final do script:

 "alias": {
    "@ledgerhq/devices": "@ledgerhq/devices/lib-es"
  }
Enter fullscreen mode Exit fullscreen mode

Seu arquivo agora deve ficar assim:

{

    "name": "e2e-eth-tutorial",

    "version": "1.0.0",

    "description": "",

    "source": "index.html",

    "scripts": {

      "start": "parcel"

    },

    "author": "",

    "license": "ISC",

    "devDependencies": {

      "parcel": "^2.3.2"

    },

    "dependencies": {

      "@ledgerhq/hw-app-eth": "^6.26.0",

      "@ledgerhq/hw-transport-webhid": "^6.24.1",

      "ethers": "^5.5.4"

    },

    "alias": {

      "@ledgerhq/devices": "@ledgerhq/devices/lib-es"

    }

}
Enter fullscreen mode Exit fullscreen mode

Teste do tutorial

Inicie o servidor de desenvolvimento

Agora que a configuração foi concluída, o aplicativo deve ser criado para ser exibido. Inicie o servidor de desenvolvimento:

npm run start

Agora o aplicativo está funcionando. Abra o navegador e vá para localhost:1234, ele exibirá:

Fig. 5: Aplicativo rodando no navegador

Conecte seu dispositivo de contabilidade

Antes de clicar no texto, conecte sua Ledger à porta USB, desbloqueie-o e execute a aplicação ethereum. As etapas são descritas abaixo.

Fig. 6: Na Ledger Insira o PIN do código

Fig. 7: Execute o aplicativo Ethereum na Ledger Nano

Fig. 8:A aplicação Ethereum está sendo executada na Ledger Nano

Conecte sua Ledger ao aplicativo

Agora você pode clicar no botão “Conectar sua carteira” e um modal será aberto. Clique no logotipo da Ledger.

Fig. 9: Escolha de Carteira

Agora escolha a Ledger Nano para conectá-la ao navegador.

Fig. 10: Conexão da Ledger Nano

Se tudo correr bem, os campos de entrada serão preenchidos com os dados. A entrada em cinza não deve ser alterada e é extraída diretamente da blockchain ou do seu aplicativo da Ledger Nano.

Fig. 11: Aplicação após conectar a Ledger Nano

Crie uma transação para transferir ethereum

Agora que as entradas estão preenchidas com dados. É hora de transferir alguns tokens ether da sua conta ethereum da Ledger para outra conta (você pode manter a conta padrão no arquivo “index.js”).

Portanto, clique em “Criar transação” para criar a transação que será assinada pelo seu ledger antes de enviá-la para a blockchain.

Fig. 12: Aplicação após conectar a Ledger Nano

Quando a transação prosseguir e finalizar, uma URL será exibida na tela. Este URL é um link para a Ropsten Etherscan, para revisar a transação.

Lá você pode encontrar todas as informações sobre a transação que você enviou anteriormente.

Fig. 13: Resultado após o envio da transação

Se você for na Etherscan, poderá ver as informações da sua transação.

Fig. 14: Informações de transação na Ropsten Etherscan

Parabéns, você construiu com sucesso seu primeiro aplicativo de transferência conectado a Ledger !!!


Este artigo foi escrito pela Ledger e traduzido por Adriano P. de Araujo. O original em inglês pode ser encontrado aqui.

Top comments (0)