Funciones de Propietario en Contratos Inteligentes Sway

Resumen

Las funciones owner-only son un patrón clave en programación blockchain que restringe ciertas acciones únicamente al dueño del contrato. Aprenderás a inicializar al propietario y a permitir que solo él retire los fondos acumulados en un marketplace hecho con Sway, asegurando que nadie más pueda drenar el contrato.

Esto es relevante para desarrolladores que están construyendo contratos inteligentes con comisiones, fees o cualquier lógica que requiera control administrativo sobre los fondos.

Por qué necesitas funciones owner-only en un smart contract

Cuando tu contrato cobra una comisión por cada transacción, ese dinero se acumula dentro del contrato. Si cualquier wallet pudiera llamar a la función de retiro, cualquiera podría vaciar el contrato. Por eso necesitas una capa de validación que pregunte: ¿quién está llamando esta función y tiene permiso para hacerlo?

¿Qué es una función owner-only? Es una función que solo puede ejecutar la dirección registrada como propietaria del contrato. Si otra wallet intenta llamarla, el contrato lanza un error y revierte la transacción.

Este patrón aparece en prácticamente todos los ecosistemas blockchain, así que dominarlo en Sway te sirve también para Solidity, Rust de Solana y otros lenguajes.

Cómo inicializar al owner del contrato con initialize_owner

En lugar de hardcodear la dirección del dueño, usas una función llamada initialize_owner que asigna al propietario desde una wallet la primera vez que se llama. La firma de la función no recibe argumentos, retorna un Identity y necesita acceso de lectura y escritura al storage.

La lógica sigue tres pasos:

  1. Lee el valor actual de storage.owner, que está definido como Option<Identity> y arranca en None.
  2. Verifica que el owner aún no haya sido inicializado usando require(owner.is_none(), InvalidError::OwnerAlreadyInitialized).
  3. Captura al sender del mensaje con msg_sender(), lo asigna a storage.owner y retorna esa identidad.

Por qué se usa Option e is_none al inicializar

El tipo Option<Identity> te permite representar dos estados: hay un dueño (Some) o no lo hay (None). Al exigir que el valor sea None antes de asignarlo, garantizas que la función solo se ejecuta una vez, justo después del deploy.

Para qué sirve unwrap al asignar el sender

La función msg_sender() retorna un Result, que envuelve dos posibles valores: un Identity exitoso o un AuthError. Para extraer la identidad real y guardarla en storage, necesitas usar .unwrap(), que abre ese envoltorio y te entrega el valor interno.

Así queda la asignación: storage.owner = Option::Some(sender.unwrap()); y al final retornas sender.unwrap() como atajo de la misma idea.

Cómo permitir que solo el owner retire los fondos

La segunda función, withdraw_funds, permite al dueño extraer las comisiones acumuladas. Imagina que tu marketplace corrió un año y quieres cobrar lo recaudado: este es el mecanismo que dispara ese retiro.

La función no recibe argumentos, no retorna nada y necesita acceso de lectura al storage.

¿Cómo se valida que solo el owner pueda retirar? Comparando sender.unwrap() == owner.unwrap() con un require. Si las direcciones no coinciden, el contrato lanza el error OnlyOwner y revierte la operación.

El flujo completo se ve así:

  • Lee al owner desde storage.owner y exige que esté inicializado con require(owner.is_some(), InvalidError::OwnerNotInitialized).
  • Captura al sender con msg_sender() para saber quién está llamando.
  • Compara sender y owner; si no son iguales, lanza OnlyOwner.
  • Obtiene el balance del contrato con this_balance(BASE_ASSET_ID).
  • Verifica que el monto sea mayor a cero con require(amount > 0, InvalidError::NotEnoughTokens(amount)).
  • Transfiere los fondos con transfer(amount, BASE_ASSET_ID, owner.unwrap()).

Qué hace this_balance y de dónde se importa

this_balance viene de la librería estándar de Sway y devuelve el balance del contrato para un asset ID específico. Se importa desde la misma ubicación que msg_amount al inicio del archivo. Le pasas el BASE_ASSET_ID y te retorna cuántos tokens hay disponibles para retirar.

Cómo funciona el método transfer en Sway

El método transfer recibe tres argumentos en este orden:

  1. El monto a enviar.
  2. El asset ID del token.
  3. La dirección destinataria.

En este caso transfieres amount del BASE_ASSET_ID hacia owner.unwrap(), que es la identidad del dueño previamente registrada.

Qué errores personalizados usar al validar permisos

Los require en Sway funcionan como puntos de control: si la condición es falsa, lanzan un error y detienen la ejecución. En estas funciones aparecen tres errores personalizados clave:

  • OwnerAlreadyInitialized, cuando alguien intenta llamar initialize_owner por segunda vez.
  • OwnerNotInitialized, cuando se intenta retirar sin haber registrado un dueño.
  • OnlyOwner, cuando una wallet distinta al propietario intenta retirar fondos.
  • NotEnoughTokens(amount), cuando el balance del contrato es cero.

Definir errores con nombres claros hace tu contrato más fácil de auditar y depurar, porque cualquier persona que lea el código entiende de inmediato qué validación falló.

Ahora te toca a ti: toma una captura de tu código mostrando exactamente dónde aplicaste la lógica owner-only y deja un comentario explicando si hay algo que aún no te queda claro o alguna duda específica sobre el patrón.