send: Envía un monto a una dirección y retorna false si la transferencia no se realiza
transfer: Envía un monto y revierte si no se puede realizar
call: Esta es más complicada, pero básicamente realiza una llamada hacia una dirección. Incluso se pueden llamar funciones de otro contrato si se le pasa un address válido y la llamada dentro del parámetro data. No obstante, al ser un mensaje, puede llevar ether, y por eso se usa para envíos. Retorna el resultado de la función llamada (si es que fué el caso)
Un wei es la unidad más pequeña de Ether.
1 ETH == 10^18 WEI == 1,000,000,000,000,000,000 WEI
No tengo el dato concreto (no he encontrado algo claro al respecto) pero el cast de la dirección en el método send, no creo que sea recomendable, tal vez dar de alta como payable en el argumento de la dirección sea lo más conveniente:
Esto porque en otros lenguajes el cast corre el riesgo de perder datos, por ejemplo al castear un float a un int. Con el tipo de datos que maneja Solidity no sé si estemos corriendo el riesgo de castear esa dirección que podría ser (por ejemplo) de un contrato (porque la copiamos equivocadamente) y al enviarle el saldo lo vamos a perder.
Bueno espero el profe nos dé más luz, eso es lo que pensé así de primeras y tal vez estoy diciendo un disparate.
En caso de que no quieras usar el parámetro que da el warning, puedes dejar el parámetro vacío:
En este caso no lo vamos a usar y es una forma válida de que Remix no nos dé el warning.
++call++ es una función de bajo nivel para interactuar con otros contratos. Es el método recomendado a usar cuando solo estás enviando ether vía una llamada a una función ++fallback++. Sin embargo, no es una forma recomendada de llamar a funciones existentes.
Fuente: Solidity by example.
RESUMEN CLASE 14:
TRANSFERENCIA
DE ETHER DESDE
UN CONTRATO
I.- FUNCIONES
Send: envía un monto de Ether a una dirección y retorna “false” si no se puede realizar la acción.
Transfer: envía un monto de Ether a una dirección e interrumpe la ejecución de la función si no se puede realizar la acción.
Call: envía un monto de Ether a una dirección y retorna el resultado de la operación.
II.- DIFERENCIAS:
Send y transfer requieren que las direcciones sean de tipo payable.
Call no lo requiere.
Send y transfer tienen un límite de gas fijo de 2300 de gas.
Call no tiene límite de gas por defecto, pero se puede configurar.
Call permite llamar a funciones si la dirección especificada es un contrato.
Hola profe, he buscado la definición de la función "call" y no encuentro más que breves ejemplos del uso, pero no la definición, mi mayor duda es en el parámetro que se envía en call, en nuestro ejemplo va vacío ("") usted me podría ayudar con algún enlace?
Muchas gracias de antemano! Saludos!
Hola Pepe, el parámetro vacío ("") indica que no se le envía ningún argumento y por lo tanto se convierte en una transferencia de ethers directa hacia la cuenta destino. Respecto a un enlace de ayuda, puedes consultar: https://solidity-by-example.org/call/ que te muestra cómo hacer la llamada con parámetros
La direccion que colocamos al hacer el ejercicio es la que envía o recibe?
Porque noto que su saldo va disminuyendo cada que ejecuto una transferencia en vez de aumentar
Hola Edgar, si es el ejercicio de transferir, la dirección que se ingresa es la que recibe. Debes considerar dos factores:
1 - El monto que ingresas está en unidad "wei", por lo tanto si pones 100, es 0,000000000000000100 ethers.
2 - Cuando realizas una transacción, debes pagar por el gas y la comisión. Por lo tanto, cada transacción que realices disminuirá el saldo de la cuenta que llame a la función.
Tal vez sea alguno o ambos puntos los que hacen que lo veas disminuir
Un wei es la unidad más pequeña de medida en la blockchain de Ethereum, equivalente a 10^(-18) Ether. Se utiliza para realizar transacciones y calcular costos de gas de manera precisa en la red. Dado que las transacciones pueden tener costos muy bajos, el uso de wei permite manejar cifras pequeñas sin perder precisión. En comparación, un Ether se refiere a la cantidad más comúnmente utilizada en las transacciones, pero en el fondo, todo se traduce a wei.
Si despues de un tiempo de desplegar el contrato, se queda sin saldo, hay alguna forma de hacer una recarga de saldo al contrato?
Hola Hernando, correcto, se puede simplemente enviandole una transferencia al contrato. Recuerda que los contratos poseen direcciones con el mismo formato que las direcciones de cuentas de usuario, por lo tanto pueden recibir transferencias normalmente
No logro que me compile por las “” de la línea 21.
Cómo se colocan?
Son dos comillas dobles consecutivas (""). Creo que en tu comentario, las comillas que tienes son las que se utilizan para citar frases y que tienen una leve inclinación. Tienen que ser de las comillas que no tienen inclinación. Puedes copiar y pegar las que acabo de utilizar en el comentario que son las correctas
Porque me produce el revert? intente varias veces pero me sigue dando el mismo resultado?
Hola Jorge, fijate si el contrato desde el que estás llamando a esa función tiene saldo en Ether. Recuerda que no es el usuario el que está haciendo la transferencia sino el contrato, entonces antes de podes ejecutar esa operación debes de darle fondos al contrato.
ya entendi! gracias era eso!
Tengo una pequeña duda, en el curso de CrowdFunding, en la que una persona podía contribuir a un proyecto enviando, se utiliza esta funcion con .transfer
functionfundProyect(uint index)public payable sendFounds(index){Proyect memory proyect=proyects[index];// 0 is open && 1 is closedrequire(proyect.state==FundraisingState.Opened,"This project is already closed, you cant send founds");require(msg.value>0,"You need to give a value greater than zero"); proyect.author.transfer(msg.value); proyect.founds+= msg.value; proyects[index]=proyect; contributions[proyect.id].push(Contributtion(msg.sender, msg.value)); emit FundProyect(proyect.id, msg.value, proyect.founds);}
Esta función cuando yo la ejecuto desde una cuenta distinta a la del creador de el proyecto y coloco 1 wei como valor, el .transfer me descuenta el valor de 1 wei (msg.value) directamente de la cuenta donde llame la función y no de el contrato como se explico en la clase, algo así como si el .transfer tomara el address from de la dirección que ejecuta la función y no de la dirección de el contrato. No se si esto sucederá por la distinta implementación de el payable, o por otro factor que desconozco.
Hola Johan, lo que está sucediendo es que al ser la función de tipo payable, tu contrato recibe los fondos efectivamente y luego en el transfer se lo envía a la dirección de proyect.author. Por lo tanto sirve como intermediario entre el usuario inicial y el usuario final que recibe. A fin de cuentas se le descuenta al usuario inicial para enviarselo al contrato y el contrato se lo da al usuario final, por lo que pareciera que lo hace directamente.
¿Esto se puede hacer con otras criptomonedas o es exclusivo con ether?
hola Alejandra, este código puntualmente muestra como transferir Ethers. Para las criptomonedas deberías ver cómo se transfieren los tokens (ERC-20 y compatibles)
¿La función que se le puede pasar como parámetro es un callback?
Hola Rodrigo, la función que se envía por parámetro no es un callback en sí, si no que le indicas cuál es la función por la que vas a estar ingresando los ethers. Esto siempre y cuando envíes value, si no envías value puedes usar call para hacer una llamada externa a esa función. Es decir:
direccion.call{value:10}(abi.encodeWithSignature("prueba()")) => envía ethers al contrato entrando por la función "prueba" (debe ser payable)
direccion.call(abi.encodeWithSignature("prueba()")) => realiza una llamada externa a prueba
Entonces en resumen "transfer" es como un send con revert?, o no exactamente asi?, porque?...
hola Leonardo, exactamente ! Es como dices. Transfer es una evolución del send, antes se usaba el send pero para dar más seguridad (por el hecho de revertir) se agregó la alternativa con transfer con la misma estructura del send.