Compreender a programação do CKB a partir da programação de aplicações Bitcoin

Autor original: Ajian

Resumo

Compreender a programabilidade de um sistema requer que identifiquemos as características estruturais do sistema. A exploração da programação de aplicativos baseada em Bitcoin Script nos ajuda a entender a estrutura básica do CKB Cell e seu paradigma de programação. Não só isso, mas ele divide os componentes de programação do CKB nas partes certas e nos ajuda a entender os ganhos de programação que cada parte traz.

I. Introdução

"Programabilidade" é uma dimensão que as pessoas costumam tomar ao comparar sistemas blockchain. No entanto, muitas vezes há desacordo sobre como a programação é descrita. Uma expressão comum é "XX blockchain suporta linguagens de programação Turing-complete", ou, "XX blockchain suporta programação de uso geral", que se destina a indicar que o "XX blockchain" aqui tem forte programabilidade. Há alguma verdade na implicação destas afirmações: os sistemas que suportam a programação Turing-completa são geralmente mais fáceis de programar do que aqueles que não suportam. No entanto, existem muitos aspetos nas características estruturais de um sistema de contrato inteligente, e esta afirmação toca em apenas um deles, por isso não é suficiente para ser entendido com profundidade suficiente em virtude do fato de que os desenvolvedores não são guiados por ele, e os usuários comuns não podem ser confiados para distinguir fraudes.

As características estruturais de um sistema de contrato inteligente incluem:

  • A forma básica de expressão do estado (contrato) (conta vs. saída comercial)
  • Se a computação arbitrária pode ou não ser programada (é disso que trata o termo "Turing-complete")
  • O processo de execução cria novos dados ou apenas distribui booleanos? (Computação vs. Validação)
  • Permitir ou não que outros Estados sejam inscritos no contrato
  • Se um contrato tem acesso ao estado de outro contrato quando é executado

Portanto, além da "computação arbitrária programável", existem pelo menos quatro características que afetam a programabilidade de um sistema de contrato inteligente. Pode-se mesmo dizer que estas outras características são mais importantes, porque determinam a um nível mais profundo o que é fácil de alcançar e o que é difícil de alcançar; O que é uma implementação mais económica e o que é uma implementação menos eficiente.

Por exemplo, o Ethereum é frequentemente citado como um exemplo de boa programabilidade, mas a forma básica de expressão de estado no Ethereum é uma conta, o que torna difícil programar contratos peer-to-peer (por exemplo, gateways de pagamento, contratos de apostas um-para-um) – não absolutamente impossível, apenas ingrato. Não é incomum que o ecossistema Ethereum tente implementar um canal de pagamento/canal estatal, e tem havido muitas discussões teóricas, mas esses projetos não parecem estar mais ativos – e isso, obviamente, não pode ser atribuído à falta de esforço por parte dos desenvolvedores. Não é por acaso que os projetos ativos no Ethereum hoje estão tomando a forma de "pools" em vez de "contratos peer-to-peer". Da mesma forma, as pessoas podem estar felizes com a programação do Ethereum, mas o modelo de conta é inerentemente deficiente em alcançar a "abstração de conta" (que também pode ser entendida como uma generalização do conceito de carteira).

Da mesma forma, explorar a programabilidade do CKB também requer que compreendamos as características estruturais do sistema de contrato inteligente CKB nesses aspetos. O que já sabemos é que o CKB permite que cálculos arbitrários sejam programados, permite que um estado adicional seja registrado dentro de um contrato e permite que um contrato acesse o estado de outro contrato quando executado. No entanto, a forma do contrato é a saída de uma transação (chamada de "célula"), o que o torna fundamentalmente diferente do Ethereum. Portanto, uma compreensão do sistema de contrato inteligente Ethereum e as instâncias de contrato dentro dele não nos ajuda a entender como o CKB implementa esses recursos estruturais, nem nos ajuda a entender a programabilidade do CKB.

Felizmente, os contratos inteligentes em Bitcoin parecem fornecer a melhor base para entender a programação do CKB. Isso não é apenas porque a forma básica de representação do estado do Bitcoin é também a saída de transações (chamadas de "UTXOs"), mas também porque, com a ajuda de um conceito proposto pela comunidade Bitcoin chamado "covenants", podemos entender por que o CKB tem essas características estruturais, e adequadamente dividir o efeito final em várias partes, identificando os ganhos de programabilidade que cada um deles traz.

II. CKB v.s. BTC: O que mais?

(1) Estrutura básica

Como forma básica de representação do estado do Bitcoin, o UTXO ("Unspent Transaction Output") do Bitcoin tem dois campos:

  1. O montante, em Satoshi, indica o valor do Bitcoin possuído pelo UTXO;
  2. A chave pública do script, também conhecida como script de bloqueio, representa as condições que precisam ser cumpridas para gastar os fundos, ou seja, o programa de contrato inteligente que define as condições para desbloquear os fundos.

Em comparação com os sistemas de contratos inteligentes que vieram mais tarde, o Bitcoin Script é bastante limitado:

  • Não permite programar cálculos arbitrários; Existem apenas alguns cálculos práticos que podem ser usados para verificação (verificação de assinatura, verificação pré-hash, verificação de tempo)
  • Não permite que estados adicionais sejam registrados no contrato; (Por exemplo, você não pode usar um script para limitar a quantidade proporcional/máxima de dinheiro gasto de cada vez; Também não há como esconder um token nele)
  • Também não permite o acesso ao estado de outro contrato no momento da execução (cada script é um universo separado e não depende um do outro).

Este tipo de scripting, embora limitado, não carece da capacidade de programar aplicações incríveis, e é a base da nossa exploração da programabilidade CKB. Haverá uma seção mais tarde que apresentará dois exemplos de programação Bitcoin Script.

Em contraste, a unidade de estado do CKB é chamada de "célula" e tem quatro campos:

  1. Capacidade, semelhante à quantidade de UTXO, expressa a quantidade de espaço que a célula pode ocupar, medida em bytes.
  2. Lock, semelhante à chave pública do script UTXO, define a propriedade da célula; Somente quando os dados fornecidos podem passar pela fechadura é que a célula pode ser "atualizada" (ou a célula pode ser liberada e a capacidade pode ser usada para cunhar novas células);
  3. Dados, dados, dados arbitrários, cujo volume é limitado pela Capacidade;
  4. Digite, um script opcional que define condições para atualizar dados.

Além disso, Lock e Type podem ser programados para cálculos arbitrários. Você pode programar qualquer algoritmo de verificação de assinatura, você pode programar qualquer algoritmo de hash para verificação de pré-imagem e assim por diante.

É fácil para os leitores verem como a programação do Cell melhora em relação aos UTXOs:

  • As células podem ser programadas com cálculos arbitrários, em vez de apenas alguns cálculos específicos; A sua verificação da propriedade será mais flexível;
  • Devido aos campos Dados e Tipo, a célula pode gravar estados adicionais; Isso permite que a célula carregue o que é conhecido como "UDT" (token definido pelo usuário).

Combinado com a estrutura de "saída de transação" da própria célula, os benefícios desses dois pontos em si são muito, muito significativos, mas a partir da descrição acima, não sabemos como a célula alcança "um contrato acessa o estado de outro contrato em tempo de execução". Para fazer isso, precisamos nos basear em um conceito que tem sido discutido há muito tempo na comunidade Bitcoin: "covenants".

(2) Limitações e introspeção

O objetivo original de uma cláusula de restrição é limitar onde uma quantia de dinheiro pode ser gasta. No Bitcoin atual (onde nenhuma restrição foi proposta), uma única quantia de dinheiro, uma vez desbloqueada, pode ser gasta em qualquer lugar (pode ser paga a uma chave pública de script arbitrário). Mas a ideia da cláusula de restrição é que ela possa ser gasta de uma forma que a limite a determinados lugares, por exemplo, uma determinada UTXO só será gasta por uma determinada transação, de modo que mesmo que alguém possa fornecer uma assinatura para a UTXO, onde ela pode ser gasta já foi determinada por essa transação. Isso pode parecer um pouco estranho, mas pode levar a algumas aplicações interessantes, que serão abordadas em uma seção mais tarde. É importante ressaltar que é fundamental para nossa compreensão adicional da programação CKB.

Rusty Russell aponta corretamente que uma restrição pode ser entendida como uma capacidade de "introspeção" para negociar, ou seja, quando um UTXO A é gasto por uma transação B, um operador de script pode ler parte (ou todas) as transações B e, em seguida, verificar se elas correspondem aos parâmetros pré-solicitados pelo script. Por exemplo, se a chave pública do script para a primeira saída da transação A corresponde ao que é exigido pela chave pública do script UTXO A (isso é o que a restrição significava originalmente).

O leitor astuto perceberá que, com introspeção completa, a entrada de uma transação pode ler o estado de outra entrada da mesma transação, o que permite a capacidade de um contrato acessar o estado de outro contrato em tempo de execução. Na verdade, foi exatamente assim que o CKB Cell foi projetado.

Com base nisso, podemos dividir essa capacidade introspetiva completa em quatro cenários:

  • Bloqueio lê outros (entrada e saída) bloqueios
  • Lock lê o tipo (bem como dados) do outro (entrada e saída)
  • Tipo lê outros bloqueios (entrada e saída)
  • Tipo lê o tipo (e dados) do outro (entrada e saída)

Isso nos permite analisar o papel das capacidades introspetivas de cada parte em diferentes casos de uso sob certos pressupostos (a divisão de funções entre Lock e Type), ou seja, o ganho de programabilidade que cada parte nos traz.

Nas duas seções seguintes, veremos a programação atual (e ainda não proposta) do Bitcoin Script, e a provável funcionalidade que se espera que a restrição proposta alcance, de modo a dar uma compreensão concreta de como o CKB Cell pode ser programado e feito melhor.

III. Programação de Scripts Bitcoin

Nesta seção, usaremos "Lightning Channel/Lightning Network" e "Caution Journal Contract (DLC)" como exemplos de programação de aplicativos baseados no Bitcoin Script. Antes de entrarmos nisso, vamos levar duas coisas para isso.

(1) OP_IF e "Acordos de Compromisso"

O primeiro conceito é o opcode de controle de fluxo no Bitcoin Script, como: OP_IF, OP_ELSE. Estes opcodes não são diferentes do IF na programação de computadores, e seu objetivo é executar diferentes instruções com base em diferentes entradas. No contexto do Bitcoin Script, isso significa que podemos definir vários caminhos de desbloqueio para fundos; Combinado com o recurso de bloqueio de tempo, isso significa que podemos atribuir prioridade às ações.

Tomemos como exemplo o famoso "Hash Timelock Contract (HTLC)", que se traduz em vernáculo:

Alternativamente, Bob poderia revelar a pré-imagem por trás de um hash H e dar sua própria assinatura, o que custaria o dinheiro
Ou, Alice pode gastar o dinheiro com sua própria assinatura após um certo período de T

Este "ou ... ou ..." O efeito é alcançado através do opcode de controle de processo.

A vantagem mais proeminente do > HTLC é que ele pode agrupar várias operações e atomizá-las. Por exemplo, se Alice quiser trocar BTC por CKB com Bob, então Bob pode primeiro dar um valor de hash e criar um HTLC na Rede Nervos. Alice então cria um HTLC no Bitcoin que usa o mesmo hash. Alternativamente, Bob pega o BTC pago por Alice no Bitcoin, enquanto também revela a pré-imagem, permitindo que Alice retire CKB na Rede Nervos. De qualquer forma, Bob não revela a imagem original, ambos os contratos expiram, e tanto Alice quanto Bob podem recuperar o dinheiro que investiram.

Após a ativação do soft fork Taproot, este recurso de caminho multi-unlock é ainda mais aprimorado pela introdução do MAST (Merkle Abstract Syntax Tree): podemos transformar um caminho de desbloqueio em uma folha na árvore Merkle, cada folha é independente, então não há mais necessidade de usar tal opcode de controle de fluxo; Além disso, como um caminho é revelado sem expor os outros, podemos adicionar um número maior de caminhos de desbloqueio a uma saída sem ter que se preocupar com economia.

O segundo conceito é "negociação de compromisso". A ideia de uma transação comprometida é que, em alguns casos, uma transação Bitcoin válida, mesmo que não seja confirmada pelo blockchain, é igualmente real e vinculativa.

Por exemplo, Alice e Bob compartilham um UTXO que exige que ambos sejam assinados para gastar. Neste ponto, Alice constrói uma transação para gastá-la, transferindo 60% de seu valor para Bob e o restante para ela mesma; Alice fornece sua própria assinatura para a transação, que é então enviada para Bob. Bem, para Bob, isso não precisa ser transmitido para a rede Bitcoin, e não precisa ser confirmado pelo blockchain, e o efeito de pagamento dessa transação também é real e crível. Como Alice não pode gastar o UTXO sozinha (e, portanto, não pode gastá-lo repetidamente), e porque a assinatura fornecida por Alice é válida, Bob sempre pode adicionar sua assinatura e transmitir a transação para honrar o pagamento. Por outras palavras, Alice forneceu a Bob um "compromisso credível" através desta transação válida (off-chain).

As transações comprometidas são um conceito central da programação de aplicativos Bitcoin. Como mencionado anteriormente, o contrato do Bitcoin é baseado em verificação, apátrida e não permite acesso cruzado; No entanto, se o contrato não tiver estados, onde esses estados estão armazenados e como o contrato pode avançar com segurança (mudar de estado)? As transações de compromisso dão uma resposta direta: o estado do contrato pode ser expresso na forma de transações, de modo que os participantes do contrato possam salvar o próprio estado sem ter que exibi-lo no blockchain; O problema de alterar o estado do contrato também pode ser transformado no problema de como atualizar com segurança a transação comprometida; Além disso, se estamos preocupados com os perigos de entrar em um contrato (por exemplo, entrar em um contrato que exige que ambas as partes assinem para gastar, e há um risco de que a outra parte não responda e fique presa), então simplesmente gerar uma transação de compromisso que custa o contrato antecipadamente e obter uma assinatura pode mitigar o risco e eliminar a confiança em outros participantes.

(2) Lightning channel e lightning network

Um canal relâmpago é um contrato um-para-um no qual duas partes podem pagar uma à outra um número ilimitado de vezes sem ter nenhum pagamento confirmado pelo blockchain. Como você pode esperar, ele usa negociação de compromisso.

Na seção que explica "Transações Comprometidas", já introduzimos um canal de pagamento. No entanto, este tipo de contrato, que apenas alavanca 2-of-2 multisig, só pode permitir pagamentos unidirecionais. Ou seja, ou Alice sempre paga Bob, ou Bob sempre paga Alice até que ele use seu saldo no contrato. Se for um pagamento bidirecional, significa que, após uma atualização de estado, uma parte pode ter menos saldo do que antes, mas a AT tem a última transação comprometida assinada pela outra parte - o que pode ser feito para impedir que a AT transmita a promessa antiga e a AT apenas a transação de compromisso mais recente?

A solução para este problema com o canal relâmpago é chamado de "LN-Penalty". Agora, digamos que Alice e Bob tenham cada um 5 BTC em um canal; Agora Alice quer pagar a Bob 1 BTC, então ela assina a transação prometida e envia para Bob:

Digite #0 e 10 BTC:
saída multi-assinatura Alie-Bob 2-of-2 (ou seja, contrato de canal)

Saída #0, 4 BTC:
Alice de assinatura única

Saída #1, 6 BTC:
ou
Alice-Bob federated ephemeral public key #1 single-signature
ou
T 1 timelock, Bob single-signed

Bob também assina um compromisso (que corresponde à transação acima) e envia-o para Alice:

Digite #0 e 10 BTC:
saída multi-assinatura Alie-Bob 2-of-2 (ou seja, contrato de canal)

Saída #0, 6 BTC:
Bob com assinatura única

Saída #1, 4 BTC:
ou
Bob-Alice federated ephemeral public key #1 single-signature
ou
T 1 timelock, Alice single-signed

O truque aqui está nessa "chave pública temporária conjunta", que é gerada usando uma de suas próprias chaves públicas e uma chave pública fornecida pela outra parte, por exemplo, a chave pública temporária conjunta Alice-Bob, que é obtida por Alice usando uma de suas próprias chaves públicas e uma chave pública fornecida por Bob, multiplicando cada uma por um valor de hash. Quando essa chave pública é gerada, ninguém sabe a sua chave privada. No entanto, se Bob disser a Alice a chave privada da chave pública que forneceu, Alice pode calcular a chave privada da chave pública temporária federada. - Esta é a chave para o fato de que o Lightning Channel pode "desfazer" o estado antigo.

Da próxima vez que as duas partes quiserem atualizar o status do canal (iniciar um pagamento), as duas partes trocam a chave privada da chave pública temporária dada uma à outra na rodada anterior. Desta forma, os participantes já não se atrevem a transmitir a última transação prometida que receberam: o resultado dessa transação prometida atribuindo valor à sua própria parte tem dois caminhos, e a chave privada do caminho de chave pública temporária já é conhecida pela outra parte; Assim, uma vez que a antiga transação de compromisso é transmitida, a outra parte pode usar imediatamente essa chave privada temporária conjunta para receber todos os fundos dessa saída. - É isto que significa "LN-Penalty".

Especificamente, a ordem de interação é a seguinte: a parte que inicia o pagamento primeiro solicita uma nova chave pública temporária da outra parte e, em seguida, constrói uma nova transação de compromisso e a entrega à outra parte; O partido que obteve a transação prometida revelou à outra parte a chave privada da chave pública temporária que ele deu na rodada anterior. Essa sequência de interações garante que os participantes sempre obtenham uma nova transação de compromisso antes de invalidar a transação de compromisso que receberam na rodada anterior e, portanto, não sejam confiáveis.

Em resumo, os principais designs do canal de iluminação são:

  1. Ambas as partes utilizam sempre as transações de compromisso para expressar o estado dentro do contrato, e a alteração no valor para expressar o pagamento;
  2. As transações de compromisso sempre custam a mesma entrada (entrada que exige que ambas as partes forneçam assinaturas ao mesmo tempo), então todas as transações de compromisso estão competindo entre si, e apenas uma pode ser confirmada pelo blockchain.
  3. Os dois participantes não estão a assinar a mesma transação de compromisso (embora estejam emparelhados); E o que eles assinam é sempre uma transação que é mais favorável a si mesmos, ou seja, a transação prometida que os participantes recebem é sempre desfavorável a si mesmos;
  4. A desvantagem disso é que a saída que atribui valor a si mesma tem dois caminhos de desbloqueio: um caminho pode ser desbloqueado com sua própria assinatura, mas precisa esperar um pouco; O outro caminho usa a chave pública da outra parte, que é protegida somente se uma de suas chaves privadas temporárias não for exposta.
  5. Em cada pagamento, ambas as partes trocam a chave privada temporária usada pela outra parte na rodada anterior por uma nova transação de compromisso, de modo que a parte que entregou a chave privada temporária não se atreve mais a transmitir a transação de compromisso antiga, então "cancela" a transação de compromisso anterior e atualiza o status do contrato; (Na verdade, essas transações prometidas são todas transações válidas e podem ser transmitidas para o blockchain, mas os participantes são forçados a serem punidos e não ousam mais transmitir)
  6. Qualquer das partes pode rescindir o contrato a qualquer momento com um compromisso assinado pela outra parte; No entanto, se ambas as partes estiverem dispostas a cooperar, podem assinar um novo acordo para que ambas as partes possam receber o seu dinheiro de volta imediatamente.

Finalmente, como o HTLC também pode ser colocado em uma transação confirmada, o canal Lightning também pode encaminhar pagamentos. Supondo que Alice possa encontrar um caminho que consiste em canais relâmpagos conectando antes e depois para chegar a Daniel, então pagamentos multi-hop sem confiança podem ser alcançados sem abrir um canal com Daniel. Esta é a Lightning Network:

Alice -- HTLC --> Bob -- HTLC --> Carol -- HTLC --> Daniel
Alice < -- Pré-imagem -- Bob < -- Pré-imagem -- Carol < -- Pré-imagem -- Daniel

Quando Alice encontra esse caminho e quer pagar Daniel, ela pede a Daniel um hash para construir um HTLC para Bob, e pede a Bob para encaminhar uma mensagem para Carol e fornecer o mesmo HTLC; A mensagem solicita que Carol encaminhe a mensagem para Daniel e forneça o mesmo HTLC. Quando a notícia chega a Daniel, ele revela a pré-imagem para Carol, o que lhe dá o valor de HTLC e atualiza o estado do contrato. Carol fez o mesmo, sendo paga por Bob e atualizando o status do canal; Por fim, Bob revela a pré-imagem para Alice e atualiza o status. Devido à natureza da HTLC, esta cadeia de pagamentos tem sucesso ou falha em conjunto e, como tal, não é confiável.

A Lightning Network é composta de um canal após o outro, cada um dos quais é independente um do outro. Isso significa que Alice só precisa saber o que está acontecendo em seu canal com Bob, independentemente de quantas interações ocorreram nos canais de outras pessoas, qual moeda essas interações usam ou até mesmo se elas estão realmente usando o canal.

A escalabilidade da Lightning Network não se reflete apenas no fato de que a velocidade de pagamento dentro de um Lightning Channel é limitada apenas pelo investimento de recursos de hardware por ambas as partes, mas também que, devido ao armazenamento descentralizado de estado, um único nó pode alavancar a alavancagem máxima com o menor custo.

(3) Seja cauteloso com os contratos de periódicos

O Cautionary Journaling Contract (DLC) usa uma técnica criptográfica chamada "assinatura adaptadora" que permite ao Bitcoin Script programar contratos financeiros que dependem de eventos externos.

As assinaturas do adaptador permitem que uma assinatura se torne uma assinatura válida somente depois que uma chave privada é adicionada. Tomemos o exemplo de uma assinatura Schnorr, onde o formulário padrão de uma assinatura Schnorr é (R, s), onde:

R = r.G

O valor nonce r usado para a assinatura é multiplicado pelo ponto de geração da curva elíptica, que também pode ser dito ser a chave pública de r

s = r + Hash(R || m || P) * p

p é a chave privada de assinatura e P é a chave pública

验证签名即验证 s.G = r.G + Hash(R || m || P) * p.G = R + Hash(R || m || P) * PK

Digamos que eu dê um par de dados (R, s') onde:

R = R 1 + R 2 = r 1.G + r 2.G
s' = r 1 + Hash(R || m || P) * p

Obviamente, esta não é uma assinatura Schnorr válida, e não passa a fórmula de validação, mas posso provar ao verificador que pode ser uma assinatura válida simplesmente conhecendo a chave privada de R 2, r 2:

s'. G + R 2 = R 1 + Hash(R || m || P) * P + R 2 = R + Hash(R || m || P) * P

As assinaturas do adaptador tornam a validade de uma assinatura dependente de dados secretos e é verificável. Mas o que isso tem a ver com contratos financeiros?

Digamos que Alice e Bob queiram apostar no resultado de um jogo de bola. Alice e Bob apostaram no Duende Verde e Alina para ganhar, respectivamente, com uma aposta de 1 BTC. Além disso, Carol, um site de análise de futebol, prometeu usar um nonce R_c para postar um s_c_i assinado dos resultados quando os resultados do jogo fossem anunciados.

Como pode ser visto, existem três resultados possíveis (portanto, há 3 possibilidades para a assinatura de Carol):

  • Duende Verde vence, Alice ganha 1 BTC

  • Alina ganha, e Bob ganha 1 BTC

  • Empate, os fundos dos dois retornam da mesma forma

Para isso, os dois criam um acordo de compromisso para cada resultado. Por exemplo, a transação de compromisso que eles criaram para o primeiro resultado ficaria assim:

Digite #0, 2 BTC:
Alie-Bob 2-of-2 saída multi-assinatura (ou seja, contrato de aposta)

Saída #0, 2 BTC:
Alice de assinatura única

No entanto, em vez de (R, s), a assinatura que Alice e Bob criaram para esta transação é uma assinatura de adaptador (R, s'); Em outras palavras, as assinaturas dadas uma à outra por ambas as partes não podem ser usadas diretamente para desbloquear o contrato, mas devem revelar um valor secreto. Este valor secreto é a pré-imagem de s_c_ 1.G, que é a assinatura de Carol! Desde que o valor nonce da assinatura de Carol foi determinado (R_c), s_c_ 1.G pode ser construído (s_c_ 1.G = R_c + Hash(R_c ||). «Duende Verde vence» || PK_c) * PK_c)。

Quando os resultados forem revelados, supondo que o Duende Verde vença, Carol emitirá uma assinatura (R_c, s_c_ 1), para que Alice ou Bob possam completar a assinatura do adaptador do oponente e adicionar sua própria assinatura para tornar a transação acima uma transação válida, e transmiti-la para a rede para acionar o efeito de liquidação. Mas se o Duende Verde não ganhar, Carol não postará s_c_ 1, e o acordo de compromisso não será um acordo válido.

E assim por diante, assim como os outros dois negócios. Desta forma, Alice e Bob fazem depender a execução do contrato de eventos externos (para ser mais preciso, da transmissão de eventos externos pela máquina assertora, na forma de uma assinatura) sem ter que confiar na contraparte. Grandes e pequenos contratos financeiros, como futuros e opções, podem ser implementados desta forma.

Em comparação com outras formas de implementação, a característica mais importante do contrato de registro cauteloso é sua privacidade: (1) Alice e Bob não precisam dizer a Carol que estão usando os dados de Carol, o que não afeta em nada a execução do contrato; (2) Os observadores on-chain (incluindo Carol) não poderão determinar qual site estão usando através da execução do contrato de Alice e Bob's, ou mesmo que seu contrato é um contrato de apostas (não um canal relâmpago).

IV. Introdução à Aplicação de Restrições

(a) OP_CTV e controlo de congestionamento

Os desenvolvedores da comunidade Bitcoin fizeram uma série de propostas que podem ser classificadas como cláusulas restritivas. No momento, uma das propostas mais conhecidas é OP_CHECKTEMPLATEVERIFY (OP_CTV), que é popular entre a comunidade Bitcoin por sua simplicidade, mas flexibilidade com seu conceito simples. A ideia de OP_CTV é comprometer um hash no script para restringir que os fundos só podem ser gastos pelas transações representadas por esse hash; Este hash promete a saída da transação e a maioria dos campos, mas não a entrada da transação, apenas o número de entradas.

"Congestion Control" é um bom exemplo de como OP_CTV pode ser demonstrado. Seu caso de uso básico é ajudar um grande número de usuários a sair de uma troca (um ambiente que requer confiança) para um pool; Uma vez que este pool usa OP_CTV para planejar como ele será gasto no futuro, ele garante que os usuários possam sair do pool sem confiança, sem a ajuda de ninguém; E como esse pool só se comporta como um UTXO, ele evita pagar muitas taxas quando a demanda por transações on-chain é alta (de n saídas para 1 saída; também reduziu de n transações para 1 transação). Os usuários no pool podem esperar por uma oportunidade para sair do pool.

Digamos que Alice, Bob e Carol queiram retirar 5 BTC, 3 BTC e 2 BTC da bolsa, respectivamente. Em seguida, a exchange pode fazer uma saída de 10 BTC com 3 OP_CTV filiais. Digamos que Alice queira sacar dinheiro, ela pode usar o ramo 1; A transação representada pelo valor de hash usado pelo OP_CTV da filial formará duas saídas, uma das quais é alocar 5 BTC para Alice; A outra saída, por sua vez, é um pool, que também usa OP_CTV para se comprometer com uma transação, permitindo que Bob retire apenas 3 BTC e envie os 2 BTC restantes para Carol.

É a mesma coisa se Bob ou Carol quiserem sacar dinheiro. Ao retirar dinheiro, eles só poderão usar transações que possam passar pelo cheque OP_CTV correspondente, ou seja, eles só poderão pagar o valor correspondente a si mesmos, e não poderão retirar dinheiro arbitrariamente; Os fundos restantes irão para um pool com um bloqueio OP_CTV, garantindo assim que os usuários restantes possam ser colocados fora do pool sem confiança, independentemente da ordem em que forem retirados.

Em abstrato, o papel de OP_CTV aqui é planejar o caminho até o fim da vida útil do contrato para o contrato, de modo que o contrato de pool aqui possa manter o atributo de saída sem confiança, não importa qual caminho ele tome ou qual estado ele vá.

Há também um uso muito interessante deste OP_CTV: "canal de pagamento unidirecional que está oculto, mas não revelado". Suponhamos que Alice forme tal pool de fundos e garanta que os fundos possam ser retirados sem confiança em uma saída com o seguinte script:

ou, Alice e Bob passam juntos
ou, depois de um tempo, Alice pode gastá-lo por conta própria

Se Alice não tivesse revelado isso a Bob, Bob não saberia que tal produção existia; Uma vez que Alice revela isso a Bob, Bob pode usar a saída como um canal de pagamento unidirecional sensível ao tempo que Alice pode usar para pagar Bob imediatamente sem ter que esperar pela confirmação do blockchain. Bob simplesmente pede a Alice para colocar sua transação de compromisso on-chain antes que Alice possa gastá-la por conta própria.

(b) OP_Vault e seguro

OP_VAULT é uma proposta de cláusula restritiva especificamente concebida para construir "cofres".

O contrato do Vault foi projetado para ser uma forma mais segura e avançada de autocustódia. Embora o contrato atual de várias assinaturas possa evitar um único ponto de falha para uma única chave privada, se um invasor obtiver um número limite de chaves privadas, o proprietário da carteira ficará desamparado. O Vault quer impor um único limite de gastos aos seus fundos; Ao mesmo tempo, ao retirar dinheiro usando a rota regular, a operação de retirada forçará um período de espera; E durante o período de espera, a operação de retirada pode ser interrompida pela operação de recuperação de emergência da carteira. Mesmo que tal contrato seja violado, o proprietário da carteira pode iniciar uma contraoperação (usando o ramo de recuperação de emergência).

Teoricamente, OP_CTV também pode programar tal contrato, mas há muitos inconvenientes, um dos quais é a comissão: ao se comprometer com a transação, também promete a taxa que a transação pagará. Dada a finalidade deste contrato, o intervalo de tempo entre a celebração do contrato e a retirada do dinheiro deve ser muito longo, por isso é quase impossível prever a comissão adequada. Embora OP_CTV não limite as entradas, de modo que a taxa pode ser aumentada aumentando a entrada, a entrada fornecida se tornará toda a comissão, por isso é irrealista; Outra forma é o CPFP, que consiste em fornecer uma comissão sobre novas transações, gastando os fundos retirados. Além disso, o uso de OP_CTV significa que tal contrato do Vault não pode ser retirado em massa (e certamente não pode ser restaurado em massa).

A proposta OP_VAULT tenta resolver estas questões propondo novos opcodes (OP_VAULT e OP_UNVAULT). OP_UNVAULT foi projetado para resiliência de lote, então não vamos mencioná-lo por enquanto. OP_VAULT se comporta assim: quando o colocamos em uma ramificação da árvore de scripts, ele pode ser usado para confirmar um opcode utilizável (por exemplo, OP_CTV) sem parâmetros específicos; Ao gastar este ramo, as transações podem ser passadas em parâmetros específicos, mas não em outros ramos. Como resultado, ele não precisa definir uma taxa predefinida, e ela pode ser definida quando a filial é gasta; Supondo que a ramificação também tenha um bloqueio de tempo, ele aplicará um bloqueio de tempo; Finalmente, como você só pode alterar a ramificação em que você está, e nenhuma outra ramificação da nova árvore de script (incluindo a ramificação de recuperação de emergência) será alterada, temos permissão para interromper tais retiradas.

Além disso, dois pontos merecem destaque: (1) o opcode OP_VAULT comporta-se de forma semelhante a outra proposta de restrição: OP_TLUV; Jeremy Rubin assinala, com razão, que isto deu origem ao conceito de "computação" até certo ponto: OP_TLUV/OP_VAULT primeiro promete um opcode para permitir que o consumidor atualize toda a folha da árvore de scripts, passando parâmetros para o opcode com uma nova transação; Já não se trata de "validar dados recebidos com base em determinados critérios", trata-se de "gerar novos dados significativos com base em dados recebidos", embora o cálculo que pode permitir seja limitado.

(2) A proposta completa do PO_VAULT recorre igualmente a algumas das propostas relativas à política de mempool (por exemplo, transações v3) para obter melhores resultados. Isso nos lembra que o significado de "programação" pode ser mais amplo do que pensamos. (Um exemplo semelhante é a Transação Aberta na Rede Nervos.) )

V. Entendendo o CKB

Nas duas seções acima, descrevemos como podemos criar scripts de aplicações interessantes em uma estrutura mais restrita (Bitcoin UTXO); Foram também apresentadas propostas para tentar acrescentar introspeção a tal estrutura.

Embora as UTXOs tenham a capacidade de programar esses aplicativos, é fácil para os leitores identificarem suas deficiências ou áreas que podem ser otimizadas, como:

  • No LN-Punishment, os participantes do canal devem salvar cada transação cometida no passado e o valor secreto da penalidade correspondente, a fim de lidar com a fraude do oponente, o que constitui um fardo de armazenamento. Se houver um mecanismo que garanta que apenas a transação de compromisso mais recente entrará em vigor, e a transação de compromisso antiga não, ele pode eliminar esse encargo, e também pode eliminar o problema de nós serem acidentalmente penalizados por colocar erroneamente uma transação de compromisso mais antiga on-chain.
  • No DLC, assume-se que há muitos resultados possíveis do evento, e há muitas assinaturas que ambas as partes têm que gerar e entregar uma à outra com antecedência, o que também é um enorme fardo; Além disso, a receita do contrato DLC está diretamente ligada à chave pública, pelo que a sua posição não é fácil de transferir, existe uma forma de transferir a posição do contrato?

Na verdade, a comunidade Bitcoin veio com respostas para essas perguntas, basicamente relacionadas a uma proposta Sighash (BIP-118 AnyPrevOut).

No entanto, se estivéssemos programando em CKB, o BIP-118 estaria disponível agora (tais tags Sighash poderiam ser simuladas com a capacidade de verificar assinaturas de forma introspetiva e proposital).

Ao aprender a programar Bitcoin, não só sabemos como eles podem ser programados no formato "Transaction Output" (o que pode ser programado em CKB), mas também como melhorar essas aplicações (e como podemos usar as capacidades do CKB para melhorá-las se as programarmos em CKB). Para desenvolvedores CKB, a programação baseada em Bitcoin Script pode ser usada como um material de aprendizagem, ou até mesmo um atalho.

Abaixo, vamos analisar a programabilidade de cada módulo de programação CKB um a um. Não vamos considerar introspeção por enquanto.

(1) Bloqueio programável calculado arbitrariamente

Como mencionado acima, as UTXOs não podem ser programadas para calcular arbitrariamente. Lock, por outro lado, significa que Lock pode programar tudo (antes da implantação da restrição) com base em UTXO, incluindo, mas não limitado ao Lightning Channel e DLC mencionados acima.

Além disso, essa capacidade de verificar cálculos arbitrários também torna o Lock mais flexível do que o UTXO em termos de métodos de autenticação. Por exemplo, podemos implementar um canal relâmpago no CKB onde uma parte assina ECDSA e a outra parte usa RSA.

Na verdade, esta é uma das primeiras áreas que as pessoas começaram a explorar no CKB: usar esse recurso de autenticação flexível na autocustódia do usuário para permitir o que é conhecido como "abstração de conta" – a autorização da validade da transação e a restauração do controle são muito flexíveis e quase ilimitadas. Em princípio, trata-se de uma combinação de "ramificações de gastos múltiplos" e "métodos de autenticação arbitrários". Exemplos de implementações são: joyid wallet, UniPass.

Além disso, o Lock pode implementar propostas eltoo, permitindo um canal relâmpago que só precisa manter a última transação comprometida (na verdade, o eltoo pode simplificar todos os contratos peer-to-peer).

(2) Tipo programável calculado arbitrariamente

Como mencionado acima, um dos grandes usos do Type é programar UDTs. Combinado com o Lock, isso significa que podemos implementar canais relâmpagos baseados em UDT (e outros tipos de contratos).

Na verdade, a divisão entre Lock e Type pode ser vista como uma atualização de segurança: Lock se concentra na implementação de métodos de custódia ou acordos contratuais, enquanto Type se concentra na definição de UDTs.

Além disso, a capacidade de iniciar verificações com base nas definições da UDT também permite que a UDT participe nos contratos de forma semelhante à CKB (a UDT é um cidadão de primeira classe).

Por exemplo, o autor uma vez propôs um protocolo para implementar empréstimos sem confiança apoiados por NFT em Bitcoin. A chave para tal protocolo é uma transação comprometida onde o valor da entrada é menor do que o valor da saída (portanto, ainda não é uma transação válida), mas uma vez que a entrada suficiente pode ser fornecida para a transação, é uma transação válida: uma vez que o credor é capaz de reembolsar, o credor não pode tomar o NFT apostado para si. No entanto, a falta de confiança desta transação de compromisso é baseada na transação verificando a quantidade de entrada e saída, então o credor só pode usar Bitcoin para pagar o empréstimo - mesmo que tanto o credor quanto o credor estejam dispostos a aceitar outra moeda (como USDT emitido sob o protocolo RGB), a transação de compromisso Bitcoin não garante que o credor receberá seu NFT de volta, desde que o credor devolva o valor total de USDT, porque a transação Bitcoin não tem ideia do status de USDT! (Revisão: Em outras palavras, não é possível construir uma transação comprometida condicionada ao reembolso do USDT.) )

Se formos capazes de iniciar uma verificação com base na definição de UDT, seremos capazes de fazer com que o credor assine outra transação comprometida que permitirá que o credor use USDT para pagar o empréstimo. A transação verificará a quantidade de USDT inserida e a quantidade de USDT fora, dando aos usuários reembolso sem confiança com USDT.

Emenda: Supondo que o NFT usado como garantia e o token usado para reembolso sejam emitidos usando o mesmo protocolo (como RGB), então o problema aqui pode ser resolvido, e podemos construir uma transação de compromisso de acordo com o protocolo RGB, para que a transição de estado e o reembolso do NFT possam ocorrer simultaneamente (duas transições de estado estão vinculadas a transações dentro do protocolo RGB). No entanto, como as transações RGB também dependem de transações Bitcoin, a construção de transações de compromisso aqui será um pouco difícil. Em suma, embora o problema possa ser resolvido, não pode ser feito Token é cidadão de primeira classe.

Em seguida, vamos considerar a introspeção.

(3) Bloqueio lê outros bloqueios

Isso significa que toda a gama de possibilidades de programação em UTXOs Bitcoin após a restrição proposta é implementada. Isso inclui os contratos do Vault mencionados acima, bem como aplicativos baseados em OP_CTV (por exemplo, controle de congestionamento).

XueJie mencionou uma vez um exemplo muito interessante: você pode implementar uma célula de conta de coleta no CKB, ao usar esse tipo de célula como a entrada da transação, se a célula de saída (a célula usando o mesmo bloqueio) tiver mais capacidade, então a entrada não precisa fornecer uma assinatura e não afeta a validade da transação. Na verdade, este tipo de célula não seria possível sem a capacidade de introspeção. Esta célula de conta de cobrança é ideal como um método institucional de receber dinheiro, porque reúne fundos e tem a desvantagem de não ter um bom senso de privacidade.

(4) O bloqueio lê outros tipos (e dados)

Uma aplicação interessante desta capacidade são os tokens de stake. O bloqueio decidirá se pode usar sua própria capacidade com base no número de tokens nas outras entradas e onde pode ser gasto (requer a capacidade de introspeccionar o bloqueio).

(5) Tipo lê outros bloqueios

Não tenho certeza, mas pode ser considerado útil. Por exemplo, você pode verificar em Tipo se os bloqueios das entradas e saídas de uma transação permanecem inalterados.

(6) Tipo Scirpt lê outros tipos (e dados)

Cartões de negociação? Colete n tokens em troca de um token maior :)

VI. Conclusão

Em comparação com os sistemas de contratos inteligentes anteriores que podem ser programados com computação arbitrária, como o Ethereum, a Nervos Network tem uma estrutura diferente; Como resultado, muitas vezes é difícil entender a Rede Nervos com base no conhecimento dos sistemas de contratos inteligentes do passado. Este artigo propõe um método para compreender a programabilidade da CKB Cell, a partir da programação da aplicação de uma estrutura mais restrita que a CKB Cell, BTC UTXO. E, usando o conceito de "introspeção" para entender as capacidades de "acesso de contrato cruzado" das células, podemos dividir as situações em que as capacidades introspetivas são usadas e determinar seus usos específicos.

Recensão:

  1. Independentemente das capacidades de acesso cruzado da Célula (ou seja, capacidades de introspeção), as fechaduras podem ser consideradas como Bitcoin com capacidades de estado e programação que atingiram o extremo, de modo que todas as aplicações baseadas em Bitcoin podem ser programadas apenas nesta base;
  2. Independentemente da capacidade de acesso cruzado (ou seja, capacidade de introspeção) da célula, a distinção entre fechaduras e tipos pode ser considerada como um upgrade de segurança: separa a definição de ativos e o método de custódia do UDT; Além disso, os tipos s (e dados) do estado exposable alcançar o efeito de UDT é cidadão de primeira classe.

Os dois pontos acima significam algo com o mesmo paradigma de "BTC + RGB", mas com mais capacidades de programação;

  1. Considerando a capacidade introspetiva de Cell, Cell pode obter capacidades de programação mais fortes do que pós-covenants BTC UTXO e implementar algo que é difícil de alcançar com BTC + RGB (porque BTC não pode ler o estado de RGB)

Não há muitos exemplos específicos desses usos, mas isso se deve à falta de compreensão do autor sobre a ecologia da CKB. Com o tempo, acredita-se que mais e mais imaginação será investida nele, e aplicações que são inimagináveis hoje serão montadas.

Agradecimentos

Obrigado a Retric, jan Xie e Xue Jie por seu feedback durante a escrita do artigo. É claro que sou responsável por todos os erros do texto.

Referências

Contas, listas de acesso estritas e UTXOs

Restrições em Bitcoin: Taxonomia para revisão

Modelo de célula

Nervos CKB em poucas palavras

Programação do Bitcoin

Abstração por Conta (2022)

O que é uma Árvore de Sintaxe Abstrata Bitcoin Merkelizada?

BIP 345: OP_VAULT proposta

Introdução aos opcodes de restrição TLUV

Os componentes que constroem o contrato são atualizados com Bitcoin

Eltoo explicou

Um contrato de empréstimo garantido por NFT baseado em transações comprometidas · btc-estudo/OP_QUESTION · Discussão #7

Link para o artigo original

Ver original
Esta página pode conter conteúdo de terceiros, que é fornecido apenas para fins informativos (não para representações/garantias) e não deve ser considerada como um endosso de suas opiniões pela Gate nem como aconselhamento financeiro ou profissional. Consulte a Isenção de responsabilidade para obter detalhes.
  • Recompensa
  • Comentário
  • Compartilhar
Comentário
0/400
Sem comentários
  • Marcar
Faça trade de criptomoedas em qualquer lugar e a qualquer hora
qrCode
Escaneie o código para baixar o app da Gate
Comunidade
Português (Brasil)
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)