Review 04_2__Interlude

This commit is contained in:
namcios 2021-06-30 17:39:32 -03:00
parent 36613e3451
commit b0e25e7a8e
No known key found for this signature in database
GPG Key ID: 8E3A368317269AB4

View File

@ -1,8 +1,8 @@
# Prefácio: Usando o JQ
# Prefácio: Usando JQ
A criação de uma transação bruta revelou como resultados mais complexos do ```bitcoin-cli``` que não podem ser salvos facilmente em variáveis de linha de comando. A resposta para isso e usar o JQ, que permite filtrar elementos individuais de dados JSON mais complexos.
A criação de uma transação bruta revelou como resultados mais complexos do ```bitcoin-cli``` não podem ser salvos facilmente em variáveis de linha de comando. A resposta para isso é usar o JQ, que permite filtrar elementos individuais de dados JSON mais complexos.
## Instalando o JQ
## Instalando JQ
O JQ está disponível em um [repositório no Github](https://stedolan.github.io/jq/). Basta fazermos o download para Linux, OS X ou Windows, de acordo com o seu sistema operacional.
@ -11,11 +11,11 @@ Depois de baixar o binário, podemos instalá-lo em nosso sistema. Se estivermos
$ mv jq-linux64 jq
$ sudo /usr/bin/install -m 0755 -o root -g root -t /usr/local/bin jq
```
> :book: ***O que é o JQ?*** O repositório explica melhor, dizendo "O jq é como o sed para dados o JSON - você pode usá-lo para dividir, filtrar, mapear e transformar dados estruturados com a mesma facilidade que o sed, awk, grep e permitem que você brinque com o texto".
> :book: ***O que é JQ?*** O repositório explica melhor, dizendo "O jq é como o sed para dados JSON - você pode usá-lo para dividir, filtrar, mapear e transformar dados estruturados com a mesma facilidade que o sed, awk, e grep permitem que você brinque com o texto".
## Usando o JQ para acessar um valor do objeto JSON pelo índice
## Usando JQ Para Acessar o Valor de um Objeto JSON Pelo Índice
**Caso de uso:** _Capturando o hex de uma transação bruta assinada._
**Caso de Uso:** _Capturando o hex de uma transação bruta assinada._
Na seção anterior, o uso de ```signrawtransaction``` não pareceu ser um bom método devido ao fato de não ser capaz de capturar os dados facilmente em variáveis devido a seu retorno no formato JSON:
```
@ -27,14 +27,14 @@ $ bitcoin-cli signrawtransactionwithwallet $rawtxhex
```
Felizmente, o JQ pode facilmente capturar os dados desse tipo!
Para usar o JQ, vamos executar ```jq``` no backend de um pipe e sempre usar a invocação padrão que é ```jq -r '.'```. O ```-r``` diz ao JQ para diminuir a saída bruta, que funcionará para variáveis de linha de comando, enquanto o ```.``` diz ao JQ para mostrar na tela Protegemos esse argumento com ```''``` porque precisaremos dessa proteção mais tarde conforme nossas invocações ```JQ``` se tornarem mais complexas.
Para usar o JQ, vamos executar ```jq``` no backend de um pipe e sempre usar a invocação padrão que é ```jq -r '.'```. O ```-r``` diz ao JQ para produzir uma saída bruta, que funcionará para variáveis de linha de comando, enquanto o ```.``` diz ao JQ para mostrar na tela. Protegemos esse argumento com ```' '``` porque precisaremos dessa proteção mais tarde conforme nossas invocações ```jq``` se tornarem mais complexas.
Para capturar um valor específico de um objeto JSON, basta listar o índice após o ```.```:
```
$ bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex'
02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000
```
Com essa ferramenta em mãos, podemos capturar as informações dos objetos JSON para variáveis na linha de comando:
Com essa ferramenta em mãos, podemos capturar as informações de objetos JSON para variáveis na linha de comando:
```
$ signedtx=$(bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex')
$ echo $signedtx
@ -45,13 +45,13 @@ Podemos usar então essas variáveis facilmente e sem erros:
$ bitcoin-cli sendrawtransaction $signedtx
3f9ccb6e16663e66dc119de1866610cc4f7a83079bfec2abf0598ed3adf10a78
```
## Usando o JQ para acessar valores únicos do objeto JSON em um array usando o índice
## Usando JQ Para Acessar Valores Únicos de um Objeto JSON em um Array Pelo Índice
**Caso de uso:** _Capturando o txid e o vout para um UTXO selecionado._
**Caso de Uso:** _Capturando o txid e o vout para um UTXO selecionado._
Extrair dados de um objeto JSON é fácil, mas e se esse objeto JSON estiver em uma matriz JSON? O comando ```listunspent``` oferece um ótimo exemplo, porque geralmente contém várias transações diferentes. E se quisermos capturar as informações específicas de _um_ deles?
Extrair dados de um objeto JSON é fácil, mas e se esse objeto JSON estiver em um array JSON? O comando ```listunspent``` oferece um ótimo exemplo, porque geralmente contém várias transações diferentes. E se quisermos capturar as informações específicas de _um_ deles?
Ao trabalhar com um array JSON, a primeira coisa que precisamos fazer é informar ao JQ qual índice acessar. Por exemplo, podemos estar olhando nossas transações no ```listunspent``` e decidimos que queremos trabalhar com a segunda. Podemos usar o ```'. [1]'``` para acessar o primeiro elemento. O ```[]``` diz que estamos referenciando um array JSON e o ```0``` diz que queremos o índice 0.
Ao trabalhar com um array JSON, a primeira coisa que precisamos fazer é informar ao JQ qual índice acessar. Por exemplo, podemos estar olhando nosswas transações no ```listunspent``` e decidimos que queremos trabalhar com a segunda. Podemos usar o ```'. [1]'``` para acessar o primeiro elemento. O ```[]``` diz que estamos referenciando um array JSON e o ```0``` diz que queremos o índice 0.
```
$ bitcoin-cli listunspent | jq -r '.[1]'
{
@ -68,7 +68,7 @@ $ bitcoin-cli listunspent | jq -r '.[1]'
"safe": true
}
```
Podemos então capturar um valor individual dessa matriz (1) selecionada usando um pipe _dentro_ dos argumentos JQ; e então o (2) solicitando o valor específico posteriormente, como no exemplo anterior. Isso iria capturar o ```txid``` do primeiro objeto JSON na matriz JSON produzida pelo comando ```listunspent```:
Podemos então capturar um valor individual desse array selecionado (1) usando um pipe _dentro_ dos argumentos JQ; e então (2) solicitando o valor específico posteriormente, como no exemplo anterior. Isso iria capturar o ```txid``` do primeiro objeto JSON no array JSON produzido pelo comando ```listunspent```:
```
$ bitcoin-cli listunspent | jq -r '.[1] | .txid'
91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c
@ -86,9 +86,9 @@ $ echo $newvout
```
Pronto! Agora podemos criar uma nova transação bruta usando nosso primeiro UTXO como entrada, sem ter que digitar qualquer uma das informações do UTXO manualmente!
## Usando o JQ para acessar valores dos objetos JSON correspondentes em um array usando os índices
## Usando JQ Para Acessar Valores de Objetos JSON Correspondentes em um Array Por Índices
**Caso de uso:** _Listar o valor de todos os UTXOs._
**Caso de Uso:** _Listar o valor de todos os UTXOs._
Ao invés de acessar um único valor específico em um objeto JSON específico, podemos acessar todos os valores específicos em todos os objetos JSON. Isso é feito com ```.[]```, Onde nenhum índice é especificado. Por exemplo, podemos listar todos os saldos não gastos:
```
@ -97,9 +97,9 @@ $ bitcoin-cli listunspent | jq -r '.[] | .amount'
0.00022
```
## Usando o JQ para cálculos simples usando índices
## Usando JQ Para Cálculos Simples Por Índices
**Caso de uso:** _Adicionando o valor de todos os UTXOs não gastos._
**Caso de Uso:** _Adicionando o valor de todos os UTXOs não gastos._
Neste ponto, podemos começar a usar o retorno do JQ para fazermos uma matemática simples. Por exemplo, somar os valores dessas transações não gastas com um script ```awk``` simples nos daria o equivalente ao ```getbalance```:
```
@ -109,9 +109,9 @@ $ bitcoin-cli getbalance
0.00032000
```
## Usando o JQ para exibir vários valores de um objeto JSON em um array usando vários índice
## Usando JQ Para Exibir Vários Valores de um Objeto JSON em um Array Por Vários Índices
**Caso de uso:** _Listar as informações de uso para todos os UTXOs._
**Caso de Uso:** _Listar as informações de uso para todos os UTXOs._
O JQ pode capturar facilmente elementos individuais de objetos JSON e arrays e colocar os elementos em variáveis. Esse será o principal uso que iremos fazer nas seções futuras. No entanto, ele também pode ser usado para reduzir grandes quantidades de informações geradas pelo ```bitcoin-cli``` em quantidades razoáveis de informações.
@ -127,7 +127,7 @@ ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36
```
Isso torna mais fácil decidir quais UTXOs gastar em uma transação bruta, mas não é muito bonito.
Felizmente, o JQ também permite que sejamos mais sofisticados. Podemos usar as ```{}``` para criar novos objetos JSON (para análise adicional ou para um retorno mais bonito). Também podemos definir o nome da nova chave para cada um dos valores. A saída resultante deve ser muito mais intuitiva e menos sujeita a erros (embora, menos útil para jogar as informações diretamente nas variáveis).
Felizmente, o JQ também permite que sejamos mais sofisticados. Podemos usar as ```{}``` para criar novos objetos JSON (para análise adicional ou para um retorno mais bonito). Também podemos definir o nome do novo índice para cada um dos valores. A saída resultante deve ser muito mais intuitiva e menos sujeita a erros (embora, menos útil para jogar as informações diretamente nas variáveis).
O exemplo a seguir mostra exatamente a mesma análise do ```listunspent```, mas com cada objeto JSON antigo reconstruído como um novo objeto JSON abreviado, com todos os novos valores nomeados com os índices antigos:
```
@ -157,13 +157,13 @@ $ bitcoin-cli listunspent | jq -r '.[] | { tx: .txid, output: .vout, bitcoins: .
"bitcoins": 0.00022
}
```
## Usando o JQ para acessar os objetos JSON usando um valor pesquisado
## Usando JQ Para Acessar Objetos JSON Por Valor Pesquisado
**Caso de uso:** _Pesquisando automaticamente os UTXOs que estão sendo usados em uma transação._
**Caso de Uso:** _Pesquisando automaticamente os UTXOs que estão sendo usados em uma transação._
As pesquisas JQ até agora o bastante simples: Usamos um índice para pesquisar um ou mais valores em um objeto JSON ou no array. Mas e se quisermos pesquisar um valor em um objeto JSON... usando outro valor? Esse tipo de pesquisa indireta tem aplicabilidade real quando estamos trabalhando com transações criadas usando as UTXOs existentes. Por exemplo, podemos calcular o valor da soma dos UTXOs sendo usados em uma transação, algo de vital importância.
As pesquisas JQ até agora têm sido bastante simples: Usamos um índice para pesquisar um ou mais valores em um objeto JSON ou no array. Mas e se quisermos pesquisar um valor em um objeto JSON... usando outro valor? Esse tipo de pesquisa indireta tem aplicabilidade real quando estamos trabalhando com transações criadas usando os UTXOs existentes. Por exemplo, podemos calcular o valor da soma dos UTXOs sendo usados em uma transação, algo de vital importância.
Este exemplo usa a seguinte transação bruta. Podemos observar que esta é uma transação bruta mais complexa com duas entradas e duas saídas. Aprenderemos como fazer isso nas próximas sessões, mas por enquanto, é necessário sermos capazes de oferecer exemplos robustos. Observe que, ao contrário dos nossos exemplos anteriores, neste, temos dois objetos em nosso array ```vin``` e dois em nosso array ```vout```.
Este exemplo usa a seguinte transação bruta. Podemos observar que esta é uma transação bruta mais complexa com duas entradas e duas saídas. Aprenderemos como fazer isso nas próximas seções, mas por enquanto, é necessário sermos capazes de oferecer exemplos robustos. Observe que, ao contrário dos nossos exemplos anteriores, neste, temos dois objetos em nosso array ```vin``` e dois em nosso array ```vout```.
```
$ bitcoin-cli decoderawtransaction $rawtxhex
{
@ -224,9 +224,9 @@ $ bitcoin-cli decoderawtransaction $rawtxhex
}
```
### Recuperando o(s) valor(es)
### Recuperando Valor(es)
Suponha que saibamos exatamente como essa transação é construída: Sabemos que ela usa dois UTXOs como entrada. Para recuperar o txid para os dois UTXOs, poderíamos usar ```jq``` para consultar o valor .vin da transação e, em seguida, fazer referência ao primeiro índice do .vin e, em seguida, ao valor .txid desse array. Posteriormente, poderíamos fazer o mesmo com o primeiro array e, em seguida, o mesmo com os dois valores .vout de .vin. Simples:
Suponha que saibamos exatamente como essa transação é construída: sabemos que ela usa dois UTXOs como entrada. Para recuperar o txid para os dois UTXOs, poderíamos usar ```jq``` para consultar o valor .vin da transação e, em seguida, fazer referência ao primeiro índice do .vin e, então, ao valor .txid deste array. Posteriormente, poderíamos fazer o mesmo com o primeiro array e, em seguida, o mesmo com os dois valores .vout de .vin. Fácil:
```
$ usedtxid1=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[0] | .txid')
$ echo $usedtxid1
@ -262,9 +262,9 @@ O único truque real aqui é como salvamos as informações usando o shell bash.
> :warning: **ATENÇÃO:** Lembre-se sempre de que um UTXO é uma transação _mais_ um vout. Perdemos o vout na primeira vez que escrevemos este exemplo JQ, e ele parou de funcionar quando acabamos com uma situação em que dois ```vouts``` foram enviados da mesma transação.
### Recuperando o(s) objeto(s) relacionado(s)
### Recuperando o(s) Objeto(s) Relacionado(s)
Agora podemos usar as informações salvas no ```txid``` e no ```vout``` para referenciar os UTXOs no ```listunspent```. Para encontrar as informações sobre os UTXOs usados pela transação bruta, precisamos examinar todo o array JSON (```[]```) com as transações não gastas. Podemos então escolher (```select```) objetos JSON individuais que incluem (```contains```) os txids. _Então_ selecionamos (```select```) as transações entre aquelas que _também_ contém (```contêm```) o valor correto.
Agora podemos usar as informações salvas no ```txid``` e no ```vout``` para referenciar os UTXOs no ```listunspent```. Para encontrar as informações sobre os UTXOs usados pela transação bruta, precisamos examinar todo o array JSON (```[]```) com as transações não-gastas. Podemos então escolher (```select```) objetos JSON individuais que incluam (```contains```) os txids. _Então_ selecionamos (```select```) as transações entre aquelas que _também_ contêm (```contain```) o valor correto.
O uso de outro nível do pipe é a metodologia padrão do JQ: Pegamos um conjunto de dados, depois a reduzimos para todas as transações relevantes e, em seguida, reduzimos para os valores que foram realmente usados nessas transações. No entanto, os argumentos ```select``` e ```contains``` são algo novo. Eles mostram um pouco da complexidade do JSON que vai além do escopo deste tutorial. Por enquanto, saiba apenas que esta invocação em particular funcionará para capturar objetos correspondentes.
@ -293,7 +293,7 @@ $ bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${usedtxid[1
"solvable": true
}
```
Ao invés disso, um simples bash usando um loop em ```for``` poderia nos dar _todos_ os nossos UTXOs:
Ao invés disso, um simples bash usando um loop ```for``` poderia nos dar _todos_ os nossos UTXOs:
```
$ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout'))'; done;
{
@ -318,13 +318,13 @@ $ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i
}
```
Observe que estamos deixando um pouquinho mais feio nosso array ```$ {# usedtxid [*]}``` para determinar o tamanho dele, em seguida, acessamos cada valor no array ```usedtxid``` e cada valor no array ```usedvout``` paralelo, os colocando em variáveis mais simples para termos um acesso menos feio.
Observe que estamos deixando um pouquinho mais feio nosso array ```${#usedtxid[*]}``` para determinar o tamanho dele e, em seguida, acessamos cada valor no array ```usedtxid``` e cada valor no array ```usedvout``` em paralelo, colocando-os em variáveis mais simples para termos um acesso menos feio.
## Usando o JSON para cálculos simples usando os valores
## Usando JSON Para Cálculos Simples Por Valor
**Caso de uso:** _Calcular automaticamente o valor dos UTXOs usados em uma transação._
**Caso de Uso:** _Calcular automaticamente o valor dos UTXOs usados em uma transação._
Agora podemos ir um passo adiante e solicitar o .amount (ou qualquer outro valor do índice do JSON) dos UTXOs que estamos recuperando.
Agora podemos ir um passo adiante e solicitar o .amount (ou qualquer outro par índice-valor do JSON) dos UTXOs que estamos recuperando.
Este exemplo repete o uso dos arrays ```$usedtxid``` e ```$usedvout``` definidos da seguinte forma:
@ -348,13 +348,13 @@ $ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i
1.3
```
Perfeito!
Ufa!
## Usando o JQ para cálculos complexos
## Usando JQ Para Cálculos Complexos
**Caso de uso:** _Calcular a taxa de uma transação._
**Caso de Uso:** _Calcular a taxa de uma transação._
Descobrir a taxa de transação completa neste ponto requer apenas mais um pouco de matemática: Bastando determinar quanto dinheiro está passando pelo .vout. Este é um uso simples de JQ onde apenas usamos o ```awk``` para somar o ```valor``` de todas as informações do ```vout```:
Descobrir a taxa completa de transação neste ponto requer apenas mais um pouco de matemática: basta determinar quanto dinheiro está passando pelo .vout. Este é um uso simples de JQ onde apenas usamos o ```awk``` para somar o ```value``` de todas as informações do ```vout```:
```
$ bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vout [] | .value' | awk '{s+=$1} END {print s}'
@ -362,7 +362,7 @@ $ bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vout [] | .value' | awk
```
Para completar o cálculo da taxa de transação, vamos subtrair o .vout .amount (1.045) do .vin .amount (1.3).
Para fazer isso, precisaremos instalar o ```bc```:
Para fazer isso, precisaremos instalar ```bc```:
```
$ sudo apt-get intall bc
@ -379,15 +379,15 @@ $ echo "$btcin-$btcout"| /usr/bin/bc
.255
```
E esse também é um bom exemplo de por que precisamos verificar nossas suas taxas: Pretendíamos enviar uma taxa de transação com 5.000 satoshis, mas invés disso enviamos pagando 255.000 satoshis de taxa. Ops!
E esse também é um bom exemplo de por que precisamos verificar nossas taxas: pretendíamos enviar uma taxa de transação com 5.000 satoshis, mas invés disso enviamos pagando 255.000 satoshis de taxa. Ops!
> :warning: **Atenção:** A primeira vez que escrevemos esta lição, realmente calculamos mal a nossa taxa e não a vimos até que executamos nossa calculadora de taxas. É *tão* fácil, que nosso dinheiro acabou. (O exemplo acima é, na verdade, de nossa segunda iteração da calculadora, e dessa vez cometemos o erro de propósito).
> :warning: **ATENÇÃO:** A primeira vez que escrevemos esta lição, realmente calculamos mal a nossa taxa e não a vimos até que executamos nossa calculadora de taxas. É *tão* fácil, que nosso dinheiro acabou. (O exemplo acima é, na verdade, de nossa segunda iteração da calculadora, e dessa vez cometemos o erro de propósito).
Para mais magia usando o JSON (e se alguma coisa não estiver clara), leia o [Manual JSON](https://stedolan.github.io/jq/manual/) e o [Livro de Receitas do JSON](https://github.com/stedolan/jq/wiki/Cookbook). Estaremos usando o JQ regularmente nos exemplos futuros.
Para mais magia usando o JQ (e se alguma coisa não estiver clara), leia o [Manual JQ](https://stedolan.github.io/jq/manual/) e o [Livro de Receitas do JQ](https://github.com/stedolan/jq/wiki/Cookbook). Estaremos usando o JQ regularmente nos exemplos futuros.
## Fazendo alguns aliases novos
## Fazendo Alguns Aliases Novos
O código JQ pode ser um pouco pesado, então devemos considerar adicionar algumas invocações mais longas e interessantes ao nosso ```~/.bash_profile```.
Código em JQ pode ser um pouco pesado, então devemos considerar adicionar algumas invocações mais longas e interessantes ao nosso ```~/.bash_profile```.
Sempre que estivermos procurando por uma grande massa de informações em uma saída de objeto JSON por um comando ```bitcoin-cli```, precisamos considerar escrever um alias para reduzi-lo exatamente ao que desejamos observar.
@ -395,11 +395,11 @@ Sempre que estivermos procurando por uma grande massa de informações em uma sa
alias btcunspent="bitcoin-cli listunspent | jq -r '.[] | { txid: .txid, vout: .vout, amount: .amount }'"
```
## Executando o script de taxa de transação
## Executando o Script de Taxa de Transação
O [script de cálculo de taxa](src/04_2_i_txfee-calc.sh) está disponível no diretório src/. Você pode baixá-lo e salvá-lo como ```txfee-calc.sh```.
O [Script de Cálculo de Taxa](src/04_2_i_txfee-calc.sh) está disponível no diretório `src/`. Você pode baixá-lo e salvá-lo como ```txfee-calc.sh```.
> :warning: **Atenção:** Este script não foi verificado extensivamente. Se for usá-lo para verificar as taxas de transação reais, só deve fazê-lo depois de fazer uma verificação pessoal dos valores.
> :warning: **ATENÇÃO:** Este script não foi verificado extensivamente. Se for usá-lo para verificar as taxas de transação reais, só deve fazê-lo depois de fazer uma verificação pessoal dos valores.
Certifique-se de que as permissões no script estejam corretas:
@ -407,7 +407,7 @@ Certifique-se de que as permissões no script estejam corretas:
$ chmod 755 txfee-calc.sh
```
Podemos então, executar o script da seguinte maneira:
Podemos, então, executar o script da seguinte maneira:
```
$ ./txfee-calc.sh $rawtxhex
@ -420,10 +420,10 @@ Também podemos criar um alias:
alias btctxfee="~/txfee-calc.sh"
```
## Resumo do Usando o JQ
## Resumo: Usando JQ
O JQ facilita a extração de informações de arrays e objetos JSON. Ele também pode ser usado em scripts shell para cálculos bastante complexos que tornarão nossa vida mais fácil.
## O que vem depois?
## O Que Vem Depois?
Continue "Enviando Transações de Bitcoin" na sessão [§4.3 Criando uma transação bruta com argumentos nomeados](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md).
Continue "Enviando Transações no Bitcoin" na sessão [§4.3 Criando uma Transação Bruta com Argumentos Nomeados](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md).