mirror of
https://github.com/ChristopherA/Learning-Bitcoin-from-the-Command-Line.git
synced 2025-06-07 16:06:26 +00:00
Finished translation of chapter 06
This commit is contained in:
parent
9712478a77
commit
463e1570ea
19
pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md
Normal file
19
pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Capítulo 6: Expandindo as transações de Bitcoin com multisigs
|
||||
|
||||
Transações básicas de Bitcoin: (1) Envia fundos; (2) Para um único destinatário P2PKH ou SegWit; (3) A partir de uma única máquina; (4) Imediatamente. No entanto, todas essas quatro partes desta definição podem ser expandidas usando transações Bitcoin mais complexas. Este primeiro capítulo sobre "Expansão" mostra como variar os pontos (2) e (3), enviando saldos para um endereço que representa vários destinatários (ou, pelo menos, vários assinantes).
|
||||
|
||||
## Objetivos deste capítulo
|
||||
|
||||
Depois de trabalhar neste capítulo, um desenvolvedor será capaz de:
|
||||
* Criar endereços de Bitcoin multi assinados (multisigs) usando os fundamentos do Bitcoin;
|
||||
* Crie endereços de Bitcoin com várias assinaturas (multisigs) usando mecanismos fáceis.
|
||||
|
||||
Os objetivos secundários do capítulo incluem a capacidade de:
|
||||
* Entender como gastar fundos enviados em uma transação multisig;
|
||||
* Planejar para obter o máximo do poder das multisigs.
|
||||
|
||||
## Tabela de conteúdo
|
||||
|
||||
* [Seção 1: Enviando uma Transação Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md)
|
||||
* [Seção 2: Gastando uma Transação Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md)
|
||||
* [Seção 3: Enviando e Gastando uma Transação Multisig de Maneira Automatizada](06_3_Sending_an_Automated_Multisig.md)
|
206
pt/06_1_Sending_a_Transaction_to_a_Multisig.md
Normal file
206
pt/06_1_Sending_a_Transaction_to_a_Multisig.md
Normal file
@ -0,0 +1,206 @@
|
||||
# 6.1: Enviando uma Transação Multsig
|
||||
|
||||
A primeira maneira de variar a forma como enviamos uma transação básica é usando uma multisig. Isso nos dá a capacidade de exigir que várias pessoas (ou, ao menos, várias chaves privadas) autorizem o uso dos fundos.
|
||||
|
||||
## Entendendo como Funcionam as Multisigs
|
||||
|
||||
Em uma transação P2PKH ou SegWit padrão, os bitcoins são enviados para um endereço baseado na chave pública, o que significa que a chave privada relacionada é necessária para desbloquear a transação, resolvendo o quebra-cabeça criptográfico e permitindo que reutilizemos o saldo. Mas e se pudéssemos bloquear uma transação com _múltiplas_ chaves privadas? Isso efetivamente permitiria que os fundos fossem enviados a um grupo de pessoas, onde todas teriam que concordar em reutilizar o saldo.
|
||||
|
||||
> :book: ***O que é uma multisignature ou multisig?*** Uma _multisignature_ é uma metodologia que permite que mais de uma pessoa crie uma assinatura digital em conjunto. É uma técnica para o uso criptográfico de chaves que vai muito além do Bitcoin.
|
||||
|
||||
Tecnicamente, um quebra-cabeça criptográfico com várias assinaturas é criado pelo Bitcoin usando o comando OP_CHECKMULTISIG e, normalmente, é encapsulado em um endereço P2SH. A seção [§10.4: Fazendo um scripto multisig](10_4_Scripting_a_Multisig.md) irá detalhar como isso funciona com mais precisão. Por enquanto, tudo que precisamos saber é que podemos usar o comando ```bitcoin-cli``` para criar endereços multi assinados. Os fundos podem ser enviados para esses endereços como qualquer endereço P2PKH ou Segwit normal, mas várias chaves privadas serão necessárias para que o saldo seja enviado.
|
||||
|
||||
> :book: ***O que é uma transação multisig?*** Uma transação com várias assinaturas é uma transação Bitcoin enviada para um endereço com várias assinaturas, exigindo assim que as pessoas de um grupo com várias assinaturas precisem assinar a transação para poder ter acesso ao saldo.
|
||||
|
||||
As multisigs simples exigem que todos no grupo assinem o UTXO quando estiver gasto. No entanto, há mais complexidade possível. As assinaturas múltiplas são geralmente descritas como sendo "M de N". Isso significa que a transação está presa com um grupo de chaves "N", mas apenas "M" delas são necessárias para desbloquear a transação.
|
||||
|
||||
> :book: ***O que é uma multisg M-de-N? *** Em uma multisig, as assinaturas "M" de um grupo de "N" são necessárias para formar a assinatura, onde "M ≤ N".
|
||||
|
||||
## Criando um Endereço Multisig
|
||||
|
||||
Para bloquear um UTXO com várias chaves privadas, devemos primeiro criar um endereço com várias assinaturas. Os exemplos usados aqui mostram a criação (e uso) de uma multisig 2 de 2 (normalmente é assim que falamos quando nos referimos a um endereço multisg, descrevemos a quantidade de chaves e a quantidade necessária para desbloquear o saldo).
|
||||
|
||||
### Criando os Endereços
|
||||
|
||||
Para criar um endereço multisig, devemos primeiro preparar os endereços que o multisig irá combinar. A prática recomendada sugere que sempre criemos novos endereços. Isso significa que cada participante irá executar o comando ```getnewaddress``` em sua própria máquina:
|
||||
```
|
||||
machine1$ address1=$(bitcoin-cli getnewaddress)
|
||||
```
|
||||
E:
|
||||
```
|
||||
machine2$ address2=$(bitcoin-cli getnewaddress)
|
||||
```
|
||||
Posteriormente, um dos destinatários (ou talvez algum terceiro) precisará combinar ambos endereços.
|
||||
|
||||
#### Coletando as Chaves Públicas
|
||||
|
||||
No entanto, não podemos criar um multisig com os endereços, pois esses são os hashes das chaves públicas: Ao invés disso, precisamos das próprias chaves públicas.
|
||||
|
||||
Esta informação está disponível facilmente com o comando ```getaddressinfo```.
|
||||
|
||||
Na máquina remota, que assumimos aqui é ```machine2```, podemos obter as informações em uma lista.
|
||||
```
|
||||
machine2$ bitcoin-cli -named getaddressinfo address=$address2
|
||||
{
|
||||
"address": "tb1qr2tkjh8rs9xn5xaktf5phct0wxqufplawrfd9q",
|
||||
"scriptPubKey": "00141a97695ce3814d3a1bb65a681be16f7181c487fd",
|
||||
"ismine": true,
|
||||
"solvable": true,
|
||||
"desc": "wpkh([fe6f2292/0'/0'/1']02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3)#zc64l8dw",
|
||||
"iswatchonly": false,
|
||||
"isscript": false,
|
||||
"iswitness": true,
|
||||
"witness_version": 0,
|
||||
"witness_program": "1a97695ce3814d3a1bb65a681be16f7181c487fd",
|
||||
"pubkey": "02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3",
|
||||
"ischange": false,
|
||||
"timestamp": 1592957904,
|
||||
"hdkeypath": "m/0'/0'/1'",
|
||||
"hdseedid": "1dc70547f2b80e9bb5fde5f34fb3d85f8d8d1dab",
|
||||
"hdmasterfingerprint": "fe6f2292",
|
||||
"labels": [
|
||||
""
|
||||
]
|
||||
}
|
||||
```
|
||||
O endereço ```pubkey``` (` 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3`) é o que precisamos. Vamos copiá-lo para nossa máquina local por qualquer meio que acharmos mais eficiente e _que seja menos sujeito a erros_.
|
||||
|
||||
Este processo precisa ser realizado para _cada_ endereço de uma máquina diferente daquela onde o multisig está sendo construída. Obviamente, se algum terceiro estiver criando o endereço, precisaremos fazer isso para cada endereço.
|
||||
|
||||
> :warning: **Atenção:** O uso de hashes de chave pública pelo Bitcoin como endereços, ao invés de chaves públicas, na verdade representa uma camada adicional de segurança. Porém, o envio de uma chave pública aumenta ligeiramente a vulnerabilidade do endereço associado, para alguma possibilidade no futuro distante de um comprometimento devido a curva elíptica. Não devemos nos preocupar em termos que enviar ocasionalmente uma chave pública para um uso como esse, mas devemos estar cientes de que os hashes de chave pública representam segurança e, portanto, as chaves públicas reais não devem ser enviadas de qualquer jeito para qualquer pessoa.
|
||||
|
||||
Se um dos endereços foi criado em nossa máquina local, que assumimos aqui que seja ```machine1```, podemos simplesmente colocar o endereço ```pubkey``` em uma nova variável.
|
||||
```
|
||||
machine1$ pubkey1=$(bitcoin-cli -named getaddressinfo address=$address1 | jq -r '.pubkey')
|
||||
```
|
||||
|
||||
### Criando o Endereço
|
||||
|
||||
Uma multisig agora pode ser criada com o comando ```createmultisig```:
|
||||
```
|
||||
machine1$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey1'","02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3"]'''
|
||||
{
|
||||
"address": "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr",
|
||||
"redeemScript": "522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae",
|
||||
"descriptor": "sh(multi(2,02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191,02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3))#0pazcr4y"
|
||||
}
|
||||
```
|
||||
> :warning: **AVISO DE VERSÃO:** Algumas versões do ```createmultisig``` permitem a entrada de chaves públicas ou endereços, algumas requerem apenas as chaves públicas. Atualmente, ambas parecem funcionar.
|
||||
|
||||
Ao criar o endereço multisig, listamos quantas assinaturas são necessárias com o argumento ```nrequired``` (que é o "M" quando falamos _uma multisig "M de N"_), então listamos o conjunto total de assinaturas possíveis com a argumento ```keys``` (que é o "N"). Observe que as entradas ```keys``` provavelmente vieram de lugares diferentes. Nesse caso, incluímos ```$pubkey1``` da máquina local e ```02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3``` de uma máquina remota.
|
||||
|
||||
> :information_source: **NOTA - M de N vs N de N:** Este exemplo mostra a criação de um multisig simples 2 de 2 . Se quisermos criar uma assinatura M de N onde "M<N", precisamos apenas ajustar o campo ```nrequired``` e/ou o número de assinaturas ```keys``` no objeto JSON. Para um multisig 1 de 2, seria definido como ```nrequired = 1``` e também listaria duas chaves, enquanto para um multisig 2 de 3, seria necessário um ```nrequired = 2```, mas adicionaria mais uma chave pública à lista de ```keys```.
|
||||
|
||||
Quando usado corretamente, o ```createmultisig``` retorna três resultados, todos criticamente importantes.
|
||||
|
||||
O _endereço_ é o que iremos distribuir para as pessoas que desejam enviar os fundos. Podemos notar que ele tem um novo prefixo ```2```, exatamente como os endereços P2SH-SegWit. Isso porque, como eles, o comando ```createmultisig``` está na verdade criando um tipo de endereço totalmente novo chamado endereço P2SH. Ele funciona exatamente como um endereço P2PKH padrão para envio de fundos, mas como este foi criado para exigir vários endereços, precisaremos trabalhar um pouco mais para utilizá-los.
|
||||
|
||||
> :link: **TESTNET vs MAINNET:** Na Testenet, o prefixo para endereços P2SH é ```2```, enquanto na Mainnet é ```3```.
|
||||
|
||||
O _redeemScript_ é o que precisaremos para resgatar os fundos (junto com as chaves privadas de "M" dos "N" endereços). Este script é outro recurso especial dos endereços P2SH e será explicado com mais detalhes na seção [§8.1: Construindo um Script Bitcoin com P2SH](08_1_Building_a_Bitcoin_Script_with_P2SH.md). Por enquanto, precisamos apenas saber que alguns dados são necessários para podemos gastar nosso dinheiro.
|
||||
|
||||
O _descritor_ é a descrição padronizada para um endereço que encontramos na seção [§3.5: Compreendendo o descriptor](03_5_Understanding_the_Descriptor.md). Ele fornece uma maneira de importar esse endereço de volta para a outra máquina, usando o RPC ```importmulti```.
|
||||
|
||||
> :book: ***O que é um endereço P2SH?*** O P2SH significa Pay-To-Script-Hash. É um tipo de destinatário diferente de um endereço P2PKH padrão ou mesmo de um Bech32, usado para fundos cujo resgate é baseado em scripts de Bitcoin mais complexos. O ```bitcoin-cli``` usa o encapsulamento P2SH para ajudar a padronizar e simplificar os multisigs como "multisigs P2SH ", assim como P2SH-SegWit estava usando o P2SH para padronizar os endereços SegWit e torná-los totalmente compatíveis com as versões legadas.
|
||||
|
||||
> :warning: **Atenção:** endereços P2SH multisig, como os criados pelo ```bitcoin-cli```, têm um limite para "M" e "N" nos multisigs com base no tamanho máximo do script de resgate, que atualmente é de 520 bytes. Praticamente, não vamos chegar a isso, a menos que estejamos nos excedendo em algo.
|
||||
|
||||
### Salvando Nosso Trabalho
|
||||
|
||||
Aqui está uma informação importante: Nada sobre nosso multisig é salvo em nossa carteira usando essas técnicas básicas. Para resgatar o saldo enviado para este endereço multisig no futuro, precisaremos reter duas informações cruciais:
|
||||
|
||||
* Uma lista dos endereços Bitcoin usados no multisig, e;
|
||||
* A saída ```redeemScript``` criada pelo comando ```createmultsig```.
|
||||
|
||||
Tecnicamente, o ```redeemScript``` pode ser recriado executando novamente o ```createmultisig``` com a lista completa de chaves públicas _na mesma ordem_ e com a contagem correta de M e de N. Mas, é melhor agarrar-se a ela e evitar qualquer tipo de estresse futuro.
|
||||
|
||||
### Observando a Ordem
|
||||
|
||||
Aqui está mais uma coisa que devemos tomar muito cuidado: A _ordem é muito importante_. A ordem das chaves usadas para criar um multisig cria um hash único, ou seja, se colocarmos as chaves em uma ordem diferente, elas irão produzir um endereço diferente, conforme mostrado abaixo:
|
||||
```
|
||||
$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey1'","'$pubkey2'"]'''
|
||||
{
|
||||
"address": "2NFBQvz57UzKWDr2Vx5D667epVZifjGixkm",
|
||||
"redeemScript": "52210342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da0321039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b352ae",
|
||||
"descriptor": "sh(multi(2,0342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da03,039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b3))#8l6hvjsk"
|
||||
}
|
||||
standup@btctest20:~$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey2'","'$pubkey1'"]'''
|
||||
{
|
||||
"address": "2N5bC4Yc5Pqept1y8nPRqvWmFSejkVeRb1k",
|
||||
"redeemScript": "5221039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b3210342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da0352ae",
|
||||
"descriptor": "sh(multi(2,039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b3,0342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da03))#audl88kg"
|
||||
}
|
||||
```
|
||||
Mais notavelmente, cada ordem cria um _redeemScript_ diferente. Isso significa que se usamos essas técnicas básicas e não conseguimos salvar o redemScript conforme as instruções, teremos que percorrer um número cada vez maior de variações para encontrar aquela correta quando tentarmos gastar os fundos!
|
||||
|
||||
O [BIP67](https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki) sugere uma maneira de ordenar lexicograficamente as chaves, de modo que sempre gerem as mesmas multisigs. A ColdCard e a Electrum estão entre as carteiras que já possuem suporte a isso. Claro, isso pode causar problemas por si só se não soubermos se um endereço multisig foi criado com chaves classificadas ou não classificadas. Mais uma vez, os [descritores](03_5_Understanding_the_Descriptor.md) vem ao nosso resgate. Se uma multisig não for classificada, ele será construído com a função ```multi``` e se for classificada, será construída com a função ```sortedmulti```.
|
||||
|
||||
Se olharmos o ```desc``` da multisig que criamos acima, veremos que o Bitcoin Core atualmente não classifica os multisigs:
|
||||
```
|
||||
"descriptor": "sh(multi(2,02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191,02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3))#0pazcr4y"
|
||||
```
|
||||
Porém, se ele importa um endereço do tipo ```sortedmulti```, ele fará o processo correto, que é o ponto principal dos descritores!
|
||||
|
||||
> :warning: **AVISO DE VERSÃO:** O Bitcoin Core só entende a função do descritor ```sortedmulti``` após a versão 0.20.0. Podemos tentar acessar o descritor em uma versão anterior do Bitcoin Core e obteremos um erro como ```A function is needed within P2WSH```.
|
||||
|
||||
## Enviando Fundos para um Endereço Multisig
|
||||
|
||||
Se tivermos uma multisig em um formato P2SH conveniente, como o gerado pelo ```bitcoin-cli```, podemos enviar como um endereço normal.
|
||||
```
|
||||
$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid')
|
||||
$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout')
|
||||
$ recipient="2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr"
|
||||
|
||||
$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.000065}''')
|
||||
$ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex
|
||||
{
|
||||
"txid": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521",
|
||||
"hash": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521",
|
||||
"version": 2,
|
||||
"size": 83,
|
||||
"vsize": 83,
|
||||
"weight": 332,
|
||||
"locktime": 0,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b",
|
||||
"vout": 0,
|
||||
"scriptSig": {
|
||||
"asm": "",
|
||||
"hex": ""
|
||||
},
|
||||
"sequence": 4294967295
|
||||
}
|
||||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.00006500,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL",
|
||||
"hex": "a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387",
|
||||
"reqSigs": 1,
|
||||
"type": "scripthash",
|
||||
"addresses": [
|
||||
"2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex')
|
||||
$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx
|
||||
b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521
|
||||
```
|
||||
Como podemos ver, não houve nada de incomum na criação da transação e ela parece normal, embora com um endereço com um prefixo diferente do normal (```2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr```). Sem surpresa, como também não vimos diferença quando enviamos para endereços Bech32 pela primeira vez na seção [§4.6](04_6_Creating_a_Segwit_Transaction.md).
|
||||
|
||||
## Resumo: Enviando uma Transação Multsig
|
||||
|
||||
Os endereços do Multisig trancam os fundos usando várias chaves privadas, possivelmente exigindo todas essas chaves privadas para resgate e, possivelmente, exigindo apenas algumas do conjunto. Eles são fáceis de serem criadas com o ```bitcoin-cli``` e são simples para serem enviadas. Essa facilidade se deve em grande parte ao uso invisível de endereços P2SH (Pay-To-Script-Hash), um tópico extenso que já falamos duas vezes, com endereços P2SH-SegWit e agora com as multisig, e um outro que receberá mais atenção no futuro.
|
||||
|
||||
> :fire: ***Qual é o poder das multisig?*** As multisig permitem a modelagem de uma variedade de arranjos financeiros, como corporações, parcerias, comitês e outros grupos. Uma multisig 1 de 2 pode ser a conta bancária conjunta de um casal, enquanto uma multisig 2 de 2 pode ser usado para grandes despesas por uma parceria de responsabilidade limitada. As multisigs também constituem uma das bases dos Smart Contracts. Por exemplo, um negócio imobiliário pode ser fechado com um multisig 2 de 3, onde as assinaturas são enviadas pelo comprador, pelo vendedor e por um agente de custódia. Depois que o agente de custódia concorda que todas as condições foram atendidas, ele libera os fundos para o vendedor, ou, alternativamente, o comprador e o vendedor podem liberar os fundos em conjunto.
|
||||
|
||||
## O Que Vem Depois?
|
||||
|
||||
Vamos continuar "Expandindo as transações de Bitcoin com multisigs" na seção [§6.2: Gastando uma transação Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md).
|
229
pt/06_2_Spending_a_Transaction_to_a_Multisig.md
Normal file
229
pt/06_2_Spending_a_Transaction_to_a_Multisig.md
Normal file
@ -0,0 +1,229 @@
|
||||
# 6.2: Gastando uma Transação Multsig
|
||||
|
||||
A maneira clássica e complexa de gastar fundos enviados para um endereço com várias assinaturas usando o ```bitcoin-cli``` requer que suemos bastante a camisa.
|
||||
|
||||
## Encontrando os fundos
|
||||
|
||||
Para começar, precisamos encontrar nossos fundos. Nosso computador não sabe procurá-los, porque não estão associados a nenhum endereço da nossa carteira. Podemos alertar o ```bitcoind``` para fazer isso usando o comando ```importaddress```:
|
||||
```
|
||||
$ bitcoin-cli -named importaddress address=2NAGfA4nW6nrZkD5je8tSiAcYB9xL2xYMCz
|
||||
```
|
||||
Se temos um node prunado (e provavelmente temos), ao invés desse jeito, precisaremos dizer não para verificar novamente:
|
||||
```
|
||||
$ bitcoin-cli -named importaddress address=2NAGfA4nW6nrZkD5je8tSiAcYB9xL2xYMCz rescan="false"
|
||||
```
|
||||
Se preferirmos, podemos importar o endereço usando nosso descritor (e esta é geralmente a melhor resposta, porque é mais padronizada):
|
||||
```
|
||||
$ bitcoin-cli importmulti '[{"desc": "sh(multi(2,02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191,02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3))#0pazcr4y", "timestamp": "now", "watchonly": true}]'
|
||||
[
|
||||
{
|
||||
"success": true
|
||||
}
|
||||
]
|
||||
```
|
||||
Depois, os fundos devem aparecer quando usarmos o comando ```listunspent```, porém, ainda não podemos gastar facilmente. Na verdade, nossa carteira pode alegar que não podemos gastá-los de forma alguma!
|
||||
|
||||
Se por algum motivo não puder incorporar o endereço da nossa carteira, podemos usar o comando ```gettransaction``` para obtermos mais informações (ou olharmos em um block explorer).
|
||||
```
|
||||
$ bitcoin-cli -named gettransaction txid=b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521 verbose=true
|
||||
{
|
||||
"amount": -0.00006500,
|
||||
"fee": -0.00001000,
|
||||
"confirmations": 3,
|
||||
"blockhash": "0000000000000165b5f602920088a7e36b11214161d6aaebf5229e3ed4f10adc",
|
||||
"blockheight": 1773282,
|
||||
"blockindex": 9,
|
||||
"blocktime": 1592959320,
|
||||
"txid": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521",
|
||||
"walletconflicts": [
|
||||
],
|
||||
"time": 1592958753,
|
||||
"timereceived": 1592958753,
|
||||
"bip125-replaceable": "no",
|
||||
"details": [
|
||||
{
|
||||
"address": "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr",
|
||||
"category": "send",
|
||||
"amount": -0.00006500,
|
||||
"vout": 0,
|
||||
"fee": -0.00001000,
|
||||
"abandoned": false
|
||||
}
|
||||
],
|
||||
"hex": "020000000001011b95a6055174ec64b82ef05b6aefc38f34d0e57197e40281ecd8287b4260dec60000000000ffffffff01641900000000000017a914a5d106eb8ee51b23cf60d8bd98bc285695f233f38702473044022070275f81ac4129e1d167ef7e700739f2899ea4c7f1adef3a4da29436f14fb97e02207310d4ec449eba49f0fa404ae45b9c82431d883490c7a0ed882ad0b5d7a623d0012102883bb5463e37d55252d8b3d5c2141b007b37c8a7db6211f75c955acc5ea325eb00000000",
|
||||
"decoded": {
|
||||
"txid": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521",
|
||||
"hash": "bdf4e3bc5d354a5dfa5528f172480976321d989d7e5806ac14f1fe9b0b1c093a",
|
||||
"version": 2,
|
||||
"size": 192,
|
||||
"vsize": 111,
|
||||
"weight": 441,
|
||||
"locktime": 0,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b",
|
||||
"vout": 0,
|
||||
"scriptSig": {
|
||||
"asm": "",
|
||||
"hex": ""
|
||||
},
|
||||
"txinwitness": [
|
||||
"3044022070275f81ac4129e1d167ef7e700739f2899ea4c7f1adef3a4da29436f14fb97e02207310d4ec449eba49f0fa404ae45b9c82431d883490c7a0ed882ad0b5d7a623d001",
|
||||
"02883bb5463e37d55252d8b3d5c2141b007b37c8a7db6211f75c955acc5ea325eb"
|
||||
],
|
||||
"sequence": 4294967295
|
||||
}
|
||||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.00006500,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL",
|
||||
"hex": "a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387",
|
||||
"reqSigs": 1,
|
||||
"type": "scripthash",
|
||||
"addresses": [
|
||||
"2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configurando as nossas variáveis
|
||||
|
||||
Quando estivermos prontos para gastar os fundos recebidos por um endereço multisig, precisaremos coletar _muitos_ dados: Muito mais do que precisamos quando fazemos uma transação usando um UTXO de um P2PKH normal ou SegWit. Isso ocorre em parte porque as informações sobre o endereço multisig não estão em nossa posse e em parte porque estamos gastando dinheiro que foi enviado para um endereço P2SH (Pay-To-Script-Hash) e isso é muito mais exigente.
|
||||
|
||||
No total, precisaremos coletar três coisas: Informações estendidas sobre o UTXO; O redemScript e; Todas as chaves privadas envolvidas. Obviamente, também iremos precisar de um novo endereço de destinatário. As chaves privadas precisam aguardar a etapa de assinatura, mas tudo pode ser feito agora.
|
||||
|
||||
### Acessando as informações do UTXO
|
||||
|
||||
Para começar, vamos pegar o ```txid``` e o ```vout``` para a transação que desejamos gastar, como de costume. Nesse caso, os dados foram recuperados das informações ```gettransaction``` acima:
|
||||
```
|
||||
$ utxo_txid=b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521
|
||||
$ utxo_vout=0
|
||||
```
|
||||
No entanto, precisamos também acessar um terceiro bit de informação sobre o UTXO, nosso ```scriptPubKey```/```hex```, que é o script que travamos a transação. Novamente, podemos fazer isso observando os detalhes da transação:
|
||||
```
|
||||
$ utxo_spk=a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387
|
||||
```
|
||||
|
||||
### Gravando o script de resgate
|
||||
|
||||
Felizmente, salvamos nosso ```redeemScript```. Agora devemos registrá-lo em uma variável.
|
||||
|
||||
O valor foi extraído da criação de endereço na seção anterior.
|
||||
```
|
||||
redeem_script="522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae"
|
||||
```
|
||||
### Decidindo o destinatário
|
||||
|
||||
Vamos apenas enviar o dinheiro de volta para nós mesmos. Isso é útil porque libera os fundos do multisig, convertendo-os em uma transação P2PKH normal que pode ser posteriormente confirmada por uma única chave privada:
|
||||
```
|
||||
$ recipient=$(bitcoin-cli getrawchangeaddress)
|
||||
```
|
||||
## Criando nossa transação
|
||||
|
||||
Agora podemos criar nossa transação. Essa parte é parecida com as transações normais.
|
||||
```
|
||||
$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00005}''')
|
||||
$ echo $rawtxhex
|
||||
020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b10000000000ffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000
|
||||
```
|
||||
|
||||
## Assinando a nossa transação
|
||||
|
||||
Agora estamos prontos para assinar a transação. Este é um processo de várias etapas porque precisaremos fazer em várias máquinas, cada uma das quais contribuirá com suas próprias chaves privadas.
|
||||
|
||||
### Carregando a primeira chave privada
|
||||
|
||||
Como essa transação não está fazendo uso total da nossa carteira, precisaremos acessar diretamente as chaves privadas. Começando com a ```máquina1```, onde devemos recuperar qualquer uma das chaves privadas do usuário que estavam envolvidas no multisig:
|
||||
```
|
||||
machine1$ bitcoin-cli -named dumpprivkey address=$address1
|
||||
cNPhhGjatADfhLD5gLfrR2JZKDE99Mn26NCbERsvnr24B3PcSbtR
|
||||
```
|
||||
> :warning: **Atenção:** Acessar diretamente as chaves privadas do shell é um comportamento muito perigoso e deve ser feito com extremo cuidado se estivermos em um ambiente produtivo. No mínimo, é importante não salvar as informações em uma variável que possa ser acessada pela nossa máquina. Remover o histórico do shell é outro grande passo. No máximo, podemos evitar de fazer isso.
|
||||
|
||||
### Fazendo a nossa primeira assinatura
|
||||
|
||||
Agora podemos fazer nossa primeira assinatura com o comando ```signrawtransactionwithkey```. É aqui que as coisas ficam diferentes das normais: Precisaremos treinar o comando sobre como assinar. Podemos fazer isso adicionando as seguintes informações novas:
|
||||
|
||||
* Incluir um argumento ```prevtxs``` que tenha o ```txid```, o ```vout```, o ```scriptPubKey``` e o ```redeemScript``` que gravamos, cada um deles um par individual do valor-chave no objeto JSON.
|
||||
* Incluir um argumento ```privkeys``` que lista as chaves privadas que pegamos nesta máquina.
|
||||
|
||||
```
|
||||
machine1$ bitcoin-cli -named signrawtransactionwithkey hexstring=$rawtxhex prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cNPhhGjatADfhLD5gLfrR2JZKDE99Mn26NCbERsvnr24B3PcSbtR"]'
|
||||
{
|
||||
"hex": "020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b100000000920047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e3010047522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352aeffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000",
|
||||
"complete": false,
|
||||
"errors": [
|
||||
{
|
||||
"txid": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521",
|
||||
"vout": 0,
|
||||
"witness": [
|
||||
],
|
||||
"scriptSig": "0047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e3010047522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae",
|
||||
"sequence": 4294967295,
|
||||
"error": "CHECK(MULTI)SIG failing with non-zero signature (possibly need more signatures)"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
Isso produz erros assustadores e mostra um status de ```failing```. Tudo bem. Podemos ver que a assinatura foi parcialmente bem-sucedida porque o ```hex``` ficou mais longo. Embora a transação tenha sido parcialmente assinada, ela não foi concluída porque precisa de mais assinaturas.
|
||||
|
||||
### Repetindo para os outros assinantes
|
||||
|
||||
Agora podemos passar a transação adiante, para ser assinada novamente por nós, que temos a outra parte da multisig. Eles fazem isso executando o mesmo comando de assinatura que fizemos, porém: (1) com o ```hex``` maior que produzimos anteriormente (```bitcoin-cli -named signrawtransactionwithkey hexstring = $ rawtxhex prevtxs = '' '[{"txid": " '$ utxo_txid'", "vout": '$ utxo_vout', "scriptPubKey": " '$ utxo_spk'", "redeemScript": " '$ redeem_script'"}] '' 'privkeys =' [ "cMgb3KM8hPATCtgMKarKMiFesLft6eEw3DY6BB8d97fkeXeqQagw"] '| jq -r'. | .hex'```) e; (2) com nossa própria chave privada.
|
||||
|
||||
> :information_source: **NOTA - M de N vs N de N:** Obviamente, se tivermos uma assinatura N de N (como a multisig 2 de 2 do exemplo), todas as partes precisarão assinar, mas se tiviermos uma multisignatura M de N onde "M <N", a assinatura estará completa quando apenas alguns ("M") tiverem assinado.
|
||||
|
||||
Para fazer isso, primeiro acessamos as chaves privadas:
|
||||
```
|
||||
machine2$ bitcoin-cli -named dumpprivkey address=$address2
|
||||
cVhqpKhx2jgfLUWmyR22JnichoctJCHPtPERm11a2yxnVFKWEKyz
|
||||
```
|
||||
Depois, assinamos o novo ```hex``` usando os mesmos valores ```prevtxs```:
|
||||
```
|
||||
machine1$ bitcoin-cli -named signrawtransactionwithkey hexstring=020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b100000000920047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e3010047522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352aeffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000 prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cVhqpKhx2jgfLUWmyR22JnichoctJCHPtPERm11a2yxnVFKWEKyz"]'
|
||||
{
|
||||
"hex": "020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b100000000d90047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e301473044022000a402ec4549a65799688dd531d7b18b03c6379416cc8c29b92011987084e9f402205470e24781509c70e2410aaa6d827aa133d6df2c578e96a496b885584fb039200147522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352aeffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000",
|
||||
"complete": true
|
||||
}
|
||||
```
|
||||
Por fim, podemos precisar enviar uma ```hexstring``` ainda mais longa que produzem para assinaturas adicionais.
|
||||
|
||||
Mas, neste caso, podemos ver que a assinatura está `complete`!
|
||||
|
||||
## Enviando nossa transação
|
||||
|
||||
Quando terminarmos, devemos recorrer à metodologia ```JQ``` padrão para salvar nossa ```hexstring``` e, em seguida, enviá-la:
|
||||
```
|
||||
$ signedtx=$(bitcoin-cli -named signrawtransactionwithkey hexstring=020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b100000000920047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e3010047522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352aeffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000 prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cVhqpKhx2jgfLUWmyR22JnichoctJCHPtPERm11a2yxnVFKWEKyz"]' | jq -r .hex)
|
||||
$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx
|
||||
99d2b5717fed8875a1ed3b2827dd60ae3089f9caa7c7c23d47635f6f5b397c04
|
||||
```
|
||||
|
||||
## Compreendendo a importância desta metodologia de assinatura expandida
|
||||
|
||||
Isso deu um belo trabalho e, como logo iremos aprender, existe uma tolice ao utilizar as chaves privadas, o redeem script e com a scriptpubkey pois eles não são realmente necessários para resgatar os endereços de multisg usando versões mais recentes do Bitcoin Core. Então qual era a questão?
|
||||
|
||||
Esta metodologia de resgate mostra uma maneira padrão de assinar e reutilizar transações P2SH. Em suma, para resgatar fundos P2SH, uma ```signrawtransactionwithkey``` precisa:
|
||||
|
||||
1. Incluir o ```scriptPubKey```, que explica o quebra-cabeça criptográfico P2SH;
|
||||
2. Incluir o ```redeemScript```, que resolve o quebra-cabeça criptográfico P2SH e apresenta um novo quebra-cabeça;
|
||||
3. Ser executado em cada máquina que contém as chaves privadas necessárias;
|
||||
4. Incluir as assinaturas relevantes, que resolvem o quebra-cabeça do redemScript.
|
||||
|
||||
Aqui, vimos essa metodologia usada para resgatar os fundos multisig. No futuro, também podemos usá-la para resgatar os fundos que foram trancados com outros scripts P2SH mais complexos, conforme explicado no Capítulo 9.
|
||||
|
||||
## Resumo: Gastando uma Transação Multsig
|
||||
|
||||
Acontece que gastar dinheiro enviado para um endereço multisig pode dar um pouco de trabalho. Mas, contanto que tenhamos os endereços originais e nosso redemScript, podemos fazer isso assinando uma transação bruta com cada endereço diferente e fornecendo mais algumas informações ao longo do caminho.
|
||||
|
||||
## O Que Vem Depois?
|
||||
|
||||
Vamos continuar "Expandindo as transações de Bitcoin com multisigs" na seção [§6.3: Enviando e Gastando uma Transação Multisig de Maneira Automatizada](06_3_Sending_an_Automated_Multisig.md).
|
120
pt/06_3_Sending_an_Automated_Multisig.md
Normal file
120
pt/06_3_Sending_an_Automated_Multisig.md
Normal file
@ -0,0 +1,120 @@
|
||||
# 6.3: Enviando e Gastando uma Transação Multisig de Maneira Automatizada
|
||||
|
||||
A técnica padrão para criar endereços com várias assinaturas e gastar os fundos é complexa, mas é um exercício interessante para entender um pouco mais como funcionam e como podemos manipulá-los em um nível relativamente baixo. No entanto, o Bitcoin Core tornou os multisigs mais fáceis de serem manipulados nas novas versões.
|
||||
|
||||
> :warning: **AVISO DE VERSÃO:** O comando ```addmultisigaddress``` está disponível no Bitcoin Core v0.10 ou superior.
|
||||
|
||||
## Criando um endereço Multisig em nossa carteira
|
||||
|
||||
Para tornar os fundos enviados para endereços multisig mais fáceis de serem gastos, só precisamos fazer algumas pré-configurações usando o comando ```addmultisigaddress```. Não é o que gostaríamos de fazer se estivéssemos escrevendo programas de carteiras que utilizam multisig, mas se estivesse apenas tentando receber alguns fundos, isso poderia evitar alguns problemas.
|
||||
|
||||
### Coletando as chaves
|
||||
|
||||
Vamos começar criando os endereços P2PKH e recuperando as chaves públicas, como de costume, para cada usuário que fará parte do multisig:
|
||||
```
|
||||
machine1$ address3=$(bitcoin-cli getnewaddress)
|
||||
machine1$ echo $address3
|
||||
tb1q4ep2vmakpkkj6mflu94x5f94q662m0u5ad0t4w
|
||||
machine1$ bitcoin-cli -named getaddressinfo address=$address3 | jq -r '. | .pubkey'
|
||||
0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc
|
||||
|
||||
machine2$ address4=$(bitcoin-cli getnewaddress)
|
||||
machine2$ echo $address4
|
||||
tb1qa9v5h6zkhq8wh0etnv3ae9cdurkh085xufl3de
|
||||
machine2$ bitcoin-cli -named getaddressinfo address=$address4 | jq -r '. | .pubkey'
|
||||
02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f
|
||||
```
|
||||
|
||||
### Criando o endereço Multisig em qualquer lugar
|
||||
|
||||
Em seguida, vamos criar o multisig em _cada máquina que contribuiu com as assinaturas_ usando um novo comando, ```addmultisigaddress```, ao invés de ```createmultisig```. Este novo comando salva algumas das informações da nossa carteira, tornando muito mais fácil gastar o dinheiro no futuro.
|
||||
```
|
||||
machine1$ bitcoin-cli -named addmultisigaddress nrequired=2 keys='''["'$address3'","02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f"]'''
|
||||
{
|
||||
"address": "tb1q9as46kupwcxancdx82gw65365svlzdwmjal4uxs23t3zz3rgg3wqpqlhex",
|
||||
"redeemScript": "52210297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc2102a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f52ae",
|
||||
"descriptor": "wsh(multi(2,[d6043800/0'/0'/15']0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc,[e9594be8]02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f))#wxn4tdju"
|
||||
}
|
||||
|
||||
machine2$ bitcoin-cli -named addmultisigaddress nrequired=2 keys='''["0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc","'$address4'"]'''
|
||||
{
|
||||
"address": "tb1q9as46kupwcxancdx82gw65365svlzdwmjal4uxs23t3zz3rgg3wqpqlhex",
|
||||
"redeemScript": "52210297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc2102a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f52ae",
|
||||
"descriptor": "wsh(multi(2,[ae42a66f]0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc,[fe6f2292/0'/0'/2']02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f))#cc96c5n6"
|
||||
}
|
||||
```
|
||||
Conforme observado na seção anterior, atualmente não importa se usamos endereços ou chaves públicas, então mostramos o outro mecanismo aqui, misturando os dois. Iremos obter o mesmo endereço multisig de qualquer maneira. No entanto, _devemos usar a mesma ordem sempre_. Portanto, é melhor que os membros do multisig verifiquem entre si a ordem dos dados para ter certeza de que todos obtiveram o mesmo resultado.
|
||||
|
||||
### Esperando para receber os fundos
|
||||
|
||||
Depois disso, os membros do multisig ainda precisarão executar o comando ```importaddress``` para observar os fundos recebidos no endereço multisig:
|
||||
```
|
||||
machine1$ bitcoin-cli -named importaddress address=2Mzw7WBvh9RAQ4ssKqxyNyP7L9NAojLqSW8 rescan="false"
|
||||
|
||||
machine2$ bitcoin-cli -named importaddress address=2Mzw7WBvh9RAQ4ssKqxyNyP7L9NAojLqSW8 rescan="false"
|
||||
```
|
||||
|
||||
## Gastando novamente com uma transação automatizada
|
||||
|
||||
Posteriormente, podemos receber os fundos no endereço com várias assinaturas sem nenhum problema. O uso do ```addmultisigaddress``` é simplesmente uma questão burocrática por parte dos destinatários: Um pouco de contabilidade para facilitar a vida deles quando desejarem gastar os saldos.
|
||||
|
||||
Mas, isso torna a vida muito mais fácil. Como as informações foram salvas na carteira, os assinantes poderão gastar os fundos enviados para o endereço com várias assinaturas exatamente como qualquer outro endereço, ao invés de assinar sempre em várias máquinas diferentes.
|
||||
|
||||
Podemos começar coletando as variáveis, mas não precisamos mais nos preocupar com o ```scriptPubKey``` ou com o ```redeemScript```.
|
||||
|
||||
Aqui está uma nova transação enviada para nosso novo endereço multisig:
|
||||
```
|
||||
machine1$ utxo_txid=b9f3c4756ef8159d6a66414a4317f865882ee04beb57a0f8349dafcc98f5acbc
|
||||
machine1$ utxo_vout=0
|
||||
machine1$ recipient=$(bitcoin-cli getrawchangeaddress)
|
||||
```
|
||||
Vamos criar uma transação bruta:
|
||||
```
|
||||
machine1$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00005}''')
|
||||
```
|
||||
E depois, assiná-la:
|
||||
```
|
||||
machine1$ bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex
|
||||
{
|
||||
"hex": "02000000000101bcacf598ccaf9d34f8a057eb4be02e8865f817434a41666a9d15f86e75c4f3b90000000000ffffffff0188130000000000001600144f93c831ec739166ea425984170f4dc6bac75829040047304402205f84d40ba16ff49e60a7fc9228ef5917473aae1ab667dad01e113ca0fef3008b02201a50da2c65f38798aea94bcbd5bbf065bc1e38de44bacee69d525dcddcc11bba01004752210297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc2102a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f52ae00000000",
|
||||
"complete": false,
|
||||
"errors": [
|
||||
{
|
||||
"txid": "b9f3c4756ef8159d6a66414a4317f865882ee04beb57a0f8349dafcc98f5acbc",
|
||||
"vout": 0,
|
||||
"witness": [
|
||||
"",
|
||||
"304402205f84d40ba16ff49e60a7fc9228ef5917473aae1ab667dad01e113ca0fef3008b02201a50da2c65f38798aea94bcbd5bbf065bc1e38de44bacee69d525dcddcc11bba01",
|
||||
"",
|
||||
"52210297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc2102a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f52ae"
|
||||
],
|
||||
"scriptSig": "",
|
||||
"sequence": 4294967295,
|
||||
"error": "CHECK(MULTI)SIG failing with non-zero signature (possibly need more signatures)"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
Observe que não precisamos mais da ajuda extra do comando ```signrawtransactionwithkey```, porque todas essas informações já estão em nossa carteira. Mais importante, não tornamos nossas chaves privadas vulneráveis ao manipulá-las diretamente. Ao invés disso, o processo é _exatamente_ o mesmo que gastar um UTXO normal, exceto que a transação não foi totalmente assinada no final.
|
||||
|
||||
### Assinando em outras máquinas
|
||||
|
||||
A etapa final é exportar o ```hex``` parcialmente assinado para a outra máquina e assinar a transação novamente:
|
||||
```
|
||||
machine2$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=02000000014ecda61c45f488e35c613a7c4ae26335a8d7bfd0a942f026d0fb1050e744a67d000000009100473044022025decef887fe2e3eb1c4b3edaa155e5755102d1570716f1467bb0b518b777ddf022017e97f8853af8acab4853ccf502213b7ff4cc3bd9502941369905371545de28d0147522102e7356952f4bb1daf475c04b95a2f7e0d9a12cf5b5c48a25b2303783d91849ba421030186d2b55de166389aefe209f508ce1fbd79966d9ac417adef74b7c1b5e0777652aeffffffff0130e1be07000000001976a9148dfbf103e48df7d1993448aa387dc31a2ebd522d88ac00000000 | jq -r '.hex')
|
||||
```
|
||||
Quando todos os os assinantes confirmaram a assinatura, estaremos prontos para enviar a transação para a rede:
|
||||
```
|
||||
machine2$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx
|
||||
3ce88839ac6165aeadcfb188c490e1b850468eff571b4ca78fac64342751510d
|
||||
```
|
||||
Tal como acontece com o atalho discutido na seção [§4.5: Enviando Moedas com Transações Brutas Automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md), o resultado é muito mais fácil, mas perdemos certo controle no processo.
|
||||
|
||||
## Resumo: Enviando e Gastando uma Transação Multisig de Maneira Automatizada
|
||||
|
||||
Existe uma maneira mais fácil de gastar fundos enviados para os nossos endereços multisig que simplesmente requerem o uso do comando ```addmultisigaddress``` quando criamos nosso endereço. Ele não demonstra os meandros do gasto do P2SH e não nos dará um controle abrangente, mas se queremos apenas receber nossas moedas, este pode ser o melhor caminho.
|
||||
|
||||
## O Que Vem Depois?
|
||||
|
||||
Saiba mais sobre "Expandindo as transações de Bitcoin com multisigs" no [Capítulo 7: Expandindo as transações do Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md).
|
Loading…
x
Reference in New Issue
Block a user