7

Why does a 'void' contract we have a long bytecode with many duplicated opcodes?

For instance, the following contract:

pragma solidity ^0.4.0;

contract A { 
    string s="s";
}

will be translated to a long list of opcodes:

.code
  PUSH 60           contract A {
\n
string s="s";...
  PUSH 40           contract A {
\n
string s="s";...
  MSTORE            contract A {
\n
string s="s";...
  PUSH 40           string s="s"
  PUSH 40           string s="s"
  MLOAD             string s="s"
  SWAP1             string s="s"
  DUP2          string s="s"
  ADD           string s="s"
  PUSH 40           string s="s"
  MSTORE            string s="s"
  DUP1          string s="s"
  PUSH 1            string s="s"
  DUP2          string s="s"
  MSTORE            string s="s"
  PUSH 20           string s="s"
  ADD           string s="s"
  PUSH 7300000000000000000000000000000000000000000000000000000000000000         string s="s"
  DUP2          string s="s"
  MSTORE            string s="s"
  POP           
  PUSH 0            string s="s"
  SWAP1             string s="s"
  DUP1          string s="s"
  MLOAD             string s="s"
  SWAP1             string s="s"
  PUSH 20           string s="s"
  ADD           string s="s"
  SWAP1             string s="s"
  DUP3          string s="s"
  DUP1          string s="s"
  SLOAD             string s="s"
  PUSH 1            string s="s"
  DUP2          string s="s"
  PUSH 1            string s="s"
  AND           string s="s"
  ISZERO            string s="s"
  PUSH 100          string s="s"
  MUL           string s="s"
  SUB           string s="s"
  AND           string s="s"
  PUSH 2            string s="s"
  SWAP1             string s="s"
  DIV           string s="s"
  SWAP1             string s="s"
  PUSH 0            string s="s"
  MSTORE            string s="s"
  PUSH 20           string s="s"
  PUSH 0            string s="s"
  SHA3          string s="s"
  SWAP1             string s="s"
  PUSH 1F           string s="s"
  ADD           string s="s"
  PUSH 20           string s="s"
  SWAP1             string s="s"
  DIV           string s="s"
  DUP2          string s="s"
  ADD           string s="s"
  SWAP3             string s="s"
  DUP3          string s="s"
  PUSH 1F           string s="s"
  LT            string s="s"
  PUSH [tag] 2          string s="s"
  JUMPI             string s="s"
  DUP1          string s="s"
  MLOAD             string s="s"
  PUSH FF           string s="s"
  NOT           string s="s"
  AND           string s="s"
  DUP4          string s="s"
  DUP1          string s="s"
  ADD           string s="s"
  OR            string s="s"
  DUP6          string s="s"
  SSTORE            string s="s"
  PUSH [tag] 1          string s="s"
  JUMP          string s="s"
tag 2           string s="s"
  JUMPDEST          string s="s"
  DUP3          string s="s"
  DUP1          string s="s"
  ADD           string s="s"
  PUSH 1            string s="s"
  ADD           string s="s"
  DUP6          string s="s"
  SSTORE            string s="s"
  DUP3          string s="s"
  ISZERO            string s="s"
  PUSH [tag] 1          string s="s"
  JUMPI             string s="s"
  SWAP2             string s="s"
  DUP3          string s="s"
  ADD           string s="s"
tag 3           string s="s"
  JUMPDEST          string s="s"
  DUP3          string s="s"
  DUP2          string s="s"
  GT            string s="s"
  ISZERO            string s="s"
  PUSH [tag] 4          string s="s"
  JUMPI             string s="s"
  DUP3          string s="s"
  MLOAD             string s="s"
  DUP3          string s="s"
  SSTORE            string s="s"
  SWAP2             string s="s"
  PUSH 20           string s="s"
  ADD           string s="s"
  SWAP2             string s="s"
  SWAP1             string s="s"
  PUSH 1            string s="s"
  ADD           string s="s"
  SWAP1             string s="s"
  PUSH [tag] 3          string s="s"
  JUMP          string s="s"
tag 4           string s="s"
  JUMPDEST          string s="s"
tag 1           string s="s"
  JUMPDEST          string s="s"
  POP           string s="s"
  SWAP1             string s="s"
  POP           string s="s"
  PUSH [tag] 5          string s="s"
  SWAP2             string s="s"
  SWAP1             string s="s"
tag 6           string s="s"
  JUMPDEST          string s="s"
  DUP1          string s="s"
  DUP3          string s="s"
  GT            string s="s"
  ISZERO            string s="s"
  PUSH [tag] 7          string s="s"
  JUMPI             string s="s"
  PUSH 0            string s="s"
  DUP2          string s="s"
  PUSH 0            string s="s"
  SWAP1             string s="s"
  SSTORE            string s="s"
  POP           string s="s"
  PUSH 1            string s="s"
  ADD           string s="s"
  PUSH [tag] 6          string s="s"
  JUMP          string s="s"
tag 7           string s="s"
  JUMPDEST          string s="s"
  POP           string s="s"
  SWAP1             string s="s"
  JUMP          string s="s"
tag 5           string s="s"
  JUMPDEST          string s="s"
  POP           string s="s"
  POP           string s="s"
  CALLVALUE             contract A {
\n
string s="s";...
  PUSH [ErrorTag]           contract A {
\n
string s="s";...
  JUMPI             contract A {
\n
string s="s";...
tag 8           contract A {
\n
string s="s";...
  JUMPDEST          contract A {
\n
string s="s";...
  PUSH #[$] 0000000000000000000000000000000000000000000000000000000000000000            contract A {
\n
string s="s";...
  DUP1          contract A {
\n
string s="s";...
  PUSH [$] 0000000000000000000000000000000000000000000000000000000000000000         contract A {
\n
string s="s";...
  PUSH 0            contract A {
\n
string s="s";...
  CODECOPY          contract A {
\n
string s="s";...
  PUSH 0            contract A {
\n
string s="s";...
  RETURN            contract A {
\n
string s="s";...
.data
  0:
    .code
      PUSH 60           contract A {
\n
string s="s";...
      PUSH 40           contract A {
\n
string s="s";...
      MSTORE            contract A {
\n
string s="s";...
    tag 1           contract A {
\n
string s="s";...
      JUMPDEST          contract A {
\n
string s="s";...
      PUSH [ErrorTag]           contract A {
\n
string s="s";...
      JUMP          contract A {
\n
string s="s";...
    .data

Why?

3

It first stores the string in the memory, fetches the string onto the stack and stores the string into the storage, meanwhile keeping track of the memory usage at the memory address 0x40.

Storing into the storage involves a loop. Here is the first part.

.code
  PUSH 60
\n
string s="s";...
  PUSH 40
\n
string s="s";...
  MSTORE            remembering the current memory usage.  The first 0x60 bytes are reserved.
\n
string s="s";...
  PUSH 40           This is the size of newly allocated memory.
  PUSH 40           This is the position of the memory location that stores the current memory usage.
  MLOAD             The current memory usage is loaded.
  SWAP1
  DUP2              The current memory usage is used as the allocated address
  ADD               The current memory usage needs to be updated.
  PUSH 40           This is the position of the memory where the new current memory usage needs to be stored.
  MSTORE            The new memory usage is stored.
  DUP1
  PUSH 1            The length of the string.
  DUP2
  MSTORE            The length of the string is stored at the allocated address.
  PUSH 20           The address is incremented by one word.
  ADD               The address is incremented by one word.
  PUSH 7300000000000000000000000000000000000000000000000000000000000000 This is the string
  DUP2              The incremented address is duplicated.
  MSTORE            The string is stored at the incremented address.
  POP               We no longer need the incremented address.
  • this is only a small portion and i understand that but what about the rest – Etherkimist Dec 28 '16 at 23:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.