To deploy a contract, you need a message/transaction of type "contract creation", i.e. without receiver. Moreover, the "input" of the transaction should contain a snippet of code, whose objective is to "return" (0xf3
) the persistent code.
So the idea is to use CODECOPY
or simply MSTORE
the part of information (0x6009
) you need and afterward call RETURN
, which takes from memory the output that will persist on the blockchain.
USING MSTORE
In your particular example, you could write (there are surely more efficient ways to do it, as with Solidity):
1. PUSH 60 // 6060
2. PUSH 0 // 6060
3. MSTORE8 // 53
4. PUSH 09 // 6009
5. PUSH 1 // 6001
6. MSTORE8 // 53
7. PUSH 0 // 6000
8. PUSH 2 // 6002
9. RETURN // f3
COMMENT
- Instructions 1-3, store in the first byte of memory
0x60
- Instructions 4-6, store in the second byte of memory
0x09
- Instructions 7-9, returns the first two byte of memory (
0
is the start index, 2
is the length)
USING CODECOPY
1. PUSH 2 // length of code to copy in memory
2. PUSH 0xD // offset of "init" code
3. PUSH 0 // offset in memory, i.e. where to store
4. CODECOPY
5. PUSH 0 // offset in memory to copy
6. PUSH 2 // length of memory to return (i.e. the length of body, 2 in your case)
7. RETURN
8. PUSH 09 // Here push is intepreted as a simple number
This version is more versatile, indeed, you can keep the first 7 instructions (you have only to change the length of bytes to copy) and then you can have arbitrary code.
Note
To have an insight you can inspect the source code of a little contract with REMIX:
pragma solidity ^0.4.24;
contract foo {
constructor() public payable {
}
}
N.B. the constructor is marked payable, otherwise the constructor is far more complicated because it requires to check the input money.
N.B.2: you must be careful with jumps ^^, because the pc to which you have to jump does not correspond to the one of the source code (you have to remove the constructor offset).