SolidityとVyperのコンパイル戦略
概要
Solidityの方がVyperより複雑なコンパイルの仕方をする
結論は、Vyperと異なるコンパイル戦略を取っていること
何のためのSWAP?
代入のみ
In Solidity(say ver0.4.18) , when I compiled this code:
code: Solidity
pragma solidity ^0.4.18;
contract C {
uint256 data;
function C() public {
data = 123;
}
}
the assembly part of data = 123 is
PUSH1 0x7B PUSH1 0x0 DUP2 SWAP1 SSTORE POP
yudetamago.icon > --optimize オプション付けると消えた(v0.5.1)ので最適化されてないだけかも
In Vyper, when I compiled the code below
code: Vyper(Python)
data: public(uint256)
@public
def __init__():
self.data = 123
the assembly part of self.data = 123 is
PUSH1 0x7B PUSH1 0x00 SSTORE
変数での代入
code: Solidity
pragma solidity ^0.4.18;
contract C {
uint256 data;
function C() public {
uint256 a = 123;
data = a;
}
}
PUSH1 0x0 PUSH1 0x7B SWAP1 POP DUP1 PUSH1 0x0 DUP2 SWAP1 SSTORE POP POP
code: Vyper
data: public(uint256)
@public
def __init__():
a: uint256 = 123
self.data = a
PUSH1 0x7b PUSH2 0x0140 MSTORE PUSH2 0x0140 MLOAD PUSH1 0x00 SSTORE PUSH2 0x016f
変数での代入、直後再代入
code: Solidity
pragma solidity ^0.4.18;
contract C {
uint256 data;
function C() public {
uint256 a = 123;
data = a;
a = 456;
}
}
code: EVM
PUSH1 0x0 PUSH1 0x7B SWAP1 POP (→stack: 0x7B )
DUP1 PUSH1 0x0 DUP2 SWAP1 SSTORE (→stack: 0x7B 0x7B)
POP PUSH2 0x1C8 SWAP1 POP POP
ストレージに入れる値はいつもスタック先頭に残されるっぽい
code: Vyper(Python)
data: public(uint256)
@public
def __init__():
a: uint256 = 123
self.data = a
a = 456
code: EVM
009F 60 PUSH1 0x7b
00A1 61 PUSH2 0x0140
00A4 52 MSTORE
00A5 61 PUSH2 0x0140
00A8 51 MLOAD
00A9 60 PUSH1 0x00
00AB 55 SSTORE
00AC 61 PUSH2 0x016f
代入する変数を直後で利用
code: Solidity
pragma solidity ^0.4.18;
contract C {
uint256 data;
uint256 data2;
function C() public {
uint256 a = 123;
data = a;
data2 = a;
}
}
code: EVM
PUSH1 0x0 PUSH1 0x7B SWAP1 POP DUP1 PUSH1 0x0 (stack: 0x0 07B 07B)
DUP2 SWAP1 (stack: 0x0 07B 07B 07B)
SSTORE POP DUP1 PUSH1 0x1 DUP2 SWAP1 SSTORE POP POP
code: Vyper(Python)
data: public(uint256)
data2: public(uint256)
@public
def __init__():
a: uint256 = 123
self.data = a
self.data2 = a
code: EVM
PUSH1 0x7b PUSH2 0x0140 MSTORE PUSH2 0x0140 MLOAD PUSH1 0x00 SSTORE PUSH2 0x0140 MLOAD PUSH1 0x01 SSTORE PUSH2 0x019c *JUMP
ORの計算方法
code: simpleOR.vy(Python)
@public
def simpleOR(a: bool, b: bool) -> bool:
return a or b
OR
code: simpleOR.sol(Javascript)
pragma solidity ^0.5.1;
contract Test {
function simpleOR(bool a, bool b) public returns(bool) {
return a || b;
}
}