Que es Parity’s ink!?

w3n:guido
Parity Technologies | Español
17 min readMar 18, 2023

Traducción en Español del Artículo: What is Parity’s ink!? by Michi Müller (Septiembre 20, 2022) / Parity Technologies: parity.io / ink!: use.ink

  • En ocasión de ink! superando las 1000 estrellas en Github, nos sumergimos profundamente en el lenguaje de programación de smart contracts.

ink! es un lenguaje de programación para smart contracts, uno de varios entre los que pueden elegir las blockchains creadas con Substrate Framework. Es un lenguaje obstinado que en Parity hemos creado mediante la ampliación del popular lenguaje de programación Rust con la funcionalidad necesaria para que sea compatible con smart contracts.

Gracias por ayudar a ink! supera las 1000 estrellas de GitHub!

El repositorio de ink! superó recientemente las mil estrellas en GitHub. Ahora es el tercer repositorio de Parity con más estrellas en GitHub, después de Substrate y Polkadot. Queremos decir un gran “¡Gracias!” a todos los que contribuyeron para que esto sucediera! En los últimos años, hemos visto contribuciones en todas las formas que llevaron el proyecto a donde se encuentra hoy. Gracias por escribir sus contratos en ink!, por crear problemas y solicitudes de incorporación de cambios, por brindarnos comentarios buenos y constructivos, por responder preguntas sobre Substrate StackExchange, por crear herramientas de terceros para ink!, por escribir publicaciones de blog sobre nosotros, y por la realización de workshops!

Han pasado muchas cosas en los últimos años en el mundo ink!. La primera confirmación fue en diciembre de 2018 y nuestra versión actual es v3.3.1. Estamos trabajando arduamente para enviar pronto la próxima iteración importante con v4.0. Un punto abierto que surge regularmente es que nunca hemos escrito una publicación de blog que explique de principio a fin qué es ink! y cómo se relaciona con Substrate y Polkadot. ¡Por lo tanto, esta ocasión es una gran oportunidad para hacer precisamente eso!

¿Cómo se relaciona ink! con Substrate?

Antes de que podamos hablar de ink! primero debemos aclarar qué es Substrate y su Contracts pallet (pallet-contracts). Substrate es un framework para construir blockchains, que pueden ser blockchains independientes o blockchains conectadas a Kusama o Polkadot como las llamadas parachains. Substrate contiene una serie de módulos, que en la terminología de Substrate se denominan pallets. Substrate viene con un conjunto de pallets para muchos requisitos que suelen tener las blockchains modernas: staking, tokens fungibles, tokens no fungibles, gobernanza, etc.

Substrate también incluye un módulo para contratos inteligentes llamado Contracts pallet. Si se desarrolla una parachain en Substrate, puede agregar fácilmente la funcionalidad de smart contract al incluir esta pallet.

¿Cómo entra en juego ink! aquí? ink! es un lenguaje de programación, específicamente es un lenguaje Embedded Domain-Specific Language (eDSL) para el popular lenguaje de programación Rust. Esto significa que puede usar toda la sintaxis normal de Rust más algunos detalles que agregamos para que el lenguaje sea adecuado para el mundo de los smart contracts. La Contracts pallet toma estos contratos ink! y los ejecuta de manera segura. Así que en resumen:

Con ink! puede escribir smart contracts en Rust para blockchains creadas con Substrate que incluyen la Contracts pallet.

Smart Contracts vs. Parachains

Una de las primeras preguntas que normalmente recibimos cuando alguien se entera de Substrate, Polkadot o Kusama es cuándo desarrollar una parachain frente a cuándo desarrollar un smart contract.

La distinción aquí es que, en el contexto de Polkadot y Kusama, una parachain arrienda un slot durante un par de meses hasta dos años. El acuerdo con un contrato de arrendamiento es que la parachain obtiene un slot fija para ejecutar su lógica comercial (normalmente denominada función de transición de estado) y puede conservar su estado modificado en un bloque. En la terminología de Substrate, esta función de transición de estado se denomina Runtime de la chain.

La distinción con otros ecosistemas aquí es que, en el contexto de Polkadot, las parachains y los smart contracts existen en diferentes capas de la pila: los smart contracts se ubican encima de las parachains. Las parachains generalmente se describirían como blockchains Layer 1, excepto que no tienen que construir su propia seguridad y son actualizables e interoperables.

Es digno de mención que la función de transición de estado de una parachain no se valida más; depende de la parachain cómo utiliza su tiempo de slot. Una vez que una parachain asegura un slot al vincular tokens (o obtenerlos de su comunidad a través de un crowdloan), el slot es esencialmente prepago, sin que se requieran tarifas adicionales para ejecutar la lógica comercial de la chain. ¡Esto significa que la parachain puede construir su propio mundo (blockchain)! Por ejemplo, puede decidir cómo se cobran las tarifas de transacción, o incluso si se cobran tarifas de transacción. Estas opciones son cruciales cuando se construyen modelos comerciales nuevos o más fáciles de usar.

Otros factores distintivos entre las parachains que observamos en la naturaleza son las diferencias en cómo funciona la gobernanza de la chain o la criptoeconomía. Sin embargo, existen algunas limitaciones sobre cómo la parachain puede construir su mundo. Al igual que la física en el mundo real, tiene que adherirse a ciertas reglas básicas. Para Polkadot y Kusama, ese es, por ejemplo, el algoritmo de consenso para que la Relay Chain se comunique con la parachain. De esas reglas básicas surgen las ventajas de Polkadot y Kusama. Ventajas como la seguridad compartida antes mencionada, la comunicación cross-chain o el runtime garantizado.

Para los smart contracts, por otro lado, una parachain existente debe incluir la Contracts pallet para que los usuarios deploy smart contracts. El smart contract implementado siempre es un código que no es de confianza. Cualquiera (o cualquier programa) que tenga tokens de la chain puede cargar un smart contract sin necesidad de permiso. Los smart contracts permiten la implementación sin permiso de programas no confiables en una blockchain. La Contracts pallet tiene que asumir que estos programas son antagónicos, tiene que establecer una serie de pilares de seguridad para garantizar que el contrato no pueda, por ejemplo, detener la chain o provocar la corrupción de estado de otros contratos. Para la Contracts pallet esos pilares de seguridad incluyen mecanismos como la medición de gas o depósitos para almacenar datos on-chain.

Para reafirmar esta importante distinción: desarrollar un Runtime de parachain es diferente de desarrollar un smart contract: un smart contract se encuentra encima de una parachain.

La compensación es que con una parachain uno tiene la libertad de decidir sobre (casi) todas las reglas que componen la parachain. Con un smart contract, uno está limitado por lo que permite la chain y los pilares de seguridad que necesariamente deben existir.

Un smart contract, por otro lado, tiene menos fricción para desarrollarlo e hacer deploy. Los desarrolladores no tienen que pensar en la gobernanza, la criptoeconomía, etc. Uno solo necesita algunos tokens y puede seguir su camino feliz implementando un smart contract. Es tan simple como eso.

¿Cómo funciona la Contracts pallet?

Diseñamos intencionalmente la Contracts pallet de manera que esté se desvinculada del lenguaje utilizado para escribir smart contracts. La pallet es solo el entorno de ejecución y toma los archivos de WebAssembly como entrada. Los smart contracts para esta plataforma deben compilarse en la arquitectura de destino WebAssembly (Wasm).

Para los desarrolladores de contratos, esto significa que pueden usar ink! para escribir smart contracts, pero también puede decidir sobre otros lenguajes. En este momento existen tres lenguajes para elegir:

  1. Parity’s ink! para Rust.
  2. ask! para AssemblyScript.
  3. The Solang compiler para Solidity.

No es difícil agregar nuevos lenguajes. Solo es necesario que haya un compilador para el lenguajes hasta WebAssembly, luego es posible hacer deploy la API de Contracts pallet. Esta API en este momento consiste en alrededor de 15–20 funciones para cualquier cosa que un smart contract pueda desear: acceso de almacenamiento, funcionalidad criptográfica, información ambiental como números de bloque, acceso a funciones para obtener números aleatorios o para cancelar el contrato, etc. No todo eso tiene que hacer deploy en el lenguaje: ink! “Hello, World!” requiere solo seis funciones API. El siguiente esquema representa esta relación:

Creemos que este diseño está más preparado para el futuro que algunas arquitecturas que se encuentran en ecosistemas competidores. No existe un acoplamiento estrecho entre el lenguaje y el entorno de ejecución. WebAssembly es un estándar de la industria y hoy en día se pueden compilar una multitud de lenguajes de programación en WebAssembly. Si dentro de, digamos, diez años, los investigadores encuentran un lenguaje innovador para escribir smar contracts (o un subconjunto de un lenguaje existente), mientras haya un compilador WebAssembly, será fácil hacer que este lenguaje sea compatible con la Contracts pallet.

¿Por qué incluir la Contracts pallet en una parachain?

Hay un par de casos de uso para incluir la funcionalidad de smart contracts en una parachain. Nosotros distinguimos tres grandes:

Caso de Uso 1: Smart Contracts como “ciudadanos de primera clase”

El caso de uso más obvio es el de una parachain que ofrece smart contracts como “ciudadano de primera clase”, lo que significa que los smart contracts son la propuesta de valor central de la chain.

Estas chains suelen tomar la Contracts pallet estándar y crear alguna innovación adicional sobre ella. Ejemplos de ello son:

  1. Astar: construyó una capa sobre la Contracts pallet para que los desarrolladores de contratos puedan ganar un ingreso pasivo siempre que sus contratos estén siendo utilizados.
  2. Phala: utiliza la Contracts pallet en un entorno de ejecución de confianza, lo que permite la ejecución confidencial de smart contracts y la interoperabilidad.
  3. Aleph Zero: utiliza la Contracts pallet en un contexto de conocimiento cero.
  4. t3rn: utiliza la Contracts pallet como un bloque de construcción para permitir la ejecución multichain de smart contracts.

Caso de Uso 2: Smart Contracts como “ciudadanos de segunda clase”

Hay otro caso de uso no tan obvio para la Contracts pallet: smart contracts como “ciudadanos de segunda clase” en una chain existente. Con esto queremos decir que la propuesta de valor central de la chain no tiene nada que ver con los smart contracts, pero aun así los incluye como complemento.

Proporcionamos una API (denominada extensiones de chain) con la que una parachain puede exponer ciertas partes de su lógica empresarial a los desarrolladores de smart contracts. A través de esto, los desarrolladores de smart contracts pueden utilizar las primitivas de lógica de negocio de la chain para construir una nueva aplicación sobre ella. Pensemos, por ejemplo, en una blockchain de intercambio descentralizada. Esta chain, en su forma más simple, tendría un libro de órdenes para colocar ofertas y demandas - no hay necesidad de tomar programas no confiables, completos de turing, desde el exterior. Sin embargo, la parachain podría decidir exponer el libro de órdenes en smart contracts, dando a los desarrolladores externos la opción de construir nuevas aplicaciones que utilicen el libro de órdenes. Por ejemplo, subir algoritmos de trading como smart contracts a la chain.

Los smart contracts son una oportunidad para aumentar la participación de los usuarios. Y la facturación por utilizar la chain ya viene incorporada con la pallet: los usuarios tienen que pagar tasas de gas por la ejecución de su smart contract.

Caso de Uso 3: Smart Contracts como primer paso en Polkadot o Kusama

Un tercer gran caso de uso para la Contracts pallet es crear un prototipo de una idea como un proof-of-concept de smart contract antes de arrendar un slot de parachain dedicado en Polkadot o Kusama.

El tiempo para desarrollar un smart contract y el deploy es más corto que la historia de incorporación de un parachain. Se puede hacer deploy primero un smart contract proof-of-concept, ver si gana tracción y la idea se mantiene en el mundo real. Posteriormente, una vez que exista la necesidad de, por ejemplo, tarifas de transacción más baratas, una ejecución más eficiente o un mecanismo de gobernanza para la comunidad, el smart contract podría migrarse a un runtime de parachain dedicado con su propio slot. Los contratos de ink! y los runtimes de Substrate están escritos en Rust y comparten primitivas similares, lo que permite un camino claro para que un proyecto se gradúe de un smart contract a su propio runtime. Los desarrolladores pueden reutilizar grandes partes de su código, sus pruebas, así como el frontend y el código cliente.

Un simple ink! smart contract

ink! es en realidad sólo Rust, ese es nuestro objetivo general. Nuestro objetivo es ser mínimamente invasivos, permitiendo a los desarrolladores utilizar todo lo que también pueden utilizar para Rust “normal” — IDEs, cargo fmt, cargo clipy, fragmentos de código, el ecosistema crates.io, etc.

En la siguiente imagen puedes ver un simple contrato ink! El contrato almacena un valor booleano. Una vez creado, el contrato establece el valor booleano en true. El contrato expone dos funciones: una para leer el valor actual del booleano (fn get()) y otra para cambiar el valor a su valor booleano opuesto (fn flip()).

Las líneas de color son anotaciones específicas de ink! en el código, el resto es sintaxis normal de Rust. Estas anotaciones hacen abstracción de lo que tiene que pasar bajo el capó para que el programa sea compatible para ser ejecutado en la chain.

Para nuestra versión actual 3.3.1, las pruebas unitarias y de integración también pueden escribirse como en Rust “normal”:

La anotación #[ink::test] tiene el efecto de ejecutar esta prueba en un entorno de blockchain simulado. Esto permite a los desarrolladores simular, por ejemplo, el valor que se transfiere a un contrato, la persona que ejecuta un contrato, el número de bloque, etc. Por ejemplo, puede utilizar ink_env::test::set_value_transferreddentro de un #[ink::test]para simular el valor (es decir, los tokens) que se envían a un contrato. Puede ver la lista completa de funcionesink_enven nuestra documentación de crate.

cargo-contract: la navaja suiza de los ink! contracts

Para construir ink! smart contracts puedes usar el flujo de trabajo normal de cargo buildpara construir programas Rust. Sin embargo, tendrías que añadir una serie de argumentos al comando para que funcione en la chain. Hemos creado una herramienta que ya elige el conjunto óptimo de banderas para usted: cargo-contract. Es una herramienta de línea de comandos que reflejacargo.Puedes pensar en ella como una navaja suiza para smart contracts, puede hacer mucho más que construir un contrato, pero hablaremos de eso más adelante.

Para construir contratos se utiliza cargo contract build. Ten en cuenta que el comportamiento típico de Rust cargo buildes que necesitas suministrar --releasesi quieres el tamaño binario más pequeño posible, lo mismo con cargo contract build --release. Si ejecutas este comando verás que cargo-contractejecuta la construcción “normal” de cargo build, pero también realiza algunos pasos más. Los tres pasos adicionales más importantes son:

  • Ejecuta un linter para contratos ink!. Este linter funciona de forma análoga al clippyde Rust, comprueba el uso idiomático de ink! en tu contrato. Estamos mejorando constantemente esta herramienta de linting y añadiremos detecciones de errores de seguridad comunes en el futuro.
  • Post-procesa y comprime el binario de tu contrato. Esto se hace para reducir los costes para los usuarios que deploy un contrato, así como las tarifas para los usuarios que interactúan con el contrato. El tamaño del contrato también se correlaciona con el rendimiento que puede alcanzar una chain y contribuye a la huella de la chain.
  • Genera metadatos para el contrato. Con el término metadatos nos referimos a cualquier información necesaria para interactuar con el binario del contrato. El binario en sí no será más que un blob de WebAssembly, un código de bytes del contrato con el que no se puede interactuar sin más información. Para saber, por ejemplo, qué funciones expone el contrato y qué argumentos toman esas funciones es necesario tener los metadatos. Puede que también conozcas este concepto bajo el término ABI de otras blockchains. En nuestro caso, los metadatos contienen algo más que la ABI, aunque también contienen información sobre, por ejemplo, cómo el contrato almacena sus datos, lo que es útil para herramientas off-chain (por ejemplo, un explorador de bloques) o documentación legible por humanos sobre las funciones del contrato.

Como resultado de la ejecución de cargo contract buildse crean tres archivos:

  • my_contract.contract: un archivo JSON que contiene el blob WebAssembly del contrato en codificación hexadecimal más los metadatos del contrato.
  • metadata.json: un archivo JSON que contiene sólo los metadatos del contrato, sin el blob de WebAssembly.
  • my_contract.wasm: el blob WebAssembly del contrato.

Cada uno de estos archivos tiene un uso diferente:

WebAssembly es el único archivo que se almacena on-chain. El almacenamiento de datos on-chain sólo debe hacerse para los datos que estrictamente necesitan estar on-chain. Cualquier cosa que no sea necesaria on-chain supondría un coste para los usuarios e hincharía la huella on-chain. No es necesario que los metadatos estén on-chain, una aplicación o interfaz puede contener los metadatos codificados para determinar cómo interactuar con el contrato.

El paquete *.contractsolo es necesario si estás desarrollando un smart contract, entonces puedes usar este archivo con una Developer UI. Las interfaces de desarrollador te permiten hacer deploy de contratos, interactuar con ellos y depurarlos.

Entornos de Desarrollo

Varias parachains han desarrollado herramientas personalizadas que proporcionan un ángulo más específico del contexto en el que utilizan la Contracts pallet y ink!. Hemos mencionado algunos de esos equipos al principio de este post. Para más información, consulte nuestro repositorio awesome-ink.

Nosotros, como el equipo que desarrolla ink! y Contracts pallet, también proporcionamos un par de herramientas útiles:

  • substrate-contracts-nodeEste repositorio contiene el node-templatede Substrate configurado para incluir pallet-contracts. Este nodo está rastreando la rama maestra de Substrate y ha sido modificado para hacerlo ideal para desarrollo y pruebas. Por ejemplo, no tiene ningún tiempo de bloqueo fijo, todo se procesa inmediatamente. Esto tiene el coste de hacer que el nodo no sea adecuado para uso en producción, pero es ideal para scripts, pruebas o un entorno de Continuous Integration (CI). Si está buscando plantillas de producción eche un vistazo al node de Substrate o a la guía How-To en la documentación de Substrate sobre cómo añadir las pallets-contracts (enlace aquí).
  • Mantenemos una red de pruebas llamada simplemente Contractsen Rococo. Rococo es una red de prueba para todo lo que sea Polkadot y Kusama. Muchas parachains están conectados a Rococo con sus propias testnets. Puedes leer más sobre cómo hacer deploy en nuestra testnet en nuestra documentación.

También hay varias redes de prueba de la comunidad, puedes encontrar algunas en nuestro repositorio awesome-ink.

Para las interfaces de usuario de desarrollador hay actualmente tres opciones:

  • Contracts UI: Ideal para principiantes, da consejos útiles y ayuda a los desarrolladores.
  • polkadot.js: Interfaz avanzada que ofrece flexibilidad a los desarrolladores, a costa de la facilidad de uso.
  • ink! playground: Una zona de juegos para probar ink! en el navegador o compartir enlaces permanentes a fragmentos de código. Un uso muy práctico es si está haciendo preguntas en Substrate StackExchange: puede compartir código con, por ejemplo, un problema al que se esté enfrentando.
  • cargo-contract: Si estás buscando hacer deploy de contratos desde la línea de comandos, llamarlos, decodificar su salida, etc. entonces esta herramienta proporciona una opción práctica para hacer todo eso desde una interfaz de línea de comandos. La herramienta también es perfecta para scripts o integraciones CI.

¿Por qué elegir esta vía en lugar de una capa de compatibilidad con Substrate Ethereum?

Además de la Contracts pallet, otras dos opciones populares para smart contracts en Substrate son pallet-evm y Frontier. Ambas son capas de compatibilidad de Ethereum para Substrate.

Hay una serie de ventajas para elegir la ruta de ink! y la Contracts pallet sobre la de EVM. Para resumir algunas que se detallaron en este artículo:

  • ink! es sólo Rust - puedes usar todas las herramientas normales de Rust: clippy, crates.io, IDE’s, etc.
  • Rust es un lenguaje que incorpora años de investigación, es seguro y rápido. Además, hemos aprendido mucho de lenguajes de smart contracts más antiguos (como Solidity) y los hemos incorporado al diseño del lenguaje ink! Hemos elegido comportamientos por defecto más sensatos, como desactivar la reentrada por defecto o hacer que las funciones sean privadas por defecto.
  • Rust es un lenguaje increíble con el que trabajar, ha sido coronado como el lenguaje de programación más querido durante siete años consecutivos en StackOverflow (fuente).
  • Si eres una empresa y buscas contratar desarrolladores de smart contracts, puedes contratar del ecosistema de Rust, que es mucho más amplio que el nicho de, por ejemplo, desarrolladores de Solidity.
  • ink! es nativo de Substrate, utilizamos primitivas similares, como el mismo sistema de tipos.
  • Hay una ruta de migración clara para pasar de un contrato a una parachain. Dado que tanto ink! como Substrate son Rust, los desarrolladores pueden reutilizar grandes partes de su código, sus tests, así como el frontend y codigo de client.
  • WebAssembly es un estándar de la industria, no solo se utiliza en el mundo del blockchain. Es mejorado continuamente por grandes empresas como Google, Apple, Microsoft, Mozilla y Facebook. En el futuro nos beneficiaremos de todas las mejoras del estándar y de sus implementaciones. Esto es algo importante. WebAssembly se utiliza sobre todo para la web, que tiene requisitos similares a los de blockchain: seguro y rápido.
  • WebAssembly amplía la familia de lenguajes disponibles para los desarrolladores de smart contracts para incluir Rust, C/C++, C#, Typescript, Haxe, Kotlin, etc. Esto significa que puedes escribir smart contracts en cualquier lenguaje con el que estés familiarizado. Creemos que este diseño está más preparado para el futuro que un acoplamiento estrecho del lenguaje y la arquitectura de ejecución.

Apoyamos la interoperabilidad con bases de código heredadas de Solidity: el proyecto Solang de HyperLedger compila Solidity para la Contracts pallet.

¿Dónde obtener más información?

  • Nuestro portal de documentación se encuentra en use.ink, contiene la información más completa sobre ink!.
  • Dado que ink! es sólo Rust, también puede consultar la documentación de crate. Hemos enlazado la documentación relevante de la crate en nuestro readme, por ejemplo, la documentación de crate para estructuras de datos.
  • Tenemos una serie de ejemplos de contratos en nuestro repositorio aquí. Cubren un amplio número de casos de uso típicos: ERC-20, contratos actualizables, etc.
  • Si lo que buscas es una introducción rápida, el tutorial guiado para principiantes de ink! es un buen punto de partida.
  • En caso de que esté interesado en el funcionamiento interno de ink!, lo explicamos en nuestro archivo ARCHITECTURE.md.
  • Para la Contracts pallet el README.mdproporciona un punto de partida.

Hacia el futuro

Nuestra intención con este artículo era ofrecer una imagen completa de lo que es ink! El próximo gran paso de ink! es la versión v4.0.0 -nuestra próxima gran iteración, de la que ya hemos publicado una versión alfa. Esta versión traerá importantes mejoras en el tamaño de los contratos, la experiencia del desarrollador y las pruebas nativas End-to-End. Además de esto, varios equipos de parachain están a punto de lanzar la Contracts pallet y ink! a Kusama o Polkadot. Las cosas siguen animándose y tenemos muchas ganas de que lleguen las próximas mil estrellas.

En caso de que te quede alguna duda, no dudes en ponerte en contacto con nosotros. La mejor forma de hacerlo es preguntar en el Substrate StackExchange o a través de https://info.polkadot.network/contact. Si ya estás construyendo, abre una incidencia en el repositorio correspondiente.

--

--

w3n:guido
Parity Technologies | Español

Polkadot Ambassador / Global Lead & On-Chain Council Member of Polimec Foundation https://x.com/web3sir