mirror of
https://github.com/ChristopherA/Learning-Bitcoin-from-the-Command-Line.git
synced 2025-06-07 07:56:31 +00:00
Revert "Chapter 04 translated"
This reverts commit 8b3b5688505007c360cdc84ea6585c64f873da40.
This commit is contained in:
parent
8b3b568850
commit
9712478a77
@ -1,30 +0,0 @@
|
||||
|
||||
# Capítulo 4: Enviando transações no Bitcoin
|
||||
|
||||
Este capítulo descreve três métodos diferentes para enviar bitcoins para endereços P2PKH normais à partir da linha de comando, usando apenas o ```bitcoin-cli```.
|
||||
|
||||
## Objetivos deste capítulo
|
||||
|
||||
Depois de trabalhar neste capítulo, um desenvolvedor será capaz de:
|
||||
|
||||
* Decidir como enviar dinheiro usando o Bitcoin;
|
||||
* Criar uma transação bruta;
|
||||
* Usar a aritmética para calcular as taxas.
|
||||
|
||||
Os objetivos secundários incluem a capacidade de:
|
||||
|
||||
* Compreender transações e taxas de transação;
|
||||
* Entender as transações ```legacy``` e ```SegWit```;
|
||||
* Usar métodos básicos para enviar dinheiro;
|
||||
* Usar métodos de cálculo de taxa automática para enviar dinheiro;
|
||||
* Entender os perigos de transações brutas.
|
||||
|
||||
## Tabela de Conteúdo
|
||||
|
||||
* [Seção 1: Enviando bitcoins no modo easy](04_1_Sending_Coins_The_Easy_Way.md)
|
||||
* [Seção 2: Criando uma transação bruta](04_2_Creating_a_Raw_Transaction.md)
|
||||
* [Prefácio: Usando o JQ](04_2__Interlude_Using_JQ.md)
|
||||
* [Seção 3: Criando uma transação bruta com argumentos nomeados](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md)
|
||||
* [Seção 4: Enviando bitcoins usando transações brutas](04_4_Sending_Coins_with_a_Raw_Transaction.md)
|
||||
* [Seção 5: Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md)
|
||||
* [Seção 6: Criando uma transação do tipo SegWit](04_6_Creating_a_Segwit_Transaction.md)
|
@ -1,102 +0,0 @@
|
||||
# 4.1: Enviando bitcoins no modo easy
|
||||
|
||||
O ```bitcoin-cli``` oferece três principais maneiras de enviar bitcoins: Utilizando um simples comando; Utilizando uma transação bruta e; Utilizando uma transação bruta com cálculos. Cada um possui seus prós e contras. Este primeiro método de envio será o mais simples.
|
||||
|
||||
## Definindo sua taxa de transação
|
||||
|
||||
Antes de enviar qualquer bitcoin pela rede, devemos pensar sobre as taxas de transação que iremos pagar.
|
||||
|
||||
> :book: ***O que é uma taxa de transação?*** Não existe almoço grátis. Os mineradores adicionam as transações nos blocos porque são pagos para fazer isso. Eles não apenas são pagos pela rede para criar o bloco, mas também são pagos pelas pessoas que realizam as transações para incluí-las na blockchain. Se não pagarmos a taxa, nossa transação pode ficar travada... Para sempre (ou, até que seja salva por alguns dos truques que falaremos no [capítulo cinco](05_0_Controlling_Bitcoin_Transactions.md)).
|
||||
|
||||
Ao usar métodos simples e automatizados para criar transações, conforme descrito aqui e na sessão [§4.5: Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md), o Bitcoin calculará as taxas de transação para nós. Isso é feito usando taxas flutuantes, onde o ```bitcoind``` observa quanto tempo as transações estão demorando para confirmar e calcula automaticamente o que devemos gastar.
|
||||
|
||||
Podemos ter um controle dessas informações colocando os valores racionais no nosso arquivo ```~/.bitcoin/bitcoin.conf```. Os valores de baixo custo a seguir garantiriam que houvesse uma taxa de transação mínima de 10.000 satoshis por kByte de dados em nossa transação e solicitariam que as taxas flutuantes calculassem uma boa quantia para colocar a nossa transação nos próximos seis blocos.
|
||||
```
|
||||
mintxfee=0.0001
|
||||
txconfirmtarget=6
|
||||
```
|
||||
No entanto, como iremos partir do pressuposto que ninguém que esteja fazendo este tutorial queira esperar para as transações serem confirmadas, vamos adotar os seguintes valores:
|
||||
```
|
||||
mintxfee=0.001
|
||||
txconfirmtarget=1
|
||||
```
|
||||
Devemos inseri-los no arquivo ```~/.bitcoin/bitcoin.conf```, na seção principal, no início do arquivo ou se quisermos ter a certeza de nunca iremos utilizá-lo em outro lugar, podemos colocar na sessão ```[test]```.
|
||||
|
||||
Para trabalharmos neste tutorial, estamos dispostos a gastar 100.000 satoshis por kB em cada transação, e queremos colocar cada transação no próximo bloco! Para colocar isso em uma perspectiva para melhor entendimento, uma transação simples é executada com um tamanho de 0,25 KB a 1 KB, então estaremos pagando algo em torno de 25 mil a 100 mil satoshis, sendo que atualmente, taxas acima de 10 mil são consideradas altíssimas para transações de quantidade média.
|
||||
|
||||
Depois de editar o arquivo ```bitcoin.conf```, vamos reiniciar o bitcoind usando dois comandos:
|
||||
```
|
||||
$ bitcoin-cli stop
|
||||
$ bitcoind -daemon
|
||||
```
|
||||
|
||||
## Obtendo um endereço
|
||||
|
||||
Precisamos encontrar algum endereço para enviar nossas moedas. Normalmente, alguém nos envia em um endereço e talvez nos dê uma assinatura para provar que é o proprietário desse endereço. Como alternativa, podemos nos fornecer um QR code para que possamos digitalizar, evitando assim possíveis erros de digitação na hora de colocar o endereço no local do destinatário. Em nosso caso, vamos enviar os bitcoins para `n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi`, que é o endereço de retorno de um antigo fauce da rede Testenet.
|
||||
|
||||
> :book: ***O que é um QR code?*** Um QR code é apenas um jeito diferente de passar o endereço Bitcoin. Muitas carteiras geram os QR codes para nós, enquanto alguns sites tentam convertê-los em um endereço usando o QR code. Obviamente, só podemos aceitar um QR code de um site no qual confiamos. Um pagador pode usar um leitor de código de barras para ler o código QR e, em seguida, pagá-lo.
|
||||
|
||||
## Enviando os bitcoins
|
||||
|
||||
Agora estamos prontos para enviar alguns bitcoins. Na verdade, isso é bastante simples por meio da linha de comando. Basta usar ```bitcoin-cli sendtoaddress [endereço] [quantidade]```. Portanto, para enviar uns satoshinhos para o endereço `n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi`, basta fazer o seguinte:
|
||||
```
|
||||
$ txid=$(bitcoin-cli sendtoaddress n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi 0.001)
|
||||
$ echo $txid
|
||||
93250d0cacb0361b8e21030ac65bc4c2159a53de1075425d800b2d7a8ab13ba8
|
||||
```
|
||||
|
||||
> 🙏 Para ajudar a manter os faucets da rede de testes vivos, tente usar o endereço que nos foi enviado os bitcoins no capítulo anterior, onde falamos sobre os recebimentos de transações.
|
||||
|
||||
Precisamos nos certificar de que o endereço digitado é o lugar para onde desejamos enviá-lo. Por isso, certifique-se _duas vezes_. Se cometermos algum erro no Bitcoin, não há como voltar atrás.
|
||||
|
||||
Iremos receber um txid de retorno quando usarmos este comando.
|
||||
|
||||
> ❕ Você pode acabar com um código de erro se não tivermos bitcoins suficientes na carteira para fazer a transação. Dependendo do nosso saldo atual, que podemos acessar usando o ```bitcoin-cli getbalance```, pode ser necessário ajustar o valor que iremos enviar para que bata com o valor que está sendo enviado, não se esquecendo da taxa de transação no meio deste processo. Se o nosso saldo atual for 0,001, podemos tentar enviar 0,0001. Como alternativa, seria melhor tirar a taxa que esperamos pagar que foi enviada na mensagem de erro do nosso saldo atual. Esta é uma boa prática, pois muitas carteiras esperam que calculemos nosso próprio valor + taxas ao fazermos as transações, mesmo as carteiras mais populares usam essa premissa.
|
||||
|
||||
> :warning: **ATENÇÃO:** O comando ```bitcoin-cli``` realmente gera comandos usando o JSON-RPC quando está se comunicando com o bitcoind. Eles podem ser muito exigentes. Este é um exemplo: Se listarmos a quantidade de bitcoin sem o zero à esquerda (ou seja usando ".1" em vez de "0.1"), o ```bitcoin-cli``` irá acusar um erro com uma mensagem misteriosa.
|
||||
|
||||
> :warning: **ATENÇÃO:** Mesmo se formos cuidadosos com nossos dados, é possível que haja este erro: _"Fee estimation failed. Fallbackfee is disabled"_. De maneira geral, isso significa que nosso ```bitcoind``` local não tem informações suficientes para estimar as taxas. Não é para vermos isso se estivermos esperado que nossa blockchain sincronize e configure nosso sistema com o Bitcoin Standup. Mas se não estivermos totalmente sincronizados, podemos nos deparar com este erro. Também pode ser que não estejamos usando um ```bitcoin.conf``` padrão: A informação ```blocksonly = 1``` fará com que nosso ```bitcoind``` não consiga estimar as taxas.
|
||||
|
||||
## Examinando nossa transação
|
||||
|
||||
Podemos ver nossa transação usando o ID de transação:
|
||||
```
|
||||
{
|
||||
"amount": -0.00100000,
|
||||
"fee": -0.00022200,
|
||||
"confirmations": 0,
|
||||
"trusted": true,
|
||||
"txid": "93250d0cacb0361b8e21030ac65bc4c2159a53de1075425d800b2d7a8ab13ba8",
|
||||
"walletconflicts": [
|
||||
],
|
||||
"time": 1592604194,
|
||||
"timereceived": 1592604194,
|
||||
"bip125-replaceable": "no",
|
||||
"details": [
|
||||
{
|
||||
"address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi",
|
||||
"category": "send",
|
||||
"amount": -0.00100000,
|
||||
"vout": 1,
|
||||
"fee": -0.00022200,
|
||||
"abandoned": false
|
||||
}
|
||||
],
|
||||
"hex": "0200000001e982921bb0189afc486e20bb05cc5825c71a0ba8868043ed04ece9ab0cb12a8e010000006a47304402200fc493a01c5c9d9574f7c321cee6880f7f1df847be71039e2d996f7f75c17b3d02203057f5baa48745ba7ab5f1d4eed11585bd8beab838b1ca03a4138516fe52b3b8012102fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9bafeffffff02e8640d0000000000160014d37b6ae4a917bcc873f6395741155f565e2dc7c4a0860100000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac780b1b00"
|
||||
}
|
||||
```
|
||||
Você pode ver não apenas o valor transferido (0,001 BTC), mas também uma taxa de transação (0,000222 BTC), que é cerca de um quarto da taxa mínima de 0,001 BTC/kB que foi definida, o que sugere que a transação foi de cerca de um quarto de kB de tamanho.
|
||||
|
||||
Enquanto esperamos que ela seja confirmada, podemos notar que o ```bitcoin-cli getbalance``` mostra que nosso dinheiro já foi debitado. Da mesma forma, o ```bitcoin-cli listunspent``` mostrará que uma transação inteira foi perdida, mesmo que fosse mais do que o que queríamos enviar. Há uma razão para isso: Sempre que temos moedas entrando, precisamos enviar _tudo_ junto, e temos que fazer um pouco de malabarismos se quisermos realmente ficar com parte dele! Mais uma vez, o ```sendtoaddress``` cuida de tudo isso para nós, o que significa que não precisamos nos preocupar em fazer qualquer alteração até enviar uma transação bruta. Nesse caso, uma nova transação aparecerá com nossa alteração quando nosso envio for incorporado a um bloco.
|
||||
|
||||
## Resumo do Enviando bitcoins no modo easy
|
||||
|
||||
Para enviar moedas facilmente, precisamos nos certificar de que nossos padrões de transação sejam racionais, obtendo um endereço e enviando as nossas moedas para lá. É por isso que esse modo é o mais fácil deles!
|
||||
|
||||
> :fire: ***Qual é o poder de enviar moedas no modo easy?***
|
||||
> _As vantagens._ É fácil. Não precisamos nos preocupar com coisas misteriosas como UTXOs. Não precisamos calcular as taxas de transação manualmente, então, é provável que não iremos cometer erros que custem grandes valores Se o nosso único objetivo é sentar na frente do computador e enviar alguns bitcoins, este é o caminho certo para fazer isso.
|
||||
> _As desvantagens._ É alto nível. Temos muito pouco controle sobre o que está acontecendo e não podemos fazer nada demais. Se estamos planejando desenvolver um software mais complexo utilizando o Bitcoin ou se desejamos um entendimento mais profundo de como o Bitcoin funciona, então o modo easy é apenas um carrossel sem graça antes de chegarmos nas montanhas russas.
|
||||
|
||||
## O Que Vem Depois?
|
||||
|
||||
Vamos continuar "Enviando Transações de Bitcoin" na sessão [§4.2 Criando uma transação bruta](04_2_Creating_a_Raw_Transaction.md).
|
@ -1,274 +0,0 @@
|
||||
# 4.2 Criando uma transação bruta
|
||||
|
||||
Agora estamos pronto para criar transações brutas no Bitcoin. Isso permite que enviemos dinheiro, mas criemos as transações com a precisão desejada. Nesta primeira seção, iremos nos concentrar em uma transação simples de uma entrada e uma saída. Este tipo de transação _não_ é realmente útil, porque raramente vamos querer enviar todo o nosso dinheiro para uma pessoa (a menos que estejamos apenas encaminhando, como se estivesse movendo coisas de uma carteira para outra). Portanto, esse _não é o melhor método_ para enviar dinheiro. É apenas um conteúdo fundamental para _realmente_ enviar dinheiro com uma transação bruta.
|
||||
|
||||
## Compreendendo a transação no Bitcoin
|
||||
|
||||
Antes de mergulhar na criação de transações brutas, devemos nos certificar de que entendemos como uma transação no Bitcoin funciona. Tudo gira entorno dos UTXOs.
|
||||
|
||||
> :book: ***O que é um UTXO?*** Quando recebemos dinheiro em nossa carteira Bitcoin, ele aparece como uma transação individual. Cada uma dessas transações é chamada de saída de transação não gasta (Unspent Transaction Output em inglês, mais conhecida como UTXO). Não importa se vários pagamentos foram feitos para o mesmo endereço ou para vários endereços: Cada transação recebida permanece distinta na carteira como um UTXO.
|
||||
|
||||
Ao criarmos uma nova transação de saída, reunimos um ou mais UTXOs, cada um representando um pouquinho do dinheiro que recebemos. Nós os usamos como entradas para uma nova transação. Juntos, o valor deles deve ser igual ao que desejamos gastar _ou mais do que o total_. Em seguida, geramos uma ou mais saídas, que dão o dinheiro representado pelas entradas a uma ou mais pessoas. Isso cria novos UTXOs para os destinatários, que podem então usá-los para financiar transações futuras.
|
||||
|
||||
Aqui está o truque: _Todos os UTXOs que coletarmos são gastos na íntegra!_ Isso significa que se quisermos enviar apenas parte do dinheiro em um UTXO para outra pessoa, também precisamos gerar uma saída adicional que envia o resto para nós! Por enquanto, não vamos nos preocupar com isso, mas o uso de um endereço de mudança será vital ao passar da teoria deste capítulo para transações mais práticas.
|
||||
|
||||
## Listando as transações não gastas
|
||||
|
||||
Para criar uma nova transação bruta, devemos saber quais UTXOs estão disponíveis para gastar. Podemos determinar essas informações com o comando ```bitcoin-cli listunspent```:
|
||||
```
|
||||
$ bitcoin-cli listunspent
|
||||
[
|
||||
{
|
||||
"txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36",
|
||||
"vout": 0,
|
||||
"address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE",
|
||||
"label": "",
|
||||
"scriptPubKey": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac",
|
||||
"amount": 0.00010000,
|
||||
"confirmations": 20,
|
||||
"spendable": true,
|
||||
"solvable": true,
|
||||
"desc": "pkh([d6043800/0'/0'/1']02fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9ba)#62rud39c",
|
||||
"safe": true
|
||||
},
|
||||
{
|
||||
"txid": "61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a",
|
||||
"vout": 1,
|
||||
"address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff",
|
||||
"label": "",
|
||||
"scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac",
|
||||
"amount": 0.00050000,
|
||||
"confirmations": 3,
|
||||
"spendable": true,
|
||||
"solvable": true,
|
||||
"desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y",
|
||||
"safe": true
|
||||
},
|
||||
{
|
||||
"txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c",
|
||||
"vout": 0,
|
||||
"address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff",
|
||||
"label": "",
|
||||
"scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac",
|
||||
"amount": 0.00022000,
|
||||
"confirmations": 3,
|
||||
"spendable": true,
|
||||
"solvable": true,
|
||||
"desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y",
|
||||
"safe": true
|
||||
}
|
||||
]
|
||||
|
||||
```
|
||||
Esta lista mostra três UTXOs diferentes, no valor de 0,0001, 0,0005 e 0,00022 BTC. Observe que cada um tem o próprio _txid_ distinto e permanece seperado na carteira, até mesmo os dois últimos, que foram enviados para o mesmo endereço.
|
||||
|
||||
Quando quisermos gastar um UTXO, não é suficiente apenas saber o id da transação. Isso porque cada transação pode ter várias saídas! Lembra daquele primeiro valor que o faucet nos enviou? Na transação, parte do dinheiro foi para nós e parte para outra pessoa. O ```txid``` se refere à transação geral, enquanto um ```vout``` diz qual das múltiplas saídas recebemos. Nesta lista, cada uma dessas transações é a primeira ```vout``` de uma transação anterior, mas _não necessariamente é sempre o caso_.
|
||||
|
||||
Portanto, o txid+vout=UTXO. Essa será a base de qualquer transação bruta.
|
||||
|
||||
## Escrevendo uma transação bruta com uma saída
|
||||
|
||||
You're now ready to write a simple, example raw transaction that shows how to send the entirety of a UTXO to another party. As noted, this is not necessarily a very realistic real-world case.
|
||||
Agora estamos prontos para escrever um exemplo simples de transação bruta que mostra como enviar um UTXO inteiro para outra parte. Conforme falamos anteriormente, este não é um caso muito realista.
|
||||
|
||||
> :warning: **Atenção:** É muito fácil perder dinheiro com uma transação bruta. Considere que todas as instruções sobre como enviar bitcoins por meio de transações brutas são _muito_, _muito_ perigosas. Sempre que estiver enviando moedas na _mainnet_ para outras pessoas, devemos usar um dos outros métodos explicados neste capítulo. Criar transações brutas é extremamente útil se estivermos escrevendo programas para o bitcoin, mas _só_ neste caso. Por exemplo: Ao escrever este exemplo para uma versão anterior deste tutorial, acidentalmente gastamos a transação errada, embora tivessemos cerca de 10 vezes mais. Quase tudo isso foi enviado para os mineradores.
|
||||
|
||||
### Preparando a transação bruta
|
||||
|
||||
Para as melhores práticas, iremos começar cada transação registrando cuidadosamente os txids e vouts que iremos gastar.
|
||||
|
||||
Nesse caso, vamos gastar um no valor de 0,00050000 BTC porque é o único com um valor decente.
|
||||
```
|
||||
$ utxo_txid="61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a"
|
||||
$ utxo_vout="1"
|
||||
```
|
||||
Da mesma forma, devemos registrar o endereço do destinatário para ter certeza de que está correto. No nosso exemplo estamos enviando novamente o saldo de volta para o faucet:
|
||||
```
|
||||
$ recipient="n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi"
|
||||
```
|
||||
Como de prache, vamos verificar as variáveis com cuidado, para ter certeza de que são aquilo que esperamos!
|
||||
```
|
||||
$ echo $utxo_txid
|
||||
61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a
|
||||
$ echo $utxo_vout
|
||||
1
|
||||
$ echo $recipient
|
||||
n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi
|
||||
```
|
||||
Esse destinatário é particularmente importante, porque se bagunçarmos tudo, nosso dinheiro terá dado _tchau tchau_! E como já vimos, escolher a transação errada pode resultar em perda de dinheiro! Portanto, vamos verificar tudo, pelo menos uma vez mais do que a quantidade de costume.
|
||||
|
||||
### Entendendo a taxa de transação
|
||||
|
||||
Cada transação tem uma taxa associada. Ela fica _implícita_ quando enviamos uma transação bruta: O valor que vamos pagar como taxa é sempre igual ao valor de entrada menos o valor de saída. Portanto, temos que diminuir um pouco o valor enviado para ter certeza de que nossa transação será realizada.
|
||||
|
||||
> :warning: **Atenção:** Esta é a parte muito perigosa das transações brutas! Como gastamos automaticamente toda a quantidade de UTXOs que tivermos, é extremamente importante certificar-se de que sabemos: (1) Precisamente quais UTXOs estamos utilizando; (2) Exatamente quanto dinheiro ele possui; (3) Exatamente quanto dinheiro estamos enviando; e (4) qual é a diferença que ficará para os mineradores. Se errarmos e, por exemplo, usarmos o UTXO errado (um que tenha mais dinheiro do que pensávamos) ou se enviarmos muito pouco dinheiro, o excesso será perdido. _Para sempre_! Não podemos cometer esse erro! Por isso, é importante sabermos as entradas e saídas com _precisão_. Ou melhor, não utilizarmos as transações brutas, exceto como parte de um programa cuidadosamente considerado e verificado três vezes.
|
||||
|
||||
> :book: ***Quanto devemos gastar com taxas de transação?*** [Bitcoin Fees](https://bitcoinfees.21.co/) tem uma ótima avaliação ao vivo. O site diz que "fastest and cheapest transaction fee is currently XXX satoshis/byte" onde o XXX será a quantidade de satoshis por byte que precisaremos pagar e também, "For the median transaction size of YYY bytes, this results in a fee of ZZ,ZZZ satoshis", onde YYY é o tamanho de uma transação média e ZZ,ZZZ é o resultado da multiplicação entre YYY e XXX. No caso, precisamos apenas observar o valor ZZ,ZZZ descrito no site.
|
||||
|
||||
No momento em que este tutorial está sendo escrito, o _Bitcoin Fees_ sugere uma taxa de transação de cerca de 10.000 satoshis, que é o mesmo que 0,0001 BTC. Obviamente, isso é para a mainnet, não para a testnet, mas queremos testar as coisas de forma realista, então iremos utilizar esta quantidade.
|
||||
|
||||
Nesse caso, isso vamos pegar 0,0005 BTC no UTXO que selecionamos, reduzindo a quantidade de 0,0001 BTC para a taxa de transação e enviar os 0,0004 BTC restantes. E este é um exemplo do porque os micropagamentos não funcionam na rede principal do Bitcoin, porque uma taxa de transação que consome 20% do valor enviado é muito cara, agora imagina se os valores forem menores do que a taxa de transação. Por isso que temos a Lightning.
|
||||
|
||||
> :warning: **Atenção:** Quanto menor for a taxa de transação, mais tempo irá demorar para que nossa transação entre na blockchain. O site _Bitcoin Fees_ lista os tempos que precisaremos esperar em relação a quantidade de satoshi por byte. Como os blocos são construídos em média a cada 10 minutos, a mudança de taxa pode significar uma mudança de espera de minutos para algumas horas ou dias! Portanto, escolha uma taxa de transação apropriada para o que estamos enviando. É importante observar que nunca devemos colocar taxas abaixo da quantidade mínima para transação, que é 0,0001 BTC.
|
||||
|
||||
### Escrevendo a transação bruta
|
||||
|
||||
Agora estamos prontos para criar a transação bruta. Usaremos o comando ```createrawtransaction```, que pode parecer um pouco intimidante. Isso porque o comando ```createrawtransaction``` não o protege inteiramente do JSON RPC que o ```bitcoin-cli``` utiliza. Ao invés disso, vamos inserir uma matriz JSON para listar os UTXOs que está gastando e um objeto JSON para listar as saídas.
|
||||
|
||||
Este é o formato padrão:
|
||||
```
|
||||
$ bitcoin-cli createrawtransaction
|
||||
'''[
|
||||
{
|
||||
"txid": "'$your_txid'",
|
||||
"vout": '$your_vout'
|
||||
}
|
||||
]'''
|
||||
'''{
|
||||
"'$your_recipient'": bitcoin_amount
|
||||
}'''
|
||||
```
|
||||
|
||||
Não, não é um erro de digitação. Existem todos os tipos de citações malucas, mas confie que elas farão a coisa certa. Vamos usar `'''` para marcar o início e o fim do array e no objeto JSON. Protegendo as palavras normais como ```"this"```, mas não precisamos proteger os números: ```0```. Se forem variáveis, vamos inserir as aspas simples, como ```"'$this_word'"``` e ```'$this_num'```. (Ufa! Não se preocupe, você pega o jeito).
|
||||
|
||||
Aqui está um comando que cria uma transação bruta para enviar $utxo para o $recipient.
|
||||
```
|
||||
$ rawtxhex=$(bitcoin-cli createrawtransaction '''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' '''{ "'$recipient'": 0.0004 }''')
|
||||
$ echo $rawtxhex
|
||||
02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f3610100000000ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000
|
||||
```
|
||||
|
||||
### Verificando a transação bruta
|
||||
|
||||
Depois disso, devemos verificar a transação bruta com o comando ```decoderawtransaction``` para ter certeza de que faremos a coisa certa.
|
||||
```
|
||||
$ bitcoin-cli decoderawtransaction $rawtxhex
|
||||
{
|
||||
"txid": "dcd2d8f0ec5581b806a1fbe00325e1680c4da67033761b478a26895380cc1298",
|
||||
"hash": "dcd2d8f0ec5581b806a1fbe00325e1680c4da67033761b478a26895380cc1298",
|
||||
"version": 2,
|
||||
"size": 85,
|
||||
"vsize": 85,
|
||||
"weight": 340,
|
||||
"locktime": 0,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a",
|
||||
"vout": 1,
|
||||
"scriptSig": {
|
||||
"asm": "",
|
||||
"hex": ""
|
||||
},
|
||||
"sequence": 4294967295
|
||||
}
|
||||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.00040000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG",
|
||||
"hex": "76a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac",
|
||||
"reqSigs": 1,
|
||||
"type": "pubkeyhash",
|
||||
"addresses": [
|
||||
"n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
É importante verificarmos o ```vin```. Estamos gastando a transação certa? Ela contém a quantia de dinheiro esperada? (Vamos verificar com o comando ```bitcoin-cli gettransaction``` e nos certificar de olhar o ```vout``` se está correto). Além disso, vamos verificar o nosso ```vout```. Estamos enviando a quantidade correta? Está indo para o endereço certo? Finalmente, vamos fazer as contas para ter certeza de que o dinheiro que irá para as taxas está correto. O valor do UTXO menos a quantia que está sendo gasta é igual à taxa da transação esperada?
|
||||
|
||||
> :information_source: **NOTA:** Podemos notar que cada entrada tem um número de sequência, definido aqui como 4294967295, que é 0xFFFFFFFF. Esta é a última fronteira das transações Bitcoin, porque é um campo padrão em transações que foram originalmente planejadas para um propósito específico, mas nunca foram totalmente implementadas. Portanto, agora existe esse inteiro parado em transações que podem ser reaproveitadas para outros usos. E, de fato, tem sido. No momento em que este livro foi escrito, havia três usos diferentes para a variável chamada ```nSequence``` no código Bitcoin Core: Ela habilita a possibilidade de RBF, ```nLockTime``` e timelocks relativos. Se não houver nada de estranho acontecendo, o ```nSequence``` será definido como 4294967295. Ajustar para um valor mais baixo sinaliza que coisas especiais estão acontecendo.
|
||||
|
||||
### Assinando a transação bruta
|
||||
|
||||
Até o momento, nossa transação bruta é apenas uma teoria: _Podemos_ enviá-la, mas nada irá acontecer. Precisamos fazer algumas coisas para colocá-la na rede.
|
||||
|
||||
Primeiro, precisamos assinar nossa transação bruta:
|
||||
```
|
||||
|
||||
$ bitcoin-cli signrawtransactionwithwallet $rawtxhex
|
||||
{
|
||||
"hex": "02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000",
|
||||
"complete": true
|
||||
}
|
||||
$ signedtx="02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000"
|
||||
```
|
||||
Observe que capturamos o hexadecimal assinado manualmente, ao invés de tentar analisá-lo a partir do objeto JSON. Um pacote de software chamado "JQ" poderia ter um desempenho melhor, como explicaremos no próximo prefácio.
|
||||
|
||||
### Enviando a transação bruta
|
||||
|
||||
Agora temos uma transação bruta pronta para ser usada, mas nada acontece com ela se não a colocarmos na rede, o que iremos fazer com o comando ```sendrawtransaction```. O retorno dele será uma txid:
|
||||
```
|
||||
$ bitcoin-cli sendrawtransaction $signedtx
|
||||
a1fd550d1de727eccde6108c90d4ffec11ed83691e96e119d842b3f390e2f19a
|
||||
```
|
||||
Iremos observar imediatamente que o UTXO e o as nossas moedas foram removidas da nossa carteira:
|
||||
```
|
||||
$ bitcoin-cli listunspent
|
||||
[
|
||||
{
|
||||
"txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36",
|
||||
"vout": 0,
|
||||
"address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE",
|
||||
"label": "",
|
||||
"scriptPubKey": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac",
|
||||
"amount": 0.00010000,
|
||||
"confirmations": 23,
|
||||
"spendable": true,
|
||||
"solvable": true,
|
||||
"desc": "pkh([d6043800/0'/0'/1']02fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9ba)#62rud39c",
|
||||
"safe": true
|
||||
},
|
||||
{
|
||||
"txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c",
|
||||
"vout": 0,
|
||||
"address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff",
|
||||
"label": "",
|
||||
"scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac",
|
||||
"amount": 0.00022000,
|
||||
"confirmations": 6,
|
||||
"spendable": true,
|
||||
"solvable": true,
|
||||
"desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y",
|
||||
"safe": true
|
||||
}
|
||||
]
|
||||
|
||||
$ bitcoin-cli getbalance
|
||||
0.00032000
|
||||
```
|
||||
Logo o ```listtransactions``` deve mostrar uma transação confirmada da categoria 'send'.
|
||||
```
|
||||
{
|
||||
"address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi",
|
||||
"category": "send",
|
||||
"amount": -0.00040000,
|
||||
"vout": 0,
|
||||
"fee": -0.00010000,
|
||||
"confirmations": 1,
|
||||
"trusted": true,
|
||||
"txid": "a1fd550d1de727eccde6108c90d4ffec11ed83691e96e119d842b3f390e2f19a",
|
||||
"walletconflicts": [
|
||||
],
|
||||
"time": 1592608574,
|
||||
"timereceived": 1592608574,
|
||||
"bip125-replaceable": "no",
|
||||
"abandoned": false
|
||||
}
|
||||
```
|
||||
Podemos observar que ele corresponde aos endereços ```txid``` e ```recipient``` (recebedor). Não só mostra o ```amount``` (montante) enviado, mas também mostra a ```fee``` (taxa) da transação. E, a transação já recebeu uma confirmação, porque oferecemos uma taxa que seria colocado no próximo bloco.
|
||||
|
||||
Parabéns! Estamos um pouco mais pobres agora!
|
||||
|
||||
## Resumo do Criando uma transação bruta
|
||||
|
||||
Quando satoshinhos entram na nossa carteira Bitcoin, eles permanecem em quantidades distintas, chamadas de UTXOs. Ao criar uma transação bruta para enviar as moedas, usamos um ou mais UTXOs para financiá-la. Podemos então, criar uma transação bruta, assiná-la e enviá-la pela rede Bitcoin. No entanto, esta é apenas uma base do que realmente acontece: Geralmente precisaremos criar uma transação bruta com várias saídas para realmente enviar algo na rede Bitcoin!
|
||||
|
||||
## O que vem depois?
|
||||
|
||||
Vamos fazer uma pausa do "Enviando transações de Bitcoin" para lermos o [Interlúdio: Usando JQ](04_2__Interlude_Using_JQ.md).
|
@ -1,429 +0,0 @@
|
||||
# Prefácio: Usando o 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.
|
||||
|
||||
## Instalando o 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.
|
||||
|
||||
Depois de baixar o binário, podemos instalá-lo em nosso sistema. Se estivermos trabalhando em um VPS Debian, fazendo o passo a passo desse curso, nossa instalação será parecida com esta:
|
||||
```
|
||||
$ 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".
|
||||
|
||||
## Usando o JQ para acessar um valor do objeto JSON pelo índice
|
||||
|
||||
**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:
|
||||
```
|
||||
$ bitcoin-cli signrawtransactionwithwallet $rawtxhex
|
||||
{
|
||||
"hex": "02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000",
|
||||
"complete": true
|
||||
}
|
||||
```
|
||||
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 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:
|
||||
```
|
||||
$ signedtx=$(bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex')
|
||||
$ echo $signedtx
|
||||
02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000
|
||||
```
|
||||
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
|
||||
|
||||
**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?
|
||||
|
||||
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.
|
||||
```
|
||||
$ bitcoin-cli listunspent | jq -r '.[1]'
|
||||
{
|
||||
"txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c",
|
||||
"vout": 0,
|
||||
"address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff",
|
||||
"label": "",
|
||||
"scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac",
|
||||
"amount": 0.00022,
|
||||
"confirmations": 9,
|
||||
"spendable": true,
|
||||
"solvable": true,
|
||||
"desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y",
|
||||
"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```:
|
||||
```
|
||||
$ bitcoin-cli listunspent | jq -r '.[1] | .txid'
|
||||
91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c
|
||||
```
|
||||
Observe cuidadosamente como os ```''``` circundam toda a expressão JQ _incluindo_ o pipe.
|
||||
|
||||
Este método pode ser usado para preencher variáveis para um UTXO que desejamos utilizar:
|
||||
```
|
||||
$ newtxid=$(bitcoin-cli listunspent | jq -r '.[1] | .txid')
|
||||
$ newvout=$(bitcoin-cli listunspent | jq -r '.[1] | .vout')
|
||||
$ echo $newtxid
|
||||
91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c
|
||||
$ echo $newvout
|
||||
0
|
||||
```
|
||||
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
|
||||
|
||||
**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:
|
||||
```
|
||||
$ bitcoin-cli listunspent | jq -r '.[] | .amount'
|
||||
0.0001
|
||||
0.00022
|
||||
```
|
||||
|
||||
## Usando o JQ para cálculos simples usando índices
|
||||
|
||||
**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```:
|
||||
```
|
||||
$ bitcoin-cli listunspent | jq -r '.[] | .amount' | awk '{s+=$1} END {print s}'
|
||||
0.00032
|
||||
$ bitcoin-cli getbalance
|
||||
0.00032000
|
||||
```
|
||||
|
||||
## Usando o JQ para exibir vários valores de um objeto JSON em um array usando vários índice
|
||||
|
||||
**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.
|
||||
|
||||
Por exemplo, podemos querer ver uma lista de todos os nossos UTXOs (```. []```) E obter uma lista de todas as informações mais importantes (```.txid, .vout, .amount```):
|
||||
```
|
||||
$ bitcoin-cli listunspent | jq -r '.[] | .txid, .vout, .amount'
|
||||
ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36
|
||||
0
|
||||
0.0001
|
||||
91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c
|
||||
0
|
||||
0.00022
|
||||
```
|
||||
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).
|
||||
|
||||
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:
|
||||
```
|
||||
$ bitcoin-cli listunspent | jq -r '.[] | { txid: .txid, vout: .vout, amount: .amount }'
|
||||
{
|
||||
"txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36",
|
||||
"vout": 0,
|
||||
"amount": 0.0001
|
||||
}
|
||||
{
|
||||
"txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c",
|
||||
"vout": 0,
|
||||
"amount": 0.00022
|
||||
}
|
||||
```
|
||||
Podemos, é claro, renomear nossos novos índices conforme acharmos necessário. Não há nada de mágico nos nomes originais:
|
||||
```
|
||||
$ bitcoin-cli listunspent | jq -r '.[] | { tx: .txid, output: .vout, bitcoins: .amount }'
|
||||
{
|
||||
"tx": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36",
|
||||
"output": 0,
|
||||
"bitcoins": 0.0001
|
||||
}
|
||||
{
|
||||
"tx": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c",
|
||||
"output": 0,
|
||||
"bitcoins": 0.00022
|
||||
}
|
||||
```
|
||||
## Usando o JQ para acessar os objetos JSON usando um valor pesquisado
|
||||
|
||||
**Caso de uso:** _Pesquisando automaticamente os UTXOs que estão sendo usados em uma transação._
|
||||
|
||||
As pesquisas JQ até agora sã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.
|
||||
|
||||
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```.
|
||||
```
|
||||
$ bitcoin-cli decoderawtransaction $rawtxhex
|
||||
{
|
||||
"txid": "6f83a0b78c598de01915554688592da1d7a3047eacacc8a9be39f5396bf0a07e",
|
||||
"hash": "6f83a0b78c598de01915554688592da1d7a3047eacacc8a9be39f5396bf0a07e",
|
||||
"size": 160,
|
||||
"vsize": 160,
|
||||
"version": 2,
|
||||
"locktime": 0,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c",
|
||||
"vout": 1,
|
||||
"scriptSig": {
|
||||
"asm": "",
|
||||
"hex": ""
|
||||
},
|
||||
"sequence": 4294967295
|
||||
},
|
||||
{
|
||||
"txid": "c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b",
|
||||
"vout": 1,
|
||||
"scriptSig": {
|
||||
"asm": "",
|
||||
"hex": ""
|
||||
},
|
||||
"sequence": 4294967295
|
||||
}
|
||||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 1.00000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DUP OP_HASH160 cfc39be7ea3337c450a0c77a839ad0e160739058 OP_EQUALVERIFY OP_CHECKSIG",
|
||||
"hex": "76a914cfc39be7ea3337c450a0c77a839ad0e16073905888ac",
|
||||
"reqSigs": 1,
|
||||
"type": "pubkeyhash",
|
||||
"addresses": [
|
||||
"mzTWVv2QSgBNqXx7RC56zEhaQPve8C8VS9"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"value": 0.04500000,
|
||||
"n": 1,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DUP OP_HASH160 166692bda9f25ced145267bb44286e8ee3963d26 OP_EQUALVERIFY OP_CHECKSIG",
|
||||
"hex": "76a914166692bda9f25ced145267bb44286e8ee3963d2688ac",
|
||||
"reqSigs": 1,
|
||||
"type": "pubkeyhash",
|
||||
"addresses": [
|
||||
"mhZQ3Bih6wi7jP1tpFZrCcyr4NsfCapiZP"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Recuperando o(s) 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:
|
||||
```
|
||||
$ usedtxid1=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[0] | .txid')
|
||||
$ echo $usedtxid1
|
||||
d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c
|
||||
$ usedtxid2=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[1] | .txid')
|
||||
$ echo $usedtxid2
|
||||
c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b
|
||||
|
||||
$ usedvout1=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[0] | .vout')
|
||||
$ echo $usedvout1
|
||||
1
|
||||
$ usedvout2=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[1] | .vout')
|
||||
$ echo $usedvout2
|
||||
1
|
||||
```
|
||||
No entanto, seria melhor ter um caso geral que salvasse _automaticamente_ todos os txids de nossos UTXOs.
|
||||
|
||||
Já sabemos que podemos acessar todos os ```.txid``` usando um valor do array ```. [] ```. Podemos usar isso para criar uma pesquisa geral no .txid:
|
||||
```
|
||||
$ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid'))
|
||||
$ echo ${usedtxid[0]}
|
||||
d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c
|
||||
$ echo ${usedtxid[1]}
|
||||
c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b
|
||||
|
||||
$ usedvout=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .vout'))
|
||||
$ echo ${usedvout[0]}
|
||||
1
|
||||
$ echo ${usedvout[1]}
|
||||
1
|
||||
```
|
||||
O único truque real aqui é como salvamos as informações usando o shell bash. Ao invés de salvar em uma variável com ```$ (command)```, nós salvamos em um array com ```($ (command))```. Fomos então capazes de acessar os elementos individuais do array bash com uma construção ```$ {variable [n]}```. Ao invés disso, poderíamos acessar todo o array usando a ```$ {variable [@]}```. (E antes que diga algo, ninguém nunca disse que o bash ficaria bonito).
|
||||
|
||||
> :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)
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Para começar de forma simples, vamos selecionar os dois UTXOs, um de cada vez:
|
||||
```
|
||||
$ bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${usedtxid[0]}'")) | select(.vout | contains('${usedvout[0]}'))'
|
||||
{
|
||||
"txid": "d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c",
|
||||
"vout": 1,
|
||||
"address": "miSrC3FvkPPZgqqvCiQycq7io7wTSVsAFH",
|
||||
"scriptPubKey": "76a91420219e4f3c6bc0f6524d538009e980091b3613e888ac",
|
||||
"amount": 0.9,
|
||||
"confirmations": 6,
|
||||
"spendable": true,
|
||||
"solvable": true
|
||||
}
|
||||
$ bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${usedtxid[1]}'")) | select(.vout | contains('${usedvout[1]}'))'
|
||||
{
|
||||
"txid": "c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b",
|
||||
"vout": 1,
|
||||
"address": "mzizSuAy8aL1ytFijds7pm4MuDPx5aYH5Q",
|
||||
"scriptPubKey": "76a914d2b12da30320e81f2dfa416c5d9499d08f778f9888ac",
|
||||
"amount": 0.4,
|
||||
"confirmations": 5,
|
||||
"spendable": true,
|
||||
"solvable": true
|
||||
}
|
||||
```
|
||||
Ao invés disso, um simples bash usando um loop em ```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;
|
||||
{
|
||||
"txid": "d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c",
|
||||
"vout": 1,
|
||||
"address": "miSrC3FvkPPZgqqvCiQycq7io7wTSVsAFH",
|
||||
"scriptPubKey": "76a91420219e4f3c6bc0f6524d538009e980091b3613e888ac",
|
||||
"amount": 0.9,
|
||||
"confirmations": 7,
|
||||
"spendable": true,
|
||||
"solvable": true
|
||||
}
|
||||
{
|
||||
"txid": "c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b",
|
||||
"vout": 1,
|
||||
"address": "mzizSuAy8aL1ytFijds7pm4MuDPx5aYH5Q",
|
||||
"scriptPubKey": "76a914d2b12da30320e81f2dfa416c5d9499d08f778f9888ac",
|
||||
"amount": 0.4,
|
||||
"confirmations": 6,
|
||||
"spendable": true,
|
||||
"solvable": true
|
||||
}
|
||||
|
||||
```
|
||||
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.
|
||||
|
||||
## Usando o JSON para cálculos simples usando os valores
|
||||
|
||||
**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.
|
||||
|
||||
Este exemplo repete o uso dos arrays ```$usedtxid``` e ```$usedvout``` definidos da seguinte forma:
|
||||
|
||||
```
|
||||
$ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid'))
|
||||
$ usedvout=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .vout'))
|
||||
```
|
||||
|
||||
O mesmo script ```for``` pode ser usado para percorrer os arrays, mas com um pipe adicionado no JQ que produz o valor ```amount``` para cada um dos UTXOs selecionados.
|
||||
|
||||
```
|
||||
$ 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')) | .amount'; done;
|
||||
0.9
|
||||
0.4
|
||||
```
|
||||
|
||||
Neste ponto, podemos somar os .amounts com um script ```awk```, para realmente ver quantas moedas estão nos UTXOs gastos na transação:
|
||||
|
||||
```
|
||||
$ 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')) | .amount'; done | awk '{s+=$1} END {print s}'
|
||||
1.3
|
||||
```
|
||||
|
||||
Perfeito!
|
||||
|
||||
## Usando o JQ para cálculos complexos
|
||||
|
||||
**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```:
|
||||
|
||||
```
|
||||
$ bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vout [] | .value' | awk '{s+=$1} END {print s}'
|
||||
1.045
|
||||
```
|
||||
|
||||
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```:
|
||||
|
||||
```
|
||||
$ sudo apt-get intall bc
|
||||
```
|
||||
|
||||
Se juntarmos tudo, iremos criar uma calculadora completa com apenas um script de cinco linhas:
|
||||
|
||||
```
|
||||
$ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid'))
|
||||
$ usedvout=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .vout'))
|
||||
$ btcin=$(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')) | .amount'; done | awk '{s+=$1} END {print s}')
|
||||
$ btcout=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vout [] | .value' | awk '{s+=$1} END {print s}')
|
||||
$ 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!
|
||||
|
||||
> :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.
|
||||
|
||||
## 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```.
|
||||
|
||||
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.
|
||||
|
||||
```
|
||||
alias btcunspent="bitcoin-cli listunspent | jq -r '.[] | { txid: .txid, vout: .vout, amount: .amount }'"
|
||||
```
|
||||
|
||||
## 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```.
|
||||
|
||||
> :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:
|
||||
|
||||
```
|
||||
$ chmod 755 txfee-calc.sh
|
||||
```
|
||||
|
||||
Podemos então, executar o script da seguinte maneira:
|
||||
|
||||
```
|
||||
$ ./txfee-calc.sh $rawtxhex
|
||||
.255
|
||||
```
|
||||
|
||||
Também podemos criar um alias:
|
||||
|
||||
```
|
||||
alias btctxfee="~/txfee-calc.sh"
|
||||
```
|
||||
|
||||
## Resumo do Usando o 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?
|
||||
|
||||
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).
|
@ -1,97 +0,0 @@
|
||||
# 4.3 Criando uma transação bruta com argumentos nomeados
|
||||
|
||||
Às vezes, pode ser assustador descobrir a ordem correta dos argumentos para um comando ```bitcoin-cli```. Felizmente, podemos usar _ argumentos nomeados_ como alternativa.
|
||||
|
||||
> :warning: **AVISO DE VERSÃO:** Esta é uma inovação do Bitcoin Core v0.14.0. Se usarmos os scripts de configuração do tutorial, o que é importante fazer, precisamos verificar novamente a versão se tiver algum problema. Há também um bug no uso do comando ```createrawtransaction``` usando argumentos nomeados que presumivelmente serão corrigidos na versão 0.14.1.
|
||||
|
||||
## Criando um alias do argumento nomeado
|
||||
|
||||
Para usar um argumento nomeado, devemos executar o ```bitcoin-cli``` com o argumento ```-named```. Se planejamos fazer isso regularmente, provavelmente precisaremos criar um alias:
|
||||
```
|
||||
alias bitcoin-cli="bitcoin-cli -named"
|
||||
```
|
||||
Como de costume, isso é apenas para facilitar o uso, mas continuaremos usando todos os comandos para manter a clareza.
|
||||
|
||||
## Testando um argumento nomeado
|
||||
|
||||
Para saber quais são os nomes dos argumentos de um comando, precisamos consultar o ```bitcoin-cli help```. Ele listará os argumentos com a ordem adequada, mas agora também fornecerá nomes para cada um deles.
|
||||
|
||||
Por exemplo, `bitcoin-cli help getbalance` lista estes argumentos:
|
||||
|
||||
1. dummy [costumava ser account]
|
||||
2. minconf
|
||||
3. include_watchonly
|
||||
4. avoid_reuse
|
||||
|
||||
O exemplo seguinte mostra um uso tradicional e não intuitivo do ```getbalance``` usando o argumento de confirmação mínimo:
|
||||
```
|
||||
$ bitcoin-cli getbalance "*" 1
|
||||
```
|
||||
Com argumentos nomeados, podemos esclarecer o que estamos fazendo, o que também minimiza os erros:
|
||||
```
|
||||
$ bitcoin-cli -named getbalance minconf=1
|
||||
```
|
||||
|
||||
## Testando uma transação bruta
|
||||
|
||||
Veja como seriam os comandos para enviar uma transação bruta com argumentos nomeados:
|
||||
```
|
||||
$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid')
|
||||
$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout')
|
||||
$ recipient="n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi"
|
||||
|
||||
$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00001 }''')
|
||||
$ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex
|
||||
{
|
||||
"txid": "2b59c31bc232c0399acee4c2a381b564b6fec295c21044fbcbb899ffa56c3da5",
|
||||
"hash": "2b59c31bc232c0399acee4c2a381b564b6fec295c21044fbcbb899ffa56c3da5",
|
||||
"version": 2,
|
||||
"size": 85,
|
||||
"vsize": 85,
|
||||
"weight": 340,
|
||||
"locktime": 0,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36",
|
||||
"vout": 0,
|
||||
"scriptSig": {
|
||||
"asm": "",
|
||||
"hex": ""
|
||||
},
|
||||
"sequence": 4294967295
|
||||
}
|
||||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.00001000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG",
|
||||
"hex": "76a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac",
|
||||
"reqSigs": 1,
|
||||
"type": "pubkeyhash",
|
||||
"addresses": [
|
||||
"n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex')
|
||||
$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx
|
||||
e70dd2aa13422d12c222481c17ca21a57071f92ff86bdcffd7eaca71772ba172
|
||||
```
|
||||
Pronto! Enviamos outra transação bruta, mas desta vez usando argumentos nomeados para ter maior clareza e redução de erros.
|
||||
|
||||
> :warning: **AVISO DE VERSÃO:** É aqui que o bug no Bitcoin Core 0.14 aparece: O argumento ```inputs``` no ```createrawtransaction``` tem o nome ```transactions``` incorreto. Portanto, se estivermos no Bitcoin Core 0.14.0, substitua o argumento nomeado ```inputs``` por ```transactions``` para este e também para os exemplos futuros. No entanto, a partir do Bitcoin Core 0.14.1, esse código deve funcionar normalmente.
|
||||
|
||||
## Resumo do Criando uma transação bruta com argumentos nomeados
|
||||
|
||||
Executando o ```bitcoin-cli``` com o argumento ```-named```, podemos usar argumentos nomeados ao invés de depender de argumentos ordenados. O comando ```bitcoin-cli help``` sempre mostrará o nome correto para cada argumento. Isso pode resultar em um código mais robusto, mais fácil de ler e menos sujeito a erros.
|
||||
|
||||
_À partir de agora, usaremos argumentos nomeados para todos os exemplos futuros, para maior clareza e para estabelecer as melhores práticas. No entanto, também mostraremos todos os argumentos na ordem correta. Portanto, se preferir não usar os argumentos nomeados, apenas retire o argumento ```-named``` e todos os ```name =``` que os exemplos devem continuar funcionando corretamente._
|
||||
|
||||
## O que vem depois?
|
||||
|
||||
Continue "Enviando Transações de Bitcoin" na sessão [§4.4: Enviando bitcoins usando transações brutas](04_4_Sending_Coins_with_a_Raw_Transaction.md).
|
@ -1,187 +0,0 @@
|
||||
# 4.4: Enviando bitcoins usando transações brutas
|
||||
|
||||
Conforme observado no início deste capítulo, a interface ```bitcoin-cli``` oferece três maneiras principais de enviar moedas. A sessão [§4.1](04_1_Sending_Coins_The_Easy_Way.md) falou sobre como enviá-la pela primeira vez, usando o comando ```sendtoaddress```. Desde então, estamos construindo coisas mais detalhadas sobre como enviar moedas de uma segunda maneira, com transações brutas. A sessão [§4.2](04_2_Creating_a_Raw_Transaction.md) nos ensinou como criar uma transação bruta, um [Prefácio](04_2__Interlude_Using_JQ.md) explicou sobre o JQ e a sessão [§4.3](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md) demonstrou os argumentos nomeados.
|
||||
|
||||
Agora podemos colocá-los juntos e realmente enviar fundos usando uma transação bruta.
|
||||
|
||||
## Criando uma endereço de troco
|
||||
|
||||
Nosso exemplo de transação bruta na seção §4.2 era simples demais: Enviamos um UTXO inteiro para um novo endereço. Com mais frequência, iremos desejar enviar a alguém uma quantia em dinheiro que não corresponde a um UTXO. Mas, devemos nos lembrar que o excesso de dinheiro de um UTXO que não é enviado ao destinatário se torna apenas a taxa de transação. Então, como enviar para alguém apenas uma parte de um UTXO, enquanto guardamos o resto pra gente?
|
||||
|
||||
A solução é _enviar_ o restante dos fundos para um segundo endereço, um endereço de troco que criamos em nossa carteira especificamente para recebê-los:
|
||||
```
|
||||
$ changeaddress=$(bitcoin-cli getrawchangeaddress legacy)
|
||||
$ echo $changeaddress
|
||||
mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h
|
||||
```
|
||||
Observe que isso usa uma nova função: ```getrawchangeaddress```. É basicamente é a mesma coisa que o ```getnewaddress```, mas é otimizado para uso como um endereço de truco em uma transação bruta, portanto, não faz coisas como criar entradas em nossa lista de endereços. Selecionamos novamente o endereço ```legacy```, ao invés de usar o padrão ```bech32```, simplesmente para consistência. Esta é uma situação em que teria sido seguro gerar um endereço Bech32 padrão, apenas usando ```bitcoin-cli getrawchangeaddress```, porque ele seria enviado e recebido por nós em nosso node Bitcoin Core, que tem suporte integral a isso. Mas, estamos adiantando as coisas. Vamos mudar sobre como mudar o endereço para Bech32 na sessão [§4.6](04_6_Creating_a_Segwit_Transaction.md).
|
||||
|
||||
Agora temos um endereço adicional em nossa carteira, para que possamos receber o troco de um UTXO! Para usá-lo, precisaremos criar uma transação bruta com duas saídas.
|
||||
|
||||
## Escolhendo os UTXOs suficientes
|
||||
|
||||
Nosso exemplo de transação bruta era simples também de outra maneira: Assumia que havia dinheiro suficiente em um único UTXO para cobrir toda a transação. Frequentemente, esse será o caso, mas às vezes desejaremos criar transações que gastem mais dinheiro do que temos em um único UTXO. Para fazer isso, devemos criar uma transação bruta com duas (ou mais) entradas.
|
||||
|
||||
## Escrevendo uma transação bruta real
|
||||
|
||||
Para resumir: A criação de uma transação bruta real para enviar moedas, às vezes, requer múltiplas entradas e, quase sempre, múltiplas saídas, uma das quais é um endereço de troco. Estaremos criando esse tipo de transação mais realista, um exemplo que mostra um caso de uso da vida real, enviando fundos por meio da segunda metodologia do Bitcoin, as transações brutas.
|
||||
|
||||
Vamos usar nossos UTXOs 0 e 2:
|
||||
```
|
||||
$ bitcoin-cli listunspent
|
||||
[
|
||||
[
|
||||
{
|
||||
"txid": "0619fecf6b2668fab1308fbd7b291ac210932602a6ac6b8cc11c7ae22c43701e",
|
||||
"vout": 1,
|
||||
"address": "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d",
|
||||
"label": "",
|
||||
"scriptPubKey": "76a914ad1ed1c5971b2308f89c1362d4705d020a40e8e788ac",
|
||||
"amount": 0.00899999,
|
||||
"confirmations": 1,
|
||||
"spendable": true,
|
||||
"solvable": true,
|
||||
"desc": "pkh([d6043800/0'/0'/4']03eae28c93035f95a620dd96e1822f2a96e0357263fa1f87606a5254d5b9e6698f)#wwnfx2sp",
|
||||
"safe": true
|
||||
},
|
||||
{
|
||||
"txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c",
|
||||
"vout": 0,
|
||||
"address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff",
|
||||
"label": "",
|
||||
"scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac",
|
||||
"amount": 0.00022000,
|
||||
"confirmations": 15,
|
||||
"spendable": true,
|
||||
"solvable": true,
|
||||
"desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y",
|
||||
"safe": true
|
||||
},
|
||||
{
|
||||
"txid": "0df23a9dba49e822bbc558f15516f33021a64a5c2e48962cec541e0bcc79854d",
|
||||
"vout": 0,
|
||||
"address": "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d",
|
||||
"label": "",
|
||||
"scriptPubKey": "76a914ad1ed1c5971b2308f89c1362d4705d020a40e8e788ac",
|
||||
"amount": 0.00100000,
|
||||
"confirmations": 1,
|
||||
"spendable": true,
|
||||
"solvable": true,
|
||||
"desc": "pkh([d6043800/0'/0'/4']03eae28c93035f95a620dd96e1822f2a96e0357263fa1f87606a5254d5b9e6698f)#wwnfx2sp",
|
||||
"safe": true
|
||||
}
|
||||
]
|
||||
|
||||
```
|
||||
Em nosso exemplo, enviaremos 0,009 BTC, que é (um pouco) maior do que qualquer um de nossos UTXOs. Para isso, será necessário que os combinemos e, em seguida, vamos usar nosso endereço de troco para recuperar os fundos não gastos.
|
||||
|
||||
### Configurando as variáveis
|
||||
|
||||
Já temos as variáveis ```$changeaddress``` e ```$recipient``` dos exemplos anteriores:
|
||||
```
|
||||
$ echo $changeaddress
|
||||
mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h
|
||||
$ echo $recipient
|
||||
n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi
|
||||
```
|
||||
Também precisamos registrar o txid e vout para cada um de nossos dois UTXOs. Tendo identificado os UTXOs que queremos gastar, podemos usar as técnicas do JQ para garantir que o acesso a eles esteja livre de erros:
|
||||
```
|
||||
$ utxo_txid_1=$(bitcoin-cli listunspent | jq -r '.[0] | .txid')
|
||||
$ utxo_vout_1=$(bitcoin-cli listunspent | jq -r '.[0] | .vout')
|
||||
$ utxo_txid_2=$(bitcoin-cli listunspent | jq -r '.[2] | .txid')
|
||||
$ utxo_vout_2=$(bitcoin-cli listunspent | jq -r '.[2] | .vout')
|
||||
```
|
||||
|
||||
### Escrevendo a transação
|
||||
|
||||
Escrever a transação bruta real é surpreendentemente simples. Tudo o que precisamos fazer é incluir um objeto JSON adicional separado por vírgula na matriz JSON de entradas e um par de valores-chave adicional separado por vírgula em um objeto JSON de saídas.
|
||||
|
||||
Aqui temos um exemplo. Observe as múltiplas entradas após o argumento ```inputs``` e as múltiplas saídas após o argumento ```outputs```.
|
||||
```
|
||||
$ rawtxhex2=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$recipient'": 0.009, "'$changeaddress'": 0.0009 }''')
|
||||
```
|
||||
Fomos _muito_ cuidadosos em calcular a quantidade. Esses dois UTXOs contêm 0,00999999 BTC. Depois de enviar 0,009 BTC, teremos 0,00099999 BTC restantes. Escolhemos 0,00009999 BTC como a nossa taxa de transação. Para acomodar essa taxa, definimos o troco como sendo 0,0009 BTC. Se não tivermos prestado atenção nisso, e definido nosso troco para 0,00009 BTC, essa quantidade de BTC adicional seria enviado para os mineradores! Se tivéssemos esquecido de fazer o troco, todo o excesso teria desaparecido. Portanto, novamente, _ tenha cuidado_.
|
||||
|
||||
Felizmente, podemos verificar três vezes com o alias ```btctxfee``` do Prefácio do JQ:
|
||||
```
|
||||
$ ./txfee-calc.sh $rawtxhex2
|
||||
.00009999
|
||||
```
|
||||
|
||||
### Concluindo
|
||||
|
||||
Agora podemos assinar, selar e entregar nossa transação, e ela é sua (e do faucet):
|
||||
```
|
||||
$ signedtx2=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex2 | jq -r '.hex')
|
||||
$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx2
|
||||
e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d
|
||||
```
|
||||
|
||||
### Esperando
|
||||
|
||||
Como de costume, nossas moedas estarão no fluxo por um tempo: O troco ficará indisponível até que a transação seja realmente confirmada e um novo UTXO seja nos dado.
|
||||
|
||||
Mas, em 10 minutos ou menos (provavelmente), teremos o dinheiro restante de volta e totalmente utilizável novamente. Por enquanto, ainda precisamos esperar:
|
||||
```
|
||||
$ bitcoin-cli listunspent
|
||||
[
|
||||
{
|
||||
"txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c",
|
||||
"vout": 0,
|
||||
"address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff",
|
||||
"label": "",
|
||||
"scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac",
|
||||
"amount": 0.00022000,
|
||||
"confirmations": 15,
|
||||
"spendable": true,
|
||||
"solvable": true,
|
||||
"desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y",
|
||||
"safe": true
|
||||
}
|
||||
]
|
||||
```
|
||||
E o troco eventualmente voltará para nós:
|
||||
```
|
||||
[
|
||||
{
|
||||
"txid": "e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d",
|
||||
"vout": 1,
|
||||
"address": "mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h",
|
||||
"scriptPubKey": "76a91432db726320e4ad170c9c1ee83cd4d8a243c3435988ac",
|
||||
"amount": 0.00090000,
|
||||
"confirmations": 1,
|
||||
"spendable": true,
|
||||
"solvable": true,
|
||||
"desc": "pkh([d6043800/0'/1'/2']02881697d252d8bf181d08c58de1f02aec088cd2d468fc5fd888c6e39909f7fabf)#p6k7dptk",
|
||||
"safe": true
|
||||
},
|
||||
{
|
||||
"txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c",
|
||||
"vout": 0,
|
||||
"address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff",
|
||||
"label": "",
|
||||
"scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac",
|
||||
"amount": 0.00022000,
|
||||
"confirmations": 16,
|
||||
"spendable": true,
|
||||
"solvable": true,
|
||||
"desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y",
|
||||
"safe": true
|
||||
}
|
||||
]
|
||||
```
|
||||
Este também pode ser um bom momento para revisitar um explorador de blockchain, para que possamos ver mais intuitivamente como as entradas, saídas e as taxas estão dispostas na transação: [e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d](https://mempool.space/pt/testnet/tx/e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d).
|
||||
|
||||
## Resumo do Enviando bitcoins usando transações brutas
|
||||
|
||||
Para enviar moedas usando transações brutas, precisamos criar uma transação bruta com uma ou mais entradas (para ter fundos suficientes) e uma ou mais saídas (para recuperar usando o troco). Então, podemos seguir nosso procedimento normal de usar o ```createrawtransaction``` com argumentos nomeados junto com o JQ, conforme descrito nas seções anteriores.
|
||||
|
||||
> :fire: ***Qual é o ponto positivo de enviar moedas com transações brutas?***
|
||||
> _As vantagens._ Oferece maior controle. Se o nosso objetivo é escrever um programa ou script Bitcoin mais complexo, provavelmente usaremos as transações brutas para saber exatamente o que está acontecendo. Essa também é a situação mais _segura_ para usar transações brutas, porque podemos garantir que não cometeremos nenhum erro na parte da programação.
|
||||
> _As desvantagens._ É muito fácil perder dinheiro. Não há avisos, bloqueios e barreiras na programação, a não ser que as criemos. Também é tudo muito misterioso. A formatação é desagradável, mesmo usando a interface ```bitcoin-cli``` que é fácil de usar, e temos que fazer muitas pesquisas e cálculos manualmente.
|
||||
|
||||
## O que vem depois?
|
||||
|
||||
Veja uma forma alternativa de inserir comandos no [Prefácio: Usando o JQ] (04_4__Interlude_Using_Curl.md).
|
||||
|
||||
Ou, se preferir pular, o que é francamente uma digressão, podemos aprender mais com "Enviando Transações de Bitcoin" na sessão [§4.5 Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md).
|
@ -1,314 +0,0 @@
|
||||
# Prefácio: Acessando o Bitcoind com Curl
|
||||
|
||||
O ```bitcoin-cli``` é, em última análise, apenas um invólucro. É uma forma de interagir com ```bitcoind``` a partir da linha de comando, fornecendo acesso simplificado aos seus diversos comandos RPC. Mas o RPC pode, é claro, ser acessado diretamente. É disso que iremos falar nessa sessão: Como nos conectarmos diretamente ao RPC com o comando ```curl```.
|
||||
|
||||
It won't be used much in the future chapters, but it's an important building block that you can see as an alternative access to `bitcoind` is you so prefer.
|
||||
Não será muito usado nos próximos capítulos, mas essas informações serão importantes caso queiramos uma alternativa para acessar o ```bitcoind```.
|
||||
|
||||
## Conhecendo o Curl
|
||||
|
||||
O ```curl```, abreviação de "ver URL", é uma ferramenta de linha de comando que permite acessar URLs diretamente usando a linha de comando. É uma maneira fácil de interagir com servidores como o ```bitcoind```, que ficam ouvindo as portas da internet e conversam utilizando uma variedade de protocolos. O Curl também está disponível como uma biblioteca para muitas linguagens de programação, como C, Java, PHP e Python. Então, depois de saber como trabalhar com o Curl, teremos uma base sólida para usar várias APIs diferentes.
|
||||
|
||||
Para usar o ```curl``` com o ```bitcoind```, devemos saber três coisas: O formato padrão, o nome de usuário e senha e a porta correta.
|
||||
|
||||
### Conhecendo o formato
|
||||
|
||||
Os comandos ```bitcoin-cli``` estão todos vinculados aos comandos RPC no ```bitcoind```. Isso torna a transição do uso de ```bitcoin-cli``` para o uso do ```curl``` muito simples. Na verdade, se olharmos qualquer uma das páginas de ajuda do ```bitcoin-cli```, veremos que eles listam não apenas os comandos ```bitcoin-cli```, mas também os comandos ```curl``` paralelos. Por exemplo, aqui temos o resultado do comando ```bitcoin-cli help getmininginfo```:
|
||||
```
|
||||
$ bitcoin-cli help getmininginfo
|
||||
getmininginfo
|
||||
|
||||
Returns a json object containing mining-related information.
|
||||
Result:
|
||||
{ (json object)
|
||||
"blocks" : n, (numeric) The current block
|
||||
"currentblockweight" : n, (numeric, optional) The block weight of the last assembled block (only present if a block was ever assembled)
|
||||
"currentblocktx" : n, (numeric, optional) The number of block transactions of the last assembled block (only present if a block was ever assembled)
|
||||
"difficulty" : n, (numeric) The current difficulty
|
||||
"networkhashps" : n, (numeric) The network hashes per second
|
||||
"pooledtx" : n, (numeric) The size of the mempool
|
||||
"chain" : "str", (string) current network name (main, test, regtest)
|
||||
"warnings" : "str" (string) any network and blockchain warnings
|
||||
}
|
||||
|
||||
Examples:
|
||||
> bitcoin-cli getmininginfo
|
||||
> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getmininginfo", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:8332/
|
||||
```
|
||||
E tem o comando ```curl```, no final da tela de ajuda! Este comando um tanto longo tem quatro partes principais: (1) Uma lista do nome de usuário; (2) Um sinalizador ```--data-binary```; (3) Um objeto JSON que diz ao ```bitcoind``` o que fazer, incluindo um array JSON com os parâmetros e; (4) Um cabeçalho HTTP que inclui a URL do ```bitcoind```.
|
||||
|
||||
Quando estamos trabalhando com o ```curl```, muitos desses argumentos do ```curl``` permanecerão os mesmos de um comando para outro, apenas as entradas ```method``` e ```params``` no array JSON normalmente mudam. No entanto, precisaremos saber como preencher o nome do usuário e endereço da URL para que funcione, antes de mais nada!
|
||||
|
||||
_Sempre que não tivermos certeza sobre como usar o curl no RPC, basta usarmos a ajuda do bitcoin-cli e continuar._
|
||||
|
||||
### Descobrindo o nome de usuário
|
||||
|
||||
Para falar com a porta do ```bitcoind```, precisamos de um nome de usuário e senha. Eles foram criados como parte da configuração inicial do Bitcoin e podem ser encontrados no arquivo `~/.bitcoin/bitcoin.conf`.
|
||||
|
||||
Por exemplo, aqui está nossa configuração atual:
|
||||
```
|
||||
$ cat ~/.bitcoin/bitcoin.conf
|
||||
server=1
|
||||
dbcache=1536
|
||||
par=1
|
||||
maxuploadtarget=137
|
||||
maxconnections=16
|
||||
rpcuser=StandUp
|
||||
rpcpassword=8eaf562eaf45c33c3328bc66008f2dd1
|
||||
rpcallowip=127.0.0.1
|
||||
debug=tor
|
||||
prune=550
|
||||
testnet=1
|
||||
mintxfee=0.001
|
||||
txconfirmtarget=1
|
||||
[test]
|
||||
rpcbind=127.0.0.1
|
||||
rpcport=18332
|
||||
[main]
|
||||
rpcbind=127.0.0.1
|
||||
rpcport=8332
|
||||
[regtest]
|
||||
rpcbind=127.0.0.1
|
||||
rpcport=18443
|
||||
```
|
||||
Nosso nome de usuário é ```StandUp``` e nossa senha é ```8eaf562eaf45c33c3328bc66008f2dd1```.
|
||||
|
||||
> **Atenção:** Obviamente, não é muito seguro ter essas informações em um arquivo de texto simples. A partir do Bitcoin Core 0.12, podemos omitir o ```rpcpassword``` do arquivo ```bitcoin.conf``` e fazer com que o ```bitcoind``` gere um novo cookie sempre que iniciarmos o serviço. A desvantagem disso é que torna o uso de comandos RPC por outros aplicativos, como os detalhados neste capítulo, mais difícil. Então, vamos ficar com as informações simples do ```rpcuser``` e ```rpcpassword``` por enquanto, mas para softwares em produção, é importante considerarmos essa alteração para cookies.
|
||||
|
||||
A maneira segura de usar o RPC com ```bitcoind``` é a seguinte:
|
||||
```
|
||||
$ curl --user StandUp --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/
|
||||
Enter host password for user 'bitcoinrpc':
|
||||
```
|
||||
Conforme observado, nossa senha será solicitada.
|
||||
|
||||
> :link: **TESTNET vs MAINNET:** A Testnet usa uma URL com a porta 18332 e a mainnet usa uma URL com a porta 8332. Se tivermos alguma dúvida, basta olharmos nosso ```bitcoin.conf```. As configurações estão todas lá.
|
||||
|
||||
A maneira insegura e errada de fazer isso é a seguinte:
|
||||
```
|
||||
$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/
|
||||
```
|
||||
> **Atenção:** Digitar a senha na linha de comando pode colocá-la na tabela de processos e/ou salvá-la em um histórico qualquer. Isso é ainda menos recomendado do que colocá-la em um arquivo, exceto para testes utilizando a testnet. Se quisermos fazer em qualquer outro lugar, precisamos nos certificar de saber o que estamos fazendo!
|
||||
|
||||
### Conhecendo os comandos e os parâmetros
|
||||
|
||||
Com tudo isso em mãos, estamos prontos para enviar os comandos RPC padrão com o ```curl```, mas ainda precisamos saber como incorporar os dois elementos que tendem a mudar no comando ```curl```.
|
||||
|
||||
O primeiro é o ```method```, que é o método RPC que está sendo utilizado. Isso geralmente deve corresponder aos nomes de comando que alimentamos no ```bitcoin-cli``` por muito tempo.
|
||||
|
||||
O segundo é o ```params```, que é uma matriz JSON de parâmetros. Eles são iguais aos argumentos (ou argumentos nomeados) que estamos usando. Eles também são a parte mais confusa do ```curl```, em grande parte porque são um array estruturado ao invés de uma simples lista.
|
||||
|
||||
Esta é a aparência de algumas matrizes de parâmetros:
|
||||
|
||||
* `[]` — Um array vazio;
|
||||
* `["000b4430a7a2ba60891b01b718747eaf9665cb93fbc0c619c99419b5b5cf3ad2"]` — Um array com dados;
|
||||
* `["'$signedhex'"]` — Um array com uma variável;
|
||||
* `[6, 9999999]` — Uma array com dois parâmetros;
|
||||
* `{}` - Um objeto vazio;
|
||||
* `[''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.298, "'$changeaddress'": 1.0}'']` — Um array com um array contendo um objeto e um objeto vazio.
|
||||
|
||||
## Obtendo a informação
|
||||
|
||||
Agora podemos enviar nosso primeiro comando ```curl``` acessando o RPC ```getmininginfo```:
|
||||
```
|
||||
$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/
|
||||
{"result":{"blocks":1772428,"difficulty":10178811.40698772,"networkhashps":91963587385939.06,"pooledtx":61,"chain":"test","warnings":"Warning: unknown new rules activated (versionbit 28)"},"error":null,"id":"curltest"}```
|
||||
Note that we provided the method, `getmininginfo`, and the parameter, `[]`, but that everything else was the standard `curl` command line.
|
||||
```
|
||||
> **Atenção:** Se obtivermos como resultado o seguinte erro: "Failed to connect to 127.0.0.1 port 8332: Connection refused", precisamos nos certificar de que uma linha como ```rpcallowip = 127.0.0.1``` esteja configurada no ```~/.bitcoin/bitcoin.conf```. Se ainda não funcionar, precisaremos permitir o acesso à porta 18332 (ou 8332) do nosso host local. Nossa configuração padrão do [Capítulo 2: Configurando um Bitcoin-Core no VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) deve fazer tudo isso.
|
||||
|
||||
The result is another JSON array, which is unfortunately ugly to read if you're using `curl` by hand. Fortunately, you can clean it up simply by piping it through `jq`:
|
||||
O resultado é outro array JSON, que infelizmente é ruim de se ler se estivermos usando o ```curl``` manualmente. Felizmente, podemos limpá-lo simplesmente usando o ```jq```:
|
||||
```
|
||||
$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.'
|
||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||
Dload Upload Total Spent Left Speed
|
||||
100 295 100 218 100 77 72666 25666 --:--:-- --:--:-- --:--:-- 98333
|
||||
{
|
||||
"result": {
|
||||
"blocks": 1772429,
|
||||
"difficulty": 10178811.40698772,
|
||||
"networkhashps": 90580030969896.44,
|
||||
"pooledtx": 4,
|
||||
"chain": "test",
|
||||
"warnings": "Warning: unknown new rules activated (versionbit 28)"
|
||||
},
|
||||
"error": null,
|
||||
"id": "curltest"
|
||||
}
|
||||
```
|
||||
Você verá um pouco de relatório de conectividade à medida que os dados são baixados, então, quando os dados chegarem a ```jq```, tudo será corretamente identado. Estaremos omitindo as informações do download nos próximos exemplos.
|
||||
|
||||
## Manipulando nossa carteira
|
||||
|
||||
Embora já estejamos acessando o ```bitcoind``` diretamente, ainda teremos acesso à funcionalidade de carteira, porque ela está amplamente armazenada no próprio ```bitcoind```.
|
||||
|
||||
### Pesquisando endereços
|
||||
|
||||
Usando o RPC ```getaddressesbylabel``` para listar todos os nossos endereços atuais:
|
||||
```
|
||||
$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getaddressesbylabel", "params": [""] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.'
|
||||
{
|
||||
"result": {
|
||||
"mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE": {
|
||||
"purpose": "receive"
|
||||
},
|
||||
"mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff": {
|
||||
"purpose": "receive"
|
||||
},
|
||||
"moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B": {
|
||||
"purpose": "receive"
|
||||
},
|
||||
"mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d": {
|
||||
"purpose": "receive"
|
||||
},
|
||||
"tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6": {
|
||||
"purpose": "receive"
|
||||
},
|
||||
"tb1qmtucvjtga68kgrvkl7q05x4t9lylxhku7kqdpr": {
|
||||
"purpose": "receive"
|
||||
}
|
||||
},
|
||||
"error": null,
|
||||
"id": "curltest"
|
||||
}
|
||||
```
|
||||
Este é o nosso primeiro exemplo de um parâmetro real, ```" "```. Este é o parâmetro ```label``` obrigatório para o ```getaddressesbylabel```, mas todos os nossos endereços estão sob o rótulo padrão, então nada de especial foi necessário neste momento.
|
||||
|
||||
O resultado é uma lista de todos os endereços que foram usados na nossa carteira. Alguns dos quais presumivelmente possuem saldo.
|
||||
|
||||
### Pesquisando pelos saldos
|
||||
|
||||
Use o RPC ```listunspent``` para listar os saldos que temos disponíveis:
|
||||
```
|
||||
$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.'
|
||||
{
|
||||
"result": [
|
||||
{
|
||||
"txid": "e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d",
|
||||
"vout": 1,
|
||||
"address": "mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h",
|
||||
"scriptPubKey": "76a91432db726320e4ad170c9c1ee83cd4d8a243c3435988ac",
|
||||
"amount": 0.0009,
|
||||
"confirmations": 4,
|
||||
"spendable": true,
|
||||
"solvable": true,
|
||||
"desc": "pkh([d6043800/0'/1'/2']02881697d252d8bf181d08c58de1f02aec088cd2d468fc5fd888c6e39909f7fabf)#p6k7dptk",
|
||||
"safe": true
|
||||
},
|
||||
{
|
||||
"txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c",
|
||||
"vout": 0,
|
||||
"address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff",
|
||||
"label": "",
|
||||
"scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac",
|
||||
"amount": 0.00022,
|
||||
"confirmations": 19,
|
||||
"spendable": true,
|
||||
"solvable": true,
|
||||
"desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y",
|
||||
"safe": true
|
||||
}
|
||||
],
|
||||
"error": null,
|
||||
"id": "curltest"
|
||||
}
|
||||
```
|
||||
Esta é quase exatamente a mesma saída que recebemos quando digitamos ```bitcoin-cli listunspent```, mostrando como as duas interfaces estão intimamente ligadas. Se nenhuma limpeza ou ajuda extra for necessária, então o ```bitcoin-cli``` apenas produzirá o RPC. Simples assim!
|
||||
|
||||
### Criando um endereço
|
||||
|
||||
Depois de saber onde estão os saldos, a próxima etapa na elaboração de uma transação é obter um endereço de alteração. Agora provavelmente já pegamos o jeito e sabemos que para os comandos RPC simples, tudo que precisamos fazer é ajustar o ```method``` no comando ```curl```:
|
||||
```
|
||||
$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": ["legacy"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.'
|
||||
{
|
||||
"result": "mrSqN37TPs89GcidSZTvXmMzjxoJZ6RKoz",
|
||||
"error": null,
|
||||
"id": "curltest"
|
||||
}
|
||||
|
||||
```
|
||||
Neste ponto, podemos até mesmo voltar à nossa prática padrão de salvar os resultados em variáveis com a ajuda adicional do `jq`:
|
||||
```
|
||||
$ changeaddress=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": ["legacy"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result')
|
||||
$ echo $changeaddress
|
||||
mqdfnjgWr2r3sCCeuTDfe8fJ1CnycF2e6R
|
||||
```
|
||||
Não precisamos nos preocupar com as informações do download. Ele irá para o ```STDERR``` e será exibido em nossa tela, enquanto os resultados irão para o ```STDOUT``` e serão salvos em nossa variável.
|
||||
|
||||
## Criando uma transação
|
||||
|
||||
Agora estamos prontos para criar uma transação com o ```curl```.
|
||||
|
||||
### Preparando as variáveis
|
||||
|
||||
Assim como no ```bitcoin-cli```, para criar uma transação usando o Curl com o RPC, devemos primeiro salvar nossas variáveis. A única mudança aqui é que o ```curl``` cria um objeto JSON que inclui um valor-chave ```result```, então sempre precisaremos usar o pipe (```|```) através da tag ```.result``` antes de fazer qualquer outra coisa.
|
||||
|
||||
Este exemplo configura nossas variáveis para usar o BTC de 1.2985 em fundos listados na primeira transação não gasta acima:
|
||||
```
|
||||
$ utxo_txid=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .[0] | .txid')
|
||||
$ utxo_vout=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .[0] | .vout')
|
||||
$ recipient=mwCwTceJvYV27KXBc3NJZys6CjsgsoeHmf
|
||||
$ changeaddress=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": ["legacy"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result')
|
||||
|
||||
$ echo $utxo_txid
|
||||
e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d
|
||||
$ echo $utxo_vout
|
||||
1
|
||||
$ echo $recipient
|
||||
mwCwTceJvYV27KXBc3NJZys6CjsgsoeHmf
|
||||
$ echo $changeaddress
|
||||
n2jf3MzeFpFGa7wq8rXKVnVuv5FoNSJZ1N
|
||||
```
|
||||
|
||||
### Criando a transação
|
||||
|
||||
A transação criada com o ```curl``` é muito semelhante à transação criada com o ```bitcoin-cli```, mas com algumas diferenças sutis:
|
||||
```
|
||||
$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createrawtransaction", "params": [''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.0003, "'$changeaddress'": 0.0005}'']}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.'
|
||||
{
|
||||
"result": "02000000010d6acd0356db222ca3a7ee7fa1e3044316223ceec1f64b58aeb2e0de921007e70100000000ffffffff0230750000000000001976a914ac19d3fd17710e6b9a331022fe92c693fdf6659588ac50c30000000000001976a9147021efec134057043386decfaa6a6aa4ee5f19eb88ac00000000",
|
||||
"error": null,
|
||||
"id": "curltest"
|
||||
}
|
||||
```
|
||||
O coração da transação é, obviamente, o array JSON ```params```, que estamos colocando em uso total pela primeira vez.
|
||||
|
||||
Podemos observar que todos os ```params``` estão alojados nos ```[]``` para marcar o array de parâmetros.
|
||||
|
||||
Nós também variamos as citações de como as coisas funcionavam no ```bitcoin-cli```, para iniciar e terminar cada array e objeto dentro do array ```params``` com ```''``` ao invés do tradicional ```'' '```. Isso porque todo o conjunto de argumentos JSON já tem um ```'``` em torno dele. Como de costume, basta dar uma olhada na bizarra citação do shell e se acostumar com isso.
|
||||
|
||||
No entanto, há uma última coisa a ser observada neste exemplo, e pode ser _enlouquecedor_ se não tivermos percebido. Quando executamos um comando ```createrawtransaction``` com ```bitcoin-cli```, o array JSON de entradas e o objeto JSON de saídas eram parâmetros distintos, portanto, foram separados por um espaço. Agora, porque eles são parte do array JSON ```params```, eles são separados por uma vírgula (```,```). Se não tivermos percebido isso obteremos um ```parse error``` sem muitas informações.
|
||||
|
||||
> **Atenção:** Todo mundo já teve problemas para depurar o ```curl```, não é mesmo? Para resolver isso basta adicionar o argumento ```--trace-ascii/tmp/foo```. Informações completas sobre o que está sendo enviado ao servidor serão salvas em ```/tmp/foo``` (ou qualquer nome de arquivo que quisermos informar).
|
||||
|
||||
Depois de verificarmos se as coisas estão funcionando, provavelmente iremos desejar salvar o código hexadecimal em uma variável:
|
||||
```
|
||||
$ hexcode=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createrawtransaction", "params": [''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.0003, "'$changeaddress'": 0.0005}'']}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result')
|
||||
```
|
||||
|
||||
### Assinando e enviando
|
||||
|
||||
Assinar e enviar a nossa transação usando ```curl``` é bem simples, basta usar os seguintes comandos do RPC ```signrawtransactionwithwallet``` e ```sendrawtransaction```:
|
||||
|
||||
```
|
||||
$ signedhex=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "signrawtransactionwithwallet", "params": ["'$hexcode'"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .hex')
|
||||
|
||||
$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "sendrawtransaction", "params": ["'$signedhex'"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.'
|
||||
{
|
||||
"result": "eb84c5008038d760805d4d9644ace67849542864220cb2685a1ea2c64176b82d",
|
||||
"error": null,
|
||||
"id": "curltest"
|
||||
}
|
||||
```
|
||||
## Resumo do Acessando o Bitcoind com Curl
|
||||
|
||||
Terminando esta seção, podemos sentir que acessar o ```bitcoind``` através de ```curl``` é muito parecido com acessá-lo através de ```bitcoin-cli```, porém, é mais complicado. E estamos certos. O ```bitcoin-cli``` tem funcionalidade RPC bem completa, então qualquer coisa que fizermos através do ```curl``` provavelmente poderemos fazer através do ```bitcoin-cli```. É por isso que vamos continuar nos concentrando no ```bitcoin-cli``` após esta digressão.
|
||||
|
||||
Mas ainda há razões para usar ```curl``` ao invés do ```bitcoin-cli```:
|
||||
|
||||
_Qual é o poder do curl?_ Obviamente, o ```curl``` elimina um nível intermediário. Ao invés de trabalhar com o ```bitcoin-cli```, que envia comandos RPC para o ```bitcoind```, estamos enviando esses comandos RPC diretamente para ele. Isso permite uma programação mais robusta, porque não precisamos nos preocupar com as coisas inesperadas que o ```bitcoin-cli``` pode fazer ou como isso pode mudar com o tempo. No entanto, também estamos dando os primeiros passos para usar uma linguagem de programação mais abrangente do que as opções pobres oferecidas por um script de shell. Como veremos nos últimos capítulos deste livro, podemos realmente ver que as bibliotecas curl são outras funções que acessam os comandos RPC em uma variedade de linguagens de programação: Mas isso ainda está muito longe, ainda.
|
||||
|
||||
## O que vem depois?
|
||||
|
||||
Aprenda mais uma maneira de "Enviando Transações de Bitcoin" com [§4.5 Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md).
|
@ -1,171 +0,0 @@
|
||||
# 4.5: Enviando bitcoins usando transações brutas automatizadas
|
||||
|
||||
Este capítulo apresenta três maneiras de enviar fundos por meio da interface cli do Bitcoin. A sessão [§4.1](04_1_Sending_Coins_The_Easy_Way.md) descreveu como fazer isso com um comando simples, a sessão [§4.4](04_4_Sending_Coins_with_a_Raw_Transaction.md) detalhou como usar uma transação bruta mais perigosa. Esta seção fica no meio termo de ambas, mostrando como tornar as transações brutas mais simples e seguras.
|
||||
|
||||
## Deixando o Bitcoin fazer os cálculos para nós
|
||||
|
||||
A metodologia para transações brutas automatizadas é simples: Criamos uma transação bruta, mas usamos o comando ```fundrawtransaction``` para pedir ao bitcoind para executar os cálculos para nós.
|
||||
|
||||
Para usar este comando, precisaremos garantir que nosso arquivo ```~/.bitcoin/bitcoin.conf``` contenha as variáveis racionais para calcular as taxas de transação. Podemos consultar a sessão [§4.1: Enviando bitcoins no modo easy](04_1_Sending_Coins_The_Easy_Way.md) para obter mais informações sobre isso.
|
||||
|
||||
Vamos usar números conservadores, por isso sugerimos adicionar o seguinte ao `bitcoin.conf`:
|
||||
```
|
||||
mintxfee=0.0001
|
||||
txconfirmtarget=6
|
||||
```
|
||||
Para manter o tutorial em constante movimento (em outras palavras, para movimentarmos nosso dinheiro rápido sem ficar esperando muito), sugerimos o seguinte:
|
||||
```
|
||||
mintxfee=0.001
|
||||
txconfirmtarget=1
|
||||
```
|
||||
|
||||
## Criando uma transação bruta
|
||||
|
||||
Para usar o ```fundrawtransaction``` primeiro precisamos criar uma transação bruta básica que liste _nenhuma_ entrada e _nenhuma_ mudança de endereço. Apenas listaremos o nosso destinatário e quanto desejamos enviar, neste caso ```$recipient``` e ```0,0002``` BTC.
|
||||
```
|
||||
$ recipient=n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi
|
||||
$ unfinishedtx=$(bitcoin-cli -named createrawtransaction inputs='''[]''' outputs='''{ "'$recipient'": 0.0002 }''')
|
||||
```
|
||||
|
||||
## Financiando nossa transação bruta
|
||||
|
||||
Dizemos ao ```bitcoin-cli``` para financiar essa transação básica:
|
||||
```
|
||||
$ bitcoin-cli -named fundrawtransaction hexstring=$unfinishedtx
|
||||
{
|
||||
"hex": "02000000012db87641c6a21e5a68b20c226428544978e6ac44964d5d8060d7388000c584eb0100000000feffffff02204e0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac781e0000000000001600140cc9cdcf45d4ea17f5227a7ead52367aad10a88400000000",
|
||||
"fee": 0.00022200,
|
||||
"changepos": 1
|
||||
}
|
||||
```
|
||||
Isso fornece muitas informações úteis, mas uma vez que tenhamos certeza de como funciona, vamos querer usar o JQ para salvar nosso hex em uma variável, como de costume:
|
||||
```
|
||||
$ rawtxhex3=$(bitcoin-cli -named fundrawtransaction hexstring=$unfinishedtx | jq -r '.hex')
|
||||
```
|
||||
## Verificando nossa transação financiada
|
||||
|
||||
Parece mágica, então nas primeiras vezes que usarmos o ```fundrawtransaction```, provavelmente vamos querer verificá-la.
|
||||
|
||||
Vamos executar o comando ```decoderawtransaction``` para mostrar que a transação bruta agora está disposta corretamente, usando um ou mais dos nossos UTXOs e enviando fundos excedentes de volta para um endereço de alteração:
|
||||
```
|
||||
$ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex3
|
||||
{
|
||||
"txid": "b3b4c2057dbfbef6690e975ede92fde805ddea13c730f58401939a52c9ac1b99",
|
||||
"hash": "b3b4c2057dbfbef6690e975ede92fde805ddea13c730f58401939a52c9ac1b99",
|
||||
"version": 2,
|
||||
"size": 116,
|
||||
"vsize": 116,
|
||||
"weight": 464,
|
||||
"locktime": 0,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "eb84c5008038d760805d4d9644ace67849542864220cb2685a1ea2c64176b82d",
|
||||
"vout": 1,
|
||||
"scriptSig": {
|
||||
"asm": "",
|
||||
"hex": ""
|
||||
},
|
||||
"sequence": 4294967294
|
||||
}
|
||||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.00020000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG",
|
||||
"hex": "76a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac",
|
||||
"reqSigs": 1,
|
||||
"type": "pubkeyhash",
|
||||
"addresses": [
|
||||
"n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"value": 0.00007800,
|
||||
"n": 1,
|
||||
"scriptPubKey": {
|
||||
"asm": "0 a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142",
|
||||
"hex": "0014a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142",
|
||||
"reqSigs": 1,
|
||||
"type": "witness_v0_keyhash",
|
||||
"addresses": [
|
||||
"tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
Uma coisa de interesse aqui é o endereço de troco, que é o segundo ```vout```. Observe que é um endereço ```tb1```, o que significa que é do tipo Bech32. Quando demos ao Bitcoin Core a capacidade total de gerenciar as alterações, ele o fez usando o tipo de endereço padrão, Bech32, e funcionou bem. É por isso que nossa mudança para endereços SegWit na sessão [§4.6](04_6_Creating_a_Segwit_Transaction.md) realmente não é um grande negócio, mas existem algumas dicas para uso mais amplo, sobre as quais falaremos lá.
|
||||
|
||||
Embora tenhamos visto a taxa na saída no ```fundrawtransaction```, ela não pode ser visível aqui. No entanto, podemos verificar isso com o script JQ ```txfee-calc.sh``` criado na sessão [Prefácio: Usando o JQ](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master /04_2__Interlude_Using_JQ.md):
|
||||
```
|
||||
$ ~/txfee-calc.sh $rawtxhex3
|
||||
.000222
|
||||
```
|
||||
Finalmente, podemos usar o ```getaddressinfo``` para ver se o endereço de alteração gerado realmente nos pertence:
|
||||
```
|
||||
$ bitcoin-cli -named getaddressinfo address=tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r
|
||||
{
|
||||
"address": "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r",
|
||||
"scriptPubKey": "0014a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142",
|
||||
"ismine": true,
|
||||
"solvable": true,
|
||||
"desc": "wpkh([d6043800/0'/1'/10']038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec5)#zpv26nar",
|
||||
"iswatchonly": false,
|
||||
"isscript": false,
|
||||
"iswitness": true,
|
||||
"witness_version": 0,
|
||||
"witness_program": "a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142",
|
||||
"pubkey": "038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec5",
|
||||
"ischange": true,
|
||||
"timestamp": 1592335137,
|
||||
"hdkeypath": "m/0'/1'/10'",
|
||||
"hdseedid": "fdea8e2630f00d29a9d6ff2af7bf5b358d061078",
|
||||
"hdmasterfingerprint": "d6043800",
|
||||
"labels": [
|
||||
]
|
||||
}
|
||||
```
|
||||
Observe os conteúdo do `ismine`.
|
||||
|
||||
## Enviando a transação financiada
|
||||
|
||||
Neste ponto, podemos assinar e enviar a transação normalmente.
|
||||
```
|
||||
$ signedtx3=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex3 | jq -r '.hex')
|
||||
$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx3
|
||||
8b9dd66c999966462a3d88d6ac9405d09e2aa409c0aa830bdd08dbcbd34a36fa
|
||||
```
|
||||
Em alguns minutos, teremos o nosso troco de volta:
|
||||
```
|
||||
$ bitcoin-cli listunspent
|
||||
[
|
||||
{
|
||||
"txid": "8b9dd66c999966462a3d88d6ac9405d09e2aa409c0aa830bdd08dbcbd34a36fa",
|
||||
"vout": 1,
|
||||
"address": "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r",
|
||||
"scriptPubKey": "0014a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142",
|
||||
"amount": 0.00007800,
|
||||
"confirmations": 1,
|
||||
"spendable": true,
|
||||
"solvable": true,
|
||||
"desc": "wpkh([d6043800/0'/1'/10']038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec5)#zpv26nar",
|
||||
"safe": true
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Resumo do Enviando bitcoins usando transações brutas automatizadas
|
||||
|
||||
Se formos enviar fundos usando transações brutas, então o ```fundrawtransaction``` oferece uma boa alternativa onde taxas, entradas e saídas são calculadas para nós, para que não percamos acidentalmente muito dinheiro.
|
||||
|
||||
> :fire: ***Qual é o poder de enviar moedas com transações brutas automatizadas?***
|
||||
> _As vantagens._ Proporciona um bom meio de campo. Se estamos enviando fundos manualmente e o ```sendtoaddress``` não oferece controle suficiente por qualquer motivo, podemos obter algumas das vantagens das transações brutas sem os perigos dela. Essa metodologia deve ser usada sempre que possível se estivermos enviando transações brutas manualmente.
|
||||
> _As desvantagens._ É uma meio termo. Embora existam algumas opções adicionais no ```fundrawtransaction``` que não foram mencionadas aqui, nosso controle ainda é limitado. Provavelmente, nunca desejaríamos usar esse método se formos escrever um programa cujo objetivo é saber exatamente o que está acontecendo.
|
||||
|
||||
## O que vem depois?
|
||||
|
||||
Vamos concluir o capítulo "Enviando transações no Bitcoin" com a sessão [§4.6: Criando uma transação do tipo SegWit](04_6_Creating_a_Segwit_Transaction.md).
|
@ -1,288 +0,0 @@
|
||||
# 4.6: Criando uma transação do tipo SegWit
|
||||
|
||||
> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um esboço que ainda pode estar aguardando revisão. Portanto, leitor, tenha cuidado.
|
||||
|
||||
Era uma vez, nos céus do Bitcoin, uma guerra entre os tamanhos de blocos eclodiu. As taxas disparavam e os usuários estavam preocupados se o Bitcoin podia realmente escalar. Os desenvolvedores do Bitcoin Core relutaram em simplesmente aumentar o tamanho do bloco, mas chegaram a um acordo: Fizeram o SegWit, que significa Segregated Witness. A Segregated Witness é uma maneira elegante de dizer "Assinatura Separada". Ele cria novos tipos de transações que removem assinaturas no final da transação. Ao combinar isso com o aumento dos tamanhos de bloco que são visíveis apenas para nós atualizados, o SegWit resolveu os problemas de dimensionamento do Bitcoin na época e também resolveu um bug de maleabilidade desagradável, tornando o dimensionamento ainda melhor para protocolos de segunda camada, como a Lightning Network.
|
||||
|
||||
A sacada? O SegWit usa endereços diferentes, alguns dos quais são compatíveis com nodes mais antigos e outros não.
|
||||
|
||||
> :warning: **AVISO DE VERSÃO:** O SegWit foi introduzido no BitCoin 0.16.0, que foi descrito na época como tendo "suporte total". Dito isso, havia algumas falhas na integração com o ```bitcoin-cli``` na época, que impediam a assinatura de funcionar corretamente em novos endereços P2SH-SegWit. O endereço Bech32, não compatível com versões anteriores, também foi introduzido no Bitcoin 0.16.0 e se tornou o tipo de endereço padrão no Bitcoin 0.19.0. Toda essa funcionalidade deve estar totalmente funcional em relação às funções ```bitcoin-cli``` (e, portanto, devem funcionar completamente neste tutorial).
|
||||
|
||||
> O problema está em interagir com o mundo. Todos devem ser capazes de enviar para um endereço P2SH-SegWit porque foi construído propositadamente para suportar compatibilidade com as versões anteriores, envolvendo a funcionalidade SegWit em um Script Bitcoin. O mesmo não é verdade para endereços Bech32: Se alguém nos disser que não pode enviar para o nosso endereço Bech32 precisaremos gerar um endereço ```legado``` ou P2SH-SegWit para fazer a transação. (Muitos sites, principalmente as exchanges, também não podem gerar ou receber em endereços SegWit, particularmente endereços Bech32, mas isso é um problema totalmente diferente e não afeta o uso delas).
|
||||
|
||||
## Compreendendo uma transação SegWit
|
||||
|
||||
Em transações clássicas, as informações de assinatura (witness) eram armazenadas no meio da transação, enquanto nas transações SegWit, elas ficavam na parte inferior. Isso anda de mãos dadas com os aumentos de tamanho do bloco que foram introduzidos na atualização do SegWit. O tamanho do bloco foi aumentado de 1 mega para um valor variável com base em quantas transações SegWit estão em um bloco, começando em 1 mega (sem transações SegWit) e podendo chegar a 4 megas (caso todas as transações sejam SegWit). Este tamanho variável foi criado para acomodar os nodes legados, de forma que tudo permaneça compatível com as versões anteriores. Se um node clássico vê uma transação SegWit, ele joga fora as informações da witness (resultando em um bloco de tamanho menor, abaixo do antigo limite de 1 mega), enquanto se um novo node vê uma transação SegWit, ele mantém as informações da witness (resultando em um maior tamanho de bloco, até o novo limite de 4 megas).
|
||||
|
||||
Portanto, acabamos de responder o quê são e como funcionam as transações SegWit. Não que precisemos saber disso para usá-las. A maioria das transações na rede Bitcoin são SegWit. Elas são aquilo que iremos utilizar nativamente para as transações e recebimentos de bitcoins. Os detalhes não são mais relevantes à partir deste ponto, tanto quanto não são mais relevantes como o Bitcoin funciona.
|
||||
|
||||
## Criando um endereço SegWit
|
||||
|
||||
Criamos um endereço SegWit da mesma maneira que qualquer outro endereço, com os comandos ```getnewaddress``` e ```getrawchangeaddress```.
|
||||
|
||||
Se precisarmos criar um endereço para alguém que não pode enviar para os endereços Bech32 mais recentes, podemos usar um endereço ```p2sh-segwit```:
|
||||
```
|
||||
$ bitcoin-cli -named getnewaddress address_type=p2sh-segwit
|
||||
2N5h2r4karVqN7uFtpcn8xnA3t5cbpszgyN
|
||||
```
|
||||
Se conseguirmos ver um endereço com o prefixo "2" significa que fizemos tudo certo.
|
||||
|
||||
> :link: **TESTNET vs MAINNET:** "3" no caso da mainnet.
|
||||
|
||||
No entanto, se a pessoa com quem estamos interagindo tem um node com uma versão mais nova, ela poderá enviar para um endereço Bech32, que criamos usando os comandos da maneira padrão:
|
||||
```
|
||||
$ bitcoin-cli getnewaddress
|
||||
tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6
|
||||
```
|
||||
Como já vimos, os endereços de troco gerados a partir do ```bitcoin-cli``` interagem bem com os endereços Bech32, então não há motivo nenhum usar o sinalizador ```legacy``` lá também:
|
||||
```
|
||||
$ bitcoin-cli getrawchangeaddress
|
||||
tb1q05wx5tyadm8qe83exdqdyqvqqzjt3m38vfu8ff
|
||||
```
|
||||
|
||||
Aqui, podemos observar que o prefixo "tb1" exclusivo denota que o endereço é um Bech32.
|
||||
|
||||
> :link: ** TESTNET vs MAINNET: ** "bc1" no caso da mainnet.
|
||||
|
||||
O Bitcoin-cli não se importa com o tipo de endereço que estamos utilizando. Podemos executar um comando como ```listaddressgroupings``` que ele irá misturar os endereços livremente não importando os tipos:
|
||||
```
|
||||
$ bitcoin-cli listaddressgroupings
|
||||
[
|
||||
[
|
||||
[
|
||||
"mfsiRhxbQxcD7HLS4PiAim99oeGyb9QY7m",
|
||||
0.01000000,
|
||||
""
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE",
|
||||
0.00000000,
|
||||
""
|
||||
],
|
||||
[
|
||||
"tb1q6dak4e9fz77vsulk89t5z92l2e0zm37yvre4gt",
|
||||
0.00000000
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff",
|
||||
0.00022000,
|
||||
""
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h",
|
||||
0.00000000
|
||||
],
|
||||
[
|
||||
"mqjrdY5raxKzXQf5t2VvVvzhvFAgersu9B",
|
||||
0.00000000
|
||||
],
|
||||
[
|
||||
"mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d",
|
||||
0.00000000,
|
||||
""
|
||||
],
|
||||
[
|
||||
"tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r",
|
||||
0.00007800
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"mpVLL7iqPr4d7BJkEG54mcdm7WmrAhaW6q",
|
||||
0.01000000,
|
||||
""
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6",
|
||||
0.01000000,
|
||||
""
|
||||
]
|
||||
]
|
||||
]
|
||||
```
|
||||
|
||||
## Enviando uma transação SegWit no modo easy
|
||||
|
||||
Então, como enviamos uma transação Segwit? Exatamente como qualquer outra transação. Não importa se o UTXO é SegWit, o endereço é SegWit ou alguma combinação dos dois. Podemos ter a certeza que o ```bitcoin-cli``` irá fazer a coisa certa. Embora possamos perceber algumas diferenças nos endereços, eles não importam para interagir com as coisas no nível do ```bitcoin-cli``` ou do RPC. (E esta é uma das vantagens de usar a linha de comando e a interface do RPC, conforme sugerido neste tutorial: Os especialistas já fizeram o trabalho duro para nós, incluindo coisas como enviar para endereços legados e Bech32. Acabamos usando essa funcionalidade para nosso próprio benefício).
|
||||
|
||||
Aqui está um exemplo de um envio para um endereço SegWit, no modo easy:
|
||||
```
|
||||
$ bitcoin-cli sendtoaddress tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx 0.005
|
||||
854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42
|
||||
```
|
||||
Se olhar para a nossa transação, podemos ver o uso do endereço Bech32:
|
||||
```
|
||||
$ bitcoin-cli gettransaction txid="854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42" verbose=true
|
||||
{
|
||||
"amount": -0.00500000,
|
||||
"fee": -0.00036600,
|
||||
"confirmations": 0,
|
||||
"trusted": true,
|
||||
"txid": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42",
|
||||
"walletconflicts": [
|
||||
],
|
||||
"time": 1592948795,
|
||||
"timereceived": 1592948795,
|
||||
"bip125-replaceable": "no",
|
||||
"details": [
|
||||
{
|
||||
"address": "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx",
|
||||
"category": "send",
|
||||
"amount": -0.00500000,
|
||||
"vout": 1,
|
||||
"fee": -0.00036600,
|
||||
"abandoned": false
|
||||
}
|
||||
],
|
||||
"hex": "0200000002114d5a4c3b847bc796b2dc166ca7120607b874aa6904d4a43dd5f9e0ea79d4ba010000006a47304402200a3cc08b9778e7b616340d4cf7841180321d2fa019e43f25e7f710d9a628b55c02200541fc200a07f2eb073ad8554357777d5f1364c5a96afe5e77c6185d66a40fa7012103ee18c598bafc5fbea72d345329803a40ebfcf34014d0e96aac4f504d54e7042dfeffffffa71321e81ef039af490251379143f7247ad91613c26c8f3e3404184218361733000000006a47304402200dd80206b57beb5fa38a3c3578f4b0e40d56d4079116fd2a6fe28e5b8ece72310220298a8c3a1193ea805b27608ff67a2d8b01e347e33a4222edfba499bb1b64a31601210339c001b00dd607eeafd4c117cfcf86be8efbb0ca0a33700cffc0ae0c6ee69d7efeffffff026854160000000000160014d591091b8074a2375ed9985a9c4b18efecfd416520a1070000000000160014751e76e8199196d454941c45d1b3a323f1433bd6c60e1b00",
|
||||
"decoded": {
|
||||
"txid": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42",
|
||||
"hash": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42",
|
||||
"version": 2,
|
||||
"size": 366,
|
||||
"vsize": 366,
|
||||
"weight": 1464,
|
||||
"locktime": 1773254,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "bad479eae0f9d53da4d40469aa74b8070612a76c16dcb296c77b843b4c5a4d11",
|
||||
"vout": 1,
|
||||
"scriptSig": {
|
||||
"asm": "304402200a3cc08b9778e7b616340d4cf7841180321d2fa019e43f25e7f710d9a628b55c02200541fc200a07f2eb073ad8554357777d5f1364c5a96afe5e77c6185d66a40fa7[ALL] 03ee18c598bafc5fbea72d345329803a40ebfcf34014d0e96aac4f504d54e7042d",
|
||||
"hex": "47304402200a3cc08b9778e7b616340d4cf7841180321d2fa019e43f25e7f710d9a628b55c02200541fc200a07f2eb073ad8554357777d5f1364c5a96afe5e77c6185d66a40fa7012103ee18c598bafc5fbea72d345329803a40ebfcf34014d0e96aac4f504d54e7042d"
|
||||
},
|
||||
"sequence": 4294967294
|
||||
},
|
||||
{
|
||||
"txid": "33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7",
|
||||
"vout": 0,
|
||||
"scriptSig": {
|
||||
"asm": "304402200dd80206b57beb5fa38a3c3578f4b0e40d56d4079116fd2a6fe28e5b8ece72310220298a8c3a1193ea805b27608ff67a2d8b01e347e33a4222edfba499bb1b64a316[ALL] 0339c001b00dd607eeafd4c117cfcf86be8efbb0ca0a33700cffc0ae0c6ee69d7e",
|
||||
"hex": "47304402200dd80206b57beb5fa38a3c3578f4b0e40d56d4079116fd2a6fe28e5b8ece72310220298a8c3a1193ea805b27608ff67a2d8b01e347e33a4222edfba499bb1b64a31601210339c001b00dd607eeafd4c117cfcf86be8efbb0ca0a33700cffc0ae0c6ee69d7e"
|
||||
},
|
||||
"sequence": 4294967294
|
||||
}
|
||||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.01463400,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "0 d591091b8074a2375ed9985a9c4b18efecfd4165",
|
||||
"hex": "0014d591091b8074a2375ed9985a9c4b18efecfd4165",
|
||||
"reqSigs": 1,
|
||||
"type": "witness_v0_keyhash",
|
||||
"addresses": [
|
||||
"tb1q6kgsjxuqwj3rwhkenpdfcjccalk06st9z0k0kh"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"value": 0.00500000,
|
||||
"n": 1,
|
||||
"scriptPubKey": {
|
||||
"asm": "0 751e76e8199196d454941c45d1b3a323f1433bd6",
|
||||
"hex": "0014751e76e8199196d454941c45d1b3a323f1433bd6",
|
||||
"reqSigs": 1,
|
||||
"type": "witness_v0_keyhash",
|
||||
"addresses": [
|
||||
"tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
Na verdade, ambos os ```vouts``` usam endereços Bech32: O nosso destinatário e o endereço de troco gerado automaticamente.
|
||||
|
||||
Mas quando retrocedemos nosso ```vin```, descobrimos que veio de um endereço legado. Isso porque não importa:
|
||||
```
|
||||
$ bitcoin-cli -named gettransaction txid="33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7"
|
||||
{
|
||||
"amount": 0.01000000,
|
||||
"confirmations": 43,
|
||||
"blockhash": "00000000000000e2365d2f814d1774b063d9a04356f482010cdfdd537b1a24bb",
|
||||
"blockheight": 1773212,
|
||||
"blockindex": 103,
|
||||
"blocktime": 1592937103,
|
||||
"txid": "33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7",
|
||||
"walletconflicts": [
|
||||
],
|
||||
"time": 1592936845,
|
||||
"timereceived": 1592936845,
|
||||
"bip125-replaceable": "no",
|
||||
"details": [
|
||||
{
|
||||
"address": "mpVLL7iqPr4d7BJkEG54mcdm7WmrAhaW6q",
|
||||
"category": "receive",
|
||||
"amount": 0.01000000,
|
||||
"label": "",
|
||||
"vout": 0
|
||||
}
|
||||
],
|
||||
"hex": "020000000001016a66efa334f06e2c54963e48d049a35d7a1bda44633b7464621cae302f35174a0100000017160014f17b16c6404e85165af6f123173e0705ba31ec25feffffff0240420f00000000001976a914626ab1ca41d98f597d18d1ff8151e31a40d4967288acd2125d000000000017a914d5e76abfe5362704ff6bbb000db9cdfa43cd2881870247304402203b3ba83f51c1895b5f639e9bfc40124715e2495ef2c79d4e49c0f8f70fbf2feb02203d50710abe3cf37df4d2a73680dadf3cecbe4f2b5d0b276dbe7711d0c2fa971a012102e64f83ee1c6548bcf44cb965ffdb803f30224459bd2e57a5df97cb41ba476b119b0e1b00"
|
||||
}
|
||||
```
|
||||
|
||||
## Enviando uma transação SegWit o modo hard
|
||||
|
||||
Da mesma forma, podemos financiar uma transação com um endereço Bech32, sem nenhuma diferença em relação às técnicas que aprendemos até agora. Aqui está uma maneira exata de fazer isso com uma transação bruta completa:
|
||||
```
|
||||
$ changeaddress=$(bitcoin-cli getrawchangeaddress)
|
||||
$ echo $changeaddress
|
||||
tb1q4xje3mx9xn7f8khv7p69ekfn0q72kfs8x3ay4j
|
||||
$ bitcoin-cli listunspent
|
||||
[
|
||||
...
|
||||
{
|
||||
"txid": "003bfdca5578c0045a76768281f05d5e6f57774be399a76f387e2a0e99e4e452",
|
||||
"vout": 0,
|
||||
"address": "tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6",
|
||||
"label": "",
|
||||
"scriptPubKey": "0014a226e1dfd08537b02de04f667a49bd46f9b9f578",
|
||||
"amount": 0.01000000,
|
||||
"confirmations": 5,
|
||||
"spendable": true,
|
||||
"solvable": true,
|
||||
"desc": "wpkh([d6043800/0'/0'/5']0327dbe2d58d9ed2dbeca28cd26e18f48aa94c127fa6fb4b60e4188f6360317640)#hd66hknp",
|
||||
"safe": true
|
||||
}
|
||||
]
|
||||
$ recipient=tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx
|
||||
$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[2] | .txid')
|
||||
$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[2] | .vout')
|
||||
$ echo $utxo_txid $utxo_vout
|
||||
003bfdca5578c0045a76768281f05d5e6f57774be399a76f387e2a0e99e4e452 0
|
||||
$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.002, "'$changeaddress'": 0.007 }''')
|
||||
$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex')
|
||||
$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx
|
||||
e02568b706b21bcb56fcf9c4bb7ba63fdbdec1cf2866168c4f50bc0ad693f26c
|
||||
```
|
||||
Tudo funciona exatamente da mesma forma que outros tipos de transações!
|
||||
|
||||
### Reconhecendo o novo descritor
|
||||
|
||||
Se olharmos o campo ```desc```, notaremos que o endereço SegWit tem um descritor de estilo diferente daqueles encontrados na sessão [§3.5: Entendendo o descritor](03_5_Understanding_the_Descriptor.md). Um descritor legado descrito nessa sessão se parecia com algo assim: `pkh ([d6043800 / 0 '/ 0' / 18 '] 03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388) # 4ahsl9pk`. Nosso novo descritor SegWit se parece mais com isso: `wpkh ([d6043800 / 0 '/ 0' / 5 '] 0327dbe2d58d9ed2dbeca28cd26e18f48aa94c127fa6fb4b60e4188f6360317640) # hd66hknp" `.
|
||||
|
||||
A grande diferença que precisamos notar é que a função mudou. Anteriormente, era ```pkh```, que é um endereço padrão de chave pública com hash P2PKH. Ao invés disso, o endereço SegWit é ```wpkh```, o que significa que é um endereço SegWit P2WPKH nativo. Isso dá destaque ao :fire: ***poder dos descritores***. Eles descrevem como criar um endereço a partir de uma chave ou outra informação, com as funções definindo de forma inequívoca como fazer o endereço com base no tipo de cada endereço.
|
||||
|
||||
## Resumo do Criando uma transação do tipo SegWit
|
||||
|
||||
Realmente não há complexidade para criar transações SegWit. Internamente, elas são estruturadas de forma diferente das transações legadas, mas na linha de comando não existe diferença: Apesar usamos um endereço com um prefixo diferente. A única coisa a ser observada é que algumas pessoas podem não conseguir enviar para um endereço Bech32 se estiverem usando um software obsoleto.
|
||||
|
||||
> :fire: ***Qual é o poder de criar transações usando o SegWit?***
|
||||
> _As vantagens._ As transações do SegWit são menores e, portanto, serão mais baratas de serem enviadas do que as transações legadas devido às taxas mais baixas. O Bech32 diminui essa vantagem e também cria endereços que são mais difíceis de errar durante a transcrição, e isso é muito importante, visto que o erro do usuário é uma das maneiras mais prováveis de terem seus bitcoins perdidos.
|
||||
> _As desvantagens._ Os endereços SegWit não tem suporte em nodes do Bitcoin obsoleto. Em particular, as pessoas podem não conseguir enviar para o nosso endereço Bech32.
|
||||
|
||||
## O que vem depois?
|
||||
|
||||
Vamos avançar mais um pouco no "bitcoin-cli" com o [Capítulo 5: Controlando as transações do Bitcoin](05_0_Controlling_Bitcoin_Transactions.md).
|
Loading…
x
Reference in New Issue
Block a user