Sumérgete en Move: el lenguaje de programación blockchain Libra de Facebook

A continuación, consideraremos en detalle las principales características del lenguaje Move y cuáles son sus diferencias clave con otro lenguaje ya popular para contratos inteligentes: Solidity (en la plataforma Ethereum). El material se basa en un estudio del documento técnico de 26 páginas disponible en línea.

introducción

Move es un lenguaje de código de bytes ejecutable que se utiliza para ejecutar transacciones de usuario y contratos inteligentes. Tenga en cuenta dos puntos:

  1. Si bien Move es un lenguaje de código de bytes que se puede ejecutar directamente en la máquina virtual Move, Solidity (el lenguaje de contrato inteligente de Ethereum) es un lenguaje de nivel superior que se compila primero en un código de bytes antes de ejecutarse en una EVM (Máquina virtual de Ethereum).
  2. Move se puede usar no solo para implementar contratos inteligentes, sino también para transacciones personalizadas (más sobre esto más adelante), mientras que Solidity es un lenguaje solo para contratos inteligentes.


La traducción fue realizada por el equipo del proyecto INDEX Protocol. Ya hemos traducido material extenso que describe el proyecto Libra, ahora es el momento de analizar el lenguaje Move con un poco más de detalle. La traducción se realizó conjuntamente con Habrauser. coolsiu

Una característica clave de Move es la capacidad de definir tipos de recursos personalizados con una semántica basada en lógica lineal: un recurso nunca puede copiarse ni eliminarse implícitamente, solo moverse. Funcionalmente, esto es similar a las capacidades del lenguaje Rust. Los valores en Rust sólo se pueden asignar a un nombre a la vez. Asignar un valor a un nombre diferente hace que no esté disponible con el nombre anterior.

Sumérgete en Move: el lenguaje de programación blockchain Libra de Facebook

Por ejemplo, el siguiente fragmento de código arrojará un error: Uso del valor movido 'x'. Esto se debe a que no hay recolección de basura en Rust. Cuando las variables quedan fuera de alcance, la memoria a la que hacen referencia también se libera. En pocas palabras, solo puede haber un "propietario" de los datos. En este ejemplo x es el propietario original y luego y se convierte en el nuevo propietario. Lea más sobre este comportamiento aquí..

Representación de activos digitales en sistemas abiertos

Hay dos propiedades de los activos físicos que son difíciles de representar digitalmente:

  • Rareza (Escasez, originalmente escasez). Se debe controlar el número de activos (emisión) en el sistema. Debe prohibirse la duplicación de activos existentes y la creación de nuevos es una operación privilegiada.
  • Control de acceso... El participante del sistema debe poder proteger los activos mediante políticas de control de acceso.

Estas dos características, que son naturales para los activos físicos, deben implementarse para los objetos digitales si queremos considerarlos como activos. Por ejemplo, un metal raro tiene una escasez natural, y solo usted tiene acceso a él (sosteniéndolo en sus manos, por ejemplo) y puede venderlo o gastarlo.

Para ilustrar cómo llegamos a estas dos propiedades, comencemos con las siguientes oraciones:

Sugerencia n. ° 1: la regla más simple sin escasez y control de acceso

Sumérgete en Move: el lenguaje de programación blockchain Libra de Facebook

  • G [K]: = n denota una actualización de un número accesible mediante una tecla К en el estado global de blockchain, con un nuevo significado n.
  • transacción ⟨Alice, 100⟩ significa establecer el saldo de la cuenta de Alice en 100.

La solución anterior tiene varios problemas importantes:

  • Alice puede recibir un número ilimitado de monedas simplemente enviando transacción ⟨Alice, 100⟩.
  • Las monedas que Alice le envía a Bob son inútiles, ya que Bob podría enviarse a sí mismo un número ilimitado de monedas utilizando la misma técnica.

Sugerencia # 2: Teniendo en cuenta el déficit

Sumérgete en Move: el lenguaje de programación blockchain Libra de Facebook

Ahora estamos monitoreando la situación para que el número de monedas Ka era al menos igual n antes de la transacción de transferencia. Sin embargo, si bien esto resuelve el problema de la escasez, no hay información sobre quién puede enviar las monedas de Alice (por ahora, cualquiera puede hacer esto, lo principal es no violar la regla de limitar la cantidad).

Propuesta # 3: Combinando escasez y control de acceso

Sumérgete en Move: el lenguaje de programación blockchain Libra de Facebook

Solucionamos este problema con un mecanismo de firma digital verificar_sig antes de verificar el saldo, lo que significa que Alice usa su clave privada para firmar la transacción y confirmar que es la propietaria de sus monedas.

Lenguajes de programación blockchain

Los lenguajes blockchain existentes enfrentan los siguientes problemas (todos se resolvieron en Move (nota: desafortunadamente, el autor del artículo solo apela a Ethereum en sus comparaciones, por lo que vale la pena tomarlas solo en este contexto. Por ejemplo, la mayor parte de lo siguiente también se resuelve en EOS.)):

Representación indirecta de activos. Un activo se codifica utilizando un número entero, pero un número entero no es lo mismo que un activo. De hecho, ¡no hay ningún tipo o valor que represente Bitcoin/Ether/<Cualquier moneda>! Esto hace que escribir programas que utilizan activos sea difícil y propenso a errores. Patrones como pasar activos hacia/desde procedimientos o almacenar activos en estructuras requieren un soporte especial del lenguaje.

El déficit no es ampliable... El idioma representa solo un activo escaso. Además, los medios de protección contra la escasez están integrados directamente en la semántica del propio idioma. El desarrollador, si quiere crear un activo personalizado, debe controlar cuidadosamente todos los aspectos del recurso por sí mismo. Estos son exactamente los problemas de los contratos inteligentes de Ethereum.

Los usuarios emiten sus activos, tokens ERC-20, utilizando números enteros para determinar tanto el valor como el suministro total. Siempre que se crean nuevos tokens, el código de contrato inteligente debe verificar de forma independiente el cumplimiento de las reglas de emisión. Además, la presentación indirecta de activos conduce, en algunos casos, a errores graves: duplicación, doble gasto o incluso pérdida total de activos.

Falta de control de acceso flexible... La única política de control de acceso que se utiliza en la actualidad es un esquema de firma que utiliza criptografía asimétrica. Al igual que la protección contra la escasez, las políticas de control de acceso están profundamente arraigadas en la semántica del lenguaje. Pero cómo extender el lenguaje para permitir a los programadores definir sus propias políticas de control de acceso es a menudo una tarea muy complicada.

Esto también se aplica a Ethereum, donde los contratos inteligentes no tienen soporte de criptografía nativa para el control de acceso. Los desarrolladores deben configurar manualmente el control de acceso, por ejemplo, utilizando el modificador onlyOwner.

Aunque soy un gran admirador de Ethereum, creo que las propiedades de los activos deberían ser compatibles de forma nativa con el lenguaje por motivos de seguridad. En particular, transferir Ether a un contrato inteligente implica un despacho dinámico, lo que ha introducido una nueva clase de errores conocidos como vulnerabilidades de reentrada. El envío dinámico aquí significa que la lógica de ejecución del código se determinará en tiempo de ejecución (dinámico) en lugar de en tiempo de compilación (estático).

Por lo tanto, en Solidity, cuando el contrato A llama a una función en el contrato B, el contrato B puede ejecutar código que no fue previsto por el desarrollador del contrato A, lo que puede resultar en vulnerabilidades de reingreso (El contrato A actúa accidentalmente como contrato B para retirar dinero antes de que se deduzcan los saldos de la cuenta).

Mover fundamentos del diseño del lenguaje

Recursos de primer orden

En un nivel alto, la interacción entre módulos / recursos / procedimientos en el lenguaje Move es muy similar a la relación entre clases / objetos y métodos en lenguajes POO.
Los módulos de movimiento son similares a los contratos inteligentes en otras cadenas de bloques. El módulo declara tipos de recursos y procedimientos que definen las reglas para crear, destruir y actualizar recursos declarados. Pero todas estas son solo convenciones ("jerga”) En movimiento. Ilustraremos este punto un poco más adelante.

Flexibilidad

Move agrega flexibilidad a Libra mediante secuencias de comandos. Cada transacción en Libra incluye un script, que es esencialmente el procedimiento central de la transacción. El script puede realizar una acción específica, por ejemplo, pagos a una lista específica de destinatarios, o reutilizar otros recursos, por ejemplo, llamando a un procedimiento en el que se especifica la lógica general. Es por eso que los scripts de transacciones Move ofrecen una mayor flexibilidad. Un script puede utilizar comportamientos únicos y repetitivos, mientras que Ethereum solo puede ejecutar scripts repetibles (llamando a un método en un método de contrato inteligente). La razón por la que se le llama "reutilizable" es porque las funciones de un contrato inteligente se pueden ejecutar varias veces. (nota: El punto aquí es muy sutil. Por un lado, en Bitcoin también existen scripts de transacciones en forma de pseudocódigo de bytes. Por otro lado, según tengo entendido, Move expande este lenguaje, de hecho, al nivel de un lenguaje de contrato inteligente completo.).

seguridad

El formato ejecutable de Move es bytecode, que es, por un lado, un lenguaje de nivel superior al lenguaje ensamblador, pero de nivel inferior al código fuente. El código de bytes se verifica en tiempo de ejecución (en cadena) para determinar los recursos, los tipos y la seguridad de la memoria mediante un verificador de código de bytes y luego el intérprete lo ejecuta. Este enfoque permite a Move proporcionar la seguridad del código fuente, pero sin el proceso de compilación ni la necesidad de agregar un compilador al sistema. Hacer de Move un lenguaje de código de bytes es una solución realmente buena. No es necesario compilarlo desde el código fuente, como es el caso de Solidity, y no hay que preocuparse por posibles fallos o ataques a la infraestructura del compilador.

Verificabilidad

Nuestro objetivo es realizar las comprobaciones de la forma más sencilla posible, ya que todo esto se realiza en cadena (nota: en línea, durante la ejecución de cada transacción, por lo que cualquier retraso conduce a una desaceleración de toda la red), sin embargo, inicialmente el diseño del lenguaje está listo para usar herramientas de verificación estática fuera de la cadena. Aunque esto es más preferible, por ahora el desarrollo de herramientas de verificación (como un conjunto de herramientas separado) se ha pospuesto para el futuro y ahora solo se admite la verificación dinámica en tiempo de ejecución (en cadena).

Modularidad

Los módulos Move proporcionan abstracción de datos y localizan operaciones críticas en recursos. La encapsulación proporcionada por el módulo, combinada con la protección proporcionada por el sistema de tipo Move, asegura que las propiedades establecidas en los tipos del módulo no puedan ser violadas por código fuera del módulo. Este es un diseño de abstracción bastante bien pensado, lo que significa que los datos dentro de un contrato solo pueden cambiar dentro del alcance del contrato, pero no externamente.

Sumérgete en Move: el lenguaje de programación blockchain Libra de Facebook

Mover descripción general

El ejemplo del script de transacción demuestra que las acciones malintencionadas o descuidadas de un programador fuera de un módulo no pueden comprometer la seguridad de los recursos de un módulo. A continuación, veremos ejemplos de cómo se utilizan los módulos, recursos y procedimientos para programar la cadena de bloques Libra.

Pagos entre pares

Sumérgete en Move: el lenguaje de programación blockchain Libra de Facebook

La cantidad de monedas especificada en la cantidad se transferirá del saldo del remitente al destinatario.
Hay algunas cosas nuevas aquí (resaltadas en rojo):

  • 0x0: dirección de la cuenta donde se almacena el módulo
  • Moneda: Nombre del módulo
  • Monedas: tipo de recurso
  • El valor de la moneda devuelto por el procedimiento es un valor de recurso de tipo 0x0.Currency.Coin
  • moverse(): el valor no se puede volver a utilizar
  • Copiar(): el valor se puede usar más tarde

Analizar el código: en el primer paso, el remitente llama a un procedimiento llamado retirar_de_enviar desde un módulo almacenado en 0x0 Moneda. En el segundo paso, el remitente transfiere fondos al destinatario moviendo el valor del recurso de la moneda al procedimiento de depósito del módulo. 0x0 Moneda.

Aquí hay tres ejemplos de errores en el código que serán rechazados por los cheques:
Fondos duplicados cambiando la llamada mover (moneda) en copiar (moneda). Los recursos sólo se pueden mover. Intentar duplicar una cantidad de un recurso (por ejemplo, llamando copiar (moneda) en el ejemplo anterior) dará como resultado un error durante la validación del código de bytes.

Reutilización de fondos especificando mover (moneda) dos veces . Agregar una línea 0x0.Currency.deposit (copiar (algún_otro_pagatario), mover (moneda)) por ejemplo, lo anterior permitirá al remitente "gastar" las monedas dos veces: la primera vez con el beneficiario y la segunda con algún_otro_beneficiario. Este es un comportamiento indeseable que no es posible con un activo físico. Por suerte, Move rechazará este programa.

Pérdida de fondos por negativa. mover (moneda). Si no mueve el recurso (por ejemplo, eliminando la línea que contiene mover (moneda)), se generará un error de verificación de código de bytes. Esto protege a los programadores de Move de pérdidas de fondos accidentales o maliciosas.

Módulo de moneda

Sumérgete en Move: el lenguaje de programación blockchain Libra de Facebook

Cada cuenta puede contener 0 o más módulos (que se muestran como rectángulos) y uno o más valores de recursos (que se muestran como cilindros). Por ejemplo, una cuenta en 0x0 contiene módulo 0x0 Moneda y el valor del tipo de recurso 0x0.Moneda.Moneda. Cuenta en la dirección 0x1 tiene dos recursos y un módulo; Cuenta en la dirección 0x2 Tiene dos módulos y un valor de recurso.

Algunos momentos:

  • El script de transacción es atómico: se ejecuta por completo o no se ejecuta en absoluto.
  • Un módulo es un fragmento de código de larga duración al que se puede acceder globalmente.
  • El estado global está estructurado como una tabla hash, donde la clave es la dirección de la cuenta.
  • Las cuentas no pueden contener más de un valor de recurso de un tipo determinado y no más de un módulo con un nombre determinado (cuenta en 0x0 no puede contener un recurso adicional 0x0.Moneda.Moneda u otro módulo llamado Moneda)
  • La dirección del módulo declarado es parte del tipo (0x0.Moneda.Moneda и 0x1.Moneda.Moneda son tipos separados que no se pueden usar indistintamente)
  • Los programadores pueden almacenar varias instancias de este tipo de recurso en una cuenta definiendo su recurso personalizado - (recurso TwoCoins {c1: 0x0.Currency.Coin, c2: 0x0.Currency.Coin})
  • Puede hacer referencia a un recurso por su nombre sin conflictos, por ejemplo puede hacer referencia a dos recursos usando DosMonedas.c1 и DosMonedas.c2.

Anuncio de recursos de monedas

Sumérgete en Move: el lenguaje de programación blockchain Libra de Facebook
Módulo nombrado Moneda y un tipo de recurso llamado Monedas

Algunos momentos:

  • Monedas es una estructura con un campo de tipo u64 (entero sin signo de 64 bits)
  • Sólo procedimientos del módulo Moneda puede crear o destruir valores de tipo Monedas.
  • Otros módulos y scripts solo pueden escribir o hacer referencia al campo de valor a través de procedimientos públicos proporcionados por el módulo.

Venta de deposito

Sumérgete en Move: el lenguaje de programación blockchain Libra de Facebook

Este procedimiento acepta un recurso. Monedas como entrada y la combina con el recurso Monedasalmacenado en la cuenta del destinatario:

  1. Destruir el recurso de entrada Coin y registrar su valor.
  2. Recibir un enlace a un recurso Coin único almacenado en la cuenta del destinatario.
  3. Cambiar el valor del número de Coins por el valor pasado en el parámetro al llamar al procedimiento.

Algunos momentos:

  • Desempacar, pedir prestado global - procedimientos incorporados
  • Deshacer Esta es la única forma de eliminar un recurso de tipo T. El procedimiento toma un recurso como entrada, lo destruye y devuelve el valor asociado con los campos del recurso.
  • PréstamoGlobal toma una dirección como entrada y devuelve una referencia a una instancia única de T publicada (propiedad) de esa dirección
  • &mut moneda este es un enlace al recurso Monedas

Implementación de retract_from_sender

Sumérgete en Move: el lenguaje de programación blockchain Libra de Facebook

Este procedimiento:

  1. Obtiene un enlace a un recurso único Monedas, vinculado a la cuenta del remitente
  2. Disminuye el valor de un recurso. Monedas a través del enlace por la cantidad especificada
  3. Crea y devuelve un nuevo recurso. Monedas con saldo actualizado.

Algunos momentos:

  • Depósitar puede ser causado por cualquiera, pero retirar_de_enviar sólo tiene acceso a las monedas de la cuenta de llamada
  • ObtenerTxnSenderAddress Similar a mensaje.remitente en Solidez
  • Rechazar a menos que Similar a exigir en Solidez. Si esta verificación falla, la transacción se detiene y todos los cambios se revierten.
  • Embalar también es un procedimiento incorporado que crea un nuevo recurso de tipo T.
  • Al igual que Deshacer, Embalar sólo se puede llamar dentro del módulo donde se describe el recurso T

Conclusión

Examinamos las características principales del lenguaje Move, lo comparamos con Ethereum y también nos familiarizamos con la sintaxis básica de los scripts. Finalmente, recomiendo encarecidamente consultar papel blanco original. Incluye muchos detalles sobre los principios de diseño del lenguaje de programación, así como muchos enlaces útiles.

Fuente: habr.com

Añadir un comentario