Mergullo en Move: a linguaxe de programación blockchain Libra de Facebook

A continuación, consideraremos en detalle as principais características da linguaxe Move e cales son as súas principais diferenzas con outra linguaxe xa popular para contratos intelixentes: Solidity (na plataforma Ethereum). O material baséase nun estudo do libro branco de 26 páxinas dispoñible en liña.

Introdución

Move é unha linguaxe de bytecode executable que se usa para executar transaccións de usuarios e contratos intelixentes. Teña en conta dous puntos:

  1. Aínda que Move é unha linguaxe de código de bytes que se pode executar directamente na máquina virtual de Move, Solidity (a linguaxe de contrato intelixente de Ethereum) é unha linguaxe de nivel superior que se compila primeiro en bytecode antes de executarse nunha EVM (Ethereum Virtual Machine).
  2. Move pódese usar non só para implementar contratos intelixentes, senón tamén para transaccións personalizadas (máis sobre isto máis adiante), mentres que Solidity é un idioma só para contratos intelixentes.


A tradución foi realizada polo equipo do proxecto INDEX Protocol. Xa o traducimos gran material que describe o proxecto Libra, agora toca mirar o idioma Move con máis detalle. A tradución realizouse conxuntamente con Habrauser coolsiu

Unha característica fundamental de Move é a capacidade de definir tipos de recursos personalizados cunha semántica baseada na lóxica lineal: un recurso nunca se pode copiar ou eliminar implícitamente, só movelo. Funcionalmente, isto é semellante ás capacidades da linguaxe Rust. Os valores en Rust só se poden asignar a un nome á vez. Asignar un valor a un nome diferente fai que non estea dispoñible co nome anterior.

Mergullo en Move: a linguaxe de programación blockchain Libra de Facebook

Por exemplo, o seguinte fragmento de código xerará un erro: Uso do valor movido 'x'. Isto débese a que non hai recollida de lixo en Rust. Cando as variables saen do ámbito, a memoria á que se refiren tamén se libera. En pocas palabras, só pode haber un "propietario" dos datos. Neste exemplo x é o propietario orixinal e despois y convértese no novo propietario. Lea máis sobre este comportamento aquí.

Representación de activos dixitais en sistemas abertos

Hai dúas propiedades dos activos físicos que son difíciles de representar dixitalmente:

  • Raridade (Escaseza, orixinalmente escaseza). O número de activos (emisión) no sistema debe ser controlado. Debe prohibirse a duplicación de activos existentes e crear outros novos é unha operación privilexiada.
  • Control de acceso... O participante do sistema debe poder protexer os activos mediante políticas de control de acceso.

Estas dúas características, que son naturais para os activos físicos, deben ser implementadas para os obxectos dixitais se queremos consideralos como activos. Por exemplo, un metal raro ten unha escaseza natural, e só tes acceso a el (téndoo nas túas mans, por exemplo) e podes vendelo ou gastalo.

Para ilustrar como chegamos a estas dúas propiedades, comecemos coas seguintes frases:

Suxestión # 1: A regra máis sinxela sen escaseza e control de acceso

Mergullo en Move: a linguaxe de programación blockchain Libra de Facebook

  • G [K]: = n indica unha actualización dun número accesible mediante unha tecla К no estado global da cadea de bloques, cun novo significado n.
  • transacción ⟨Alice, 100⟩ significa establecer o saldo da conta de Alice en 100.

A solución anterior ten varios problemas importantes:

  • Alice pode recibir un número ilimitado de moedas simplemente enviando transacción ⟨Alice, 100⟩.
  • As moedas que Alicia envía a Bob son inútiles, xa que Bob podería enviarse un número ilimitado de moedas usando a mesma técnica.

Suxestión # 2: Tendo en conta o déficit

Mergullo en Move: a linguaxe de programación blockchain Libra de Facebook

Agora estamos vixiando a situación para que o número de moedas Ka era polo menos igual n antes da transacción de transferencia. Non obstante, aínda que isto resolve o problema da escaseza, non hai información sobre quen pode enviar as moedas de Alicia (polo momento, calquera pode facelo, o principal é non violar a regra de limitar a cantidade).

Proposta # 3: Combinar escaseza e control de acceso

Mergullo en Move: a linguaxe de programación blockchain Libra de Facebook

Resolvemos este problema cun mecanismo de sinatura dixital verificar_sig antes de comprobar o saldo, o que significa que Alice usa a súa clave privada para asinar a transacción e confirmar que é a propietaria das súas moedas.

Linguaxes de programación blockchain

As linguaxes blockchain existentes enfróntanse aos seguintes problemas (todos eles foron resoltos en Move (nota: desafortunadamente, o autor do artigo só apela a Ethereum nas súas comparacións, polo que paga a pena tomalos só neste contexto. Por exemplo, a maioría dos seguintes tamén se resolven en EOS.)):

Representación indirecta do patrimonio. Un activo codificase mediante un número enteiro, pero un enteiro non é o mesmo que un activo. De feito, non hai ningún tipo ou valor que represente Bitcoin/Ether/<Calquera moeda>! Isto dificulta a escritura de programas que usan recursos e sexan propensos a erros. Os patróns como o paso de activos a/desde procedementos ou o almacenamento de activos en estruturas requiren un apoio especial da lingua.

O déficit non é ampliable... A lingua representa só un ben escaso. Ademais, os remedios contra a escaseza están conectados directamente á semántica da propia lingua. O desenvolvedor, se quere crear un activo personalizado, debe controlar coidadosamente todos os aspectos do recurso. Estes son exactamente os problemas dos contratos intelixentes de Ethereum.

Os usuarios emiten os seus activos, tokens ERC-20, utilizando números enteiros para determinar tanto o valor como a oferta total. Sempre que se crean novos tokens, o código de contrato intelixente debe verificar de forma independente o cumprimento das regras de emisión. Ademais, a presentación indirecta dos activos leva, nalgúns casos, a graves erros: duplicación, dobre gasto ou mesmo perda total de activos.

Falta de control de acceso flexible... A única política de control de acceso que se usa hoxe en día é un esquema de sinatura que utiliza criptografía asimétrica. Do mesmo xeito que a protección da escaseza, as políticas de control de acceso están profundamente incrustadas na semántica da linguaxe. Pero como estender a linguaxe para que os programadores poidan definir as súas propias políticas de control de acceso adoita ser unha tarefa moi complicada.

Isto tamén é certo en Ethereum, onde os contratos intelixentes non teñen soporte de criptografía nativa para o control de acceso. Os desenvolvedores deben configurar manualmente o control de acceso, por exemplo, usando o modificador onlyOwner.

Aínda que son un gran fan de Ethereum, creo que as propiedades dos activos deberían estar soportadas de forma nativa polo idioma por motivos de seguridade. En particular, transferir Ether a un contrato intelixente implica un envío dinámico, que introduciu unha nova clase de erros coñecidas como vulnerabilidades de reingreso. O envío dinámico aquí significa que a lóxica de execución do código determinarase en tempo de execución (dinámico) e non en tempo de compilación (estático).

Así, en Solidity, cando o contrato A chama a unha función no contrato B, o contrato B pode executar código que non estaba previsto polo desenvolvedor do contrato A, o que pode producir vulnerabilidades de reingreso (o contrato A actúa accidentalmente como contrato B para retirar diñeiro antes de que se deduzan os saldos da conta).

Move Fundamentos de deseño lingüístico

Recursos de primeira orde

A un alto nivel, a interacción entre módulos/recursos/procedementos na linguaxe Move é moi semellante á relación entre clases/obxectos e métodos nas linguaxes OOP.
Os módulos de movemento son similares aos contratos intelixentes noutras cadeas de bloques. O módulo declara os tipos de recursos e procedementos que definen as regras para crear, destruír e actualizar os recursos declarados. Pero todo isto son só convencións ("xerga”) En Movemento. Ilustraremos este punto un pouco máis adiante.

Flexibilidade

Move engade flexibilidade a Libra mediante scripts. Cada transacción en Libra inclúe un script, que é esencialmente o procedemento principal da transacción. O script pode realizar unha acción especificada, por exemplo, pagos a unha lista especificada de destinatarios, ou reutilizar outros recursos, por exemplo, chamando a un procedemento no que se especifica a lóxica xeral. É por iso que os scripts de transacción Move ofrecen unha maior flexibilidade. Un script pode usar comportamentos únicos e repetitivos, mentres que Ethereum só pode executar scripts repetibles (chamando a un método nun método de contrato intelixente). A razón pola que se chama "reutilizable" é porque as funcións dun contrato intelixente pódense executar varias veces. (Nota: O punto aquí é moi sutil. Por unha banda, os scripts de transacción en forma de pseudo-bytecode tamén existen en Bitcoin. Por outra banda, segundo o entendo, Move amplía esta linguaxe, de feito, ao nivel dunha linguaxe de contrato intelixente de pleno dereito).

Безопасность

O formato executable de Move é bytecode, que é, por unha banda, unha linguaxe de nivel superior á linguaxe ensambladora, pero de nivel inferior ao código fonte. O bytecode compróbase en tempo de execución (en cadea) para ver os recursos, os tipos e a seguridade da memoria mediante un verificador de bytecode, e despois execútase polo intérprete. Este enfoque permite que Move proporcione a seguridade do código fonte, pero sen o proceso de compilación e a necesidade de engadir un compilador ao sistema. Facer que Move sexa unha linguaxe de código de bytes é unha solución moi boa. Non é necesario compilalo desde a fonte, como é o caso de Solidity, e non hai que preocuparse por posibles fallos ou ataques á infraestrutura do compilador.

Verificación

Pretendemos realizar comprobacións o máis sinxelas posible, xa que todo isto faise en cadea (nota: en liña, durante a execución de cada transacción, polo que calquera atraso leva a unha desaceleración de toda a rede), con todo, inicialmente o deseño da linguaxe está preparado para usar ferramentas de verificación estática fóra da cadea. Aínda que isto é máis preferible, polo momento o desenvolvemento de ferramentas de verificación (como un conxunto de ferramentas separado) aprazouse para o futuro, e agora só se admite a verificación dinámica en tempo de execución (en cadea).

Modularidade

Os módulos Move proporcionan abstracción de datos e localizan operacións críticas sobre recursos. A encapsulación proporcionada polo módulo, combinada coa protección proporcionada polo sistema de tipo Move, garante que as propiedades establecidas nos tipos do módulo non poidan ser violadas por código fóra do módulo. Este é un deseño de abstracción ben pensado, o que significa que os datos dun contrato só se poden cambiar dentro do ámbito do contrato, pero non externamente.

Mergullo en Move: a linguaxe de programación blockchain Libra de Facebook

Mover a vista xeral

O exemplo do script de transacción demostra que as accións maliciosas ou descoidadas dun programador fóra dun módulo non poden comprometer a seguridade dos recursos dun módulo. A continuación, veremos exemplos de como se usan módulos, recursos e procedementos para programar a cadea de bloques Libra.

Pagos entre pares

Mergullo en Move: a linguaxe de programación blockchain Libra de Facebook

O número de moedas especificado en cantidade transferirase do saldo do remitente ao destinatario.
Hai algunhas cousas novas aquí (resaltadas en vermello):

  • 0x0: enderezo da conta onde está almacenado o módulo
  • Moeda: nome do módulo
  • Moeda: tipo de recurso
  • O valor da moeda devolto polo procedemento é un valor de recurso de tipo 0x0.Currency.Coin
  • mover (): o valor non se pode usar de novo
  • copiar (): o valor pódese usar máis tarde

Analizar o código: no primeiro paso, o remitente chama a un procedemento denominado retirar_do_remitente desde un módulo almacenado en 0x0.Moeda. No segundo paso, o remitente transfire fondos ao destinatario movendo o valor do recurso de moeda ao procedemento de depósito do módulo 0x0.Moeda.

Aquí tes tres exemplos de erros no código que serán rexeitados mediante verificacións:
Duplicar fondos cambiando a chamada mover (moeda) en copia (moeda). Os recursos só se poden mover. Tentando duplicar unha cantidade dun recurso (por exemplo, chamando copia (moeda) no exemplo anterior) producirá un erro ao comprobar o bytecode.

Reutilización de fondos especificando mover (moeda) dúas veces . Engadindo unha liña 0x0.Currency.deposit (copiar (algún_otro_beneficiario), mover (moeda)) por exemplo, o anterior permitirá ao remitente "gastar" as moedas dúas veces: a primeira co beneficiario e a segunda co algún_outro_beneficiario. Este é un comportamento indesexable que non é posible cun activo físico. Afortunadamente, Move rexeitará este programa.

Perda de fondos por negativa mover (moeda). Se non moves o recurso (por exemplo, eliminando a liña que contén mover (moeda)), producirase un erro de verificación de bytecode. Isto protexe aos programadores de Move da perda accidental ou maliciosa de fondos.

Módulo de moeda

Mergullo en Move: a linguaxe de programación blockchain Libra de Facebook

Cada conta pode conter 0 ou máis módulos (mostrados como rectángulos) e un ou máis valores de recursos (mostrados como cilindros). Por exemplo, unha conta en 0x0 contén módulo 0x0.Moeda e o valor do tipo de recurso 0x0.Moeda.Moeda. Conta no enderezo 0x1 ten dous recursos e un módulo; Conta no enderezo 0x2 ten dous módulos e un valor de recurso.

Momentos de Nekotory:

  • O script de transacción é atómico: ou se executa completamente ou non se executa en absoluto.
  • Un módulo é unha peza de código de longa duración que é accesible globalmente.
  • O estado global estrutúrase como unha táboa hash, onde a clave é o enderezo da conta
  • As contas non poden conter máis dun valor de recurso dun tipo determinado e non máis dun módulo cun nome dado (conta en 0x0 non pode conter un recurso adicional 0x0.Moeda.Moeda ou outro módulo denominado Moeda)
  • O enderezo do módulo declarado forma parte do tipo (0x0.Moeda.Moeda и 0x1.Moeda.Moeda son tipos separados que non se poden usar indistintamente)
  • Os programadores poden almacenar varias instancias deste tipo de recurso nunha conta definindo o seu recurso personalizado - (recurso TwoCoins {c1: 0x0.Currency.Coin, c2: 0x0.Currency.Coin})
  • Podes facer referencia a un recurso polo seu nome sen conflitos, por exemplo podes referirte a dous recursos usando Dúas moedas.c1 и Dúas moedas.c2.

Anuncio de recursos de moedas

Mergullo en Move: a linguaxe de programación blockchain Libra de Facebook
Módulo nomeado Moeda e un tipo de recurso denominado Moeda

Momentos de Nekotory:

  • Moeda é unha estrutura cun campo de tipo u64 (enteiro sen signo de 64 bits)
  • Só procedementos do módulo Moeda pode crear ou destruír valores de tipo Moeda.
  • Outros módulos e scripts só poden escribir ou facer referencia ao campo de valor mediante procedementos públicos proporcionados polo módulo.

Venda de depósito

Mergullo en Move: a linguaxe de programación blockchain Libra de Facebook

Este procedemento acepta un recurso Moeda como entrada e combínao co recurso Moedaalmacenado na conta do destinatario:

  1. Destruír o recurso de entrada Coin e rexistrar o seu valor.
  2. Recibir unha ligazón a un recurso de moeda único almacenado na conta do destinatario.
  3. Cambiando o valor do número de moedas polo valor pasado no parámetro ao chamar ao procedemento.

Momentos de Nekotory:

  • Descomprimir, BorrowGlobal - procedementos incorporados
  • Desembalar Esta é a única forma de eliminar un recurso de tipo T. O procedemento toma un recurso como entrada, destrúeo e devolve o valor asociado aos campos do recurso.
  • BorrowGlobal toma un enderezo como entrada e devolve unha referencia a unha instancia única de T publicada (propiedade) por ese enderezo
  • &mut Coin esta é unha ligazón ao recurso Moeda

Implementación de withdraw_from_sender

Mergullo en Move: a linguaxe de programación blockchain Libra de Facebook

Este procedemento:

  1. Obtén unha ligazón a un recurso único Moeda, ligada á conta do remitente
  2. Diminúe o valor dun recurso Moeda a través da ligazón polo importe especificado
  3. Crea e devolve un novo recurso Moeda con saldo actualizado.

Momentos de Nekotory:

  • Depósito pode ser causado por calquera, pero retirar_do_remitente só ten acceso ás moedas da conta de chamada
  • GetTxnSenderAddress semellante a msg.sender en Solidez
  • RexeitarA non ser semellante a requirir en Solidez. Se esta comprobación falla, a transacción detense e todos os cambios son revertidos.
  • Pack tamén é un procedemento incorporado que crea un novo recurso de tipo T.
  • Así como Desembalar, Pack só se pode chamar dentro do módulo onde se describe o recurso T

Conclusión

Examinamos as principais características da linguaxe Move, comparámolo con Ethereum e tamén nos familiarizamos coa sintaxe básica dos scripts. Por último, recomendo encarecidamente que o fagades papel branco orixinal. Inclúe moitos detalles sobre os principios de deseño da linguaxe de programación, así como moitas ligazóns útiles.

Fonte: www.habr.com

Engadir un comentario