У меня есть этот простой смарт-контракт
contract C {
uint256 a;
function C() {
a = 1;
}
}
бег
solc --bin --asm c1.sol
он выбрасывает:
======= C =======
EVM assembly:
.code:
PUSH 60 contract C {...
PUSH 40 contract C {...
MSTORE contract C {...
tag2:
JUMPDEST function C() {...
PUSH 1 1
PUSH 0 a
PUSH 0 a
POP a = 1
DUP2 a = 1
SWAP1 a = 1
SSTORE a = 1
POP a = 1
tag3:
JUMPDEST function C() {...
PUSH #[$00000000…00000000] contract C {...
DUP1 contract C {...
PUSH [$00000000…00000000] contract C {...
PUSH 0 contract C {...
CODECOPY contract C {...
PUSH 0 contract C {...
RETURN contract C {...
.data:
0:
.code:
PUSH 60 contract C {...
PUSH 40 contract C {...
MSTORE contract C {...
PUSH [tag2] contract C {...
JUMP contract C {...
tag2:
JUMPDEST contract C {...
STOP contract C {...
Binary:
60606040525b60016000600050819055505b600a80601d6000396000f360606040526008565b00
Я не могу понять эти два OPCODE
PUSH 0 и POP a = 1
Я пытаюсь восстановить стек:
Зачем нужна инструкция по пунктам 3 и 4? Они выглядят бесполезными
Вы правы, они бесполезны и просто мусор, сгенерированный компилятором.
Количество мусора зависит от версии компилятора. Я использую 0.4.19-develop.2017.11.6+commit.dc154b4e.Linux.g++
, и он производит на одну бессмысленную комбинацию push/pop меньше, чем в вашем примере.
Оптимизатор Solidity неплохо убирает эти вещи, если они вас беспокоят. Вы можете использовать --optimize
флаг, чтобы увидеть эффект. Но некоторые люди предпочитают не использовать оптимизатор, так как это еще один шаг в цепочке инструментов, что означает еще один шаг, на котором могут быть внесены ошибки.
Если вы действительно обеспокоены этим (как и я!), вы можете проверить другие языки смарт-контрактов, такие как LLL , который создает очень чистый байт-код EVM — сродни встроенному ассемблеру.