¿Cómo escribir un contrato inteligente WebAssembly en la red Ontology? Parte 1: óxido

¿Cómo escribir un contrato inteligente WebAssembly en la red Ontology? Parte 1: óxido

La tecnología Ontology Wasm reduce el costo de migrar contratos inteligentes de dApp con lógica comercial compleja a la cadena de bloques, lo que enriquece enormemente el ecosistema de dApp.

En la actualidad Ontología Wasm Admite simultáneamente el desarrollo de Rust y C++. El lenguaje Rust admite mejor Wasm y el código de bytes generado es más simple, lo que puede reducir aún más el costo de las llamadas de contrato. Entonces, ¿Cómo usar Rust para desarrollar un contrato en la red Ontology?

Desarrollo de un contrato WASM con Rust

crear un contrato

es una buena herramienta de creación de proyectos y gestión de paquetes para el desarrollo de Rust, que ayuda a los desarrolladores a organizar mejor la interacción del código y las bibliotecas de terceros. Para crear un nuevo contrato de Ontology Wasm, simplemente ejecute el siguiente comando:

¿Cómo escribir un contrato inteligente WebAssembly en la red Ontology? Parte 1: óxido

La estructura del proyecto que genera:

¿Cómo escribir un contrato inteligente WebAssembly en la red Ontology? Parte 1: óxido

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] del 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 parámetros de dependencia a la sección [dependencias] del archivo de configuración Cargo.toml:

¿Cómo escribir un contrato inteligente WebAssembly en la red Ontology? Parte 1: óxido

Con esta dependencia, los desarrolladores pueden llamar a las interfaces que interactúan con la cadena de bloques de Ontology y herramientas como el parámetro de serialización.

función de entrada de contrato

Todo programa tiene una función de entrada, como la función principal que solemos ver, pero el contrato no tiene una función principal. Cuando se desarrolla un contrato de Wasm con Rust, la función de invocación predeterminada se usa como función de entrada para usar el contrato. El nombre de una función en Rust no estará claro al compilar el código fuente de Rust en un código de bytes que pueda ejecutar una máquina virtual. Para evitar que el compilador genere código redundante 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 de invocación parámetros para ejecutar una transacción?

La biblioteca ontio_std proporciona una función runtime::input() para obtener los parámetros para ejecutar una transacción. Los desarrolladores pueden usar ZeroCopySource para deserializar la matriz de bytes resultante. En el que la primera matriz de bytes leída es el nombre del método de invocación, seguido de 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 la biblioteca ontio_std devuelve el resultado de la ejecución de un método.

La función de invocación completa se ve así:

¿Cómo escribir un contrato inteligente WebAssembly en la red Ontology? Parte 1: óxido

Serialización y deserialización de datos de contratos

En el proceso de desarrollo de contratos, los desarrolladores siempre tienen problemas con la serialización y la deserialización, específicamente con cómo almacenar un tipo de datos de estructura en la base de datos y cómo deserializar una lectura de matriz de bytes de la base de datos para obtener un tipo de datos de estructura.

La biblioteca ontio_std proporciona interfaces de codificador y decodificador para la serialización y deserialización de datos. Los campos de una estructura también implementan las interfaces decodificador y codificador para que la estructura pueda serializarse y deserializarse. Se requieren instancias de la clase Sink cuando se serializan varios tipos de datos. Una instancia de la clase Sink tiene un campo de tipo conjunto buf que almacena los datos de tipo byte, y todos los datos serializados se almacenan en buf.

Para datos de longitud fija (p. ej., 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, la longitud debe serializarse primero, luego Ddata (por ejemplo, enteros sin signo de tamaño desconocido, incluidos u16, u32 o u64, etc.).

La deserialización es exactamente 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 la clase Source. Esta instancia de clase 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. Cuando se lee un tipo particular de datos, si conoce su longitud, puede leerlos directamente, para datos de longitud desconocida: lea primero la longitud y luego el contenido.

Acceder y actualizar datos en la cadena

ontología-wasm-cdt-rust - encapsuló un método operativo para trabajar con datos en la cadena, que es conveniente para que los desarrolladores implementen operaciones como agregar, eliminar, cambiar y consultar datos en la cadena de la siguiente manera:

  • base de datos::get(clave) - se utiliza para solicitar datos de la cadena y la clave solicita la implementación de la interfaz AsRef;
  • base de datos::put(clave, valor) - utilizado para almacenar datos en la red. Key solicita la implementación de la interfaz AsRef y value solicita la implementación de la interfaz Encoder;
  • base de datos::borrar(clave) - se utiliza para eliminar datos de la cadena y la clave solicita la implementación de la interfaz AsRef.

Pruebas de contrato

Cuando se implementan los métodos de un contrato, necesitamos acceso a los datos en la cadena y necesitamos una máquina virtual adecuada 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 este método de prueba es problemático. Para facilitar a los desarrolladores la prueba de contratos, la biblioteca ontio_std proporciona un módulo simulado para la prueba. Este módulo proporciona una simulación de los datos en el circuito, lo que facilita a los desarrolladores la prueba unitaria de los métodos del contrato. Se pueden encontrar ejemplos específicos aquí.

Depuración de contratos

console::debug(msg) muestra información de depuración mientras se depura un contrato. La información del mensaje se agregará al archivo de registro del nodo. Un requisito previo es establecer el nivel del archivo de registro en modo de depuración cuando se está ejecutando el nodo de prueba de ontología local.

runtime::notify(msg) genera la información de depuración adecuada mientras se depura el contrato. Este método almacenará la información ingresada en la cadena y se puede consultar desde la cadena utilizando el método getSmartCodeEvent.

El artículo fue traducido por los editores de Hashrate&Shares especialmente para OntologyRussia. клик

¿Eres desarrollador? Únase a nuestra comunidad tecnológica en Discord. Además, eche un vistazo a Centro de desarrolladores en nuestro sitio web, donde puede encontrar herramientas para desarrolladores, documentación y más.

Ontología

Fuente: habr.com

Añadir un comentario