Este artigo foi escrito por Salvatore Ingala traduzido por Fernando T. Barros. O original em inglês pode ser encontrado aqui.
O Bitcoin é capaz de expressar condições de gastos complexas e poderosas, mas essa capacidade é atualmente subutilizada.
O Miniscript permitirá que os desenvolvedores de software de wallets (carteiras) aproveitem todo o poder do Bitcoin Script.
Estamos trabalhando para trazê-lo para os usuários da Ledger Nano.
Uma versão futura do aplicativo Ledger Nano Bitcoin terá suporte nativo para um recurso muito aguardado: miniscript .
Isso traz a promessa de liberar um zoológico de soluções flexíveis para auto custódia que podem tornar mais fácil e seguro manter suas próprias chaves. Lembre-se: not your keys, not your coins (as chaves não são suas, as moedas também não)! Uma corretora é como um banco, e manter suas moedas em um banco anula todo o propósito.
As carteiras de hardware são infraestrutura fundamental para a auto custódia. Ao apoiar inovações diretamente no núcleo, queremos torná-las acessíveis a todo o ecossistema.
Mas o que é miniscript e por que estamos trabalhando para apoiá-lo?
Vamos começar com algum contexto.
Scripts de bloqueio
A maioria das transações na blockchain bitcoin é muito simples: o proprietário de algumas moedas fornece uma assinatura criptográfica que autoriza a transação, e tudo o que os nós bitcoin precisam fazer é verificar se essa assinatura é, de fato, válida.
Um número menor de transações usa condições mais complexas, como multi-assinatura . Um bitcoin bloqueado usando uma carteira multi-assinatura m-de-n requer que pelo menos m das n chaves possíveis aprovem uma transação, assinando-a.
Alguns exemplos são os seguintes:
- Uma carteira 1-de-2 pode ser uma conta conjunta onde qualquer um dos dois parceiros pode aprovar gastos; uma 2-de-2 poderia ser a conta poupança, onde ambos devem aprovar para gastar com ela.
- Uma empresa com 3 diretores pode usar uma carteira multi-assinatura 2-de-3 para permitir que quaisquer 2 deles autorizem um gasto do tesouro da empresa (especialmente útil para uma empresa que já mudou para um padrão bitcoin).
- Um único indivíduo poderia usar uma carteira 2-de-3 para evitar um único ponto de falha para seu backup de sementes, mantendo uma semente em casa, uma semente no escritório e uma semente em um banco seguro. A perda de qualquer chave ainda permitirá a recuperação, e será muito mais difícil para um intruso coagi-lo a enviar as moedas - já que isso não seria possível de um único local.
Scripts maiores e mais complexos também são possíveis: desde o início, o bitcoin veio equipado com uma linguagem chamada Script, que permite especificar programaticamente as condições que devem ser atendidas para desbloquear os fundos.
Por exemplo, o Script habilita timelocks (travas no tempo), que permitem que as condições de gastos sejam válidas apenas após um determinado período de tempo: um pai de três filhos poderia configurar uma carteira onde ele é o único proprietário, mas caso ele não consiga mais mover o moedas, dois de seus três filhos ou filhas podem gastar as moedas, mas somente após 1 ano . Planejamento sucessório sem cartório!
Script é uma linguagem muito rudimentar semelhante ao assembly, o que torna fácil para as máquinas executarem e verificarem, mas difícil para os humanos programarem e verificarem se não há bugs! Devido a essa complexidade, uma carteira de software que deseja usar uma condição de bloqueio específica precisa saber como representá-la usando a linguagem Script do bitcoin e codificar essas regras na carteira de software, juntamente com as regras sobre como realmente satisfazer esse script ao bloquear as moedas (para construir o que é chamado de testemunha nas transações do SegWit). Isso é demorado e caro (os engenheiros de script são escassos…) e, além disso, não é flexível: cada script exigirá suporte específico em softwares de wallets – mas o número de scripts possíveis é potencialmente infinito. De jeito nenhum eles podem ser codificados em um catálogo!
Essa é provavelmente a principal razão pela qual o suporte na indústria tem sido geralmente limitado a scripts relativamente simples como multi assinatura.
Era necessária uma solução mais geral – e isso é miniscript .
Miniscript e políticas
Miniscript foi anunciado por Pieter Wuille e Andrew Poelstra da Blockstream, mais tarde acompanhados por Sanket Kanjalkar. Com mais de 4 anos de trabalho (e contribuições de muitos colaboradores externos), agora está se preparando para o grande momento. Está em andamento para ser mesclado ao bitcoin-core, e já projetamos o novo aplicativo Ledger Bitcoin versão 2 com miniscript no fundo da nossa mente.
Existem três etapas para ir das condições de bloqueio de uma carteira para o Script bitcoin real. Primeiro, escrevemos essas condições de bloqueio em uma Policy, que é simplesmente sua representação formal, sem levar em conta as restrições e ressalvas do Script. Uma policy (política) é basicamente quais condições queremos expressar, sem nos importarmos exatamente em como podemos expressá-las. Como um exemplo simples, observe a seguinte política (onde as chaves reais são substituídas pelos espaços reservados A
e B
):
or(99@pk(A),1@and(pk(B),older(1008)))
Isso representa a seguinte condição de bloqueio: A
pode assinar imediatamente, enquanto a chave B
só fica ativa após cerca de uma semana (1008 blocos). Além disso, a política especifica que a primeira condição de gasto é 99 vezes mais provável que a segunda (isso não afeta a semântica das condições de bloqueio em si, mas afeta qual das diferentes maneiras possíveis de expressá-las no Script é mais eficiente na prática). O compilador de políticas produz o seguinte miniscript:
or_d(pk(A),and_v(v:pkh(B),older(1008)))
que por sua vez compila diretamente para o seguinte Script:
<A> OP_CHECKSIG OP_IFDUP OP_NOTIF
OP_DUP OP_HASH160 <HASH160(B)> OP_EQUALVERIFY OP_CHECKSIGVERIFY <f003>
OP_CHECKSEQUENCEVERIFY
OP_ENDIF
Nada muito empolgante sobre este Script (o bitcoin pode fazer isso há muito tempo!), exceto que:
- O compilador de políticas pode encontrar o melhor miniscript possível automaticamente
- A política em si é muito mais legível para um humano (ou pelo menos um engenheiro).
- O compilador garante que o Script resultante final está correto e pode aplicar certas verificações de sanidade.
- A linguagem miniscript, sendo estruturada, pode ser analisada por uma carteira com reconhecimento de miniscript.
- Tudo o que acabamos de dizer se aplicaria igualmente a qualquer outra política!
Com Política e miniscript, cada passo após a elaboração da política é totalmente automatizado; isso elimina qualquer espaço para erro humano e torna possível construir carteiras que são interoperáveis mesmo ao usar scripts complexos - desde que possam falar miniscript.
Demonstração
Nesta seção, mostramos como o registro da política de miniscript pode ser feito em um dispositivo Ledger Nano. Isso é baseado em um novo código não lançado de app-bitcoin-new e testado usando um bitcoin-core ainda não lançado com suporte a miniscript. No entanto, poderíamos produzir um gasto real de transação testnet a partir do endereço tb1qlmtlptrgr8v03leledzss43jgcfcc23u2qu43zg6ka4zh8dgwlas58hqav
, tornando-o o primeiro gasto de uma carteira miniscript protegida com chaves em uma carteira de hardware Ledger Nano. Demais!
Aviso: nada mostrado nesta seção é definitivo. Especificações exatas e UX podem e serão diferentes na versão lançada.
A política
Neste exemplo, trabalharemos com a seguinte política:
and(pk(key_user),or(99@pk(key_service),older(1008)))
Em outras palavras, existem duas chaves: nossa chave (key_user
) e a chave de um serviço externo de autenticação de 2 fatores (key_service
). Normalmente, o segundo serviço vai contra-assinar todas as nossas transações (possivelmente de acordo com algumas regras que estabelecemos antecipadamente, por exemplo “não mais que 1 milhão de satoshis por dia”). O que acontece se o serviço desaparecer? Ao contrário de um multi assinaturas 2-de-2 mais simples, as moedas não são queimadas com esta política! Depois de esperar 1008 blocos (cerca de 1 semana), nossa própria chave é suficiente para assinar uma transação e, portanto, recuperar nossos fundos.
A compilação desta política produz o seguinte miniscript:
and_v(v:pk(key_user),or_d(pk(key_service),older(1008)))
e aqui está como o Script correspondente ficará:
<key_user> OP_CHECKSIGVERIFY <key_service> OP_CHECKSIG OP_IFDUP OP_NOTIF
<f003> OP_CHECKSEQUENCEVERIFY
OP_ENDIF
Registro de política no Nano
Para usar uma conta de carteira miniscript com o dispositivo, primeiro é necessário registrar seu modelo de descritor no dispositivo. Isso ensina ao seu Ledger tudo sobre a carteira miniscript, e é exatamente o mesmo processo descrito em um post anterior no contexto de carteiras multi assinatura.
É assim que ficará, em um Nano X simulado (escolhemos o nome “2FA wallet” para a carteira que estamos usando):
Registrando uma política de miniscript
Observe que os modelos de descritor do Ledger usam @0
, @1
, etc para os espaços reservados, e as chaves públicas estendidas completas (o chamado “xpub” na mainnet bitcoin, “tpub” na testnet) são inspecionados separadamente ao registrar a política de carteira. Além disso, o miniscript está contido em um wsh
descritor. Apenas P2WSH (script segwit nativo) e P2SH-WSH (script segwit encapsulado) serão suportados na primeira versão.
Recebendo e gastando
O recebimento em uma carteira multi assinatura tem uma interface familiar para nossos usuários, com a única diferença de que uma tela adicional menciona explicitamente o nome da conta da carteira (anteriormente registrada) − neste exemplo “2FA wallet”.
Gastar de uma “conta miniscript” é semelhante: após uma tela inicial notificando que você está gastando de uma carteira registrada chamada “2FA wallet”, o UX é o mesmo de sempre.
Recebendo/gastando de uma política registrada
Nós gastamos com sucesso da nossa primeira conta de carteira miniscript testnet com esta transação .
Se você estava esperando que as carteiras suportassem scripts avançados de bitcoin, a hora de codificar é agora.
Miniscript está chegando!
O código
Mas quanto código é necessário para fazer tudo isso acontecer na carteira de hardware? Não muito:
from ledger_bitcoin import createClient, Chain, PolicyMapWallet
from ledger_bitcoin.psbt import PSBT
with createClient(chain=Chain.TEST) as client:
policy_map = PolicyMapWallet(
name="2FA wallet",
policy_map="wsh(and_v(v:pk(@0),or_d(pk(@1),older(1008))))",
keys_info=[
"[f5acc2fd/48'/1'/0'/2']tpubDFAq…4dK/**",
"[67d0577f/44'/1'/0']tpubDC2r…Lar/**"
])
# Registra a carteira
wallet_id, wallet_hmac = client.register_wallet(policy_map)
# Obtém o primeiro endereço de recebimento
addr = client.get_wallet_address(policy_map, wallet_hmac, 0, 0, True)
psbt_base64 = None # TODO: carrega o PSBT de algum lugar
psbt = PSBT()
psbt.deserialize(psbt_base64)
res = client.sign_psbt(psbt, policy_map, wallet_hmac)
print(res) # imprime as assinaturas
Obviamente, a complexidade de lidar com a chave do usuário e gerar e preencher corretamente o PSBT estão fora do escopo deste exemplo.
Construindo o futuro da auto custódia de bitcoin
O roteiro do aplicativo Ledger Nano Bitcoin é empolgante.
O suporte a PSBT e miniscript, estendendo o suporte a scripts Taproot e aproveitando ao máximo o taproot com soluções como MuSig2 dará início a uma nova era para a auto custódia do bitcoin. Mais fácil, mais seguro, mais flexível, mais interoperável, mais privado.
Hora de construir!
Descontinuação do aplicativo legado
No momento deste post, o aplicativo Ledger ainda contém integralmente o protocolo antigo; portanto, o software escrito para uma versão do aplicativo abaixo de 2.0.0 pode interagir com o aplicativo atual e tudo funcionará conforme o esperado.
Infelizmente, isso tem um impacto substancial no tamanho do aplicativo, tornando-o insustentável a longo prazo. Portanto, nosso objetivo é descartar o suporte ao protocolo legado até outubro de 2022 do canal de distribuição padrão no Ledger Live.
Garantiremos que o aplicativo legado estará disponível para download, a fim de garantir que nenhum usuário seja bloqueado em seus fundos caso precise usar software não atualizado que não suporte o novo protocolo.
Graças ao trabalho de Andrew Chow, a versão 2.1.0 da biblioteca HWI suporta nativamente a versão 2.0.0 e superior do aplicativo Ledger Bitcoin, mantendo-se compatível com o aplicativo legado para transações simples. Atualmente, o suporte para os recursos de registro de política de carteira está incompleto (mas a atualização deve ser perfeita para a maioria dos casos de uso).
A biblioteca ledger-bitcoin já está disponível para desenvolvedores com suporte total para o novo aplicativo, e um pacote cliente TypeScript está disponível no repositório do aplicativo.
Gostaríamos de solicitar a qualquer empresa que integrou dispositivos Ledger em seu fluxo de trabalho para planejar adequadamente e, por favor, entre em contato conosco se precisar de ajuda com a transição ou se encontrar alguma dificuldade durante a integração com o novo aplicativo.
Reconhecimentos
Podemos construir o aplicativo bitcoin mais incrível para carteiras de hardware porque nos sentamos no ombro de gigantes.
Gostaríamos de agradecer a Antoine Poinsot e Sanket Kanjalkar pelas inúmeras discussões e por impulsionar o estado da arte em miniscript.
Da mesma forma, nossa apreciação vai para Andrew Chow pelo formato PSBT e os descritores de saída que estamos construindo.
Recursos
- github.com/LedgerHQ/app-bitcoin-new : o aplicativo Ledger Nano para bitcoin
- bitcoin.sipa.be/miniscript : o site e o playground do miniscript
- miniscript.fun : um playground gráfico para miniscript
- bitcoinops.org/en/topics/miniscript : mais links e informações adicionais sobre miniscript
- pt.bitcoin.it/wiki/Script : Referência do Script
Oldest comments (0)