Resumen

Construir la función de compra en un smart contract de marketplace requiere múltiples validaciones antes de procesar cualquier pago. Desde verificar el tipo de token hasta calcular la comisión de la plataforma, cada línea de código cumple un papel crucial para garantizar transacciones seguras y confiables.

¿Cómo se estructura la función buy_item y qué validaciones necesita?

La función buy_item es la encargada de procesar la compra de un artículo dentro del marketplace. Utiliza la anotación de storage access con permisos de lectura y escritura, ya que modifica datos almacenados en el contrato [01:07].

Recibe un único argumento: item_id de tipo U64. Este identificador es la forma en que el contrato distingue cada artículo listado, y sin él sería imposible saber qué producto quiere adquirir el usuario.

¿Cómo se valida el tipo de token enviado?

Lo primero que hace la función es obtener el asset ID del mensaje entrante mediante msg_asset_id(), una utilidad importada desde la librería estándar de Sway bajo el módulo call frames [02:06]. Este valor se almacena en una variable de tipo ContractId.

A continuación se usa la sentencia require para comparar ese asset ID contra BASE_ASSET_ID, una constante importada desde std::constants [02:50]. Si no coinciden, el contrato lanza el error InvalidError::IncorrectAssetId. Este patrón de validación con require es equivalente a un guard clause: si la condición no se cumple, la ejecución se detiene de inmediato.

¿Cómo se verifica que el monto enviado sea suficiente?

El siguiente paso es capturar la cantidad de tokens con msg_amount(), almacenándola en una variable amount de tipo U64 [03:24]. Para saber si el monto es correcto, primero se necesita recuperar el artículo correspondiente.

Aquí entra en juego el storage map llamado item_map. Se accede con storage.item_map.get(item_id) para obtener el struct Item completo [04:17]. La variable se declara como mutable con la palabra clave mut, porque más adelante se actualizará el campo total_bought.

Se realizan dos validaciones adicionales:

  • Que el item_id sea mayor que cero, ya que el contador inicia en cero y se incrementa al listar artículos. Un ID de cero nunca corresponde a un producto válido [05:05].
  • Que amount sea mayor o igual a item.price. Si no lo es, se devuelve InvalidError::NotEnoughTokens(amount), informando al usuario cuánto envió [05:40].

¿Cómo se actualiza el estado del contrato tras una compra?

Una vez superadas todas las validaciones, el contrato actualiza el campo total_bought del artículo con la expresión item.total_bought += 1 [06:27]. Este operador es un atajo que toma el valor existente y le suma uno, sin importar cuál sea su valor actual.

Para persistir este cambio se vuelve a insertar el struct en el storage map con storage.item_map.insert(item_id, item) [07:02]. La clave sigue siendo el mismo item_id y el valor es el struct ya modificado.

¿Cómo se registra la compra en el vector de purchases?

El contrato también mantiene un storage vector llamado purchases que almacena tuplas [07:30]. Cada tupla es un par formado por el item_id y la identidad del comprador.

Para obtener la identidad del comprador se usa msg_sender(), que devuelve un tipo Result<Identity, AuthError> [07:50]. El tipo Result puede contener un valor exitoso o un error, y para extraer el valor se aplica el método .unwrap().

La inserción se realiza con storage.purchases.push((item_id, sender.unwrap())), agregando dinámicamente el nuevo elemento al final del vector [08:22].

¿Cómo funciona la lógica de comisión del marketplace?

El marketplace cobra comisión únicamente cuando el monto supera 1,000 tokens [09:00]. La fórmula es sencilla:

  • Commission: amount / 20 — por cada 100 monedas, el contrato retiene 5.
  • New amount: amount - commission — el pago neto para el vendedor.

La transferencia se ejecuta con la función transfer, que recibe tres parámetros:

  • El monto a enviar (new_amount o amount según el caso).
  • El asset_id del token.
  • El destinatario, que es item.owner, la identidad del vendedor registrada al momento del listado [09:42].

Si el monto no supera los 1,000 tokens, se transfiere el total sin descuento alguno.

Esta función es una de las más complejas del smart contract porque combina validación de activos, verificación de montos, actualización de estado, registro de compras y cálculo de comisiones en un solo flujo. Como ejercicio, intenta modificar la lógica de comisión para que dependa del número de ventas del artículo en lugar del monto: por ejemplo, que el marketplace solo cobre a partir de la quinta venta. Comparte tu implementación y compara enfoques con otros desarrolladores.