mirror of
https://github.com/ChristopherA/Learning-Bitcoin-from-the-Command-Line.git
synced 2025-06-07 07:56:31 +00:00
Merge pull request #383 from KoreaComK/chapter11
Chapter 11 Translated by @koreacomk need review
This commit is contained in:
commit
8beb904f5a
23
pt/11_0_Empowering_Timelock_with_Bitcoin_Scripts.md
Normal file
23
pt/11_0_Empowering_Timelock_with_Bitcoin_Scripts.md
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
# Capítulo 11: Expandindo o timelock com scripts do Bitcoin
|
||||
|
||||
O recurso ```nLockTime``` da seção [§8.1](08_1_Sending_a_Transaction_with_a_Locktime.md) foi apenas o começo dos Timelocks. Quando começamos a escrever scripts do Bitcoin, dois opcodes de timelocks ficam disponíveis.
|
||||
|
||||
## Objetivos deste capítulo
|
||||
|
||||
Depois de trabalhar neste capítulo, um desenvolvedor será capaz de:
|
||||
|
||||
* Decidir qual Timelock usar;
|
||||
* Criar scripts com CLTV;
|
||||
* Criar scripts com CSV.
|
||||
|
||||
Os objetivos secundários do capítulo incluem a capacidade de:
|
||||
|
||||
* Compreender as diferenças entre os diferentes timelocks;
|
||||
* Gerar tempos relativos.
|
||||
|
||||
## Índice
|
||||
|
||||
* [Seção 1: Compreendendo as Opções de Timelocks](11_1_Understanding_Timelock_Options.md)
|
||||
* [Seção 2: Usando o CLTV nos Scripts](11_2_Using_CLTV_in_Scripts.md)
|
||||
* [Seção 3: Usando o CSV nos Scripts](11_3_Using_CSV_in_Scripts.md)
|
49
pt/11_1_Understanding_Timelock_Options.md
Normal file
49
pt/11_1_Understanding_Timelock_Options.md
Normal file
@ -0,0 +1,49 @@
|
||||
# 11.1: Compreendendo as Opções de Timelocks
|
||||
|
||||
Na seção [§8.1: Enviando uma transação com Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md), o ```nLocktime``` ofereceu uma ótima opção inicial para bloquear as transações para que não pudessem ser gastas até algum ponto no futuro, com base no tempo (data/hora) ou na altura do bloco. Mas, essa não é a única maneira de colocar um timelock em uma transação.
|
||||
|
||||
## Compreendendo as limitações do nLockTime
|
||||
|
||||
O ```nLockTime``` é uma maneira simples e poderosa de bloquear uma transação, mas possui algumas limitações:
|
||||
|
||||
1. **Sem divisões.** O `nLocktime` bloqueia toda a transação;
|
||||
2. **Sem rede.** A maioria dos nodes modernos não aceita um ```nLockTime``` na mempool até que esteja na hora ou próximo para ser finalizada;
|
||||
3. **Sem Scripts.** O uso simples e original do ```nLockTime``` não permitia que fosse usado em Scripts;
|
||||
4. **Sem proteção.** O ```nLockTime``` permite que os fundos sejam gastos com uma transação diferente e não bloqueada.
|
||||
|
||||
O último item costumava ser o _dealbreaker_ para o ```nLockTime```. Isso evitou que uma transação fosse gasta, mas não impediu que os fundos fossem usados em uma transação diferente. Então, havia certos usos, mas todos dependiam de confiança.
|
||||
|
||||
## Compreendendo as possibilidades dos scripts de Timelock
|
||||
|
||||
Nos últimos anos, o Bitcoin Core foi expandido para permitir a manipulação dos timelocks no nível do opcode com os _OP_CHECKLOCKTIMEVERIFY_ (CLTV) e _OP_CHECKSEQUENCEVERIFY_ (CSV). Ambos trabalham sob uma nova metodologia que fortalece ainda mais o Bitcoin.
|
||||
|
||||
_Eles são opcodes._ Por serem opcodes, o CLTV e o CSV podem ser usados como parte de condições de resgate mais complexas. Na maioria das vezes, eles estão vinculados às condicionais que ireimos descrever no próximo capítulo.
|
||||
|
||||
_Eles bloqueiam as saídas._ Por serem opcodes incluídos nas transações como parte de uma ```sigPubKey```, eles apenas bloqueiam aquela saída única. Isso significa que as transações são aceitas na rede Bitcoin e que as UTXOs usadas para financiar essas transações são gastos. Não há como voltar atrás em uma transação bloqueada por tempo com o CLTV ou o CSV como acontece com um ```nLockTime``` vazio. Gastar novamente a UTXO resultante requer que as condições do timelock sejam atendidas.
|
||||
|
||||
Aqui está um ponto importante sobre a utilização dos timelocks: _Eles são bloqueios de mão única._ Os bloqueios de tempo são projetados para desbloquear fundos em um determinado momento. Eles não podem bloquear novamente um fundo: Uma vez que um fundo bloqueado por tempo está disponível, ele ficará disponível para ser gasto.
|
||||
|
||||
### Compreendendo as possibilidades do CLTV
|
||||
|
||||
O _OP_CHECKLOCKTIMEVERIFY_ ou CLTV é compativel com o clássico recurso ```nLockTime```, mas no novo paradigma baseado em opcode. Ele permite que uma UTXO se torne acessível em um determinado momento ou em uma determinada altura de bloco.
|
||||
|
||||
O CLTV foi detalhado pela primeira vez no [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki).
|
||||
|
||||
### Compreendendo as possibilidades do CSV
|
||||
|
||||
O _OP_CHECKSEQUENCEVERIFY_ ou CSV depende de um novo tipo de "locktime relativo", que é definido no campo _nSequence_ da transação. Como de costume, ele pode ser definido como uma data/hora ou uma altura de bloco. Se for definido como um tempo "n", então uma transação bloqueada em um tempo relativo pode ser gasta "n x 512" segundos depois que a UTXO foi minerada, e se for definido como um bloco "n", então uma transação bloqueada em tempo relativo pode ser gasta em "n" blocos depois que a UTXO foi minerada.
|
||||
|
||||
O uso do ```nSequence``` para um bloqueio de tempo relativo foi detalhado primeiramente no [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki), e o opcode CSV foi adicionado no [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki).
|
||||
|
||||
## Resumo: Compreendendo as Opções de Timelocks
|
||||
|
||||
Agora possuímos quatro opções de Timelocks:
|
||||
|
||||
* ```nLockTime``` para manter uma transação fora do blockchain até um dado momento específico;
|
||||
* ```nSequence``` para manter uma transação fora do blockchain até um dado momento relativo;
|
||||
* CLTV para tornar uma UTXO impossível de ser gasto até uma data/hora específica;
|
||||
* CSV para tornar uma UTXO impossível de ser gasto até uma data/hora ou altura do bloco relativa.
|
||||
|
||||
## O Que Vem Depois?
|
||||
|
||||
Vamos continuar "Aumentando o poder do timelock com scripts do Bitcoin" na seção [§11.2: Usando o CLTV nos Scripts](11_2_Using_CLTV_in_Scripts.md).
|
153
pt/11_2_Using_CLTV_in_Scripts.md
Normal file
153
pt/11_2_Using_CLTV_in_Scripts.md
Normal file
@ -0,0 +1,153 @@
|
||||
# 11.2: Usando o CLTV nos Scripts
|
||||
|
||||
O ```OP_CHECKLOCKTIMEVERIFY``` (ou CLTV) é o complemento natural para o ```nLockTime```. Ele muda a ideia de bloquear transações por um tempo absoluto ou altura de bloco para o âmbito dos opcodes, permitindo o bloqueio das UTXOs individuais.
|
||||
|
||||
> :warning: **AVISO DE VERSÃO:** O CLTV ficou disponível no Bitcoin Core 0.11.2, mas deve ser amplamente implementado neste momento.
|
||||
|
||||
## Lembrando do nLockTime
|
||||
|
||||
Antes de nos aprofundarmos no CLTV, devemos primeiro lembrar do funcionamento do ```nLockTime```.
|
||||
|
||||
Conforme detalhado na seção [§8.1:Enviando uma transação com Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md), o locktime é habilitado pela configuração de duas variáveis, o ```nLockTime``` e o ```nSequence```. O ```nSequence``` deve ser definido para ser menor do que 0xffffffff (geralmente: 0xffffffff-1), então o ```nLockTime``` será interpretado da seguinte forma:
|
||||
|
||||
* Se o ```nLockTime``` for inferior a 500 milhões, será interpretado como uma altura de bloco;
|
||||
* Se o ```nLockTime``` for 500 milhões ou mais, será interpretado como um carimbo de data/hora UNIX.
|
||||
|
||||
Uma transação com ```nLockTime``` definida não pode ser gasta (ou mesmo colocada na blockchain) até que a altura do bloco ou a data/hora sejam alcançados. Neste meio tempo, a transação pode ser cancelada, ao se utilizar qualquer uma das UTXOs que constituem a transação.
|
||||
|
||||
## Compreendendo o Opcode CLTV
|
||||
|
||||
O ```OP_CHECKLOCKTIMEVERIFY``` funciona dentro do mesmo paradigma de altura de blocos ou tempos UNIX, ambos absolutos, mas é executado como parte de um Script do Bitcoin. Ele lê um argumento, que pode ser os dois já mencionados. Por meio de uma metodologia um tanto complicada, ele compara esse argumento ao tempo atual. Se for muito cedo, o script irá falhar, porém, se a condição de tempo for atendida, o script continua.
|
||||
|
||||
Como o CLTV é apenas parte de um script (e presumivelmente parte de uma transação P2SH), uma transação CLTV não é mantida fora da mempool como uma transação ```nLockTime```. Logo, assim que for verificado, ele vai para a blockchain e os fundos são considerados gastos. O truque é que todas as saídas que foram bloqueadas com o CLTV não estão disponíveis para _serem gastas_ até que o CLTV permita.
|
||||
|
||||
### Compreendendo um CLTV de tempo absoluto
|
||||
|
||||
É assim que o ```OP_CHECKLOCKTIMEVERIFY``` seria utilizado para verificar o locktime de 24 de maio de 2017:
|
||||
```
|
||||
1495652013 OP_CHECKLOCKTIMEVERIFY
|
||||
```
|
||||
Mas geralmente vamos descrever isso em uma abstração:
|
||||
```
|
||||
<May24> OP_CHECKLOCKTIMEVERIFY
|
||||
```
|
||||
Ou assim:
|
||||
```
|
||||
<AbsoluteTime> OP_CHECKLOCKTIMEVERIFY
|
||||
```
|
||||
|
||||
### Compreendendo um CLTV de altura de bloco absoluta
|
||||
|
||||
É assim que o ```OPCHECKLOCKTIMEVERIFY``` compararia a uma altura de bloqueio alcançada no dia 24 de maio de 2017:
|
||||
```
|
||||
467951 OP_CHECKLOCKTIMEVERIFY
|
||||
```
|
||||
Mas geralmente vamos abstrair assim:
|
||||
```
|
||||
<AbsoluteBlockHeight> OP_CHECKLOCKTIMEVERIFY
|
||||
```
|
||||
|
||||
### Entendendo como o CLTV realmente funciona
|
||||
|
||||
A explicação acima é suficiente para usar e entender o CLTV. No entanto, o [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) apresenta todos os seguintes detalhes.
|
||||
|
||||
Um script de bloqueio só permitirá que uma transação reenvie uma UTXO bloqueado com um CLTV se o ```OP_CHECKLOCKTIMEVALUE``` verificar todas as seguintes condições:
|
||||
|
||||
* O campo ```nSequence``` deve ser definido como sendo menor do que 0xffffffff, geralmente 0xffffffff-1 para evitar conflitos com os timelocks relativos;
|
||||
* CLTV deve retirar um operando da pilha e deve ser 0 ou maior.
|
||||
* Tanto o operando da pilha quanto o ```nLockTime``` devem estar acima ou abaixo de 500 milhões, para representar o mesmo tipo de locktime absoluto;
|
||||
* O valor ```nLockTime``` deve ser maior ou igual ao operando da pilha.
|
||||
|
||||
Portanto, a primeira coisa a se notar aqui é que o ```nLockTime``` ainda é utilizado com o CLTV. Para ser mais preciso, ele é necessário na transação que tenta _gastar novamente_ uma UTXO com o temporizador CLTV. Isso significa que não faz parte dos requisitos do script. É apenas o cronômetro que é usado para liberar os fundos, _como definido no script_.
|
||||
|
||||
Isso é gerenciado por meio de um entendimento inteligente de como o ```nLockTime``` funciona: Um valor para o ```nLockTime``` deve sempre ser escolhido sendo menor ou igual ao tempo presente (ou altura do bloco), de modo que a transação de gasto possa ser colocada na blockchain. Porém, devido aos requisitos do CLTV, também deve ser escolhido um valor maior ou igual ao operando do CLTV. A união desses dois conjuntos é ```NULL``` até que o tempo presente corresponda ao operando CLTV. Posteriormente, qualquer valor pode ser escolhido entre o operando do CLTV e o tempo atual. Normalmente, apenas iríamos configurar para a hora atual (ou para o bloco atual).
|
||||
|
||||
## Escrevendo um Script CLTV
|
||||
|
||||
O ```OP_CHECKLOCKTIMEVERIFY``` inclui um ```OP_VERIFY```, o que significa que ele irá parar imediatamente o script se nossa verificação não for bem-sucedida. Ele tem uma outra peculiaridade: Ao contrário da maioria dos comandos de "verificação", ele deixa o que está sendo testado na pilha (apenas no caso de querermos fazer qualquer outra verificação no tempo). Isso significa que um ```OP_CHECKLOCKTIMEVERIFY``` geralmente é seguido por um ```OP_DROP``` para limpar a pilha.
|
||||
|
||||
O seguinte script de bloqueio simples pode ser usado para transformar uma saída P2PKH em uma transação P2PKH bloqueada por tempo:
|
||||
```
|
||||
<NextYear> OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
|
||||
```
|
||||
|
||||
### Codificando um script CLTV
|
||||
|
||||
Obviamente, como acontece com quaisquer scripts Bitcoin complexos, este script CLTV seria realmente codificado em um script P2SH, conforme explicado na seção [§10.1: Entendendo a Fundação do P2SH](10_1_Understanding_the_Foundation_of_P2SH.md) e na [§10.2: Construindo a Estrutura de P2SH](10_2_Building_the_Structure_of_P2SH.md).
|
||||
|
||||
Supondo que o ```<NextYear>``` fosse o número inteiro "1546288031" (little-endian hex: 0x9f7b2a5c) e o ```<pubKeyHash>``` fosse "371c20fb2e9899338ce5e99908e64fd30b789313", este ```redeemScript``` seria construído assim:
|
||||
```
|
||||
OP_PUSHDATA (4 bytes) 0x9f7b2a5c OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 OP_PUSHDATA (20 bytes) 0x371c20fb2e9899338ce5e99908e64fd30b789313 OP_EQUALVERIFY OP_CHECKSIG
|
||||
```
|
||||
O que se traduz em hexadecimal como sendo:
|
||||
```
|
||||
04 9f7b2a5c b1 75 76 a9 14 371c20fb2e9899338ce5e99908e64fd30b789313 88 ac
|
||||
```
|
||||
Ou se preferir:
|
||||
```
|
||||
$ btcc 0x9f7b2a5c OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 0x371c20fb2e9899338ce5e99908e64fd30b789313 OP_EQUALVERIFY OP_CHECKSIG
|
||||
049f7b2a5cb17576a914371c20fb2e9899338ce5e99908e64fd30b78931388ac
|
||||
```
|
||||
O RPC ```decodescript``` pode verificar se acertamos a decodificação:
|
||||
```
|
||||
{
|
||||
"asm": "1546288031 OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 371c20fb2e9899338ce5e99908e64fd30b789313 OP_EQUALVERIFY OP_CHECKSIG",
|
||||
"type": "nonstandard",
|
||||
"p2sh": "2MxANZMPo1b2jGaeKTv9rwcBEiXcXYCc3x9",
|
||||
"segwit": {
|
||||
"asm": "0 07e55bf1eaedf43ec52af57b77ad7330506c209a70d17fa2e1853304aa8e4e5b",
|
||||
"hex": "002007e55bf1eaedf43ec52af57b77ad7330506c209a70d17fa2e1853304aa8e4e5b",
|
||||
"reqSigs": 1,
|
||||
"type": "witness_v0_scripthash",
|
||||
"addresses": [
|
||||
"tb1qqlj4hu02ah6ra3f274ah0ttnxpgxcgy6wrghlghps5esf25wfedse4yw4w"
|
||||
],
|
||||
"p2sh-segwit": "2N4HTwMjVdm38bdaQ5h3X3VktLY74D2qBoK"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Não vamos mostrar continuamente como todos os Scripts do Bitcoin são codificados em transações P2SH, ao invés disso, ofereceremos estes atalhos: Quando descrevemos um script, ele será um ```redeemScript```, que normalmente seria serializado e codificado em um script de bloqueio e serializado no script de desbloqueio. Quando mostramos um procedimento de desbloqueio, será a segunda rodada de validação, seguindo a confirmação do hash do script de bloqueio.
|
||||
|
||||
## Gastando uma UTXO do CLTV
|
||||
|
||||
No caso do exemplo acima, o script de desbloqueio abaixo seria suficiente, desde que o ```nLockTime``` fosse definido em algum lugar antes da data ```<NextYear>```, e desde que o momento atual fosse, de fato, pelo menos ```<NextYear>```:
|
||||
```
|
||||
<signature> <pubKey>
|
||||
```
|
||||
|
||||
### Executando um script CLTV
|
||||
|
||||
Para executar o Script, primeiro devemos concatenar os scripts de desbloqueio e bloqueio:
|
||||
```
|
||||
Script: <signature> <pubKey> <NextYear> OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
|
||||
Stack: [ ]
|
||||
```
|
||||
As três constantes seriam colocadas na pilha:
|
||||
```
|
||||
Script: OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
|
||||
Stack: [ <signature> <pubKey> <NextYear> ]
|
||||
```
|
||||
Então, o ```OP_CHECKLOCKTIMEVERIFY``` é executado. Ele encontra algo na pilha e verifica se o ```nSequence``` não é 0xffffffff. Finalmente, ele compara o ```<NextYear>``` com o ```nLockTime```. Se ambos são o mesmo tipo de representação e se ```nLockTime ≥ <NextYear>```, então ele é processado com sucesso (caso contrário, termina o script):
|
||||
```
|
||||
Script: OP_DROP OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
|
||||
Running: <NextYear> OP_CHECKLOCKTIMEVERIFY
|
||||
Stack: [ <signature> <pubKey> <NextYear> ]
|
||||
```
|
||||
Então, o ```OP_DROP``` se livra daquele ```<NextYear>``` restante:
|
||||
```
|
||||
Script: OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
|
||||
Running: <NextYear> OP_DROP
|
||||
Stack: [ <signature> <pubKey> ]
|
||||
```
|
||||
Finalmente, o restante do script é executado, que é uma verificação normal de uma assinatura e chave pública.
|
||||
|
||||
## Resumo: Usando o CLTV nos Scripts
|
||||
|
||||
O ```OP-CHECKLOCKTIMEVERIFY``` é um opcode simples que olha para um único argumento, o interpreta como uma altura de bloco ou timestamp UNIX, e só permite que a UTXO seja desbloqueada se àquela altura de bloco ou timestamp UNIX estiver no passado. Definir o ```nLockTime``` na transação de gastos é o que permite ao Bitcoin fazer este cálculo.
|
||||
|
||||
> :fire: ***Qual é o poder do CLTV?*** Já vimos que os tempos de bloqueio simples eram uma das bases dos Contratos Inteligentes. O CLTV dá o próximo passo. Agora podemos garantir que uma UTXO não possa ser gasta antes de um certo tempo _e_ podemos garantir que ela também não será gasta. Em sua forma mais simples, isso poderia ser usado para criar um fundo que alguém só poderia ter acesso aos 18 anos ou um fundo de aposentadoria que só poderia ser acessado quando fizesse 50 anos. No entanto, o verdadeiro poder vem quando combinado com condicionais, onde apenas o CLTV apenas é ativado em certas situações.
|
||||
|
||||
## O Que Vem Depois?
|
||||
|
||||
Vamos continuar "Aumentando o poder do timelock com scripts do Bitcoin" na seção [§11.3: Usando o CSV nos Scripts](11_3_Using_CSV_in_Scripts.md).
|
148
pt/11_3_Using_CSV_in_Scripts.md
Normal file
148
pt/11_3_Using_CSV_in_Scripts.md
Normal file
@ -0,0 +1,148 @@
|
||||
# 11.3: Usando o CSV nos Scripts
|
||||
|
||||
O ```nLockTime``` e o ```OP_CHECKLOCKTIMEVERIFY``` (ou CLTV) são apenas um lado da equação do timelock. Do outro lado estão o ```nSequence``` e o ```OP_CHECKSEQUENCEVERIFY```, que podem ser usados para verificar tempos relativos ao invés de tempos absolutos.
|
||||
|
||||
> :warning: **AVISO DE VERSÃO:** O CSV está disponível no Bitcoin Core 0.12.1.
|
||||
|
||||
## Compreendendo o nSequence
|
||||
|
||||
Cada entrada em uma transação tem um valor ```nSequence``` (ou se preferirmos ```sequence```). Tem sido uma ferramenta principal para melhorias do Bitcoin, conforme discutido anteriormente na seção [§5.2: Reenviando uma transação com o RBF](05_2_Resending_a_Transaction_with_RBF.md) e na [§8.1 Enviando uma transação com Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md), onde o usamos para sinalizar o RBF e o ```nLockTime```, respectivamente. No entanto, há mais um uso para o ```nSequence```, descrito no [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki): Podemos usá-lo para criar um timelock relativo em uma transação.
|
||||
|
||||
Um timelock relativo é um bloqueio colocado em uma entrada específica de uma transação e que é calculado em relação à data de mineração da UTXO que está sendo usado na entrada. Por exemplo, se uma UTXO foi minerada no bloco #468260 e uma transação foi criada onde a entrada para aquela UTXO foi uma ```nSequence``` de 100, então a nova transação não poderia ser minerada até o bloco #468360.
|
||||
|
||||
Simples assim!
|
||||
|
||||
> :information_source: **NOTA - SEQUÊNCIA:** Este é o terceiro uso do ```nSequence``` no Bitcoin. Qualquer valor no ```nSequence``` sem o conjunto de 32 bits (1 << 31), ou seja, do 0x00000001 a 0x7ffffffff, será interpretado como um bloqueio de tempo relativo se a ```nVersion ≥ 2``` (que é o padrão do Bitcoin Core depois da versão 0.14.0). Devemos ter cuidado para garantir que os timelocks relativos não entrem em conflito com os outros dois usos de ```nSequence```, que é para sinalizar o ```nTimeLock``` e o RBF. O ```nTimeLock``` geralmente define um valor como sendo 0xffffffff-1, onde um timelock relativo não é permitido e, o RBF geralmente define um valor de "1", onde um bloqueio de tempo relativo é irrelevante, porque define um timelock de 1 bloco.
|
||||
|
||||
> De maneira geral, podemos lembrar do seguinte: Com um valor ```nVersion``` de 2, um valor ```nSequence``` que vai de 0x00000001 a 0x7fffffff permite um timelock relativo, o RBF e o ```nTimeLock```. Um valor ```nSequence``` de 0x7fffffff a 0xffffffff-2 permite o RBF e o ```nTimeLock```. Um valor ```nSequence``` de 0xffffffff-1 permite apenas o ```nTimeLock```. Um valor ```nSequence``` de 0xffffffff não permite nenhum dos três. Um ```nVersion``` pode ser definido como 1 para não permitir bloqueios de tempo relativos para qualquer valor do ```nSequence```. Ufa!
|
||||
|
||||
### Criando um CSV de Tempo de Bloco Relativo
|
||||
|
||||
O formato para usar o ```nSequence``` para representar bloqueios de tempo relativos é definido no [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki) e é um pouco mais complexo do que apenas inserir um número qualquer, como fizemos no ```nTimeLock```. Ao invés disso, as especificações do BIP dividem o número de quatro bytes em três partes:
|
||||
|
||||
* Os primeiros dois bytes são usados para especificar um timelock relativo;
|
||||
* O 23º bit é usado para sinalizar positivamente se o bloqueio se refere a um tempo ou a uma altura de bloco;
|
||||
* O 32º bit é usado para sinalizar positivamente se os timelocks relativos estão desativados.
|
||||
|
||||
Com isso dito, a construção de um timelock relativo baseado em bloco é bem fácil, porque os dois bits sinalizados são definidos como ```0```, então apenas precisamos definir o ```nSequence``` para um valor entre 1 e 0xffff (65535). A nova transação pode ser extraída naquele número de blocos depois que o UTXO associado foi extraído.
|
||||
|
||||
### Criando um CSV de Tempo Relativo
|
||||
|
||||
Podemos definir o ```nSequence``` como um tempo relativo, onde o bloqueio dura 512 segundos vezes o valor do ```nSequence```.
|
||||
|
||||
A fim de fazer isso, precisamos:
|
||||
|
||||
1. Decidir o quanto no futuro definiremos o nosso bloqueio de tempo relativo;
|
||||
2. Converter isso para segundos;
|
||||
3. Dividir por 512;
|
||||
4. Arredondar esse valor para cima ou para baixo e defini-lo como ```nSequence```;
|
||||
5. Definir o 23º bit como verdadeiro.
|
||||
|
||||
Para definir um período de 6 meses no futuro, devemos primeiro calcular da seguinte forma:
|
||||
```
|
||||
$ seconds=$((6*30*24*60*60))
|
||||
$ nvalue=$(($seconds/512))
|
||||
```
|
||||
Em seguida, transformar isso em hexadecimal:
|
||||
```
|
||||
$ hexvalue=$(printf '%x\n' $nvalue)
|
||||
```
|
||||
Finalmente, definimos o 23º bit do valor hexadecimal que criamos:
|
||||
```
|
||||
$ relativevalue=$(printf '%x\n' $((0x$hexvalue | 0x400000)))
|
||||
$ echo $relativevalue
|
||||
4224679
|
||||
```
|
||||
Se convertermos de volta, teremos o valor de 4224679 = 10000000111011010100111. O 23º dígito é definido como "1", enquanto os primeiros 2 bytes, 0111011010100111, são convertidos em 76A7 em hexadecimal ou 30375 em decimal. Multiplicando isso por 512, teremos 15,55 milhões de segundos, o que de fato é 180 dias.
|
||||
|
||||
## Criando uma transação com um timelock relativo
|
||||
|
||||
Então desejamos criar uma transação simples com um timelock relativo? Tudo que precisamos fazer é emitir uma transação onde o ```nSequence``` de uma entrada é definido como mostramos acima: Com o ```nSequence``` para essa entrada definido de forma que os primeiros dois bytes definam o timelock, o 23º bit define o tipo do timelock, e o 32º bit é definido como sendo falso.
|
||||
|
||||
Vamos enviar a transação e veremos que ela não pode ser legalmente minerada até que blocos ou tempo suficientes tenham passado além do tempo que a UTXO foi minerada.
|
||||
|
||||
Exceto que praticamente ninguém faz isso. As definições do [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki) para ```nSequence``` foram incorporadas ao Bitcoin Core ao mesmo tempo que o [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki), que descreve o opcode CSV e o ```nSequence``` equivalente ao opcode CLTV. Assim como o CLTV, o CSV oferece recursos aprimorados. Portanto, quase todo o uso dos timelocks relativos foi com o opcode CSV, não com o valor ```nSequence``` bruto por si só.
|
||||
|
||||
| | Absolute Timelock | Relative Timelock |
|
||||
|:--------------------:|-------------------|-------------------|
|
||||
| **Transaction Bloqueada** | nTimeLock | nSequence |
|
||||
| **Saída do Bloqueio** | OP_CHECKLOCKTIMEVERIFY| OP_CHECKSEQUENCEVERIFY |
|
||||
|
||||
## Compreendendo o Opcode CSV
|
||||
|
||||
O ```OP_SEQUENCEVERIFY``` nos Scripts do Bitcoin funciona quase como o ```OP_LOCKTIMEVERIFY```.
|
||||
|
||||
Podemos exigir que uma UTXO seja mantida por cem blocos após sua mineração:
|
||||
```
|
||||
100 OP_CHECKSEQUENCEVERIFY
|
||||
```
|
||||
Ou podemos fazer um cálculo mais complexo para exigir que uma UTXO seja retida daqui seis meses, neste caso acabaremos com um número mais complexo:
|
||||
```
|
||||
4224679 OP_CHECKSEQUENCEVERIFY
|
||||
```
|
||||
Neste caso, usaremos uma abreviatura:
|
||||
```
|
||||
<+6Months> OP_CHECKSEQUENCEVERIFY
|
||||
```
|
||||
|
||||
> :warning: **ATENÇÃO:** Lembre-se de que um timelock relativo é um intervalo de tempo desde a mineração da UTXO usada como uma entrada. _Não_ é um intervalo de tempo após a criação da transação. Se usarmos uma UTXO que já foi confirmada cem vezes, e colocarmos um timelock relativo de 100 blocos nela, ela será elegível para mineração imediatamente. Os timelocks relativos têm alguns usos muito específicos, mas provavelmente não se aplicam se nosso único objetivo for determinar algum tempo definido no futuro.
|
||||
|
||||
### Entendendo como o CSV realmente funciona
|
||||
|
||||
O CSV tem muitas das mesmas sutilezas de uso que CLTV:
|
||||
|
||||
* O campo ```nVersion``` deve ser definido como 2 ou mais;
|
||||
* O campo ```nSequence``` deve ser definido como sendo menor do que 0x80000000;
|
||||
* Quando CSV é executado, deve haver um operando na pilha que esteja entre 0 e 0xf0000000-1;
|
||||
* Tanto o operando da pilha quanto o ```nSequence``` devem ter o mesmo valor no 23º bit;
|
||||
* O ```nSequence``` deve ser maior ou igual ao operando da pilha.
|
||||
|
||||
Assim como no CLTV, quando estiver usando uma UTXO com um CSV em condições de bloqueio, devemos definir o ```nSequence``` para habilitar a transação. Normalmente, o configuraremos com o valor exato no script de bloqueio.
|
||||
|
||||
## Escrevendo um script CSV
|
||||
|
||||
Assim como o ```OP_CHECKLOCKTIMEVERIFY```, o ```OP_CHECKSEQUENCEVERIFY``` inclui um ```OP_VERIFY``` implícito e deixa os argumentos na pilha, exigindo um ```OP_DROP``` quando finalizar tudo.
|
||||
|
||||
Um script que bloquearia fundos por até seis meses após a mineração e que exigiria uma assinatura no estilo P2PKH padrão teria a seguinte aparência:
|
||||
```
|
||||
<+6Months> OP_CHECKSEQUENCEVERIFY OP_DROP OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
|
||||
```
|
||||
|
||||
### Codificando um script CSV
|
||||
|
||||
Ao codificar um script CSV, precisamos tomar cuidado ao codificar o valor inteiro para o timelock relativo. Deve ser passado como um número inteiro de 3 bytes, o que significa que iremos ignorar o maior byte, o que pode desativar o timelock relativo. Como é um número inteiro, precisamos nos certificar de convertê-lo para little-endian.
|
||||
|
||||
Isso pode ser feito com o script de shell ```integer2lehex.sh``` do capítulo anterior.
|
||||
|
||||
Para um tempo relativo de 100 blocos:
|
||||
```
|
||||
$ ./integer2lehex.sh 100
|
||||
Integer: 100
|
||||
LE Hex: 64
|
||||
Length: 1 bytes
|
||||
Hexcode: 0164
|
||||
```
|
||||
Embora deva ser preenchido como ```000064```, exigindo um código de ```03000064```.
|
||||
|
||||
Por um período relativo de 6 meses:
|
||||
```
|
||||
$ ./integer2lehex.sh 4224679
|
||||
Integer: 4224679
|
||||
LE Hex: a77640
|
||||
Length: 3 bytes
|
||||
Hexcode: 03a77640
|
||||
```
|
||||
|
||||
## Gastando uma UTXO do CSV
|
||||
|
||||
Para gastar uma UTXO bloqueado com um script CSV, devemos definir o ```nSequence``` dessa entrada para um valor maior que o requerido no script, mas menor que o tempo entre a UTXO e o bloco atual. Isso mesmo, isso significa que precisamos saber o requisito exato no script de bloqueio. Mas temos uma cópia do ```redeemScript```, então se não conhecermos os requisitos, podemos desserializá-lo e, em seguida, definir o ```nSequence``` como sendo o número que é mostrado lá.
|
||||
|
||||
## Resumo: Usando o CSV nos Scripts
|
||||
|
||||
O ```nSequence``` e o CSV oferecem uma alternativa para o ```nLockTime``` e o CLTV onde bloqueamos uma transação com base em um tempo relativo desde que a entrada foi extraída, ao invés de basear o bloqueio em um tempo definido no futuro. Eles funcionam quase de forma idêntica, exceto pelo fato de que o valor do ```nSequence``` é codificado de forma ligeiramente diferente do valor do ```nLockTime```, com bits específicos significando coisas específicas.
|
||||
|
||||
> :fire: ***Qual é o poder do CSV?*** O CSV não é apenas uma maneira preguiçosa de bloquear uma transação, quando não queremos calcular um tempo no futuro. Ele é um paradigma totalmente diferente, um bloqueio que usaríamos se fosse importante criar uma duração mínima específica entre o momento em que uma transação é minerada e o momento em que os fundos podem ser gastos. O uso mais óbvio é (mais uma vez) para uma conta de garantia, quando desejamos um tempo preciso entre a entrada dos fundos e a saída. No entanto, ele tem possibilidades muito mais poderosas em transações fora da rede, incluindo canais de pagamento. Esses aplicativos são, por definição, construídos em transações que não são realmente colocadas na blockchain, o que significa que, se forem posteriormente colocados em um bloco, um período de tempo pode ser muito útil. Os [Hashed Timelock Contracts](https://en.bitcoin.it/wiki/Hashed_Timelock_Contracts) foram uma dessas implementações, dando a base para a rede de pagamento Lightning. Eles serão discutidos na seção [§13.3: Expandindo os Scripts do Bitcoin](13_3_Empowering_Bitcoin_with_Scripts.md).
|
||||
|
||||
## O Que Vem Depois?
|
||||
|
||||
Vamos avançar "Criando Scripts do Bitcoin" no capítulo [12: Expandindo os Scripts do Bitcoin](12_0_Expanding_Bitcoin_Scripts.md).
|
Loading…
x
Reference in New Issue
Block a user