El atributo payable en Solidity

Resumen

El atributo payable en Solidity habilita direcciones y funciones de un smart contract para recibir la criptomoneda nativa del ecosistema, como Celo Gold o Ether. Si estás aprendiendo desarrollo de contratos inteligentes, dominar este atributo es clave para construir flujos de donaciones, pagos o transferencias on-chain.

¿Qué hace el atributo payable en un smart contract?

El atributo payable autoriza a una dirección o a un método a recibir transferencias de criptomonedas. Sin él, cualquier intento de enviar fondos al contrato o a una dirección desde el contrato falla.

¿Qué es payable en Solidity? Es un modificador que marca direcciones o funciones como aptas para recibir la moneda nativa de la red, como Ether o Celo Gold. Sin payable, la transferencia se revierte.

En la práctica, lo verás aplicado en dos lugares: junto al tipo address cuando una variable necesita recibir fondos, y junto a una función cuando quieres que acepte un value al ser invocada.

¿Cómo se estructura un contrato de donaciones con payable?

El ejemplo trabajado en clase simula una organización benéfica que recibe aportes y los retira hacia una wallet designada. El contrato tiene dos variables de estado.

  • Una variable address llamada charity, que representa a la organización beneficiaria.
  • Un mapping que asocia cada address donante con un entero, dejando un registro público de cuánto aportó cada quien.

En el constructor, quien despliega el contrato queda asignado como charity. Esto puede modificarse para recibir la dirección por parámetro, pero en este caso pedagógico se mantiene simple.

¿Para qué sirve la función deposit?

La función deposit lleva el atributo payable, lo que le permite aceptar criptomonedas al ser llamada. Cuando alguien la invoca enviando un value, ocurren dos cosas a la vez: el monto se suma al balance del contrato y la dirección del donante queda registrada en el mapping de donaciones junto con la cantidad enviada.

¿Y qué hace la función withdraw?

La función withdraw transfiere todo el balance acumulado del contrato hacia la dirección charity. Aquí está el detalle importante: para que esa transferencia funcione, la variable charity debe estar declarada como address payable. Sin ese atributo, la dirección no está habilitada para recibir fondos y la transacción falla.

¿Cómo se prueba el contrato en Remix?

Una vez compilado el código sin errores, el flujo de prueba en Remix muestra cómo interactúan las wallets y el atributo payable en tiempo real [02:43].

  1. Despliega el contrato con la primera wallet disponible, por ejemplo una que inicia con 5B. Esa dirección queda como charity.
  2. Cambia a otra wallet, como una que empiece con AB8, para simular un donante distinto.
  3. En el campo value, ingresa el monto a transferir, por ejemplo 20, y elige la unidad: Wei es la más pequeña, y la mayor aparece como Ether, que en el contexto de Celo equivale a Celo Gold.
  4. Llama al método deposit. En Remix lo identificas porque su botón aparece en rojo en lugar de naranja, señal de que es payable.

¿Cómo identifico una función payable en Remix? Su botón se muestra en rojo en lugar de naranja. Ese color indica que la función puede recibir transferencias de cripto al ejecutarse.

Después de ejecutar el deposit, el balance de la wallet donante baja por dos razones: el gas del método y los 20 Ether enviados. Si copias la dirección y la consultas en el mapping de donaciones, verás un número enorme: eso ocurre porque el valor se almacena en Wei, la unidad mínima. Convertido, equivale a los 20 Ether donados.

¿Qué pasa al ejecutar withdraw?

Al repetir el aporte con otra wallet, esta vez por 10 Ether, el contrato acumula 30 Ether en total. Luego, al invocar withdraw, los fondos se transfieren a la wallet charity. Su balance pasa de los 100 Ether iniciales a cerca de 130, demostrando que la transferencia funciona porque la dirección destino tenía el atributo payable.

¿Qué conceptos clave deja esta práctica?

Más allá del ejemplo, hay ideas que vale la pena fijar para tu trabajo con Solidity.

  • Mapping: estructura que asocia claves con valores, ideal para registros como donaciones por dirección [01:05].
  • Constructor: función que se ejecuta una sola vez al desplegar el contrato y define el estado inicial.
  • Wei: la unidad mínima de Ether; recuerda convertir cuando leas balances directamente desde el contrato.
  • Gas: costo de ejecutar cualquier transacción, que se descuenta de la wallet que invoca el método.
  • address payable: variante del tipo address requerida para que una dirección reciba transferencias desde el contrato [02:10].

Este flujo es pedagógico y simplificado. En producción agregarías validaciones, control de acceso y manejo de errores, pero la mecánica de payable se mantiene igual. ¿Te animas a modificar el contrato para que el constructor reciba la dirección de charity como parámetro? Cuéntame cómo te fue en los comentarios.