Вопрос о стеке EVM

У меня есть этот простой смарт-контракт

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

Я пытаюсь восстановить стек:

  1. НАЖМИТЕ 1 --> [1]
  2. НАЖАТЬ 0 --> [0,1]
  3. НАЖАТЬ 0 --> [0,0,1]
  4. ПОП --> [0,1]
  5. ДУП2 --> [1,0,1]
  6. СВАП1 --> [0,1,1]
  7. МАГАЗИН --> [1]
  8. ПОП --> []

Зачем нужна инструкция по пунктам 3 и 4? Они выглядят бесполезными

Ответы (1)

Вы правы, они бесполезны и просто мусор, сгенерированный компилятором.

Количество мусора зависит от версии компилятора. Я использую 0.4.19-develop.2017.11.6+commit.dc154b4e.Linux.g++, и он производит на одну бессмысленную комбинацию push/pop меньше, чем в вашем примере.

Оптимизатор Solidity неплохо убирает эти вещи, если они вас беспокоят. Вы можете использовать --optimizeфлаг, чтобы увидеть эффект. Но некоторые люди предпочитают не использовать оптимизатор, так как это еще один шаг в цепочке инструментов, что означает еще один шаг, на котором могут быть внесены ошибки.

Если вы действительно обеспокоены этим (как и я!), вы можете проверить другие языки смарт-контрактов, такие как LLL , который создает очень чистый байт-код EVM — сродни встроенному ассемблеру.