Вот пример из документов Solidity по методам типа адресаcall
(в частности, по методу):
имя адресаReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2;
nameReg.call("зарегистрироваться", "МоеИмя");
nameReg.call(bytes4(sha3("fun(uint256)")), a);
Я не могу понять, что делает вторая строка. Вызывает ли он резервную функцию с этими двумя аргументами? Или он передает строку MyName для регистрации функции в контракте nameReg ?
Из ссылки в вопросе важная часть 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
.
Этот фрагмент кода основан на одном из примеров контрактов на странице «Контракты» в документации Solidity:
contract NameReg {
function register(bytes32 name);
function unregister();
}
Так:
Или он передает строку MyName для регистрации функции в контракте nameReg?
Да.
кк-dev11
эт
nameReg.call("register", "MyName")
пройдет больше газа: это.call
и см. Случай 2 на ethereum.stackexchange.com/a/5993/42.