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
6 . Implementação do código
..... . Página index em HTML
..... . Recurso index em JS
..... . Estilização style em CSS
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
Inicialize o projeto executando o seguinte:
npm init
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
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>
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
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;
}
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
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"
},
Adicione isso no final do script:
"alias": {
"@ledgerhq/devices": "@ledgerhq/devices/lib-es"
}
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"
}
}
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.
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.
Oldest comments (0)