Этот тривиальный контракт:
contract Test {
function test() returns (string) {
return "foobar";
}
}
В результате вывод ассемблерного кода (в веб-компиляторе Solidity) для функции 'test' выглядит следующим образом:
tag 2 function test() returns (strin...
JUMPDEST function test() returns (strin...
PUSH 0 contract Test {\n function ...
PUSH 60 contract Test {\n function ...
MSTORE string
PUSH C0 return "foobar"
PUSH 40 contract Test {\n function ...
MSTORE return "foobar"
PUSH 6 return "foobar"
PUSH 80 string
SWAP1 return "foobar"
DUP2 return "foobar"
MSTORE return "foobar"
PUSH 666F6F6261720000000000000000000000000000000000000000000000000000 return "foobar"
PUSH A0 return "foobar"
MSTORE return "foobar"
PUSH 20 string
PUSH C0 return "foobar"
SWAP1 function test() returns (strin...
DUP2 function test() returns (strin...
MSTORE function test() returns (strin...
PUSH 6 return "foobar"
PUSH E0 function test() returns (strin...
DUP2 function test() returns (strin...
SWAP1 function test() returns (strin...
MSTORE function test() returns (strin...
DUP2 return "foobar"
SWAP1 return "foobar"
PUSH 100 function test() returns (strin...
SWAP1 function test() returns (strin...
PUSH A0 return "foobar"
SWAP1 return "foobar"
DUP1 return "foobar"
DUP4 function test() returns (strin...
DUP2 return "foobar"
DUP5 return "foobar"
PUSH 0 contract Test {\n function ...
PUSH 4 function test() returns (strin...
PUSH 12 function test() returns (strin...
CALL function test() returns (strin...
POP
POP
DUP2 function test() returns (strin...
MLOAD function test() returns (strin...
PUSH FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
NOT
AND function test() returns (strin...
SWAP1 function test() returns (strin...
SWAP2 function test() returns (strin...
MSTORE function test() returns (strin...
POP
POP
PUSH 40 contract Test {\n function ...
MLOAD function test() returns (strin...
PUSH 120 function test() returns (strin...
DUP2 function test() returns (strin...
SWAP1 function test() returns (strin...
SUB function test() returns (strin...
SWAP3 function test() returns (strin...
POP
SWAP1 function test() returns (strin...
POP
RETURN
Я вижу, что шестнадцатеричная версия строки и ее длина записываются в память довольно рано. Затем он делает много странных вещей и, насколько я могу судить, выдает ЗВОНОК с очень небольшим количеством газа по адресу «4». В желтой книге Ethereum говорится, что контракт по адресу 4 реализует функцию идентификации, которую в данном контексте кажется совершенно бессмысленной.
Почему он делает это для того, что выглядит очень простым «возвратом»?
При обсуждении с разработчиками Solidity на Gitter становится ясно: Solidity использует функцию идентификации как дешевую memcpy
операцию, а оптимизатор в настоящее время недостаточно умен, чтобы понять, что он может просто загрузить строковый литерал в память как полноту возвращаемое значение. Таким образом, он загружает строку в память, использует функцию идентификации для memcpy в место возврата, а затем возвращает ее.
Ассемблерный код включает в себя все функции, необходимые для создания контракта, одной из которых является идентификация, т. е. контракт должен быть идентифицируемым. Фактическая функция «тест» не использует все функции ассемблерного кода.
эт