Migration
La migración se refiere al proceso de actualización o sustitución del código de un contrato inteligente existente y, en algunos casos, a la modificación de los datos de estado.
CosmWasm ha hecho de la migración de contratos una experiencia fluida. Durante la instanciación del contrato, hay un campo admin opcional que se puede establecer. Si no se especifica este campo, el contrato se convierte en inmutable. Sin embargo, si se asigna a una cuenta externa o a un contrato de gobierno, esa cuenta puede iniciar la migración. El administrador también puede transferir la propiedad a otra cuenta o hacer que el contrato sea completamente inmutable después de algún tiempo estableciendo el campo admin en un valor vacío.
Aquí es donde entra en juego la especificación CW2. Especifica un Singleton especial que contiene el nombre del contrato y la información de la versión que deben almacenar todos los contratos compatibles con CW2 durante la instanciación. Cuando se invoca la función de migración, el contrato recién creado puede acceder a esta información para determinar si es compatible con la migración del contrato anterior.
La Especificación CW2 proporciona una función set_contract_version que debe utilizarse al instanciar un nuevo contrato a través de la función instantiate para almacenar la información de versionado del contrato. Para el contrato que migra, es importante utilizar la función set_contract_version como parte de la lógica de migración dentro de la función migrate(...), en lugar de la función instantiate, para actualizar el versionado del contrato durante el proceso de migración:
Para el contrato en migración, además de utilizar set_contract_version, también puede utilizar la función get_contract_version para determinar la versión anterior del contrato. Es importante asegurarse, por ejemplo, de que la actualización sólo se realiza si la versión que se está actualizando es posterior a la versión original del contrato:
Tanto el método set_contract_version como el método get_contract_version operan sobre una estructura de datos Item de cw_storage_plus, que gestiona esta información:
Así, un ejemplo serializado puede ser el siguiente:
Establecer un contrato para las migraciones
Realizar una migración de contrato implica tres pasos. En primer lugar, escriba una versión más reciente del contrato que desea actualizar. En segundo lugar, almacene el nuevo código en la cadena, pero no lo instancie. En tercer lugar, utilice una transacción MsgMigrateContract dedicada para dirigir el contrato antiguo hacia el nuevo código, y la migración se habrá completado. Vea Ejecutar una transacción de migración más abajo para saber cómo ejecutar una transacción de migración usando archwayd, Archway Developer CLI o arch3.js.
Durante el proceso de migración se ejecuta la función migrar definida en el nuevo contrato y no la función migrar del código antiguo, por lo que es necesario que el código del nuevo contrato tenga una función migrar definida y correctamente exportada como entry_point:
La función migrate ofrece la posibilidad de realizar cualquier cambio granular deseado en el Estado, de forma similar a una migración de base de datos.
Si la función migrate devuelve un error, la transacción se abortará, todos los cambios de Estado se revertirán y la migración no se llevará a cabo.
A continuación se presentan diversas variantes de migración para dar una idea de algunos casos de uso habituales.
Migración básica de contratos
Esta migración puede ser la más frecuente. Se limita a sustituir el código de un contrato. Sin embargo, no se implementan comprobaciones de seguridad, ya que no se realiza ninguna comprobación cw2::set_contract_version.
Migración por versión de código y nombre de contrato
Esta migración es un ejemplo más completo. La función migrar garantiza:
Migrar desde el mismo tipo de contrato verificando su nombre.
La actualización a partir de una versión anterior del contrato verificando su versión
Migrar usando comparación semver
Esta migración utiliza Semver en lugar de una comparación String.
Este ejemplo utiliza Semver para ayudar con la comprobación de versiones. También necesitaría añadir la dependencia semver a sus dependencias de carga:
También puede implementar errores personalizados Semver:
Uso de migrate para actualizar un estado que de otro modo sería inmutable
Este ejemplo muestra cómo puede utilizarse una migración para actualizar un valor que normalmente es inmutable. Esta característica permite cambiar el valor sólo durante una migración si es necesario.
En el ejemplo anterior, nuestro MigrateMsg tiene un campo verificador que contiene el nuevo valor para el campo verificador de nuestro contrato ubicado en el Estado. Siempre que su contrato no exponga también un UpdateState o algo como UpdateVerifier ExecuteMsgs, entonces este proporciona el único método para cambiar el valor del verificador.
Utilizar las migraciones para "quemar" un contrato
Las migraciones también pueden utilizarse para abandonar un contrato antiguo y borrar su estado. Esto tiene varias aplicaciones, pero si lo necesita, puede encontrar un ejemplo aquí:
En el ejemplo anterior, el estado se elimina completamente durante la migración. Además, todo el saldo del contrato se envía a una dirección de pago designada especificada en el MigrationMsg. Como resultado, todos los fondos son drenados y todo el estado es eliminado, quemando efectivamente el contrato.
Crear un contrato mutable
En CosmWasm, un contrato mutable se refiere a un contrato inteligente que permite la modificación de su estado y código después de su despliegue. Por defecto, los contratos CosmWasm son inmutables, lo que significa que su estado no se puede cambiar una vez que se despliegan en la blockchain. Sin embargo, si el contrato es instanciado con una dirección de administrador, esa cuenta puede ejecutar migraciones para actualizar el código y el estado del contrato.
Crear un contrato mutable a través de archway developer CLI
Archway Developer CLI es nuestra herramienta recomendada para interactuar con tus contratos inteligentes ya que simplifica muchas complejidades asociadas a otros métodos. Para crear un contrato mutable, necesitas establecer una dirección admin durante el proceso de instanciación del contrato.
Sustituya [valor] por la dirección que servirá de dirección de administración del contrato. Sólo esta dirección puede ejecutar migraciones de contrato. Si el contrato requiere argumentos, sustituya [arg value] por un objeto JSON que represente los argumentos, por ejemplo '{"count": 0}'.
Crear un contrato mutable mediante archwayd
Cuando todo lo demás falla, archwayd permite un acceso de bajo nivel a los diversos comandos que pueden ejecutarse contra la blockchain.
El [code_id] debe corresponder al código ID del contrato almacenado que quieres instanciar. [json_encoded_init_args] es un objeto json que contiene los argumentos que necesita la función de instanciación. El [label_text] es un nombre legible por humanos para el contrato. [admin_address] es la dirección que actuará como administrador del contrato. El valor [coins] son los tokens que se enviarán al contrato durante la instanciación y el valor [wallet] puede ser el nombre del monedero o la dirección de la cuenta que firmará la transacción.
Crear un contrato mutable mediante arch3.js
Este es un ejemplo básico de cómo podrías instanciar un contrato con una dirección admin usando arch3.js. Crea un nuevo proyecto npm e instala las siguientes dependencias:
npm install --save @archwayhq/arch3.js
npm install --save dotenv
También tendrá que crear un archivo .env en la raíz de la carpeta de su proyecto y añadir lo siguiente:
El siguiente código Javascript puede almacenarse en un archivo index.js y ejecutarse ejecutando node index.js.
Ejecutar una operación de migración
En esta sección, demostraremos el proceso de realizar una migración usando la CLI de Archway Developer, archwayd, y arch3.js.
Ejecutar la migración a través de archwayd
Deberá sustituir [direccion_contrato] por la dirección del contrato que desea actualizar. El [new_code_id] debe corresponder al ID de código del nuevo contrato almacenado que sustituirá al contrato antiguo. [json_encoded_migration_args] es un objeto json que contiene los argumentos que requiere tu función de instanciación. El valor [wallet] puede ser el nombre del monedero o la dirección de la cuenta que firmará la transacción.
Ejecutar la migración mediante arch3.js
Este es un ejemplo básico de cómo podrías migrar un contrato usando arch3.js. Crea un nuevo proyecto npm e instala las siguientes dependencias:
npm install --save @archwayhq/arch3.js
npm install --save dotenv
También tendrá que crear un archivo .env en la raíz de la carpeta de su proyecto y añadir lo siguiente:
El siguiente código Javascript puede almacenarse en un archivo index.js y ejecutarse ejecutando node index.js.
Hacer un contrato inmutable
En algunos casos, puede ser necesario hacer que un contrato sea inmutable. El concepto de inmutabilidad en el contexto de los contratos inteligentes se refiere a la imposibilidad de modificar o alterar el código o el estado del contrato una vez que se ha desplegado en una red blockchain.
Hay varias situaciones en las que hacer que un contrato sea inmutable puede ser beneficioso. Una de ellas es cuando se trata de funciones o procesos críticos que no deben ser susceptibles de modificaciones no autorizadas. Al hacer el contrato inmutable, te aseguras de que la lógica del contrato permanece intacta y sin cambios, proporcionando un mayor nivel de seguridad y confianza.
Para hacer que un contrato sea inmutable, es esencial establecer la dirección admin en un valor vacío, impidiendo así la ejecución de cualquier migración de contrato.
Hacer inmutable el contrato mediante archwayd
Deberá sustituir [contract_address] por la dirección del contrato que desea actualizar. Establezca el valor [new_admin_address] en una cadena vacía.
Hacer inmutable un contrato mediante arch3.js
Este es un ejemplo básico de cómo podrías actualizar la dirección admin de un contrato usando arch3.js. Crea un nuevo proyecto npm e instala las siguientes dependencias:
npm install --save @archwayhq/arch3.js
npm install --save dotenv
También tendrá que crear un archivo .env en la raíz de la carpeta de su proyecto y añadir lo siguiente:
El siguiente código Javascript puede almacenarse en un archivo index.js y ejecutarse ejecutando node index.js.
Last updated