Learning-Bitcoin-from-the-C.../pt/18_3_Accessing_Bitcoind_with_NodeJS.md
2021-08-24 09:55:33 -03:00

274 lines
9.7 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 17.3: Acessando o Bitcoind com NodeJS
> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão.
Esta seção explica como interagir com o `bitcoind` usando a linguagem de programação NodeJS e o [pacote BCRPC](https://github.com/dgarage/bcrpc).
## Set Up Node.js
## Configurando o Node.js
O BCRPC é construído em node.js. Portanto, primeiro precisamos instalar os pacotes `node.js` e o `npm` (o gerenciador de pacotes do node) em nosso sistema.
Se estiver usando uma máquina Ubuntu, podemos executar os seguintes comandos para obter uma nova versão do `node.js`, ao invés da versão terrivelmente desatualizada no sistema de pacotes do Ubuntu.
```
$ curl -sL https://deb.nodesource.com/setup_14.x | sudo bash -
$ sudo apt-get install -y nodejs
$ sudo npm install mocha -g
```
### Configurando o BCRPC
Agora podemos clonar o pacote BCRPC do GitHub e instalar as dependências.
```
$ git clone https://github.com/dgarage/bcrpc.git
$ cd bcrpc
$ npm install
```
Para testar o pacote BCRPC, devemos primeiro definir as variáveis ambientais para o rpcuser e rpcpassword. Como de costume, eles vêm do `~/.bitcoin/bitcoin.conf`. Também devemos definir a porta RPC como sendo 18332, que deve ser a correta para a configuração Testnet padrão descrita nos documentos.
```
$ export BITCOIND_USER=StandUp
$ export BITCOIND_PASS=d8340efbcd34e312044c8431c59c792c
$ export BITCOIND_PORT=18332
```
> :warning: **AVISO:** Obviamente, nunca colocaria nossa senha definida em uma variável de ambiente em um ambiente de produção.
> :link: **MAINNET VS TESTNET:** A porta seria 8332 para uma configuração na Mainnet.
Agora podemos verificar se tudo está funcionando corretamente:
```
$ npm test
> bcrpc@0.2.2 test /home/user1/bcrpc
> mocha tests.js
BitcoinD
✓ is running
bcrpc
✓ can get info
2 passing (36ms)
```
Parabéns, agora temos um wrapper RPC pronto para usar o Bitcoin com o Node.js que está funcionando com nossa configuração do Bitcoin.
### Criando um Projeto BCRPC
Agora podemos criar um novo projeto Node.js e instalar o BCRPC via npm.
```
$ cd ~
$ mkdir myproject
$ cd myproject
$ npm init
[continue with default options]
$ npm install bcrpc
```
## Construindo nossa conexão
Em nosso diretório `myproject`, criamos um arquivo `.js` onde nosso código JavaScript será executado.
Podemos iniciar uma conexão RPC criando um `RpcAgent`:
```
const RpcAgent = require('bcrpc');
agent = new RpcAgent({port: 18332, user: 'StandUp', pass: 'd8340efbcd34e312044c8431c59c792c'});
```
Obviamente, nosso `user` e `pass` devem coincidir novamente com o que está em nosso `~/.bitcoin/bitcoin.conf`, e usamos a `porta 18332` se estivermos na Testnet.
### Fazendo uma chamada RPC
Usando o BCRPC, podemos usar os mesmos comandos RPC que normalmente usaríamos via `bitcoin-cli` com nosso `RpcAgent`, exceto que eles precisam estar em camelCase. Por exemplo, `getblockhash` seria `getBlockHash`.
Para imprimir o número do bloco mais recente, basta chamar o `getBlockCount` através do nosso `RpcAgent`:
```
agent.getBlockCount(function (err, blockCount) {
if (err)
throw Error(JSON.stringify(err));
console.log(blockCount.result);
});
```
### Fazendo uma chamada RPC com argumentos
As funções BCRPC podem aceitar argumentos. Por exemplo, o `getBlockHash` recebe o `blockCount.result` como uma entrada.
```
agent.getBlockHash(blockCount.result, function (err, hash) {
if (err)
throw Error(JSON.stringify(err));
console.log(hash.result);
})
```
O resultado das funções BCRPC é um objeto JSON contendo informações sobre quaisquer erros e o id da solicitação. Ao acessar nosso resultado, adicionamos o `.result` no final dele para especificar que estamos interessados no resultado real, não em informações sobre os erros.
### Executando nosso código
Podemos encontrar o código `getinfo` no [diretório src/](src / 17_3_getinfo.js).
```
$ node getinfo.js
1831094
00000000000002bf8b522a830180ad3a93b8eed33121f54b3842d8838580a53c
```
Isto é o que a saída do exemplo acima pareceria se substituíssemos o `console.log(blockCount.result);` e o `console.log(hash.result);` por `console.log(blockCount);` e `console.log (hash);`, respectivamente:
```
{ result: 1774686, error: null, id: null }
{
result: '00000000000000d980c495a2b7addf09bb0a9c78b5b199c8e965ee54753fa5da',
error: null,
id: null
}
```
## Pesquisando os fundos
É útil ao aceitar Bitcoin verificar os Bitcoin recebidos em um endereço específico em nossa carteira. Por exemplo, se administrássemos uma loja online que aceita Bitcoin, para cada pagamento de um cliente, geraríamos um novo endereço, mostraríamos esse endereço ao cliente e, em seguida, verificaríamos o saldo do endereço após algum tempo, para certificar-se de que o montante foi recebido:
```
agent.getReceivedByAddress('mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', function (err, addressInfo) {
if (err)
throw Error(JSON.stringify(err));
console.log(addressInfo.result);
});
```
> :information_source: **NOTA:** Obviamente, precisaremos inserir um endereço reconhecido por nossa máquina.
Por padrão, esta função verifica as transações que foram confirmadas uma vez, no entanto, podemos aumentar para um número maior, como 6:
```
agent.getReceivedByAddress('mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', 6, function (err, addressInfo) {
if (err)
throw Error(JSON.stringify(err));
console.log(addressInfo.result);
});
```
### Pesquisando informações da carteira
Também podemos procurar informações adicionais sobre nossa carteira e visualizar nosso saldo, contagem de transações etc.
```
agent.getWalletInfo(function (err, walletInfo) {
if (err)
throw Error(JSON.stringify(err));
console.log(walletInfo.result);
});
```
O código está disponível como [walletinfo.js](src/17_3_walletinfo.js).
```
$ node walletinfo.js
0.008498
{
walletname: '',
walletversion: 169900,
balance: 0.010438,
unconfirmed_balance: 0,
immature_balance: 0,
txcount: 4,
keypoololdest: 1596567843,
keypoolsize: 999,
hdseedid: 'da5a1b058deb9e51ecffef1b0ddc069a5dfb2c5f',
keypoolsize_hd_internal: 1000,
paytxfee: 0,
private_keys_enabled: true,
avoid_reuse: false,
scanning: false
}
```
Ao invés de imprimir todos os detalhes associados à nossa carteira, podemos imprimir informações específicas, como nosso saldo. Como um objeto JSON está sendo acessado, podemos fazer isso alterando a linha `console.log(walletInfo.result);` para `console.log(walletInfo.result.balance);`:
## Criando um endereço
Também podemos passar argumentos adicionais para os comandos RPC. Por exemplo, o seguinte gera um novo endereço legado, com o sinalizador `-addresstype`.
```
agent.getNewAddress('-addresstype', 'legacy', function (err, newAddress) {
if (err)
throw Error(JSON.stringify(err));
console.log(newAddress.result);
});
```
Isso é o mesmo que executar o seguinte na linha de comando:
```
$ bitcoin-cli getnewaddress -addresstype legacy
mtGPcBvRPZFEHo2YX8un9qqPBydhG82uuZ
```
No BCRPC, geralmente podemos usar os mesmos sinalizadores que no `bitcoin-cli` no BCRPC. Embora usamos o camelCase (`getNewAddress`) para os métodos, os sinalizadores, que normalmente são separados por espaços na linha de comando, são colocados em strings e separados por vírgulas.
## Enviando uma transação
Podemos enviar saldos para um endereço muito facilmente, usando a função `sendToAddress`:
```
agent.sendToAddress(newAddress.result, 0.00001, function(err, txid) {
if (err)
throw Error(JSON.stringify(err));
console.log(txid.result);
});
```
Isso deve retornar o txid da transação:
```
1679bee019c61608340b79810377be2798efd4d2ec3ace0f00a1967af70666b9
```
### Pesquisando uma transação
Agora podemos desejar visualizar uma transação, como a que acabamos de enviar.
```
agent.getTransaction(txid.result, function (err, transaction) {
if (err)
throw Error(JSON.stringify(err));
console.log(transaction.result);
});
```
Devemos obter uma saída semelhante a esta:
```
{
amount: 0.001,
confirmations: 4776,
blockhash: '000000006628870b0a8a66abea9cf0d4e815c491f079e3fa9e658a87b5dc863a',
blockindex: 117,
blocktime: 1591857418,
txid: '1661ce322c128e053b8ea8fcc22d17df680d2052983980e2281d692b9b4ab7df',
walletconflicts: [],
time: 1591857343,
timereceived: 1591857343,
'bip125-replaceable': 'no',
details: [
{
address: 'mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha',
category: 'receive',
amount: 0.001,
label: '',
vout: 0
}
],
hex: '02000000000101e9e8c3bd057d54e73baadc60c166860163b0e7aa60cab33a03e89fb44321f8d5010000001716001435c2aa3fc09ea53c3e23925c5b2e93b9119b2568feffffff02a0860100000000001976a914600c8c6a4abb0a502ea4de01681fe4fa1ca7800688ac65ec1c000000000017a91425b920efb2fde1a0277d3df11d0fd7249e17cf8587024730440220403a863d312946aae3f3ef0a57206197bc67f71536fb5f4b9ca71a7e226b6dc50220329646cf786cfef79d60de3ef54f702ab1073694022f0618731902d926918c3e012103e6feac9d7a8ad1ac6b36fb4c91c1c9f7fff1e7f63f0340e5253a0e4478b7b13f41fd1a00'
}
```
O código completo está disponível no [sendtx.js](src/17_3_sendtx.js).
## Resumo: Acessando o Bitcoind com NodeJS
Com o BCRPC podemos acessar todos os comandos RPC disponíveis através do `bitcoin-cli`, usando o JavaScript. O [BCRPC README](https://github.com/dgarage/bcrpc) tem alguns exemplos que usam promises (os exemplos neste livro usam callbacks). O [JavaScript por trás dele](https://github.com/dgarage/bcrpc/blob/master/index.js) é curto e bem legível.
Com base nesses exemplos, devemos ser capazes de incorporar Bitcoin em um projeto Node.js e fazer coisas como enviar e receber fundos.
## O Que Vem Depois?
Vamos aprender mais sobre "Conversando com o Bitcoind com Outras Linguagens" na seção [§17.4: Acessando o Bitcoind com Python](17_2_Accessing_Bitcoind_with_Java.md).