Por que o desenvolvimento do blockchain é difícil – Parte 1: publicação de transações

François-René Rideau Blocked Desbloquear Seguir Seguindo 8 de janeiro

Nós da Alacris.io queremos que os desenvolvedores de aplicativos possam dedicar seu tempo ao design de alto nível de seus aplicativos, em termos de interações econômicas entre várias partes. Queremos evitar que eles tenham que lidar com a complexidade de problemas, como postar uma transação.

Espere, alguns dirão: Postar uma transação é complexo? Já não existe uma função para chamar isso? Bem, sim e não. Já existe uma função que funciona bem o suficiente para o simples caso de pagamentos manuais; mas essa função falha muito e é totalmente inadequada para uso nos casos mais elaborados que importam para um aplicativo distribuído respaldado por um contrato inteligente.

Quando o dispositivo mais simples (uma máquina de Turing) já é extremamente complexo…

Funções existentes para lançar transações estão faltando

Claro, você encontrará funções para criar e publicar transações na API Ethereum JSON-RPC, ou nas bibliotecas equivalentes para Go, Javascript, Python, Rust ou seu idioma favorito. Mas chamar uma dessas funções não garante nem garante que a transação seja executada. E se o seu aplicativo travar no meio da interação? E se o seu cliente de nó Ethereum travar? E se você for vítima de uma interrupção de rede? E se você não usar um limite de GAS alto o suficiente ou usar um preço GAS alto o suficiente? E se a sua transação perder a corrida para outra transação que você postou, ou para uma transação postada por outra pessoa usando o mesmo contrato? E se sua transação chegar a um bloqueio, mas esse bloqueio será revertido por um tio mais pesado? E se alguma das situações acima acontecer, não por um infeliz acidente, mas por um ataque deliberado de um inimigo?

Em todos esses casos, a resposta simples é “depois de dez, trinta ou sessenta minutos, verifique se a transação foi aprovada e, se não, tente novamente.” E enquanto você for apenas um humano enviando pagamento e não estiver muita pressa, provavelmente é uma resposta boa o suficiente. Tudo o que você precisa é que sua "carteira" avise que a transação falhou e que você tente novamente com os parâmetros atualizados ao pressionar um botão. O comerciante ou parceiro comercial do outro lado normalmente espera pacientemente pelo pagamento antes de qualquer coisa, de qualquer maneira. E assim a função existente é boa o suficiente para implementar uma carteira.

Agora, para escrever um aplicativo que não seja apenas uma carteira de pagamento, você precisa de mais do que isso. Em um típico "contrato inteligente", uma ou várias partes, cada uma, publica um grande título que perderão se postarem as transações prometidas por eles em um prazo apertado. Sua função "pós-transação" é boa o suficiente para ser usada em um contrato tão inteligente? Se funcionar 99% do tempo, isso significa que a cada cem vezes alguém perderá seu grande vínculo. Isso é bom o bastante pra você? Se a função funcionar 99,9999% do tempo, ela ainda falhará uma vez em um milhão de chamadas. Se é para ser usado um bilhão de vezes por ano, isso ainda é um grande número de usuários de descontentamento, cada um perdendo uma quantidade significativa de dinheiro. E, no entanto, 99,9999% de confiabilidade “nove noves” já são considerados difíceis de alcançar na prática. Você pode realmente tornar esta função tão confiável ou melhor? Quantos noves de confiabilidade você pode se dar ao luxo de ter? E quantos você não pode deixar de ter? Quando sua função eventualmente falha porque o mundo conspira contra você, então o que? Lembre-se de que, ao escrever a função, você não está apenas lutando contra probabilidades acidentais de falha: você está lutando contra tentativas deliberadas de frustrar você por maus atores que assinarão um contrato com você apenas para impedi-lo de postar sua transação e coletar parte de seu vínculo como reparações. Mesmo que eles não consigam cobrar reparações de fazer você fracassar, inimigos e vândalos podem querer ver você perder, mesmo quando eles não puderem se beneficiar diretamente; e gângsteres elaborados podem ameaçar fazer você não conseguir manter seu refém, chantageá-lo e resgatá-lo. Sua função permanecerá tão confiável quanto você precisa estar nesse ambiente contraditório?

O que uma API adequada de publicação de postagem faria

A função “pós-transação” existente não é de forma alguma uma API funcional utilizável por aplicativos distribuídos além de simples carteiras. Todo o propósito de uma API funcional é tornar possível escrever programas automatizados que chamam a API, deixar que ela faça sua mágica e não ter que lidar com os detalhes abaixo desse nível de abstração. Uma função adequada de "pós-transação" garantirá que a transação passará, apesar de todos os possíveis problemas dentro do controle do programa: ela incluirá um bom modelo algorítmico para acompanhar o progresso da transação na rede. Ele manipulará a persistência de dados para que o aplicativo sobreviva a uma falha. Ele manterá várias réplicas de aplicativos em vários datacenters, de modo que o aplicativo não possa ser “apenas” frustrado por um inimigo fazendo um DDoS. Se necessário, ele roteará todas as comunicações relevantes através de circuitos virtuais e / ou redes de mixagem para que os inimigos não possam localizar facilmente a máquina que usa contrato e atacá-la. Recompensará automaticamente nonces para ajustar às condições de corrida. Ele usará alguma estratégia baseada em modelo para observar a rede e ajustar dinamicamente o preço a ser usado, para resistir a ataques de compra de blocos participando de um leilão adequado de espaço para transações (e ataques de compra de bloco não são apenas ataques teóricos). , mas coisas que realmente aconteceram no passado: considere o caso do contrato Fomo3D: 1 , 2 , 3 ). Em suma, uma função “pós-transação” adequada irá pacientemente cuidar de um conjunto de transações desejadas até que cada uma delas seja postada e confirmada no blockchain, uma vez e apenas uma vez, em uma ordem adequada.

E se algumas questões fora do controle do programa ainda surgirem e impedirem que a transação seja publicada? Em seguida, a função "pós-transação" enviará alertas adequados antes que seja tarde demais. O programa que chama a função tem a opção de manipular alguns desses alertas; mas, no final das contas, quaisquer alertas deixados sem tratamento chegarão a algum guarda humano de plantão. É o papel do Sistema Operacional Blockchain para assumir neste momento, como o desenvolvedor do aplicativo não tem acesso a todo o contexto necessário para lidar com esses problemas complexos. O aplicativo está implantado em um celular? O usuário para alertar é o proprietário do celular, usando alertas de celular. O aplicativo é implantado em uma rede redundante abrangendo três datacenters em diferentes continentes? O usuário para alertar pode ser um engenheiro de confiabilidade do sistema profissional de plantão. Os usuários podem estar usando um sistema de alerta patenteado que simplesmente não existia quando o aplicativo foi escrito e, ainda assim, o aplicativo o usará indiretamente, porque os alertas fazem parte da abstração oferecida pelo sistema operacional, em vez de recursos do próprio aplicativo . Qual mecanismo de alerta é usado dependerá da configuração de implantação do aplicativo. Não é responsabilidade do desenvolvedor do aplicativo, que não apenas não pode conhecer todas as situações de implantação existentes, mas, por definição, não pode prever as situações de implantação que só serão inventadas no futuro. Permitir que o desenvolvedor do aplicativo acesse os detalhes da implantação e lide com as situações de emergência seria, na verdade, uma grande preocupação de segurança que vai contra todas as boas práticas de segurança de software.

Agora, o que quando um aplicativo falha? O humano de plantão terá que assumir a partir daí. E a menos que você seja uma grande empresa ou um indivíduo rico que ofereça um engenheiro de operações de software como suporte técnico, esse ser humano de plantão será você. Então, uma ótima API funcional tornará mais fácil para o ser humano de plantão avaliar a situação e tomar as medidas apropriadas:

  • conectando um pouco de cabo antes de tentar novamente, tentando novamente usando uma conexão de rede de backup,
  • chamando um amigo que vai postar a transação para ele através de uma rede diferente,
  • usando parâmetros diferentes com mais gás ou um preço de gás mais alto,
  • deixando cair a transação e perdendo a ligação porque afixar a transação custaria mais do que a ligação vale a pena afinal,
  • ainda postando a transação e perdendo mais em gás do que a transação vale, porque a falha em postar recompensaria os bandidos, ou causaria uma perda de confiança e negócios futuros de outros usuários,
  • usar algum caminho de execução alternativo ou jogo de mitigação previsto no contrato inteligente,
  • aceitar uma oferta de acordo da outra parte, em vez de ter uma regra de juiz inteligente contra você, etc.

Muitos modos de falha e recuperação são possíveis e, em geral, não é responsabilidade da função de chamada manipular dolorosamente estratégias de recuperação que envolvam estado global além do escopo da função. Em vez disso, o Sistema Operacional Blockchain deduzirá automaticamente essas interações de monitoramento da estrutura regular do programa de chamada.

Entretanto, antes de tomar qualquer ação, o humano deve ser capaz de entender o que está acontecendo, que transação está sendo realizada, que valor está em jogo. Portanto, é essencial que o sistema operacional ofereça ao humano a capacidade de inspecionar a estrutura do programa de chamada. A interface do usuário deve permitir que o usuário inspecione o estado atual do programa que está sendo interrompido. Esta é a razão pela qual o programa geralmente não pode ser escrito como “simples” chamadas de função em Python, Go, Javascript ou qualquer outra linguagem “blub”: o programa deve ser escrito em uma linguagem específica de domínio (DSL) apropriada, compilada por um metaprograma que tem acesso a toda a estrutura do programa, em vez de meramente a chamadas locais (embora o programa possa ser construído a partir de um metaprograma escrito em linguagem blub, no estilo do Google TensorFlow ou de um metaprograma destinado à linguagem blub). Escrever aplicativos distribuídos em DSLs adequados também significa que esses aplicativos podem ser modulares, onde os módulos comuns podem ser reutilizados e compostos em aplicativos maiores, quando escritos corretamente. Por outro lado, escrever esses aplicativos manualmente em uma linguagem procedural levaria a todas as abstrações vazando e tornando o programa resultante inadequado para a composição modular.

Para um sistema operacional Blockchain

Em conclusão, algo tão enganadoramente simples como “postar uma transação” justifica que os aplicativos distribuídos não devem ser escritos usando APIs existentes ou usando qualquer API expressa como chamadas de função em qualquer idioma existente. Em vez disso, ele deve ser escrito em uma linguagem específica de domínio criada com o propósito de escrever tais aplicativos, rodando sobre um “Sistema Operacional Blockchain” que não apenas fornecerá abstração robusta e reforçará as práticas de segurança, mas também ajudará os humanos a lidar com situações de emergência. dependendo da configuração de implantação específica. E postar uma transação é apenas um dos vários aspectos de um aplicativo distribuído, cada um dos quais deve ser tratado adequadamente. Na Alacris, acreditamos que esses aspectos são mais bem implementados uma vez por especialistas em infraestrutura, em seguida, compartilhados entre todos os aplicativos, em vez de implementados várias vezes por cada desenvolvedor de aplicativos saindo de sua função regular e possivelmente sem suas habilidades. É por isso que nós da Alacris.io estamos construindo um Sistema Operacional Blockchain, que irá gerenciar esses aspectos para os desenvolvedores de aplicativos.

Este artigo é o primeiro de uma série em andamento intitulada "Por que Blockchain é Difícil". Um novo artigo será lançado a cada três semanas. Fique atento ao nosso próximo artigo "Computação".