Controlar quién puede ejecutar funciones críticas dentro de un smart contract es uno de los patrones más importantes en el desarrollo blockchain. En esta sesión se implementan dos funciones fundamentales: una para inicializar al propietario del contrato y otra para permitir el retiro de fondos exclusivamente al dueño. Ambas demuestran cómo proteger recursos y restringir accesos usando lógica de autorización en Sway.
¿Cómo se inicializa el propietario de un smart contract?
La función initialize_owner establece quién es el dueño del contrato, es decir, la persona que recibirá las comisiones que el marketplace acumula con cada transacción. En lugar de codificar esta identidad directamente en el código (hard coding), se asigna dinámicamente desde una wallet al momento de ejecutar la función [01:23].
El flujo de esta función sigue estos pasos:
- Se anota el acceso a storage como read y write, ya que necesita leer y modificar el estado almacenado.
- Se obtiene el valor actual de
storage.owner, que es de tipo Option<Identity>.
- Se usa
require para verificar que el owner sea None, asegurando que solo se pueda llamar una vez después del despliegue del contrato.
- Si el owner ya fue establecido, se lanza un error de tipo
owner already initialized.
¿Qué papel juegan Option, Result y unwrap en esta lógica?
El tipo Option es un enum que puede contener un valor (Some) o estar vacío (None). Esto permite representar la ausencia de un propietario antes de la inicialización. El método .is_none() verifica precisamente si el valor está vacío [02:30].
Por otro lado, message_sender() retorna un tipo Result, que puede ser exitoso (conteniendo una Identity) o un error (AuthError). Para extraer el valor real que envuelve un Result, se utiliza el método unwrap [03:15]. Este método es esencial cuando necesitas asignar el contenido interno de un valor envuelto a una variable concreta.
Una vez verificado todo, se almacena la identidad del remitente en storage:
sway
storage.owner = Option::Some(sender.unwrap());
Finalmente, la función retorna la identidad del nuevo propietario con sender.unwrap().
¿Cómo funciona el retiro de fondos solo para el propietario?
La función withdraw_funds permite al dueño del contrato retirar las comisiones acumuladas. Imagina un marketplace que ha funcionado durante un año recolectando comisiones; esta función es el mecanismo para disparar ese retiro [04:20].
El proceso de validación es riguroso:
- Se verifica que el propietario ya haya sido inicializado usando
require(owner.is_some()). Si no lo está, se lanza el error owner not initialized.
- Se obtiene la identidad del remitente de la transacción con
message_sender().
- Se compara el remitente con el propietario almacenado:
require(sender.unwrap() == owner.unwrap()). Si no coinciden, se lanza el error only owner [05:40].
Este patrón se conoce como only owner function, un estándar en la arquitectura blockchain que restringe la ejecución de funciones sensibles exclusivamente al propietario del contrato.
¿Cómo se valida y transfiere el balance del contrato?
Después de confirmar la identidad, se consulta el balance actual del contrato con this_balance(BASE_ASSET_ID), importado desde la biblioteca estándar de Sway [06:15]. Esta función retorna cuántos tokens posee el contrato para el activo base.
- Se requiere que el
amount sea mayor que cero. Si no hay fondos disponibles, se lanza un error not enough tokens con el monto actual.
- Si la validación pasa, se ejecuta la transferencia con el método
transfer, que recibe tres argumentos:
sway
transfer(amount, BASE_ASSET_ID, owner.unwrap());
- amount: la cantidad a enviar.
- BASE_ASSET_ID: el identificador del token.
- owner.unwrap(): el destinatario de los fondos.
¿Por qué las funciones de solo propietario son esenciales en blockchain?
Sin este tipo de restricciones, cualquier persona podría llamar funciones sensibles como el retiro de fondos y drenar el contrato. El patrón only owner se utiliza en prácticamente todos los ecosistemas blockchain y lenguajes de programación de contratos inteligentes. Combina la verificación de identidad con el manejo seguro de errores para garantizar que solo la dirección autorizada pueda ejecutar operaciones críticas.
Si ya implementaste estas funciones, comparte una captura de tu código mostrando dónde usaste la funcionalidad only owner y comenta cualquier duda que tengas sobre el proceso.