¿Alguien puede explicar las diferencias entre usar un envío y una llamada para contratos y cuándo usar y no usar estos métodos diferentes?
Por ejemplo :
msg.sender.send(number);
msg.sender.call.value(number)();
Sé que enviar usa 2300 de gas y que usar llamar no usa nada de gas.
EDITAR Dic 2019: call.value()()
ahora debe usarse para transferir ether. (No use enviar o transferir.)
Ver: ¿La transferencia () sigue siendo segura después de la actualización de Estambul?
1 Send()
ya no envía gas. Simplemente utiliza el estipendio codificado (gas 2300) desviado del costo de transferencia de valor (mínimo 9040). Es suficiente para enviar ether, pero también para realizar básicamente una pequeña operación de registro adicional (en una función de respaldo). Las siguientes operaciones consumirán más gas que el estipendio proporcionado a una función alternativa:
• Escritura en el almacenamiento
• Creación de un contrato
• Llamar a una función externa que consume una gran cantidad de gas
• Envío de éter
2 Si una send()
llamada se queda sin gasolina, no arroja un error, simplemente devuelve falso.
de solidez Doc:
Si un contrato recibe Ether (sin que se llame a una función), se ejecuta la función de reserva. El contrato solo puede depender de que el "estipendio de gas" (gas 2300) esté disponible para él en ese momento. Este estipendio no es suficiente para acceder al almacenamiento de ninguna manera. Para asegurarse de que su contrato pueda recibir Ether de esa manera, verifique los requisitos de gas de la función de respaldo (por ejemplo, en la sección "detalles" en la solidez del navegador).
• Hay una forma de reenviar más gas al contrato receptor usando addr.call.value(x)(). Esto es esencialmente lo mismo que addr.send(x), solo que reenvía todo el gas restante y abre la capacidad para que el destinatario realice acciones más costosas. Esto podría incluir volver a llamar al contrato de envío u otros cambios de estado en los que quizás no haya pensado. Por lo tanto, permite una gran flexibilidad para los usuarios honestos pero también para los actores malintencionados.
Advertencia : los contratos que reciben Ether pero no definen una función de respaldo lanzan una excepción y devuelven el Ether (esto era diferente antes de Solidity v0.4.0). Entonces, si desea que su contrato reciba Ether, debe implementar una función de respaldo.
.call()
. Y no puedo enfatizar lo suficiente que .call()
"permite una gran flexibilidad para los usuarios honestos pero también para los actores maliciosos".2,300
, seguro contra reingresofalse
en caso de falla2,300
, seguro contra reingresofalse
en caso de fallaPuede leer más detalles aquí https://ethereum.stackexchange.com/a/38642/18932
Alex Darby
ética
.call
no crea una transacción; acabo de escribir esto que tiene otros detalles que puede estar buscando: ethereum.stackexchange.com/a/6477/42tjaden hess
send
envía más de 0 gas, ¿no? Envía 23000ética
send
envía 0 gasolina, pero hay una regla EVM de que el receptor siempre recibe un estipendio de 2300 gasolina (para que, si quiere, siempre tenga suficiente gasolina para registrar que recibió algo).Xavier Leprêtre B9lab
.call
Javascript (sin transacción) con.call
Solidity (ya en una transacción).Alex Darby