Introducción al contrato inteligente de Bitcoin (2): introducción al lenguaje de alto nivel sCrypt

Misterio del guion

En el artículo anterior , presentamos brevemente la base operativa de los contratos inteligentes de Bitcoin, es decir, el lenguaje de script subyacente Script de la red Bitcoin y el principio operativo de su máquina virtual. Creo que muchos estudiantes que están en contacto por primera vez tendrán cierta confusión después de leerlo: ¿Cómo es que esto no se parece en nada a lenguajes de script como Python y JavaScript con los que todos están familiarizados? ¿Cómo aprender y utilizar el lenguaje de programación de "el esqueleto es tan asombroso"? Con estas preguntas, hablemos más profundamente.

¿Por qué Script?

Como todos sabemos, la red de Bitcoin es esencialmente un conjunto de libros de contabilidad públicos ejecutados y mantenidos por muchos nodos mineros. Todos los nodos deben asegurarse de que los datos de este libro de contabilidad sean legales y precisos. En otras palabras, cualquier transacción puede ser transmitida y verificada por cualquier nodo. El minero realmente necesita ejecutar el script para verificar si la "clave" proporcionada en la nueva transacción puede "abrir" el "candado" en la transacción anterior. para verificar la legalidad de la transacción. En el proceso de verificación, las ventajas de Script se reflejan en estos dos aspectos:

  • No es necesario compilar, ejecutar eficientemente : debido Script El código del script es una cadena de bytes 1 , antes de la necesidad de compilar el proceso de la máquina virtual nuevamente, con el fin de explicar los resultados obtenidos se puede ejecutar la instrucción directamente, asegurando así la eficiencia.

  • Diseñar seguridad y prevenir ataques : una característica muy importante de Script es que no hay instrucciones de salto, lo que puede evitar que alguien escriba maliciosamente (o por negligencia) un bucle sin fin en el script para atacar la red minera. Esto a menudo se critica como lo incompleto de Turing, incapaz de lograr muchas funciones. Pero, de hecho, se trata de un malentendido. La integridad de Turing se puede lograr a través de algunos medios técnicos (seguimiento, planeo escribir otro artículo para hablar sobre esto).

Sin embargo, Script no es tan amigable para los desarrolladores. Existen umbrales muy altos para el aprendizaje, el desarrollo y las pruebas, porque es esencialmente un lenguaje ensamblador.

Lenguaje de alto nivel (sCrypt) vs lenguaje ensamblador (Script)

Creo que la mayoría de los estudiantes que han estudiado lenguaje ensamblador tienen recuerdos similares: ¡recuerde aprenderlo en la escuela! Eso es todo, la mayoría de la gente nunca lo encontrará en proyectos reales. Para los estudiantes que no están familiarizados con el lenguaje ensamblador, es posible que solo necesiten saber que es un lenguaje de programación que nació en los primeros días de la invención de la computadora. Escribir programas en él suele ser muy complicado y requiere mucho tiempo.

El proyecto sCrypt nació debido a la ineficacia del desarrollo del lenguaje Script como el lenguaje ensamblador. Su objetivo es proporcionar a los desarrolladores un lenguaje de desarrollo más avanzado y un entorno de desarrollo familiar, mejorando así la eficiencia general de I + D. En pocas palabras, los desarrolladores usan el lenguaje sCrypt para desarrollar contratos inteligentes y luego usan un compilador para convertir el código fuente en un lenguaje de secuencias de comandos y ponerlos en la transacción para enviarlos a la cadena. Finalmente, los mineros se aseguran de que el código del contrato se ejecute correctamente .

A continuación se presenta formalmente el lenguaje de desarrollo de alto nivel de los contratos inteligentes de Bitcoin: sCrypt (pronunciación en inglés: ess crypt).

Sintaxis y estructura básica de sCrypt

La sintaxis 2 de sCrypt fue diseñada con el objetivo de minimizar el costo de aprendizaje de los desarrolladores, por lo que tiene muchas similitudes con algunos otros lenguajes de alto nivel (como Javascript, Solidity, etc.) en su conjunto, lo cual también es intencional.

Tipo de datos básico

sCrypt es un lenguaje fuertemente tipado. Los tipos de datos básicos incluyen:

  • bool: Valor booleano trueo false;

  • int: Valor entero con signo;

int a1 = 42;
int a2 = -4242424242424242;
int a3 = 55066263022277343669578718895168534326250603453777594175500187360389116729240;
int a4 = 0xFF8C;
  • bytes: Representación de matriz de bytes hexadecimal, contenida entre comillas simples y letras bcomo prefijo;
bytes b1 = b'ffee1234';
bytes b2 = b'414136d08c5ed2bf3ba048afe6dcaebafeffffffffffffffffffffffffffffff00';

Para mejorar aún más la seguridad de los tipos, bytestambién se puede convertir a una descripción de subtipo más precisa para que el compilador pueda encontrar o reducir posibles errores de código. Los tipos específicos incluyen:

  • PubKey: Tipo de clave pública
PubKey pubKey = PubKey(b'0200112233445566778899aabbccddeeffffeeddccbbaa99887766554433221100');
  • SigHashType: Tipo de hash de firma
SigHashType s = SigHashType(b'01');
SigHashType s = SigHash.ALL | SigHash.ANYONECANPAY;
  • Sig: Tipo de firma en formato DER , que contiene el valor del tipo de hash de la firma;
Sig sig = Sig(b'3045022100b71be3f1dc001e0a1ad65ed84e7a5a0bfe48325f2146ca1d677cf15e96e8b80302206d74605e8234eae3d4980fcd7b2fdc1c5b9374f0ce71dea38707fccdbd28cf7e41');
  • Ripemd160: Tipo hash RIPEMD-160
Ripemd160 r = Ripemd160(b'0011223344556677889999887766554433221100');
  • Sha1: Tipo de hash Sha1
Sha1 s = Sha1(b'0011223344556677889999887766554433221100');
  • Sha256: Tipo de hash Sha256
Sha256 s = Sha256(b'00112233445566778899aabbccddeeffffeeddccbbaa99887766554433221100');
  • OpCodeType: Tipo numérico de código de operación
OpCode.OP_ADD // b'93'

Variable de propiedad (propiedad)

Cada contrato puede constar de varias variables de propiedades (es decir, lenguajes orientados a objetos generalmente variables de instancia), el contrato puede ser una función de la thisclave de acceso. Como:

contract Test {
    
    
    int x;
    bool y;
    bytes z;
    ...
}

Constructor

Cada contrato tiene como máximo 1 constructor (de lo contrario, el compilador generará uno automáticamente), que generalmente se utiliza para inicializar las variables de atributo. Como:

contract Test {
    
    
    constructor(int x) {
    
    
        this.x = x;
    }
    ...
}

Funciones integradas

  • require(bool expr): Cuando se llama a esta función para comprobar los exprresultados del valor booleano de la expresión del parámetro . Si truecontinúa hacia abajo; de lo contrario, interrumpa inmediatamente el proceso de ejecución, la ejecución del contrato falló. Equivalente a C / C ++, Java y Python assert().

  • exit(bool status): Esta función se llama inmediatamente interrumpir el proceso de ejecución, el statusvalor del parámetro es truecuando el contrato se ejecuta con éxito; de lo contrario, la ejecución del contrato falló.

Función pública

La función pública es la interfaz para llamar externamente al contrato. El código lógico principal contenido en el cuerpo de la función se puede considerar como el script de bloqueo; los parámetros de la función se pueden considerar como el script de desbloqueo correspondiente. El minero realmente verifica el resultado de ejecución de este par de combinaciones.

Las particularidades de este tipo de funciones son las siguientes:

  1. Sin returnsdeclaraciones de tipo explícitas y el final de la returndeclaración de función , que es invisible para devolver true;
  2. El final de la función debe ser una require()llamada de función;
  3. Solo cuando la función finaliza, todas las ejecuciones encontradas require()han pasado, la secuencia de comandos se considera mediante verificación; de lo contrario, se considerará que la verificación de secuencia de comandos falla, lo que provocará que la transacción falle.
contract Test {
    
    
    public function equal(int y) {
    
    
        require(this.valueOf(y) == this.x);
    }
    ...
}

Función no pública (función)

Las funciones no públicas pueden considerarse funciones privadas del contrato, cuyo objetivo principal es encapsular la lógica interna y la reutilización del código. Debe usarse cuando la definición de una palabra clave returnsse describirá con el tipo de retorno, como por ejemplo:

contract Test {
    
    
    function valueOf(int x) returns(int) {
    
    
        return x;
    }
    ...
}

Además de parte del contenido presentado brevemente anteriormente, aquí se puede ver la documentación oficial completa que contiene algunas otras características del idioma (en actualización iterativa continua).

Ejemplo de contrato sCrypt

Finalmente, mire este contrato sCrypt completo (debería ser fácil de entender):

contract Test {
    
      // 定义合约 
    int x;  // 属性变量

    constructor(int x) {
    
      // 定义构造函数
        this.x = x;  // 初始化属性变量值
    }

    public function equal(int y) {
    
      // 定义公共函数,解锁参数 y 为 int 类型
        require(this.valueOf(y) == this.x);  // 调用 require 函数,只有参数表达式值为 true 时,合约才能执行成功
    }
    
    function valueOf(int x) returns (int) {
    
       // 定义内部函数
        return x;		// 返回值
    }
}

En los siguientes artículos, continuaré presentando herramientas de desarrollo relacionadas con sCrypt y algunos diseños e implementación de contratos más complejos. Si está interesado, continúe prestando atención :)

apéndice


  1. Código de operación de script (código de operación) Obras completas Complete

  2. sCrypt documento oficial ↩︎

Supongo que te gusta

Origin blog.csdn.net/freedomhero/article/details/107104952
Recomendado
Clasificación