Neste artigo, tentamos examinar em detalhes as alterações no protocolo Bitcoin que ocorreram como resultado da atualização do softfork da Segregated Witness. Abordamos questões relacionadas à maleabilidade das transações, mantendo a compatibilidade com versões anteriores, aumentando a taxa de transferência, novos formatos de serialização de transações, novas opções de script, formato de endereço Bech32 e suas vantagens, conceitos de peso, tamanho e tamanho virtual. Além disso, a seguir, são apresentadas as estatísticas mais importantes sobre a adaptação da atualização e as respostas às perguntas freqüentes sobre o tópico desta atualização.
Antes de prosseguir com uma descrição detalhada de todas as alterações nesta atualização, sugerimos que você se familiarize com a idéia principal de Testemunha Segregada. Literalmente, a Testemunha Segregada é traduzida do inglês como "testemunha separada". O Concurso Bitcoin implica que as evidências de propriedade das moedas serão armazenadas separadamente dos dados mestre da transação, conforme indicado no diagrama.

Se considerarmos toda a atualização do protocolo, ela inclui muitas outras melhorias. O SegWit permite aumentar a largura de banda da rede, separar a evidência de propriedade de moedas do restante dos dados da transação, corrigir as deficiências do formato da transação associado à capacidade de modificar dados em transações assinadas (maleabilidade da transação), mantendo a compatibilidade com versões anteriores do protocolo. E o maior valor desta atualização é que ela permite implementar muitas soluções off-chain muito importantes sobre o protocolo Bitcoin.
Problema e solução de maleabilidade da transação
A conclusão é que, ao trabalhar no Bitcoin, há a oportunidade de alterar a transação, para que ela permaneça correta durante a verificação. Essas alterações são muito pequenas, não afetam os endereços do remetente e do destinatário, mas são suficientes para alterar o resultado do hash. Em outras palavras, a transação transferirá as moedas para seus endereços anteriores, mas seu valor de hash alterado não corresponderá mais à transação modificada com a original.
Obviamente, a situação descrita acima só pode acontecer com transações que ainda não receberam confirmação. Sem sua solução, é impossível obter uma operação confiável de protocolos fora da cadeia, que incluem a construção de cadeias de transações não confirmadas. Como ao compilar uma transação, nem todos os dados são assinados (por exemplo, você não pode assinar scriptSig), existe a possibilidade de vários tipos de ataques:
- Mude o formato da assinatura . No protocolo Bitcoin, o formato da assinatura não é estritamente aprovado e depende da implementação da biblioteca OpenSSL, na qual o formato estrito também não está definido para a assinatura. Um terceiro pode modificar a transação interceptada, o que implicará uma alteração no valor do hash.
- Impacto diretamente no scriptSig . Como observado anteriormente, o scriptSig contém um conjunto de operações para verificar evidências de que um usuário específico é o proprietário das moedas. Mas, além dessas operações, você pode adicionar outros. Algumas operações inofensivas que não afetam nada levarão a uma alteração no valor de hash da transação.
Assim, você pode alterar o valor do hash de uma transação sem ter acesso a chaves privadas. Por que alterar um valor de hash é tão indesejável?
Antes de tudo, note-se que é possível criar uma cópia da transação original, adicionar alterações que não afetem sua correção durante a verificação e enviá-la para a rede. Uma cópia modificada com um valor de hash diferente gasta as mesmas moedas que o original, para que possa competir com a transação original pela confirmação.
Protocolos fora da cadeia foram mencionados acima. Para sua implementação, é necessária uma solução para o problema da maleabilidade das transações. No centro de seu trabalho está a construção de cadeias de transações não confirmadas. Alterar o valor do hash da primeira transação implicará a invalidade de toda a cadeia de transações não confirmadas.
A atualização do SegWit definiu regras estritas para o preenchimento dos campos, para que os problemas associados à maleabilidade de transações para transações do novo formato possam ser considerados resolvidos. Isso nos permitiu especificar dados e serializá-los sem ambiguidade, eliminando a dualidade.
Compatibilidade com versões anteriores ao distribuir um bloco pela rede
De acordo com as regras antigas, o tamanho máximo do bloco é de 1 MB e contém transações com evidências internas. Enquanto as novas regras assumem que o tamanho máximo do bloco base é de 1 MB, além disso, há uma estrutura de dados com evidências. Assim, o tamanho total do novo bloco excede 1 MB.
Para compatibilidade com versões anteriores, as regras de protocolo permitem que os nós antigos trabalhem com novos blocos, mas eles receberão o bloco apenas na configuração básica com um tamanho máximo de 1 MB. A estrutura da testemunha não está disponível para eles. Novos nós obtêm um bloco completo com transações e evidências. A figura a seguir ajudará você a se familiarizar com esta pergunta.

À esquerda, está um diagrama da operação do protocolo Bitcoin antes de ativar a Testemunha Segregada. O bloco tinha um tamanho máximo de 1 MB e foi distribuído entre diferentes nós da rede em um formulário.
Como o tamanho do bloco é limitado, o número de transações que podem ser feitas nele também é limitado e a capacidade do sistema depende disso. Obviamente, quando surgiu a questão de aumentar a taxa de transferência, a primeira coisa que começaram a procurar foram as maneiras de aumentar o tamanho máximo do bloco.
Maneiras de aumentar a produtividade
Considere as duas principais maneiras de resolver o problema de aumentar a taxa de transferência do sistema. Qualquer oferta é cuidadosamente verificada e testada pela equipe de desenvolvimento do protocolo Bitcoin. Se a comunidade chegou a um acordo e decidiu implementar a proposta no protocolo, uma atualização é emitida.
Atualização do Hardfork. O mais comum das atualizações é aumentar o tamanho do bloco. Supõe-se que uma unidade acomodará mais transações, aumentando a taxa de transferência. No entanto, essa unidade não será aceita pelos nós que operam de acordo com o protocolo antigo, cujas regras determinam que o tamanho máximo do bloco não pode exceder 1 MV. Essa mudança requer hardfork, que é organizacionalmente mais complexo que softfork.
Atualização do SoftFork. A Testemunha segregada nos permite resolver esse problema com o softfork. Como exatamente? Ele nos permite dividir o bloco em duas partes, a primeira das quais armazena transações e a segunda contém evidências. Ao mesmo tempo, os novos nós da rede recebem as duas partes, enquanto os antigos recebem apenas um bloco de transações de 1 MB. Os nós antigos não podem receber blocos com evidências e, consequentemente, não podem validar as transações que recebem, mas isso lhes permite participar da construção de consenso e não recorrer ao hardfork, mas alternar gradualmente para o novo software.
Testemunhas Segregadas de Inovações
Considere o que está incluído na atualização Segregated Witness. A primeira e mais importante inovação do Segregated Witness é o novo formato de serialização de transações. Além dos campos já conhecidos, há três novos campos na nova transação: marcador, sinalizador, que são usados para controle de versão e, neste caso, são estritamente definidos, mas nos protocolos a seguir podem ser alterados, assim como o campo testemunha. A testemunha (dados da testemunha) é na verdade um conjunto de evidências de propriedade de moedas retiradas da parte principal da transação. Estruturalmente, parece um conjunto de entradas, com cada elemento de dados de testemunha correspondendo a uma entrada com um número específico, o que permite comparar evidências com moedas específicas gastas.
ID da transação testemunha
Para obter o identificador da transação (ID da transação, txid), é necessário trazer a transação para uma sequência de dados em um formato de serialização especial e, em seguida, obter o valor de hash dessa sequência de dados. Com a introdução do Segregated Witness, um novo identificador, identificação de transação de testemunha (wtxid) e um novo formato de serialização, respectivamente, apareceram. Para transações antigas que gastam dinheiro sem usar o Segregated Witness, wtxid será o mesmo que txid porque eles não terão novos campos adicionados ao Segregated Witness.

O Wtxid é necessário para construir uma árvore Merkle alternativa para evidências. Ele é construído da mesma maneira que para transações comuns, apenas wtxid é usado em vez do hash da transação. Consequentemente, os wtxid são divididos em pares e resultam na raiz de Merkle.
É importante observar que a raiz do Merkle é inserida em uma transação de base de moeda e não no cabeçalho do bloco. Se a raiz estivesse no cabeçalho do bloco, a estrutura do bloco mudaria. Os nós que suportam o protocolo antigo não podiam funcionar com esses blocos. E todos os esforços para manter a compatibilidade com versões anteriores estariam contra essa inconsistência. Portanto, o root é inserido em uma das saídas da transação de base de moeda. Quando todos os nós mudam para Testemunha Segregada, essa situação pode mudar e novas abordagens serão consideradas.
Programas de testemunhas para estabelecer condições para gastar moedas
Vejamos como o script de transações Segregated Witness é construído e como permite que os nós de rede mais antigos entendam que as transações Segregated Witness estão corretas, apesar de não receberem evidências de propriedade de moedas.
O script que descreve as regras para gastar moedas de uma nova transação de formato consiste em duas partes. A primeira parte é o byte da versão testemunha (o byte especificando a versão do programa testemunha). Pode levar valores de 0 a 16 (OP0-OP16), agora usa OP0. No futuro, novas versões do protocolo poderão aparecer com suporte para outras versões do programa testemunha. A segunda parte é o programa de testemunhas. Esta parte pode ter um tamanho de 2 a 40 bytes.
O programa Testemunha é o resultado do hash de um script de testemunha. O próprio script de testemunha contém uma descrição completa das condições para gastar moedas. Os dados da testemunha contêm prova de propriedade de moedas que devem satisfazer as condições no script de testemunha. Consequentemente, os dados das testemunhas sempre consistem em duas partes: um script de testemunha e prova de propriedade de moedas.
Vale ressaltar que o programa testemunha não contém nenhuma operação (correspondência de valores de hash, verificação de assinaturas eletrônicas) e o próprio script inicia com o código OP0, portanto, é válido para todos os nós antigos. Além disso, os nós que não foram atualizados para o SegWit não verificam evidências de propriedade de moedas para novos resultados de formato; eles consideram esse desperdício correto em qualquer caso. A rigor, os nós antigos aceitarão transações de um novo formato, mesmo que o remetente não possua as moedas correspondentes. É por isso que o SegWit exige que os proprietários da maior parte da mineração de Bitcoin aceitem essa atualização. Outra característica é que o scriptSig de uma transação que gasta moedas da saída do novo formato estará vazio.
Novas opções para definir as condições para gastar moedas
Com a introdução do SegWit, foram propostos dois formatos padrão para scriptPubKey, que se tornaram uma alternativa aos dois formatos mais comuns para definir regras de gastos com moedas antes que essa atualização aparecesse. Vamos considerá-los em ordem.
Pagar para testemunhar o hash de chave pública (P2WPKH) é um análogo do pagamento padrão para o hash de chave pública. Qual a diferença? Conforme observado anteriormente, o scriptSig não é preenchido e permanece vazio. Todas as evidências de propriedade de moedas são transferidas para a estrutura de dados da testemunha.
Nesse caso, o script que foi considerado anteriormente, a versão e o hash da chave pública, que é o programa testemunha, é inserido no scriptPubKey. Um nó na rede distingue esse script de gasto de outros devido ao fato de possuir uma versão de um e um tamanho de dados de 20 bytes. Outra versão e um tamanho diferente têm regras de gastos diferentes.

Nesse caso, scriptPubKey contém duas partes: o número da versão da testemunha é zero e o valor do hash da chave pública do destinatário. O ScriptSig estará vazio e os dados da testemunha conterão uma assinatura eletrônica e uma chave pública para verificá-los.
Pagamento para testemunhar hash de script (P2WSH) é um análogo do pagamento padrão para hash de script. Nesse caso, um script personalizado pode ser usado para definir as regras para gastar moedas. Como um host distingue esse script do anterior? Nesse caso, a versão ainda possui um valor de um e o programa testemunha recebe 32 bytes e é um valor de hash do script testemunha. Se uma transação chegar a um host que contém um script que terá a primeira versão, mas seu tamanho será diferente dos valores de 20 ou 32 bytes, o host rejeitará essa transação porque não saberá como trabalhar com ela.
Os dados das testemunhas aqui são divididos em duas partes. O primeiro contém um conjunto de evidências de propriedade de moedas, ou seja, um conjunto de assinaturas. Na segunda parte, é colocado um script de testemunha, cujo conteúdo apenas define as regras para gastar moedas, mas, neste caso, é indicado no momento do gasto e no momento do envio de moedas, seu valor de hash foi indicado.

Nesse caso, scriptPubKey contém duas partes: o número de testemunha da versão é zero e o valor do hash do script de testemunha para o caso de várias assinaturas 1-de-2. O ScriptSig estará vazio e os dados da testemunha conterão a assinatura eletrônica e o script original da testemunha em texto não criptografado.
Invólucro P2SH
O novo formato de script é diferente do antigo. Dessa forma, serviços e carteiras antigos não saberão como trabalhar com esse formato de script e como compor. Para compatibilidade com versões anteriores, as transações Segregated Witness usando P2SH usam um "invólucro" especial, que permite criar uma transação que possui as propriedades de uma transação Segregated Witness, mas não difere do P2SH usual no mundo externo.
O P2SH é usado para simplificar o trabalho do remetente e não sobrecarregá-lo com os detalhes da implementação do Script de Resgate do destinatário. Nesse caso, o destinatário fornece ao remetente apenas o valor de hash Resgatar Script, e o próprio script passa para scriptSig junto com a evidência.

Nesse caso, scriptPubKey contém uma operação de hash, um valor de hash de script de resgate e uma operação de comparação (como na versão antiga do P2SH). O ScriptSig aqui conterá o valor de hash da chave pública e os dados da testemunha conterão a assinatura eletrônica e a chave pública.
Essa abordagem permite que carteiras digitais não atualizadas enviem transações para endereços de Testemunha Segregada, sem saber nada sobre as novas maneiras de definir as condições para gastar moedas.
Novo formato de endereço Bech32
Vale mencionar separadamente os endereços Bech32 que são considerados endereços nativos do SegWit. Durante a maior parte de sua história, o Bitcoin usou a codificação Base58 para endereços com a adição de uma soma de verificação, que é um resultado truncado do hash duplo usando a função de hash SHA-256. Eles faziam parte do software original e seu escopo foi expandido no BIP13 para P2SH. Mas o conjunto de caracteres e o algoritmo de soma de verificação têm limitações:
- o endereço na Base58 ocupa mais memória nos códigos QR, porque não pode usar o modo de representação alfanumérica;
- base58 é muito inconveniente para escrever de maneira confiável no papel, digitar em um teclado móvel ou ler em voz alta;
- o hash de soma de verificação dupla é lento;
- decodificação base58 é complexa e relativamente lenta.

A atualização do SegWit inclui uma nova classe de saídas (programas testemunha) e dois de seus casos: P2WPKH e P2WSH. Sua funcionalidade está indiretamente disponível para nós antigos através do uso de P2SH, mas será mais ideal e mais seguro usá-lo diretamente, para isso é necessário introduzir um novo formato de endereço.
Especificação de Endereço Bech32
O endereço Bech32 tem um comprimento não superior a 90 caracteres e contém:
- Uma parte que é legível por humanos. Isso inclui dados que talvez precisem ser transmitidos ou que tenham algo a ver com o proprietário do endereço, com pelo menos 1 caractere. Por exemplo, por padrão para endereços da rede principal, os caracteres são "bc" e para a rede de teste os caracteres são "tb".
- Um delimitador que é sempre 1. Se "1" for permitido dentro da parte legível por humanos, o separador será o último dos caracteres "1".
- A parte dos dados possui um comprimento de pelo menos 6 caracteres e consiste apenas em caracteres alfanuméricos, excluindo "1", "b", "i" e "o". Aqui, a versão do programa testemunha e os dados do próprio programa testemunha (de 2 a 40 bytes) são usados aqui como dados principais.

Por que incluir um separador nos endereços? Isso permite que você separe claramente a parte legível por humanos da parte legível por dados, evitando possíveis colisões com outras partes legíveis por humanos que usam o prefixo. Também evita restrições do conjunto de caracteres para a parte legível por humanos. O separador é 1 porque o uso de um caractere não alfanumérico dificulta a cópia de endereços (sem clicar duas vezes em vários aplicativos). Portanto, um caractere alfanumérico foi selecionado fora do conjunto de caracteres principal. Além disso, o uso do sistema de números base 32 é acompanhado por um aumento no comprimento do endereço em 15% em comparação com o sistema de números base 58, mas isso não importa ao copiar endereços.
Soma de verificação Bech32 endereços
Os últimos 6 caracteres do endereço são uma soma de verificação. A soma de verificação é criada com base no código BCH, que garante a detecção de qualquer erro que afeta não mais que 4 caracteres, e a chance de a soma de verificação convergir quando mais de 4 erros são cometidos é uma das 109.
Uma das vantagens do uso de códigos BCH é que eles podem ser usados para corrigir erros. Se até 4 erros foram cometidos no endereço, eles serão corrigidos automaticamente. E se mais erros forem cometidos, eles serão detectados com uma alta probabilidade, mas sem a possibilidade de sua correção automática.
Maiúsculas e minúsculas no endereço
Minúsculas são usadas quando um valor de caractere é necessário para uma soma de verificação.
O software sempre exibe toda a cadeia de endereços do Bech32 em letras minúsculas. (, QR-), . , , , . , QR- , - , 45% , .
, Segregated Witness, , . Segregated Witness . 1 MB. . , .
(weight units). 3, witness data 1. , , witness data 3 , . . .
block weight = base size * 3 + total sizeblock weight – ( )
base size – ( )
total size – ( )
, , . .
, , , , 4 . Segregated Witness , .
, . (virtual size) , , , spb (satoshi per byte).
virtual size = weight units / 4Segregated Witness 4 , , . , . , . , , . , witness data (base size) 1 MB, 4 MB.
: « witness data?». . , 1 MB 4 MB. . 1.8 MB. ? 60% . 1 MB, 40% , .
400000 * 4 = 1600000600000 * 1 = 6000001600000 + 600000 = 22000004000000 / 2200000 = 1.81 MB, , 1.8 MB. , .
2018 SegWit 35% . Segregated Witness (, Electrum Bitxfy).
BitMex Research. 1 MB, 2 MB. , , SegWit .
BitMex Research, .
, Segregated Witness off-chain Bitcoin. , lightning network – SegWit, , .
Perguntas frequentes
— , Segregated Witness RBF (replace-by-fee)?, replace by fee Segregated Witness , , , , sequence number . , , , , .
— ?- , . ScriptSig, , , . , , - . , , , - .
— witness data?, Segregated Witness . , , , . , . : , , ( ), , Witness data, . .
— , RFC3548 z-base-32 Bech32 ?O conjunto de caracteres é escolhido de modo a minimizar a ambiguidade associada à sua similaridade visual. A ordem é selecionada para minimizar o número de pares de caracteres que diferem em menos de um bit de dados. A soma de verificação é escolhida para maximizar a probabilidade de detectar um pequeno número de erros, o que melhora sua eficiência para erros típicos.