Понимание вызова стиля nameReg.call("register", "MyName") между контрактами

Вот пример из документов Solidity по методам типа адресаcall (в частности, по методу):

имя адресаReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2;

nameReg.call("зарегистрироваться", "МоеИмя");

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

Я не могу понять, что делает вторая строка. Вызывает ли он резервную функцию с этими двумя аргументами? Или он передает строку MyName для регистрации функции в контракте nameReg ?

Ответы (2)

Из ссылки в вопросе важная часть nameReg.call("register", "MyName")(выделена жирным шрифтом):

для взаимодействия с контрактами, которые не придерживаются ABI , предусмотрена функция call, которая принимает произвольное количество аргументов любого типа. Эти аргументы дополняются до 32 байтов и объединяются.

См. примечание здесь :

Примечание: ABI — это абстракция, которая не является частью основного протокола Ethereum. Любой может определить свой собственный ABI для своих контрактов, и любые вызывающие стороны таких контрактов должны будут соответствовать этому ABI, чтобы получить значимые результаты. Однако всем разработчикам проще использовать Solidity, Serpent и web3.js, которые соответствуют приведенному выше ABI.

nameReg.call("register", "MyName") не будет ссылаться registerна nameRegконтракт, составленный Solidity. Причина в том, что Solidity не использует «регистр» для поиска «функций» (он использует первые 4 байта в качестве идентификатора метода. Например, псевдокод EVM, который создает Solidity, см . здесь ). Вот код для быстрого теста :

contract NameReg {
    bytes32 public nn;
    bytes public calldata;

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

    function() {
        calldata = msg.data;
    }

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

С nameRegконтрактом, скомпилированным Solidity, nameReg.call("register", "MyName")будет вызвана резервная функция, где msg.dataбудет «register», «MyName», дополненное до 32 байтов и объединенное: 0x72656769737465720000000000000000000000000000000000000000000000004d794e616d650000000000000000000000000000000000000000000000000000.

резервная функция сохраняет msg.data в calldata. Это мутирует государство? Достаточно ли для этого 2300 газа при вызове резервной функции?
@ kk-dev11 Да, резервная функция в этом случае изменяет состояние и стоит более 2300 газа. Но при вызове nameReg.call("register", "MyName")пройдет больше газа: это .callи см. Случай 2 на ethereum.stackexchange.com/a/5993/42.

Этот фрагмент кода основан на одном из примеров контрактов на странице «Контракты» в документации Solidity:

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

Так:

Или он передает строку MyName для регистрации функции в контракте nameReg?

Да.