Parceros
  • 👽Recursos
    • 💻Nodos validadores
      • Buenas prácticas y seguridad de un validador
      • Montaje de nodo validador de Stargaze
      • Montaje de nodo validador de Tgrade
      • Montaje de nodo validador de Juno
      • Instalacion del Cosmovisor
      • Instalación de AutoCompound
      • Guía de instalación Prometheus y Grafana para un Validador
    • 🎓Desarrollo
      • Fundamentos en Gnu/Linux
      • Fundamentos en Blockchain
      • Billeteras
      • Introducción a Cosmos Hub
      • Guia de Inicio en Rust
      • Clases de CosmWasm
        • Introducción a CosmWasm
        • Puntos de entrada de un contrato vacio
        • Consultas - Query
      • Clases de Rust
        • Introducción a Rust
        • Ciclos
        • Funciones
        • Manejo de la memoria
        • Tipos de datos avanzados
        • Macros
        • Manejo de paquetes
        • Manejo de errores
      • Guia Archway
        • Instalación de requisitos
        • Configuración del proyecto
        • Solicitud de tokens Testnet
        • Mi primera app
          • Configuracion
          • Produciendo ejecutables wasm
          • Despliegue e instanciación de contratos en la cadena
          • Interactuar con su contrato
          • Construir el frontend de la dApp
        • Proyecto NFT
          • Creando un proyecto NFT
          • Despliegue del contrato de tokens
          • Acuñación y envío de tokens
          • Construye la Dapp NFT
        • Fee Grant
          • Comprendiendo los Fee grant
          • Grant asignación
          • Utilizando asignaciones grant
        • Multifirmas
          • Archway multi firma hub
          • Navegar por la interfaz multi firmas
      • Cosmwasm Documentacion
        • Introducción
        • Primeros pasos
          • Introducción
          • Configuración del entorno
          • Elaborar un contrato
          • Test Unitarios
          • Despliegue e interacción
          • Integración con contratos inteligentes
          • Próximos pasos
        • Arquitectura
          • ¿Qué son los contratos multicadena?
          • Modelo de actor para las convocatorias de contratos
          • Nombres y direcciones
          • Consulta del estado del contrato
          • Formatos de serialización
          • Composición del contrato
          • Comparación con los contratos de solidity
        • Contratos inteligentes
          • Semántica contractual
          • Message
            • Messages
            • Submensajes
          • State
            • Simple state
            • Complex state y maps
          • Result y option
          • Entry points
          • Query
          • Events
          • Math
          • Verificación de contratos inteligentes
          • Migration
          • Migrar una dapp a una red diferente
          • Testing
          • Ejecución Sudo
          • CosmWasm y CIB
        • Tutoriales
          • Opcion simple
            • Testing
          • Storage
            • ¿Cómo funciona el almacenamiento de valores clave?
            • Índices
            • Modelización avanzada de estados
          • Cosmwasm con ejemplos
            • Operaciones matemáticas de Cosmowasm
            • Crear una instancia de un contrato CosmWasm
            • Timelock
            • Contrato Crowdfunding
            • Respuestas y atributos en Cosmwasm
            • Lee y escribe
            • Envío de tokens
            • Token Vaults
            • Creador de mercado automático de productos constantes (AMM)
      • Guia Celestia
        • Descripcion general de celestia
          • Introduccion
          • Blockchains monolíticos vs modulares
          • Capa de disponibilidad de datos
            • La capa de disponibilidad de datos de Celestia
            • El ciclo de vida de una transacción celestia-app
            • Recuperabilidad de datos y poda
            • Disponibilidad de datos FAQ
          • Recursos adicionales
            • Aprende modular
            • Glosario de Celestia
            • Especificaciones de aplicación de celestes
            • Documentación API de nodo celestial
        • Ejecutar un nodo
          • Descripción general de los nodos en ejecución en Celestia
          • Guía de inicio rápido
            • Decidir qué nodo ejecutar
            • Entorno de desarrollo
            • Instalar celestia-node
            • Instalar celestia-app
            • 🐳 Configuración de Docker
          • Redes
            • Resumen de redes
            • Mainnet Beta
            • Mocha testnet
            • Arábica devnet
          • Tipos de nodos
            • Disponibilidad de datos
              • Nodo ligero
              • Nodo completo
              • Nodo puente
            • Consenso
            • Relay de IBC
              • Guía de retransmisión IBC
              • Relays de IBC
          • Recursos
            • nodo-celestia
              • Metricas
              • guía config.toml
              • Redes y valores personalizados
              • Solución de problemas
            • celestia-app
              • Especificaciones
              • Métricas, visualización y alertas
              • Mecánica de corte
              • Crear un testnet Celestia
              • Comandos CLI útiles
              • Monitor de Actualización
              • Carteras en celestia-app
              • Multisig
              • Crea una cuenta de adquisición
            • SystemD
            • Proceso de hardfork
        • Desarrolladores
          • Construir modular
          • Envío de blobs de datos a Celestia
          • Directrices de reenvío de transacciones
          • API de nodo
            • Celestia-node RPC CLI tutorial
            • Documentación de la API RPC de Celestia-Node
            • Rápido Scavenger
            • Page
          • Integrar con Blobstream
            • Descripción general de Blobstream
            • Integrarse con contratos de Blobstream
            • Integrar con el cliente Blobstream
            • Consultando las pruebas de Blobstream
            • Operadores locales de Blobstream X
              • Solicitar rangos de compromiso de datos
              • Nuevas implementaciones de Blobstream X
          • Implementar un rollup
            • L2s Ethereum
              • Ethereum fallback
              • Arbitro
                • Introducción a los rollups de Arbitrum con Celestia como DA
                • Implementar un arbitrum rollup devnet
                • Testnet de nitrógeno
                • Implementar un contrato inteligente sobre la implementación de Arbitrum
                • Implemente un dapp en su devnet Arbitrum rollup
                • Optimismo
                  • Introducción a la integración de OP Stack
                  • Bubs testnet
                  • Implemente un contrato inteligente en Bubs testnet
                  • Implemente un dapp en Bubs testnet
                  • Implemente un devnet OP Stack
                  • Implemente un devnet OP Stack en Celestia
                  • Auditoría
                  • Implemente un dapp con thirdweb
                  • Rollups-as-a-Servicio
                    • Caldera
            • Rollkit
            • Astria
              • Documentación
              • Implementar a Dusknet
            • SDK Soberano
            • Vistara
            • Dimensión
          • Carteras
            • Crea una billetera con celestia-node
            • Integraciones de billeteras con Celestia
          • Integre Celestia para proveedores de servicios
      • Unión
        • Arquitectura
          • CometBLS
          • Galois
          • Voyager
        • Conceptos
          • BLS Firmas
          • Clientes de Luz Condicional
          • Verificación de Consenso
          • Tecnología de validador distribuido
          • IBC
          • Sin permiso versus sin confianza
        • Infraestructura
          • Operador de nodo
            • Empezando
            • Docker Compose
            • Kubernetes
            • NixOS
            • Configuración del Nodo
        • Integracion
          • IBC Enabled Solidity
        • Demostrar
          • Dirigiendo el Union Devnet
          • PingPong
        • Unirse al testnet
          • Empezando
          • Ejecutar el binario cliente
          • Ejecución de Unionvisor
          • Obteniendo Tokens Testnet
          • Crear un Validador
          • Endpoints publicos
          • Sincronización de estado
          • Liberar un validador
          • Preguntas frecuentes
          • Historial de actualizaciones
        • Guia de estilo
          • Lista de palabras
      • Avail
        • Introducción a Avail
          • Aprovechar DA
          • Aprovechar Nexus
          • Aprovechar la fusión
        • Informacion de red
        • Más información sobre disponibilidad
          • El conseso
            • BABE
            • GRANDPA
            • NPoS
          • EIP-4844 y disponible
        • Guia de nuevo usuario
          • Cómo crear y administrar una cuenta disponible
          • Cómo utilizar el Explorador Goldberg Testnet
          • Cómo utilizar el faucet Testnet
          • Cómo establecer una identidad en cadena
          • Cómo generar una identificación de aplicación disponible
          • Cómo realizar transferencias de saldo disponibles
          • Cómo crear grupos de nominaciones disponibles
        • Construir con disponibilidad
          • Cree un paquete acumulativo con Avail
          • Comience con Avail
          • Optimium
            • OP Stack
            • Aprovechando la pila OP con Avail
            • Cómo utilizar la pila OP con Avail
            • Adaptador de pila OP 🔗
          • Validium
            • Polygon zkEVM
              • Construyendo sobre Polygon zkEVM con Avail
              • Cómo utilizar Polygon zkEVM con Avail
              • Nodo Validium 🔗
              • Contratos de Validium 🔗
              • Puente Validium 🔗
            • Madara Starknet
              • Construyendo sobre Madara Stack con Avail
              • Cómo utilizar Madara con Avail
              • Madara Starknet🔗
            • Referencia
          • Sovereign Rollups
            • Sovereign SDK 🔗
            • Rollkit 🔗
            • OpEVM 🔗
        • Glosario
        • Preguntas generales frecuentes
      • Dymension
        • Aprender
          • ELI5
          • RollApps
            • RollApps
            • Tokens
            • Gobernancia
            • Puente
            • En profundidad
              • Dymension RDK
                • Dymint
              • Gobernanza
                • Gobernador
                  • Descripción general
                  • Crear gobernador
                  • Otros comandos
                • Votación
                  • Parámetros ajustables
                  • Gasto comunitario
                  • Registro de tokens ERC-20
              • IBC Puente
                • Visión general
                • Seguridad
                • Retransmisores
          • Dymension
            • Visión general
            • DYM
              • Supply
              • Demanda
              • Crecimiento
              • Distribución
            • Seguridad
              • Estándares
              • Actualizable
              • Disponibilidad de datos
              • Pruebas de fraude
              • Resistencia a la censura
              • Page 1
            • Puentes
              • IBC
              • eIBC
            • Liquidez
              • Descripción general
              • Depositar tokens
              • Vinculación de tokens LP
              • Incentivos
              • Comisiones
            • Gobernanza
              • Descripción general
              • Preparando una propuesta
              • Proponiendo a la dimocracia
        • Construir
          • Descripción general
          • Testnet
            • EVM
              • Descripción general
            • CosmWasm
              • Descripción general
              • Información
              • Ejemplo de cosmoWasm
          • Roller CLI
            • Descripción general
            • Comenzar
              • Instalar
              • Inicializar RollApp
              • Registro
              • Correr
                • Simple
                • Avanzado
                  • Cliente ligero DA
                  • Secuenciador
                  • Retransmisor
            • Nodo en ejecución
              • Ejecutando en producción
              • Supervisión
              • Información de RollApp
              • Exportar claves
              • Mejora
              • Editar la configuración de RollApp
              • Sincronización de estado
            • Solución de problemas
              • Descripción general
              • Saldos
              • Hardware
              • Rollapp de importación/exportación
              • Acceso externo
              • Estado
              • Archivos de registro
            • RollApp local
              • Ejecute la aplicación EVM RollApp
              • Ejecute la aplicación CosmWasm RollApp
        • Validar
          • Preguntas frecuentes sobre nodos
          • Construir dimensión
          • Configuración de nodo
          • Únase a una red
          • Nodo de sincronización
          • Validador
          • Actualizaciones
          • Solución de problemas
          • Programa de delegación
            • objetivos del programa
            • Parámetros de evaluación
            • Solicitud
      • Movement
        • Desarrolladores
          • Inicio rápido
          • Configuración
            • Usando contenedores
            • Usando el instalador
          • Tutoriales
            • Desplegar
              • Módulo Aptos
              • Módulo Sui
              • Contratos EVM
                • Implementación de contratos de solidez en movimiento utilizando Foundry y Fractal
                • Implementación de contratos de solidez en M1 usando Hardhat y Fractal
                • Implementación de contratos inteligentes de Solidity en M1 utilizando el tiempo de ejecución Fractal
            • Ejecute MoveVM
              • Ejecutando M1 usted mismo
            • Construir dApp
              • Aptos Move dApp
              • Aplicación Sui Move
              • DApp de solidity
            • Interoperar
              • AptosVM<>MEVM
          • Herramientas de desarrollo
            • Movement CLI
              • Movement aptos
                • cuenta
                  • crear
                  • crear-cuenta-de-recursos
                    • derivar-dirección-de-cuenta-de-recursos
                  • fondo-con-grifo
                  • lista
                  • dirección de búsqueda
                  • rotar llave
                  • transferir
                • configuración
                  • generar-compleciones-de-shell
                  • configurar-global-config
                  • show-global-config
                  • mostrar-perfiles
                • génesis
                  • generar-admin-escritura-conjunto
                  • generar-génesis
                  • obtener direcciones de grupo
                  • generar-claves
                  • generar-plantilla-de-diseño
                  • configuración-git
                  • configuración-del-validador-de-conjuntos
                • gobernancia
                  • proponer
                  • votar
                  • propuesta de show
                  • lista-propuestas
                  • verificar-propuesta
                  • ejecutar propuesta
                  • generar-propuesta-de-actualización
                  • aprobar-ejecución-hash
                • información
                • init
                • llave
                  • generar
                  • extraer-peer
                • mover
                  • construir-publicar-carga útil
                  • limpio
                  • compilar
                  • script de compilación
                  • cobertura
                    • resumen
                    • fuente
                    • código de bytes
                  • crear-cuenta-de-recursos-y-publicar-paquete
                  • desmontar
                  • documento
                  • descargar
                  • init
                  • list
                  • probar
                  • publicar
                  • correr
                  • ejecutar guión
                  • prueba
                  • prueba transaccional
                  • verificar-paquete
                  • vista
                • multifirma
                  • aprobar
                  • crear
                  • crear-transacción
                  • ejecutar
                  • ejecutar-rechazar
                  • ejecutar con carga útil
                  • rechazar
                  • verificar-propuesta
                • nodo
                  • analizar-validador-rendimiento
                  • arranque-db
                  • verificar-conectividad-de-red
                  • conseguir-participación-pool
                  • inicializar-validador
                  • conjunto de validadores de unión
                  • conjunto de validadores de licencia
                  • mostrar-información-de-época
                  • mostrar-validador-config
                  • mostrar-conjunto-validador
                  • mostrar-validador-participación
                  • ejecutar-testnet-local
                  • actualización-clave-de-consenso
                  • actualizar-validador-direcciones-de-red
                • apostar
                  • agregar apuesta
                  • crear-contrato-de-participación
                  • distribuir-monedas-adquiridas
                  • aumentar-bloqueo
                  • inicializar-propietario de la participación
                  • solicitud-comisión
                  • establecer-votante-delegado
                  • operador de conjunto
                  • desbloquear-apuesta
                  • desbloquear-monedas-adquiridas
                  • retirar-apuesta
                • actualizar
              • movement sui
                • comenzar
                • génesis
                • ceremonia-genesis
                  • init
                  • estado de validación
                  • agregar-validador
                  • validadores de lista
                  • punto de control de compilación sin firmar
                  • examinar-punto-de-control-génesis
                  • verificar y firmar
                  • finalizar
                • herramienta clave
                  • convertir
                  • decodificar-tx-bytes
                  • decodificar-multi-sig
                  • generar
                  • importar
                  • lista
                  • par de claves de carga
                  • dirección multifirma
                  • multi-sig-combinar-sig-parcial
                  • herencia-sig-parcial-combinada-multi-sig
                  • espectáculo
                  • firmar
                  • señal-kms
                  • deshacer
                  • zk-login-firmar-y-ejecutar-tx
                  • zk-login-ingresar-token
                  • zk-login-sig-verificar
                  • zk-login-signo-inseguro-mensaje-personal
                • consola
                • cliente
                  • dirección activa
                  • entorno-activo
                  • direcciones
                  • llamar
                  • identificador de cadena
                  • campo dinámico
                  • env
                  • ejecutar-tx firmado
                  • gas
                  • fusionar moneda
                  • nueva direccion
                  • nuevo-ambiente
                  • objeto
                  • objetos
                  • pagar
                  • pago todo-sui
                  • pay-sui
                  • publicar
                  • moneda dividida
                  • cambiar
                  • bloque tx
                  • transferir
                  • transferencia-sui
                  • mejora
                  • verificar-bytecode-metro
                  • verificar-fuente
                  • transacción-repetición
                  • lote de repetición
                  • punto de control de repetición
                • validador
                  • hacer-información-validador
                  • convertirse en candidato
                  • comité conjunto
                  • comité de licencia
                  • metadatos de visualización
                  • actualizar-metadatos
                    • nombre
                    • descripción
                    • URL de la imagen
                    • URL del proyecto
                    • dirección de red
                    • dirección primaria
                    • dirección-trabajador
                    • dirección-p2p
                    • clave-pub-de-red
                    • clave-pub-trabajador
                    • protocolo-pub-clave
                  • actualizar-precio-de-gas
                  • validador de informes
                  • serializar-carga útil-pop
                  • mostrar-actualización-del-precio-del-gas-raw-txn
                • move
                  • construir
                  • cobertura
                    • resumen
                    • fuente
                    • código de bytes
                  • desmontar
                  • nuevo
                  • probar
                  • prueba
                • simulacro de incendio
                  • rotación de metadatos
              • movement ctl
              • movement manage
            • fractales
              • marco evm
          • Desarrolladores Aptos
            • Configurar la CLI de Aptos
            • Usando la CLI de Aptos
          • Desarrolladores Sui
            • Configurar Sui CLI
            • Usando Sui CLI
          • Preguntas más frecuentes
        • Ecosistema
          • Wallets
          • Tokens
          • Faucet
          • Move idioma
            • Módulos y scripts
            • Tipos primitivos
              • Enteros
              • booleano
              • DIRECCIÓN
              • Vector
              • Firmante
              • Referencias
              • Tuplas y unidad
          • Recursos de aprendizaje
          • Techpedia
            • Paralelización
            • Mover recursos
            • SDK de movement
      • Initia
        • ACERCA DE
          • Bienvenido a Inicia
          • Arquitectura Omnitia
            • Inicia (Capa 1)
            • Minitia (Capa 2)
          • Ciclo de vida de la transacción
          • Liquidez y apuestas consagradas
            • IniciaDEX
          • Programa de intereses adquiridos
        • CONSTRUIR SOBRE LA INICIATIVA
          • iniciado
          • inicia.js
          • Creando cuenta
          • Tutoriales específicos de VM
            • MoverVM
              • Implementación de módulos de movimiento
              • Creando moneda de movimiento
              • Envío de moneda de movimiento
              • Creando movimiento NFT
              • Módulos relacionados con el replanteo
              • Interactuar con Oracle en MoveVM
              • Mover ganchos IBC
            • WASMVM
              • Implementación del contrato CosmWasm
              • Interactuando con Oracle en WasmVM
              • Ganchos Wasm IBC
              • Fábrica de fichas
            • EVM
              • Implementación del contrato de solidez
              • Crear un token ERC-20 personalizado
              • Consultar estados del cosmos
              • Ejecutando mensajes de Cosmos
              • Conversión de direcciones entre EVM y Cosmos
              • Conversión entre direcciones Denom y ERC-20
              • Interactuar con Oracle en EVM
              • Ganchos EVM IBC
              • Ethereum JSON-RPC
          • Tutoriales generales
            • Oráculo: Furtivo
            • Mensajes entre cadenas
            • Saltar API
            • Miniswap
              • Interactuando con Minitswap
            • Conversión entre nombres de usuario y direcciones
            • Usando el Explorador local de Initia
            • Interactuando con InitiaDEX
            • Usando el widget de billetera Initia
        • IMPLEMENTAR MINITIA
          • Empezando
            • Implementación de su propia Minitia (Capa 2)
          • Configuración
          • Implementación de una Minitia independiente
          • Implementación completa de Minitia
            • Dirigiendo la Minitia
            • Pila de OPinit
              • Módulo OPinit: OPhost y OPchild
              • Configurar robots OPinit
                • Ejecutor del puente
                • Remitente de salida
                • Desafiador
                • Envío por lotes
                  • Envío de lotes a Inicia L1
                  • Envío de lotes a Celestia
            • Relé Hermes (IBC)
            • Habilitando oráculos
          • Retroceder
          • Agregar tokens a Initia Wallet
          • Personalizando Minitia
        • EJECUTAR EL NODO DE INICIO
          • Ejecutando el nodo de inicio
          • Arrancar un nodo de inicio
          • Conéctese a la red Inicial
          • Oráculo
          • Automatización de actualizaciones de software con Cosmovisor
          • Convertirse en un validador
        • RECURSOS
          • Registro de Iniciación
          • Información de la cadena Testnet
          • Parámetros de cadena
          • Documentación de la API
          • Documentos API (MiniMove)
          • Documentos API (MiniWasm)
          • Documentos API (MiniEVM)
      • Internet Computer
        • ¡Hola, mundo!
        • Descripción general del ICP
Powered by GitBook
On this page
  • Establecer un contrato para las migraciones
  • Crear un contrato mutable
  • Ejecutar una operación de migración
  • Hacer un contrato inmutable
  1. Recursos
  2. Desarrollo
  3. Cosmwasm Documentacion
  4. Contratos inteligentes

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:

const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME");
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(deps: DepsMut, env: Env, info: MessageInfo, msg: InstantiateMsg) -> Response {
    // Use CW2 to set the contract version, this is needed for migrations
    set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
}

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:

use semver::Version;
// Migrate contract if version is lower than current version
#[entry_point]
pub fn migrate(deps: DepsMut, _env: Env, _msg: Empty) -> Result<Response, ContractError> {
    let version: Version = CONTRACT_VERSION.parse()?;
    let storage_version: Version = get_contract_version(deps.storage)?.version.parse()?;
    if storage_version < version {
        set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
        // If state structure changed in any contract version in the way migration is needed, it
        // should occur here
    }
    Ok(Response::new())
}

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:

#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)]
pub struct ContractVersion {
    /// contract is a globally unique identifier for the contract.
    /// it should build off standard namespacing for whichever language it is in,
    /// and prefix it with the registry we use.
    /// For rust we prefix with `crates.io:`, to give us eg. `crates.io:cw20-base`
    pub contract: String,
    /// version is any string that this implementation knows. It may be simple counter "1", "2".
    /// or semantic version on release tags "v0.7.0", or some custom feature flag list.
    /// the only code that needs to understand the version parsing is code that knows how to
    /// migrate from the given contract (and is tied to it's implementation somehow)
    pub version: String,
}

Así, un ejemplo serializado puede ser el siguiente:

{
    "contract": "crates.io:cw20-base",
    "version": "v0.1.0"
}

Establecer un contrato para las migraciones

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:

use cosmwasm_std::{
    Empty, Env, DepsMut, Response,
};
use crate::error::ContractError;
use cosmwasm_std::entry_point;
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(deps: DepsMut, _env: Env, _msg: Empty) -> Result<Response, ContractError> {
}

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.

use cosmwasm_std::{ Env, DepsMut, Response };
use crate::error::ContractError;
use crate::msg::{ MigrateMsg };
use cosmwasm_std::entry_point;
const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME");
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
#[entry_point]
pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result<Response, ContractError> {
    // No state migrations performed, just returned a Response
    Ok(Response::default())
}

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

const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME");
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
#[entry_point]
pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result<Response, ContractError> {
    let ver = cw2::get_contract_version(deps.storage)?;
    // ensure we are migrating from a compatible contract
    if ver.contract != CONTRACT_NAME {
        return Err(StdError::generic_err("Can only upgrade from same contract type").into());
    }
    // note: it's better to do a proper semver comparison, but a string comparison *usually* works
    #[allow(clippy::cmp_owned)]
    if ver.version >= CONTRACT_VERSION {
        return Err(StdError::generic_err("Cannot upgrade from a newer contract version").into());
    }
    // set the new version
    cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
    // do any required state migrations...
    Ok(Response::default())
}

Migrar usando comparación semver

Esta migración utiliza Semver en lugar de una comparación String.

const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME");
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
#[entry_point]
pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result<Response, ContractError> {
    let version: Version = CONTRACT_VERSION.parse()?;
    let storage_version: Version = get_contract_version(deps.storage)?.version.parse()?;
    if storage_version < version {
        set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
        // If state structure changed in any contract version in the way migration is needed, it
        // should occur here
    }
    Ok(Response::default())
}

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:

[dependencies]
semver = "1"

También puede implementar errores personalizados Semver:

#[derive(Error, Debug, PartialEq)]
pub enum ContractError {
    #[error("Semver parsing error: {0}")]
    SemVer(String),
}
impl From<semver::Error> for ContractError {
    fn from(err: semver::Error) -> Self {
        Self::SemVer(err.to_string())
    }
}

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.

#[entry_point]
pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result<Response, HackError> {
    let data = deps
        .storage
        .get(CONFIG_KEY)
        .ok_or_else(|| StdError::not_found("State"))?;
    let mut config: State = from_slice(&data)?;
    config.verifier = deps.api.addr_validate(&msg.verifier)?;
    deps.storage.set(CONFIG_KEY, &to_vec(&config)?);
    Ok(Response::default())
}

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í:

#[entry_point]
pub fn migrate(deps: DepsMut, env: Env, msg: MigrateMsg) -> StdResult<Response> {
    // delete all state
    let keys: Vec<_> = deps
        .storage
        .range(None, None, Order::Ascending)
        .map(|(k, _)| k)
        .collect();
    let count = keys.len();
    for k in keys {
        deps.storage.remove(&k);
    }
    // get balance and send all to recipient
    let balance = deps.querier.query_all_balances(env.contract.address)?;
    let send = BankMsg::Send {
        to_address: msg.payout.clone(),
        amount: balance,
    };
    let data_msg = format!("burnt {} keys", count).into_bytes();
    Ok(Response::new()
        .add_message(send)
        .add_attribute("action", "burn")
        .add_attribute("payout", msg.payout)
        .set_data(data_msg))
}

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.

archway instantiate --admin-address [value]  -a [arg value]

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.

archwayd tx wasm instantiate [code_id] [json_encoded_init_args] --label [label_text] --admin [admin_address] --amount [coins] --from [wallet] --chain-id "archway-1" --node "https://rpc.mainnet.archway.io:443" --broadcast-mode sync --output json -y --gas auto --gas-adjustment 1.4 --gas-prices $(archwayd q rewards estimate-fees 1 --node 'https://rpc.mainnet.archway.io:443' --output json | jq -r '.gas_unit_price | (.amount + .denom)')

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:

MNEMONIC="enter mnemonic here"

El siguiente código Javascript puede almacenarse en un archivo index.js y ejecutarse ejecutando node index.js.

import { SigningArchwayClient } from '@archwayhq/arch3.js';
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
import dotenv from "dotenv";
dotenv.config();
async function main() {
  const network = {
    chainId: 'archway-1',
    endpoint: 'https://rpc.mainnet.archway.io',
    prefix: 'archway',
  };
  // Get wallet and accounts from mnemonic
  const mnemonic = process.env.MNEMONIC;
  const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { prefix: network.prefix });
  const accounts = await wallet.getAccounts();
  const accountAddress = accounts[0].address;
  const signingClient = await SigningArchwayClient.connectWithSigner(network.endpoint, wallet);
  // Instantiate a contract
  const codeId = 1; // Update with your stored contract code id
  // Add the message values required
  const msg = {
    
  };
  const instantiateOptions = {
    memo: "Instantiating a new contract",
    admin: accountAddress // This sets the admin address to the address of the signer
  };
  const contractLabel = "my-instance-label";
  const instantiateResult = await signingClient.instantiate(
    accountAddress,
    codeId,
    msg,
    contractLabel,
    'auto',
    instantiateOptions
  );
  if (instantiateResult.code !== undefined && instantiateResult.code !== 0) {
    console.log("Instantiation failed:", instantiateResult.log || instantiateResult.rawLog);
  } else {
    console.log("Instantiation successful:", instantiateResult.transactionHash);
  }
}
main();

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

archwayd tx wasm migrate [contract_address] [new_code_id] [json_encoded_migration_args] --from [wallet] --chain-id "archway-1" --node "https://rpc.mainnet.archway.io:443" --broadcast-mode sync --output json -y --gas auto --gas-adjustment 1.4 --gas-prices $(archwayd q rewards estimate-fees 1 --node 'https://rpc.mainnet.archway.io:443' --output json | jq -r '.gas_unit_price | (.amount + .denom)')

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:

MNEMONIC="enter mnemonic here"

El siguiente código Javascript puede almacenarse en un archivo index.js y ejecutarse ejecutando node index.js.

import { SigningArchwayClient } from '@archwayhq/arch3.js';
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
import dotenv from "dotenv";
dotenv.config();
async function main() {
  const network = {
    chainId: 'archway-1',
    endpoint: 'https://rpc.mainnet.archway.io',
    prefix: 'archway',
  };
  // Get wallet and accounts from mnemonic
  const mnemonic = process.env.MNEMONIC;
  const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { prefix: network.prefix });
  const accounts = await wallet.getAccounts();
  const accountAddress = accounts[0].address;
  const signingClient = await SigningArchwayClient.connectWithSigner(network.endpoint, wallet);
  const codeId = 1; // Update with your stored contract code id
  const contractAddress = ""; // Enter contract address
  const memo = "Migrating contract";
  // Add the message values required
  const migrateMsg = {
    
  };
  const instantiateResult = await signingClient.migrate(
    accountAddress,
    contractAddress,
    codeId,
    migrateMsg,
    'auto',
    memo
  );
  if (result.code !== undefined && result.code !== 0) {
    console.log("Migration failed:", result.log || result.rawLog);
  } else {
    console.log("Migration successful:", result.transactionHash);
  }
}
main();

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

archwayd tx wasm set-contract-admin [contract_address] [new_admin_address] --from [wallet] --chain-id "archway-1" --node "https://rpc.mainnet.archway.io:443" --broadcast-mode sync --output json -y --gas auto --gas-adjustment 1.4 --gas-prices $(archwayd q rewards estimate-fees 1 --node 'https://rpc.mainnet.archway.io:443' --output json | jq -r '.gas_unit_price | (.amount + .denom)')

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:

MNEMONIC="enter mnemonic here"

El siguiente código Javascript puede almacenarse en un archivo index.js y ejecutarse ejecutando node index.js.

import { SigningArchwayClient } from '@archwayhq/arch3.js';
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
import dotenv from "dotenv";
dotenv.config();
async function main() {
  const network = {
    chainId: 'archway-1',
    endpoint: 'https://rpc.mainnet.archway.io',
    prefix: 'archway',
  };
  // Get wallet and accounts from mnemonic
  const mnemonic = process.env.MNEMONIC;
  const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { prefix: network.prefix });
  const accounts = await wallet.getAccounts();
  const accountAddress = accounts[0].address;
  const signingClient = await SigningArchwayClient.connectWithSigner(network.endpoint, wallet);
  // Instantiate a contract
  const codeId = 1; // Update with your stored contract code id
  // Add the message values required
  const msg = {
    
  };
  const instantiateOptions = {
    memo: "Instantiating a new contract",
    admin: accountAddress // This sets the admin address to the address of the signer
  };
  const contractLabel = "my-instance-label";
  const instantiateResult = await signingClient.instantiate(
    accountAddress,
    codeId,
    msg,
    contractLabel,
    'auto',
    instantiateOptions
  );
  if (instantiateResult.code !== undefined && instantiateResult.code !== 0) {
    console.log("Instantiation failed:", instantiateResult.log || instantiateResult.rawLog);
  } else {
    console.log("Instantiation successful:", instantiateResult.transactionHash);
  }
}
main();

PreviousVerificación de contratos inteligentesNextMigrar una dapp a una red diferente

Last updated 1 year ago

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 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.

👽
🎓
MsgMigrateContract