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
  • Explicaci贸n
  • Ejemplo
  1. Recursos
  2. Desarrollo
  3. Cosmwasm Documentacion
  4. Tutoriales
  5. Cosmwasm con ejemplos

Contrato Crowdfunding

Explicaci贸n

Este contrato de Crowdfunding permite a los usuarios financiar proyectos, pero s贸lo si alcanzan sus objetivos de financiaci贸n en un plazo determinado. Si se alcanza el objetivo, se puede invocar un mensaje de ejecuci贸n. Si no se alcanza, el contrato permitir谩 autom谩ticamente que cualquiera pueda reclamar sus fondos y/o reembolsar a otros.

Crear una instancia

Owner: La persona que crea el contrato debe ser el propietario.

Denom: especifica el tipo de tokens utilizados para la financiaci贸n.

Goal: establece el objetivo de financiaci贸n en tokens.

Start: Determina cu谩ndo comienza el per铆odo de financiaci贸n (puede ser inmediato o futuro).

Deadline: Especifica cu谩ndo se debe cumplir la meta de financiamiento (dentro de los 60 d铆as a partir de ahora, en el futuro).

Name: El nombre del proyecto (menos de 32 caracteres).

Description: Una breve descripci贸n del proyecto (menos de 256 caracteres).

Consultas

get_config: devuelve detalles del proyecto como objetivo, fecha l铆mite, nombre y descripci贸n.

get_shares: muestra las acciones de un usuario en el proyecto.

get_funders: proporciona una lista de todos los financiadores y sus acciones.

get_funds: revela el total de fondos recaudados hasta el momento.

Comportamiento

fund: permite a los usuarios contribuir con tokens al proyecto (el proyecto debe iniciarse, no cerrarse y los tokens deben ser v谩lidos).

execute: ejecuta el proyecto si se alcanza el objetivo de financiaci贸n (el proyecto debe estar cerrado y totalmente financiado).

refund: Reembolsa a los contribuyentes si no se cumple el objetivo de financiaci贸n (el proyecto debe estar cerrado y parcialmente financiado).

claim: Permite reclamar fondos del proyecto si se alcanza la meta (el proyecto debe estar cerrado y parcialmente financiado).

Estado

config: Almacena la configuraci贸n del proyecto.

shares: realiza un seguimiento de los recursos compartidos de todos los usuarios en el proyecto.

total_shares: muestra el total de tokens recaudados.

execute_msg: Contiene el mensaje que se ejecutar谩 si se logra el objetivo de financiaci贸n.

Ejemplo

Para crear un contrato de financiaci贸n colectiva con CosmWasm, puede crear los siguientes archivos: lib.rs contract.rs msg.rs error.rs state.rs helpers.rs reglas.rs

lib.rs

pub mod contract;
mod error;
pub mod helpers;
pub mod msg;
pub mod rules;
pub mod state;
pub use crate::error::ContractError;

contract.rs

#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128, StdError, CosmosMsg, Empty, Order, BankMsg, coins, Addr, coin};
use cw2::set_contract_version;
use cw_storage_plus::Bound;
use crate::error::ContractError;
use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg, QueryResponseWrapper, GetConfigResponse, GetSharesResponse, GetFundersResponse, GetTotalFundsResponse};
use crate::state::{Config,CONFIG,SHARES,TOTAL_SHARES,EXECUTE_MSG};
use crate::rules;
const CONTRACT_NAME: &str = "crates.io:crowdfunding";
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,
) -> Result<Response, ContractError> {
    set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
    let config = Config {
        owner: env.contract.address,
        denom: msg.denom,
        goal: msg.goal,
        start: msg.start.unwrap_or(env.block.time),
        deadline: msg.deadline,
        name: msg.name,
        description: msg.description,
    };
    config.validate()?;
    CONFIG.save(deps.storage, &config)?;
    TOTAL_SHARES.save(deps.storage, &Uint128::zero())?;
    EXECUTE_MSG.save(deps.storage, &msg.execute_msg)?;
    Ok(Response::new()
        .add_attribute("action", "instantiate")
        .add_attribute("name", config.name))
}
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
    deps: DepsMut,
    env: Env,
    info: MessageInfo,
    msg: ExecuteMsg,
) -> Result<Response, ContractError> {
    use ExecuteMsg::*;
    match msg {
        Fund {} => {
            rules::HAS_STARTED(&deps, &env, &info)?;
            rules::NOT_CLOSED(&deps, &env, &info)?;
            rules::SENT_FUNDS(&deps, &env, &info)?;
            try_fund(deps, env, info)
        }
        Execute {} => {
            rules::IS_CLOSED(&deps, &env, &info)?;
            rules::FULLY_FUNDED(&deps, &env, &info)?;
            try_execute(deps, env, info)
        }
        Claim {} => {
            rules::IS_CLOSED(&deps, &env, &info)?;
            rules::NOT_FULLY_FUNDED(&deps, &env, &info)?;
            try_claim(deps, env, info)
        }
        Refund {} => {
            rules::IS_CLOSED(&deps, &env, &info)?;
            rules::NOT_FULLY_FUNDED(&deps, &env, &info)?;
            try_refund(deps, env, info)
        }
    }
}
pub fn try_fund(deps: DepsMut, _env: Env, info: MessageInfo) -> Result<Response, ContractError> {
    let config = CONFIG.load(deps.storage)?;
    let sent_funds = info
        .funds
        .iter()
        .find_map(|v| {
            if v.denom == config.denom {
                Some(v.amount)
            } else {
                None
            }
        })
        .unwrap_or_else(Uint128::zero);
        SHARES
        .update::<_, StdError>(deps.storage, info.sender, |shares| {
            let mut shares = shares.unwrap_or_default();
            shares += sent_funds;
            Ok(shares)
        })?;
    
        TOTAL_SHARES
        .update::<_, StdError>(deps.storage, |total_shares| {
            let mut total_shares = total_shares;
            total_shares += sent_funds;
            Ok(total_shares)
        })?;
    Ok(Response::new())
}
pub fn try_execute(deps: DepsMut, _env: Env, _info: MessageInfo) -> Result<Response, ContractError> {
    let execute_msg = EXECUTE_MSG
        .load(deps.storage)?
        .ok_or_else(|| StdError::generic_err("execute_msg not set".to_string()))?;
    // execute can only run once ever.
    EXECUTE_MSG.save(deps.storage, &None)?;
    Ok(Response::new().add_message(execute_msg))
}
pub fn try_refund(deps: DepsMut, env: Env, _info: MessageInfo) -> Result<Response, ContractError> {
    let config = CONFIG.load(deps.storage)?;
    let contract_balance = deps
        .querier
        .query_balance(env.contract.address, config.denom.clone())?
        .amount;
    let total_shares = TOTAL_SHARES.load(deps.storage)?;
    let user_shares = SHARES
        .range(deps.storage, None, None, Order::Ascending)
        // batch execute 30 transfers at a time
        .take(30)
        .collect::<Result<Vec<_>, _>>()?;
    let mut next_shares = total_shares;
    let msgs: Vec<CosmosMsg> = vec![];
    for (addr, shares) in user_shares {
        let refund_amount = contract_balance.multiply_ratio(shares, total_shares);
        let _bank_transfer_msg = CosmosMsg::<Empty>::Bank(BankMsg::Send {
            to_address: addr.to_string(),
            amount: coins(refund_amount.u128(), config.denom.clone()),
        });
        SHARES.remove(deps.storage, addr);
        next_shares -= shares;
    }
    TOTAL_SHARES.save(deps.storage, &next_shares)?;
    Ok(Response::new().add_messages(msgs))
}
pub fn try_claim(deps: DepsMut, env: Env, info: MessageInfo) -> Result<Response, ContractError> {
    let config = CONFIG.load(deps.storage)?;
    let contract_balance = deps
        .querier
        .query_balance(env.contract.address, config.denom.clone())?
        .amount;
    let total_shares = TOTAL_SHARES.load(deps.storage)?;
    let user_shares = SHARES.load(deps.storage, info.sender.clone())?;
    let mut next_total_shares = total_shares;
    let refund_amount = contract_balance.multiply_ratio(user_shares, total_shares);
    let bank_transfer_msg = CosmosMsg::<Empty>::Bank(BankMsg::Send {
        to_address: info.sender.to_string(),
        amount: coins(refund_amount.u128(), config.denom),
    });
    SHARES.remove(deps.storage, info.sender);
    next_total_shares -= user_shares;
    TOTAL_SHARES.save(deps.storage, &next_total_shares)?;
    Ok(Response::new().add_message(bank_transfer_msg))
}
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
    let output: StdResult<QueryResponseWrapper> = match msg {
        QueryMsg::GetConfig {} => get_config(deps, env),
        QueryMsg::GetShares { user } => get_shares(deps, env, user),
        QueryMsg::GetFunders { limit, start_after } => {
            get_funders(deps, env, limit, start_after)
        }
        QueryMsg::GetTotalFunds {} => get_funds(deps, env),
    };
    output?.to_binary()
}
pub fn get_config(deps: Deps, _env: Env) -> StdResult<QueryResponseWrapper> {
    let config = CONFIG.load(deps.storage)?;
    Ok(QueryResponseWrapper::GetConfigResponse(GetConfigResponse {
        goal: coin(config.goal.u128(), config.denom),
        deadline: config.deadline,
        name: config.name,
        description: config.description,
    }))
}
pub fn get_shares(deps: Deps, _env: Env, address: String) -> StdResult<QueryResponseWrapper> {
    let addr = deps.api.addr_validate(&address)?;
    let shares = SHARES.load(deps.storage, addr)?;
    Ok(QueryResponseWrapper::GetSharesResponse(GetSharesResponse {
        shares,
        address,
    }))
}
pub fn get_funders(
    deps: Deps,
    _env: Env,
    limit: Uint128,
    start_after: Option<String>,
) -> StdResult<QueryResponseWrapper> {
    let start = start_after
        .map(|s| deps.api.addr_validate(&s))
        .transpose()?
        .map(|addr| Bound::InclusiveRaw::<Addr>(addr.as_bytes().to_vec()));
    let funders = SHARES
        .range(deps.storage, start, None, Order::Ascending)
        .take(limit.u128() as usize)
        .collect::<Result<Vec<_>, _>>()?
        .iter()
        .map(|(addr, shares)| (addr.to_string(), *shares))
        .collect::<Vec<(String, Uint128)>>();
    Ok(QueryResponseWrapper::GetFundersResponse(
        GetFundersResponse { funders },
    ))
}
pub fn get_funds(deps: Deps, _env: Env) -> StdResult<QueryResponseWrapper> {
    let funds = TOTAL_SHARES.load(deps.storage)?;
    let config = CONFIG.load(deps.storage)?;
    Ok(QueryResponseWrapper::GetTotalFundsResponse(
        GetTotalFundsResponse {
            total_funds: coin(funds.u128(), config.denom),
        },
    ))
}
#[cfg(test)]
mod tests {
    use super::*;
    use cosmwasm_std::{
        testing::{mock_dependencies, mock_env, mock_info},
        coins, CosmosMsg, Empty, Uint128,
    };
    #[test]
    fn test_instantiate() {
        let mut deps = mock_dependencies();
        let  env = mock_env();
        let info = mock_info("creator", &coins(100, "earth"));
        // Instantiate the contract
        let msg = InstantiateMsg {
            denom: "earth".to_string(),
            goal: Uint128::new(100),
            start: None,
            deadline: env.block.time.plus_seconds(86400),
            name: "Crowdfunding Campaign".to_string(),
            description: "Test campaign".to_string(),
            execute_msg: Some(CosmosMsg::Custom(Empty {})),
        };
        let res=instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap();
        assert_eq!(res.messages.len(),0);
        
     }
     #[test]
     fn test_fund(){
        let mut deps = mock_dependencies();
        let mut env = mock_env();
        let info = mock_info("creator", &coins(100, "earth"));
        // Instantiate the contract
        let msg = InstantiateMsg {
            denom: "earth".to_string(),
            goal: Uint128::new(100),
            start: None,
            deadline: env.block.time.plus_seconds(86400),
            name: "Crowdfunding Campaign".to_string(),
            description: "Test campaign".to_string(),
            execute_msg: Some(CosmosMsg::Custom(Empty {})),
        };
        let res=instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap();
        assert_eq!(res.messages.len(),0);
        env.block.time = env.block.time.plus_seconds(60);
        // Execute with Fund case
        let msg = ExecuteMsg::Fund {};
        let res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap();
        assert_eq!(res.messages.len(), 0);
     }
     #[test]
     fn test_execute(){
        let mut deps = mock_dependencies();
        let mut env = mock_env();
        let info = mock_info("creator", &coins(100, "earth"));
        // Instantiate the contract
        let msg = InstantiateMsg {
            denom: "earth".to_string(),
            goal: Uint128::new(100),
            start: None,
            deadline: env.block.time.plus_seconds(86400),
            name: "Crowdfunding Campaign".to_string(),
            description: "Test campaign".to_string(),
            execute_msg: Some(CosmosMsg::Custom(Empty {})),
        };
        let res=instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap();
        assert_eq!(res.messages.len(),0);
        env.block.time = env.block.time.plus_seconds(60);
        // Execute with Fund case
        let msg = ExecuteMsg::Fund {};
        let res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap();
        assert_eq!(res.messages.len(), 0);
        // Execute with Execute case
        env.block.time = env.block.time.plus_seconds(86401);
        let msg = ExecuteMsg::Execute {};
        let res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap();
        assert_eq!(res.messages.len(), 1);
        assert_eq!(res.messages[0].msg, CosmosMsg::Custom(Empty {}));
     }
     #[test]
     fn test_refund(){
        let mut deps = mock_dependencies();
        let mut env = mock_env();
        let info = mock_info("creator", &coins(80, "earth"));
        // Instantiate the contract
        let msg = InstantiateMsg {
            denom: "earth".to_string(),
            goal: Uint128::new(100),
            start: None,
            deadline: env.block.time.plus_seconds(86400),
            name: "Crowdfunding Campaign".to_string(),
            description: "Test campaign".to_string(),
            execute_msg: Some(CosmosMsg::Custom(Empty {})),
        };
        let res=instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap();
        assert_eq!(res.messages.len(),0);
        // Execute with Fund case
        let msg = ExecuteMsg::Fund {};
        env.block.time = env.block.time.plus_seconds(60);
        let res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap();
        assert_eq!(res.messages.len(), 0);
         // Execute with Refund case
         env.block.time = env.block.time.plus_seconds(86400);
        let msg = ExecuteMsg::Refund {};
        let res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap();
        assert_eq!(res.messages.len(), 0);
     }
     #[test]
     fn test_claim()
     {
        let mut deps = mock_dependencies();
        let mut env = mock_env();
        let info = mock_info("creator", &coins(80, "earth"));
        // Instantiate the contract
        let msg = InstantiateMsg {
            denom: "earth".to_string(),
            goal: Uint128::new(100),
            start: None,
            deadline: env.block.time.plus_seconds(86400),
            name: "Crowdfunding Campaign".to_string(),
            description: "Test campaign".to_string(),
            execute_msg: Some(CosmosMsg::Custom(Empty {})),
        };
        let res=instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap();
        assert_eq!(res.messages.len(),0);
        // Execute with Fund case
        let msg = ExecuteMsg::Fund {};
        env.block.time = env.block.time.plus_seconds(60);
        let res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap();
        assert_eq!(res.messages.len(), 0);
        // Execute with Claim case
        env.block.time = env.block.time.plus_seconds(86400);
        let msg = ExecuteMsg::Claim {};
        let res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap();
        assert_eq!(res.messages.len(), 1);
        assert_eq!(
            res.messages[0].msg,
            CosmosMsg::Bank(BankMsg::Send {
                to_address: "creator".to_string(),
                amount: coins(0, "earth"),
            })
        );
     }
}

error.rs

use cosmwasm_std::StdError;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum ContractError {
    #[error("{0}")]
    Std(#[from] StdError),
    #[error("Custom Error val: {val:?}")]
    CustomError { val: String },
}

state.rs

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use cosmwasm_std::{Addr, CosmosMsg, StdError, Timestamp, Uint128};
use cw_storage_plus::{Item, Map};
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct Config {
    pub owner: Addr,
    pub denom: String,
    pub goal: Uint128,
    pub start: Timestamp,
    pub deadline: Timestamp,
    pub name: String,
    pub description: String,
}
impl Config {
    pub fn validate(&self) -> Result<(), StdError> {
        if self.goal <= Uint128::zero() {
            return Err(StdError::generic_err(
                "goal must be greater than 0".to_string(),
            ));
        }
        if self.start >= self.deadline {
            return Err(StdError::generic_err(
                "start must be before deadline".to_string(),
            ));
        }
        // description must be less than 256 characters
        if self.description.len() > 256 {
            return Err(StdError::generic_err(
                "description must be less than 256 characters".to_string(),
            ));
        }
        // title must be less than 32 characters
        if self.name.len() > 32 {
            return Err(StdError::generic_err(
                "title must be less than 32 characters".to_string(),
            ));
        }
        Ok(())
    }
}
pub const CONFIG: Item<Config> = Item::new("config");
pub const SHARES: Map<Addr,Uint128> = Map::new("shares");
pub const TOTAL_SHARES: Item<Uint128> = Item::new("total_shares");
pub const EXECUTE_MSG: Item<Option<CosmosMsg>> = Item::new("execute_msg");

helpers.rs

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use cosmwasm_std::Addr;
/// CwTemplateContract is a wrapper around Addr that provides a lot of helpers
/// for working with this. Rename it to your contract name.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct CwTemplateContract(pub Addr);
// impl CwTemplateContract {
//     pub fn addr(&self) -> Addr {
//         self.0.clone()
//     }
//     pub fn call<T: Into<ExecuteMsg>>(&self, msg: T) -> StdResult<CosmosMsg> {
//         let msg = to_binary(&msg.into())?;
//         Ok(WasmMsg::Execute {
//             contract_addr: self.addr().into(),
//             msg,
//             funds: vec![],
//         }
//         .into())
//     }
//     /// Get Custom
//     pub fn custom_query<Q, T, CQ>(&self, querier: &Q, val: String) -> StdResult<CustomResponse>
//     where
//         Q: Querier,
//         T: Into<String>,
//         CQ: CustomQuery,
//     {
//         let msg = QueryMsg::CustomMsg { val };
//         let query = WasmQuery::Smart {
//             contract_addr: self.addr().into(),
//             msg: to_binary(&msg)?,
//         }
//         .into();
//         let res: CustomResponse = QuerierWrapper::<CQ>::new(querier).query(&query)?;
//         Ok(res)
//     }
// }

rules.rs

use cosmwasm_std::{DepsMut, Env, MessageInfo, StdError, Uint128};
use crate::state::{CONFIG, TOTAL_SHARES};
type Rule =
    fn(deps: &DepsMut, env: &Env, info: &MessageInfo) -> Result<(), StdError>;
pub const HAS_STARTED: Rule = |deps, env, _info| {
    if CONFIG.load(deps.storage)?.start >= env.block.time {
        return Err(StdError::generic_err(
            "project has not started yet".to_string(),
        ));
    }
    Ok(())
};
pub const NOT_CLOSED: Rule = |deps, env, _info| {
    if CONFIG.load(deps.storage)?.deadline <= env.block.time {
        return Err(StdError::generic_err("Project is closed"));
    }
    Ok(())
};
pub const SENT_FUNDS: Rule = |deps, _env, info| {
    let denom = CONFIG.load(deps.storage)?.denom;
    if info
        .funds
        .iter()
        .find_map(|v| {
            if v.denom == denom {
                Some(v.amount)
            } else {
                None
            }
        })
        .unwrap_or_else(Uint128::zero)
        .is_zero()
    {
        return Err(StdError::generic_err("Amount must be positive"));
    }
    Ok(())
};
pub const FULLY_FUNDED: Rule = |deps, _env, _info| {
    let config = CONFIG.load(deps.storage)?;
    let goal = config.goal;
    let _denom = config.denom;
    let total_shares = TOTAL_SHARES.load(deps.storage)?;
    if total_shares < goal {
        return Err(StdError::generic_err(format!(
            "Project must be fully funded: {} < {}",
            total_shares, goal
        )));
    }
    Ok(())
};
pub const IS_CLOSED: Rule = |deps, env, _info| {
    if CONFIG.load(deps.storage)?.deadline > env.block.time {
        return Err(StdError::generic_err("Project is open"));
    }
    Ok(())
};
pub const NOT_FULLY_FUNDED: Rule = |deps, _env, _info| {
    let config = CONFIG.load(deps.storage)?;
    let goal = config.goal;
    let total_shares = TOTAL_SHARES.load(deps.storage)?;
    if total_shares >= goal {
        return Err(StdError::generic_err(format!(
            "Project must not be fully funded: {} >= {}",
            total_shares, goal
        )));
    }
    Ok(())
};
PreviousTimelockNextRespuestas y atributos en Cosmwasm

Last updated 1 year ago

馃懡
馃帗