¿Qué significa la función de "llamada" de Solidity?

address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2;
nameReg.call("register", "MyName"); //1
nameReg.call(bytes4(sha3("fun(uint256)")), a); //2
if(!nameReg.call.value(10)){throw;} //3

Aquí dice,

Además, para interactuar con contratos que no se adhieren a la ABI, se proporciona la llamada de función que toma un número arbitrario de argumentos de cualquier tipo. Estos argumentos se rellenan a 32 bytes y se concatenan. Una excepción es el caso en el que el primer argumento está codificado en exactamente cuatro bytes. En este caso, no se rellena para permitir el uso de firmas de función aquí.

  • ¿Son legales 1 y 2?
  • ¿Significa que 2 es ilegal?
  • ¿Qué significa el 3?

Respuestas (1)

Solidity's calles una interfaz de bajo nivel para enviar un mensaje a un contrato. Devuelve falsesi la subllamada encuentra una excepción; de lo contrario, devuelve true. No hay noción de llamada legal, si compila, es Solidez válida.

  1. nameReg.call("register", "MyName")es un mensaje que pasa ciertos bytes a nameReg. Para los bytes, consulte: Descripción de la llamada de estilo nameReg.call("registrar", "MiNombre") entre contratos

  2. nameReg.call(bytes4(sha3("fun(uint256)")), a)es un mensaje que invocaría una función llamada fun(si nameReg se adhiere a la ABI) y le pasaría los datos sin procesar y sin arelleno (primero debe rellenar correctamente ahasta 32 bytes si desea que el comportamiento coincida con la ABI . Para uint256usar el relleno izquierdo. ).

Para 3, contract.call.value(...)(...)es una forma de agregar Ether al invocar un contrato. if(!nameReg.call.value(10)()){throw;}es un ejemplo de manejo del caso de falla de la subllamada. Tenga en cuenta los paréntesis adicionales value(10)()que invocan la función de reserva.

calles una interfaz de bajo nivel y es más sencillo invocar una función directamente, nameReg.fun(a)en lugar del segundo ejemplo. La invocación directa también es de tipo seguro y permite que se use el valor de retorno de fun.

Tenga en cuenta que en el caso de 1, "register"y "MyName"se rellenan con 32 bytes, mientras que en 2, ase concatena directamente en 4 bytes.bytes4(sha3("fun(uint256)"))
@eth, ¿quiere decir que ignora el valor devuelto por el contrato?
@ user2284570 Sí, Solidity callno devuelve el valor de retorno de una función de contrato: solo devuelve si la función encontró una excepción o no.
Tal como lo entiendo, (bool success, bool returnBytes) = addr.call{...}(abi.encodeWithSignature(...), ...)es la nueva forma recomendada de (1) llamar a funciones sin lanzar si no se puede llamar a la función, y (2) enviar pagos a funciones pagables. Así que estoy bastante seguro de que el comentario de chriseth callsolo se aplica a las versiones anteriores.
@LukeHutchison Creo que tiene razón, votó a favor y eliminó el comentario de chriseth. No estoy seguro de cuánto editar el resto de esta respuesta; siéntase libre de escribir una segunda respuesta que sea mucho más actual :)