Saltar al contenido principal

Token No Fungible

Código Fuente

Abrir en Codespaces

En el mundo de los activos digitales, no todos los tokens son iguales. Esto es importante en situaciones como bienes raíces, derechos de voto o coleccionables, donde algunos artículos tienen más valor debido a su utilidad, rareza, etc. En Stellar, puedes crear tokens no fungibles (NFTs), donde cada token es único y representa algo distinto, con la propiedad rastreada mediante contratos inteligentes Soroban.

Resumen

El módulo non-fungible ofrece tres variantes diferentes de NFT que difieren en cómo se manejan ciertas características como el seguimiento de la propiedad, la creación y destrucción de tokens:

  1. Base: Variante de contrato que implementa la lógica base para la interfaz NonFungibleToken. Adecuada para la mayoría de los casos de uso.
  2. Consecutiva: Variante de contrato para la creación optimizada de lotes de tokens. Se basa en la variante base y sobrescribe las funciones necesarias de la variante Base.
  3. Enumerada: Variante de contrato que permite enumerar los tokens on-chain. Se basa en la variante base y sobrescribe las funciones necesarias de la variante Base.

Estas tres variantes comparten funcionalidades principales y una interfaz común, exponiendo funciones idénticas del contrato como puntos de entrada. Sin embargo, la composición de flujos personalizados debe manejarse con especial cuidado. Esto es necesario debido a la naturaleza incompatible entre la lógica de negocio de las diferentes variantes de NFT o la necesidad de envolver la funcionalidad base con lógica adicional.

Ejecutar el Ejemplo

Primero realiza el proceso de Configuración para preparar tu entorno de desarrollo, luego clona el repositorio OpenZeppelin Stellar Contracts:

git clone https://github.com/OpenZeppelin/stellar-contracts

O, omite la configuración del entorno de desarrollo y abre este ejemplo en GitHub Codespaces o Code Anywhere.

Para ejecutar las pruebas del ejemplo, navega al directorio nft-sequential-minting y usa cargo test.

cd examples/nft-sequential-minting
cargo test

Código

nota

Este ejemplo demuestra cómo usar la biblioteca OpenZeppelin Stellar Contracts para crear un token no fungible. La biblioteca proporciona implementaciones desarrolladas y auditadas que siguen las prácticas recomendadas.

examples/nft-sequential-minting/src/contract.rs
use soroban_sdk::{contract, contractimpl, Address, Env, String};
use stellar_access::ownable::{self as ownable, Ownable};
use stellar_macros::{default_impl, only_owner};
use stellar_tokens::non_fungible::{
burnable::NonFungibleBurnable, Base, ContractOverrides, NonFungibleToken,
};

#[contract]
pub struct NonFungibleTokenContract;

#[contractimpl]
impl NonFungibleTokenContract {
pub fn __constructor(e: &Env, owner: Address) {
// Set token metadata
Base::set_metadata(
e,
String::from_str(e, "www.example.com"),
String::from_str(e, "My NFT Collection"),
String::from_str(e, "MNFT"),
);

// Set the contract owner
ownable::set_owner(e, &owner);
}

#[only_owner]
pub fn mint(e: &Env, to: Address) -> u32 {
Base::sequential_mint(e, &to)
}
}

#[default_impl]
#[contractimpl]
impl NonFungibleToken for NonFungibleTokenContract {
type ContractType = Base;
}

#[default_impl]
#[contractimpl]
impl NonFungibleBurnable for NonFungibleTokenContract {}

#[default_impl]
#[contractimpl]
impl Ownable for NonFungibleTokenContract {}

Ref: https://github.com/OpenZeppelin/stellar-contracts/tree/main/examples/nft-sequential-minting

Cómo Funciona

Este ejemplo muestra cómo crear un token no fungible utilizando la biblioteca OpenZeppelin Stellar Contracts. La biblioteca proporciona implementaciones preconstruidas y auditadas que garantizan seguridad y siguen las prácticas recomendadas de la industria.

El contrato implementa varias características clave:

  1. Creación Secuencial: Asigna automáticamente IDs de token secuenciales comenzando desde 1
  2. Control de Propiedad: Usa el patrón Ownable para funciones administrativas
  3. Tokens Quemables: Permite que los poseedores de tokens puedan quemarlos
  4. Creación Segura: Solo el propietario del contrato puede crear nuevos tokens

Al aprovechar la biblioteca OpenZeppelin, los desarrolladores pueden concentrarse en su lógica de negocio específica mientras confían en implementaciones probadas para la funcionalidad central de los NFT.

Uso de Componentes de la Biblioteca OpenZeppelin

La biblioteca OpenZeppelin Stellar Contracts proporciona componentes modulares que pueden componerse fácilmente:

  • Base: Funcionalidad central de tokens no fungibles con operaciones estándar de NFT
  • Ownable: Patrón de control de acceso para funciones administrativas
  • NonFungibleBurnable: Extensión que permite quemar tokens
  • Macros: #[only_owner] para control de acceso declarativo

La macro #[default_impl] genera automáticamente las implementaciones estándar, reduciendo el código repetitivo y manteniendo la plena compatibilidad con los estándares NFT.

Características Mejoradas de Seguridad

Este ejemplo muestra varias características de seguridad integradas en la biblioteca OpenZeppelin:

Control de Acceso: La macro #[only_owner] asegura que solo el propietario designado pueda realizar acciones administrativas como crear nuevos tokens.

Generación Secuencial de IDs: La biblioteca maneja la generación segura de IDs de token, evitando colisiones y asegurando unicidad.

Valores Predeterminados Seguros: La biblioteca implementa valores predeterminados seguros para todas las operaciones NFT, incluyendo verificaciones apropiadas de autorización y emisión de eventos.

consejo

La biblioteca OpenZeppelin Stellar Contracts ha sido auditada y sigue las prácticas recomendadas de la industria. Usar estos componentes preconstruidos reduce el riesgo de vulnerabilidades de seguridad en tus contratos NFT.

Uso

Usaremos un NFT para rastrear elementos de juego, cada uno con sus propios atributos únicos. Cada vez que uno de estos se deba otorgar a un jugador, será creado y enviado a él. Los jugadores pueden conservar, quemar o intercambiar su token como deseen. Ten en cuenta que cualquier cuenta puede llamar a award_item y quizás quieras implementar control de acceso para restringir quién puede crear tokens.

Así podría lucir un contrato para objetos tokenizados:

use soroban_sdk::{contract, contractimpl, Address, Env, String};
use stellar_macros::default_impl;
use stellar_tokens::non_fungible::{
burnable::NonFungibleBurnable,
Base, ContractOverrides, NonFungibleToken,
};

#[contract]
pub struct GameItem;

#[contractimpl]
impl GameItem {
pub fn __constructor(e: &Env) {
Base::set_metadata(
e,
String::from_str(e, "www.mygame.com"),
String::from_str(e, "My Game Items Collection"),
String::from_str(e, "MGMC"),
);
}

pub fn award_item(e: &Env, to: Address) -> u32 {
// access control might be needed
Base::sequential_mint(e, &to)
}
}

#[default_impl]
#[contractimpl]
impl NonFungibleToken for GameItem {
type ContractType = Base;
}

#[default_impl]
#[contractimpl]
impl NonFungibleBurnable for GameItem {}

Pruebas

El ejemplo de OpenZeppelin incluye pruebas completas que verifican tanto la funcionalidad estándar de NFT como las características adicionales de seguridad.

Los escenarios clave de prueba incluyen:

  • Operaciones de Token: Pruebas de funciones de creación, transferencia, quema y aprobación
  • Control de Acceso: Verificación de que solo el propietario puede realizar acciones administrativas
  • Generación de ID de Token: Asegurar que se generen IDs secuenciales correctamente
  • Autorización: Confirmar los requisitos adecuados de autenticación para cada función
  • Casos Límite: Pruebas de condiciones límite y escenarios de error

Para ejecutar las pruebas:

cd examples/nft-sequential-minting
cargo test

Las pruebas demuestran cómo la biblioteca OpenZeppelin maneja escenarios complejos manteniendo la seguridad y el control de acceso apropiado.

Crear el Contrato

Para crear el contrato, usa el comando stellar contract build.

stellar contract build

Se debe generar un archivo .wasm en el directorio target:

target/wasm32v1-none/release/nft_sequential_minting.wasm