Comprender la llamada de estilo nameReg.call("registrar", "MiNombre") entre contratos

Aquí hay un ejemplo de solidity docs sobre métodos de tipo de dirección ( callmétodo específicamente):

dirección nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2;

nameReg.call("registrar", "MiNombre");

nameReg.call(bytes4(sha3("fun(uint256)")), a);

No puedo entender lo que hace la segunda línea. ¿Llama a la función de reserva con estos dos argumentos? ¿O pasa la cadena MyName al registro de funciones en el contrato nameReg ?

Respuestas (2)

Desde el enlace en la pregunta , la parte importante nameReg.call("register", "MyName")es (negrita mía):

para interactuar con contratos que no se adhieren a la ABI , callse proporciona la función que toma un número arbitrario de argumentos de cualquier tipo. Estos argumentos se rellenan a 32 bytes y se concatenan.

Mira la nota aquí :

Nota: el ABI es una abstracción que no forma parte del protocolo central de Ethereum. Cualquiera puede definir su propia ABI para sus contratos, y cualquier llamador de dichos contratos tendría que cumplir con esa ABI para obtener resultados significativos. Sin embargo, es más sencillo para todos los desarrolladores usar Solidity, Serpent y web3.js, que cumplen con el ABI anterior.

nameReg.call("register", "MyName") no invocará registeren un nameRegcontrato compilado por Solidity. La razón es que Solidity no usa "registrar" para buscar "funciones" (usa los primeros 4 bytes como la identificación del método. Por ejemplo, el pseudocódigo EVM que produce Solidity, vea esto ). Aquí hay un código para una prueba rápida :

contract NameReg {
    bytes32 public nn;
    bytes public calldata;

    function register(bytes32 name) {
      nn = name;    
    }

    function() {
        calldata = msg.data;
    }

    function doesNotCallRegister() {
        this.call("register", "MyName");
    }
 }

Con un nameRegcontrato compilado por Solidity, nameReg.call("register", "MyName")invocará la función de respaldo donde msg.dataestará "registrar", "MiNombre" rellenado a 32 bytes y concatenado: 0x72656769737465720000000000000000000000000000000000000000000000004d794e616d650000000000000000000000000000000000000000000000000000.

La función de reserva almacena msg.data en calldata. ¿Está mutando el estado? ¿Es suficiente gas 2300 para eso cuando se invoca la función de reserva?
@ kk-dev11 Sí, la función de reserva en este caso muta de estado y cuesta más de 2300 de gas. Pero invocar nameReg.call("register", "MyName")pasará más gas: es un .cally ver Caso 2 de ethereum.stackexchange.com/a/5993/42

Este fragmento de código se basa en uno de los contratos de ejemplo en la página Contratos en la documentación de Solidity:

contract NameReg {
    function register(bytes32 name);
    function unregister();
}

Asi que:

¿O pasa la cadena MyName al registro de funciones en el contrato nameReg?

Sí.