|
| 1 | +# 3.5: Compreendendo o Descritor |
| 2 | + |
| 3 | +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão. Cuidado, leitor. |
| 4 | +
|
| 5 | + |
| 6 | +Você deve ter notado um campo `desc:` estranho no comando `listunspent` da seção anterior. Aqui está o que está acontecendo (e como ele pode ser usado para transferir endereços). |
| 7 | + |
| 8 | +> :warning: **AVISO DE VERSÃO:** Esta é uma inovação do Bitcoin Core v 0.17.0 que continuou a ser expandida através do Bitcoin Core 0.20.0. A maioria dos comandos nesta seção são de 0.17.0, mas o `importmulti` atualizado que suporta descritores é de 0.18.0. |
| 9 | +
|
| 10 | +## Sabendo Sobre Transferência de Endereços |
| 11 | + |
| 12 | +A maior parte deste curso presume que estejamos trabalhando inteiramente a partir de um único node onde gerenciamos nossa própria carteira, enviando e recebendo pagamentos com os endereços criados por essa carteira. No entanto, não é necessariamente assim que funciona o ecossistema Bitcoin por completo. Nesse caso, é mais provável que movamos endereços entre carteiras e até mesmo configuremos carteiras para vigiar fundos controlados por carteiras diferentes. |
| 13 | + |
| 14 | +É aí que entram os descritores. Eles são mais úteis se estivermos interagindo com _outro_ software que não seja o Bitcoin Core, e se realmente precisemos nos apoiar neste tipo de função de compatibilidade: consulte [§6.1] (https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/pt/06_1_Sending_a_Transaction_to_a_Multisig.md) para um exemplo do mundo real de como ter a capacidade de descritores é fundamental. |
| 15 | + |
| 16 | +Mover endereços entre carteiras costumava focar em `xpub` e` xprv`, e esses ainda são suportados. |
| 17 | + |
| 18 | +> :book: ***O que é xprv?*** Uma chave privada estendida (_xtended private key_). Esta é a combinação de uma chave privada e um código de cadeia. É uma chave privada da qual uma sequência inteira de chaves privadas filhas pode ser derivada. |
| 19 | +
|
| 20 | +> :book: ***O que é xpub?*** Uma chave pública estendida (_xtended public key_). Esta é a combinação de uma chave pública e um código de cadeia. É uma chave pública da qual uma sequência inteira de chaves públicas filhas pode ser derivada. |
| 21 | +
|
| 22 | + |
| 23 | +O fato de que podemos ter uma "sequência inteira de chaves filhas" revela o fato de que "xpub" e "xprv" não são chaves padrão como falamos até agora. Em vez disso, são chaves hierárquicas que podem ser usadas para criar famílias inteiras de chaves, baseadas na ideia de carteiras HD. |
| 24 | + |
| 25 | +> :book: ***O que é uma Carteira HD?*** A maioria das carteiras modernas é construída com base no [BIP32: Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki). Este é um design hierárquico em que uma única semente pode ser usada para gerar uma sequência completa de chaves. A carteira inteira pode então ser restaurada a partir dessa semente, em vez de exigir a restauração de cada chave privada. |
| 26 | +
|
| 27 | +> :book: ***O que é um caminho de derivação?*** Quando você tem chaves hierárquicas, precisa ser capaz de definir chaves individuais como descendentes de uma semente. Por exemplo, `[0]` é a 0ª chave, `[0/1]` é o primeiro filho da 0ª chave, `[1/0/1]` é o primeiro neto do filho zero da 1ª chave. Algumas chaves também contêm um `'` após o número, para mostrar que estão protegidas, o que as protege de um ataque específico que pode ser usado para derivar uma `xprv` de uma `xpub`. Você não precisa se preocupar com os detalhes, a não ser o fato de que esses `'`s causarão problemas de formatação ao trabalhar na linha de comando. |
| 28 | +
|
| 29 | +> :information_source: **NOTA:** um caminho de derivação define uma chave, o que significa que uma chave representa um caminho de derivação. Eles são equivalentes. No caso de um descritor, o caminho de derivação permite ao `bitcoind` saber de onde veio a chave que segue no descritor! |
| 30 | +
|
| 31 | +`xpubs` e `xprvs` provaram ser insuficientes quando os tipos de chaves públicas multiplicadas sob a [expansão SegWit](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/04_6_Creating_a_Segwit_Transaction.md), portanto a necessidade de "descritores de saída". |
| 32 | + |
| 33 | +> :book: ***O que é um descritor de saída?*** Uma descrição precisa de como derivar um endereço Bitcoin de uma combinação de uma função com uma ou mais entradas para essa função. |
| 34 | +
|
| 35 | +A introdução de funções nos descritores é o que os torna poderosos, porque eles podem ser usados para transferir todos os tipos de endereços, desde os endereços legados com os quais estamos trabalhando agora até os endereços Segwit e multisig que encontraremos no futuro. Uma função individual corresponde a um determinado tipo de endereço e se correlaciona com regras específicas para gerar esse endereço. |
| 36 | + |
| 37 | +## Capturando um Descritor |
| 38 | + |
| 39 | +Descritores são visíveis em vários comandos, como por exemplo `listunspent` e `getaddressinfo`: |
| 40 | +``` |
| 41 | +$ bitcoin-cli getaddressinfo ms7ruzvL4atCu77n47dStMb3of6iScS8kZ |
| 42 | +{ |
| 43 | + "address": "ms7ruzvL4atCu77n47dStMb3of6iScS8kZ", |
| 44 | + "scriptPubKey": "76a9147f437379bcc66c40745edc1891ea6b3830e1975d88ac", |
| 45 | + "ismine": true, |
| 46 | + "solvable": true, |
| 47 | + "desc": "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk", |
| 48 | + "iswatchonly": false, |
| 49 | + "isscript": false, |
| 50 | + "iswitness": false, |
| 51 | + "pubkey": "03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388", |
| 52 | + "iscompressed": true, |
| 53 | + "ischange": false, |
| 54 | + "timestamp": 1592335136, |
| 55 | + "hdkeypath": "m/0'/0'/18'", |
| 56 | + "hdseedid": "fdea8e2630f00d29a9d6ff2af7bf5b358d061078", |
| 57 | + "hdmasterfingerprint": "d6043800", |
| 58 | + "labels": [ |
| 59 | + "" |
| 60 | + ] |
| 61 | +} |
| 62 | +``` |
| 63 | +Neste caso, o descritor é `pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk`. |
| 64 | + |
| 65 | +## Compreendendo um Descritor |
| 66 | + |
| 67 | +Um descritor é composto de várias partes: |
| 68 | +``` |
| 69 | +função([caminho-de-derivação]chave)#checksum |
| 70 | +``` |
| 71 | +Aqui está o que tudo isso significa: |
| 72 | +* **Função.** A função que é usada para criar um endereço a partir dessa chave. Nestes casos, é `pkh`, que é o endereço padrão P2PKH legado que você encontrou em [§3.3: Configurando Nossa Carteira](03_3_Setting_Up_Your_Wallet.md). Da mesma forma, um endereço P2WSH SegWit usaria `wsh` e um endereço P2WPKH usaria` wpkh`. |
| 73 | +* **Caminho de Derivação.** Descreve qual parte de uma carteira HD está sendo exportada. Neste caso, é uma semente com a impressão digital `d6043800` e então o 18º filho do 0º filho do 0º filho (`0 '/ 0' / 18'`) dessa semente. Também pode haver uma derivação adicional após a chave: `função([caminho-de-derivação]chave/mais-derivação)#checksum` |
| 74 | + * É importante notar aqui que, se algum dia recebermos um caminho de derivação sem uma impressão digital, poderemos inventá-lo. Acontece que, se houver um existente, devemos usá-lo, porque se algum dia voltarmos para o dispositivo que criou a impressão digital, precisaremos ter o mesmo. |
| 75 | +* **Chave**. A chave ou as chaves que estão sendo transferidas. Isso pode ser algo tradicional como uma `xpub` ou `xprv`, pode ser apenas uma chave pública para um endereço, como neste caso, pode ser um conjunto de endereços para uma multi-assinatura, ou pode ser outra coisa. Estes são os dados principais: a função explica o que fazer com eles. |
| 76 | +* **Checksum**. Os descritores são feitos para poderem ser transferidos por humanos. Esta soma de verificação (checksum) garante que o fizemos corretamente. |
| 77 | + |
| 78 | +Podemos ver [Informações do Suporte do Bitcoin Core ao Descritor](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md) para maiores informações. |
| 79 | + |
| 80 | +## Examinando um Descritor |
| 81 | + |
| 82 | +Podemos examinar um descritor com o comando RPC `getdescriptorinfo`: |
| 83 | +``` |
| 84 | +$ bitcoin-cli getdescriptorinfo "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk" |
| 85 | +{ |
| 86 | + "descriptor": "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk", |
| 87 | + "checksum": "4ahsl9pk", |
| 88 | + "isrange": false, |
| 89 | + "issolvable": true, |
| 90 | + "hasprivatekeys": false |
| 91 | +} |
| 92 | +``` |
| 93 | +Observe que ele retorna um checksum. Se algum dia recebermos um descritor sem um checksum, podemos buscá-lo com este comando: |
| 94 | +``` |
| 95 | +$ bitcoin-cli getdescriptorinfo "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)" |
| 96 | +{ |
| 97 | + "descriptor": "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk", |
| 98 | + "checksum": "4ahsl9pk", |
| 99 | + "isrange": false, |
| 100 | + "issolvable": true, |
| 101 | + "hasprivatekeys": false |
| 102 | +} |
| 103 | +``` |
| 104 | +Além de nos dar o checksum, esse comando também verifica a validade do descritor e nos dá informações úteis, como se o descritor contém chaves privadas. |
| 105 | + |
| 106 | +Um dos poderes de um descritor é a capacidade de derivar um endereço de forma padrão. Isto é feito com o RPC `deriveaddresses`. |
| 107 | +``` |
| 108 | +$ bitcoin-cli deriveaddresses "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk" |
| 109 | +[ |
| 110 | + "ms7ruzvL4atCu77n47dStMb3of6iScS8kZ" |
| 111 | +] |
| 112 | +``` |
| 113 | +Podemos observar que ele nos retorna o endereço inicial (como deveria). |
| 114 | + |
| 115 | +## Importando um Descritor |
| 116 | + |
| 117 | +Mas a coisa realmente importante sobre um descritor é que podemos levá-lo a outra máquina (remota) e importá-lo. Isto é feito com o RPC `importmulti` usando a opção `desc`: |
| 118 | +``` |
| 119 | +remote$ bitcoin-cli importmulti '[{"desc": "pkh([d6043800/0'"'"'/0'"'"'/18'"'"']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk", "timestamp": "now", "watchonly": true}]' |
| 120 | +[ |
| 121 | + { |
| 122 | + "success": true |
| 123 | + } |
| 124 | +] |
| 125 | +``` |
| 126 | +Primeiro, podemos notar nosso primeiro uso muito feio de aspas. Toda `'` no caminho de derivação pode ser substituído com `'"'"'`. Devemos esperar fazer isso se estivermos manipulando um descritor que contenha um caminho de derivação. (Outra opção é trocar o `'` com um `h` de "hardened", mas isto irá alterar nosso checksum, então caso tenhamos essa preferência pela facilidade de uso, precisaremos de umm novo checksum com o `getdescriptorinfo`.) |
| 127 | + |
| 128 | +Segundo, podemos notar que o marcamos como `watchonly`. Isso ocorre porque sabemos que é uma chave pública, então não podemos usá-la para gastar fundos. Se tivéssemos esquecido de colocar esta sinalização, `importmulti` teria dito algo como o seguinte: `Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag.`. |
| 129 | + |
| 130 | +> :book: ***O que é um endereço watch-only?*** Um endereço watch-only nos permite atentar a transações de certo endereço (ou para toda uma família de endereços se tivermos usado uma `xpub`), mas não nos permite gastarmos fundos destes endereços. |
| 131 | +
|
| 132 | +Usando `getaddressbylabel`, podemos ver que nosso endereço foi importado corretamente na nossa máquina remota! |
| 133 | +``` |
| 134 | +remote$ bitcoin-cli getaddressesbylabel "" |
| 135 | +{ |
| 136 | + "ms7ruzvL4atCu77n47dStMb3of6iScS8kZ": { |
| 137 | + "purpose": "receive" |
| 138 | + } |
| 139 | +} |
| 140 | +``` |
| 141 | +## Resumo: Compreendendo o Descritor |
| 142 | + |
| 143 | +Descritores nos permitem passar chaves públicas e privadas entre carteiras, mas mais do que isso, nos permitem definir endereços de forma correta e precisa, além de derivar endereços de tipos diversos a partir de um formato descritivo e padronizado. |
| 144 | + |
| 145 | +> :fire: ***Qual é o poder dos descritores?*** Descritores nos permitem importar e exportar chaves e seeds. O que é excelente se queremos movê-las entre carteiras diferentes. Como um desenvolvedor, eles também nos permitem construir o tipo preciso de endereços que queremos criar. Por exemplo, nós os utilizamos na [FullyNoded 2](https://github.com/BlockchainCommons/FullyNoded-2/blob/master/Docs/How-it-works.md) para gerarmos um multisig de três seeds. |
| 146 | +
|
| 147 | +Faremos uso real dos descritores em [§7.3](07_3_Integrating_with_Hardware_Wallets.md), quando estivermos importando endereços de uma hardware wallet. |
| 148 | + |
| 149 | +## O Que Vem Depois? |
| 150 | + |
| 151 | +Vamos avançar no "bitcoin-cli" com o [Capítulo Quatro: Enviando Transações no Bitcoin](04_0_Sending_Bitcoin_Transactions.md). |
0 commit comments