Frage zum EVM-Stack

Ich habe diesen einfachen Smart Contract

contract C {
    uint256 a;

    function C() {
        a = 1;
    }
}

Betrieb

solc --bin --asm c1.sol

es wirft aus:

======= 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

Ich kann diese beiden OPCODE nicht verstehen

PUSH 0 a POP a = 1

Ich versuche, den Stack zu rekonstruieren:

  1. DRÜCKEN 1 --> [1]
  2. DRÜCKEN 0 --> [0,1]
  3. DRÜCKEN 0 --> [0,0,1]
  4. POP --> [0,1]
  5. DUP2 --> [1,0,1]
  6. SWAP1 --> [0,1,1]
  7. SSTORE --> [1]
  8. POP --> []

Warum brauche ich eine Einweisung bei Punkt 3 und 4? Sie sehen unbrauchbar aus

Antworten (1)

Sie haben Recht, sie sind nicht nützlich und werden nur vom Compiler generiert.

Die Menge an Müll ist abhängig von der Compiler-Version. Ich verwende 0.4.19-develop.2017.11.6+commit.dc154b4e.Linux.g++und es erzeugt eine sinnlose Push / Pop-Kombination weniger als in Ihrem Beispiel.

Der Solidity-Optimierer ist ziemlich gut darin, diese Dinge zu bereinigen, wenn sie Sie stören. Sie können die --optimizeFlagge verwenden, um den Effekt zu sehen. Einige Leute ziehen es jedoch vor, den Optimierer nicht zu verwenden, da er ein weiterer Schritt in der Werkzeugkette ist, was bedeutet, dass ein weiterer Schritt ist, in dem Fehler eingeführt werden könnten.

Wenn Sie sich wirklich Sorgen um dieses Zeug machen (so wie ich!), können Sie sich andere intelligente Vertragssprachen ansehen, z. B. LLL , das sehr sauberen EVM-Bytecode erzeugt - ähnlich wie Inline-Assembler-Code.