Desde que se lanzó Ontology Wasm en Ontology TestNet, ha recibido una gran atención por parte de los desarrolladores de la comunidad, ya que esta tecnología reduce el costo de trasladar contratos de dApp con lógica empresarial compleja a la cadena de bloques, lo que enriquece enormemente el ecosistema de dApp.
Ontology Wasm actualmente admite el desarrollo en los lenguajes Rust y C ++. El lenguaje Rust tiene un mejor soporte para Wasm, y el bytecode generado es más simple, lo que puede reducir aún más el costo de las llamadas contractuales. Entonces, ¿cómo utiliza Rust para desarrollar un contrato sobre ontología?
Crear un contrato
Carga es una buena herramienta de creación de proyectos y gestión de paquetes para desarrollar programas Rust que ayuda a los desarrolladores a organizar mejor el código y las dependencias de bibliotecas de terceros. Para crear un nuevo contrato de Ontology Wasm, simplemente ejecute el siguiente comando:
La estructura del proyecto que genera es:
El archivo Cargo.toml se usa para configurar la información básica del proyecto y la información de la biblioteca dependiente. La sección (lib) en el archivo debe establecerse en crate-type = ("cdylib"); el archivo lib.rs se usa para escribir el código lógico del contrato. Además, debe agregar configuraciones de dependencia en la sección (dependencias) del archivo de configuración Cargo.toml:
Con esta dependencia, los desarrolladores pueden llamar a interfaces que interactúan con la cadena de bloques de Ontology y herramientas como la serialización de parámetros.
Función de entrada de contrato
Cada programa tiene una función de entrada, como la función principal que vemos comúnmente, pero el contrato no tiene una función principal. Al desarrollar un contrato Wasm con Rust, la función de invocación se usa por defecto como la función de entrada para la ejecución del contrato. El nombre de la función en Rust se confundirá al compilar el código fuente de Rust en bytecode que la máquina virtual puede ejecutar. Para evitar que el compilador genere código de bytes adicional y reducir el tamaño del contrato, la función de invocación agrega la anotación # (no_mangle).
¿Cómo obtiene la función invocar los parámetros para la ejecución de la transacción? los ontio_std La biblioteca proporciona la función runtime :: input () para recibir parámetros para la ejecución de la transacción. Los desarrolladores pueden usar ZeroCopySource para deserializar la matriz de bytes recibida. Entre ellos, el primer conjunto de bytes que se lee es el nombre del método de invocación y luego los parámetros del método.
¿Cómo se devuelve el resultado de la ejecución del contrato? La función runtime :: ret proporcionada por ontio_std La biblioteca devuelve el resultado de la ejecución del método.
Una función de invocación completa es la siguiente:
Serialización y deserialización de datos contractuales
En el proceso de desarrollo del contrato, los desarrolladores siempre encuentran problemas de serialización y deserialización, es decir, cómo guardar un tipo de datos de estructura en la base de datos y cómo la matriz de bytes leída de la base de datos se deserializa para obtener datos de tipo estructura.
los ontio_std La biblioteca proporciona las interfaces Decoder y Encoder para serializar y deserializar datos. Los campos de la estructura de estructura también implementan las interfaces Decoder y Encoder para que la estructura se pueda serializar y deserializar. Se requieren instancias de sumidero al serializar varios tipos de datos. La instancia de Sink tiene un buf de campo de tipo establecido, que almacena datos de tipo byte, y todos los datos serializados se almacenan en buf.
Para datos de longitud fija (por ejemplo: byte, u16, u32, u64, etc.), los datos se convierten directamente en una matriz de bytes y luego se almacenan en buf; para datos de longitud no fija, primero se debe serializar la longitud y luego los datos D (como enteros sin signo de tamaño desconocido, incluidos u16, u32 o u64, etc.).
La deserialización es todo lo contrario. Para cada método de serialización, hay un método de deserialización correspondiente. La deserialización requiere el uso de instancias de origen. Esta instancia tiene dos campos, buf y pos. Buf se usa para almacenar los datos que se deserializarán, y pos se usa para almacenar la posición de lectura actual. Al leer un tipo específico de datos, si conoce su longitud, puede leerlo directamente; para datos de longitud desconocida, lea primero la longitud y luego lea el contenido.
Acceso y actualización de datos en la cadena
Ontología-wasm-cdt-rust ha encapsulado el método de operación de los datos en cadena, lo cual es conveniente para que los desarrolladores implementen operaciones tales como agregar, eliminar, cambiar y consultar datos en la cadena de la siguiente manera:
Ø database :: get (key) se utiliza para consultar datos de la cadena, y key requiere la implementación de la interfaz AsRef.
Ø database :: put (clave, valor) se usa para almacenar datos en la cadena. La clave requiere la implementación de la interfaz AsRef y el valor requiere la implementación de la interfaz Encoder.
Ø database :: delete (key) se utiliza para eliminar datos de la cadena, y la clave requiere la implementación de la interfaz AsRef.
Prueba de contrato
Al implementar métodos de contrato, necesitamos acceder a los datos en la cadena y necesitamos la máquina virtual correspondiente para ejecutar el código de bytes del contrato, por lo que generalmente es necesario implementar el contrato en la cadena para realizar pruebas. Pero tal método de prueba es problemático. Para facilitar que los desarrolladores prueben los contratos, el ontio_std la biblioteca proporciona un simulacro de módulo de prueba. Este módulo proporciona la simulación de los datos en la cadena, lo que facilita a los desarrolladores probar los métodos en el contrato. Ejemplos específicos se pueden encontrar aquí.
Depuración de contratos
Los desarrolladores pueden usar console :: debug (msg) para generar información de depuración durante la depuración del contrato. La información del mensaje se imprimirá en el registro de nodos. Existe una condición previa de que el nivel de registro debe establecerse en modo de depuración cuando se inicia el nodo de prueba local de Ontology.
Además, los desarrolladores también pueden usar runtime :: notify (msg) para generar información de depuración relevante durante la depuración del contrato. Este método guardará la información impresa en la cadena y puede consultarse desde la cadena a través del método getSmartCodeEvent.
Como cadena pública líder, Ontology es uno de los primeros proyectos que respaldan el contrato de Wasm y está haciendo todo lo posible para desarrollar la tecnología de Wasm. Al mismo tiempo, también damos la bienvenida a más entusiastas de la tecnología Wasm a unirse a la comunidad de desarrolladores de Ontology para construir un ecosistema tecnológico.