Solidity
為什麼一個返回“字元串”的簡單函式會呼叫另一個合約?
這個微不足道的契約:
contract Test { function test() returns (string) { return "foobar"; } }
函式“test”的彙編程式碼輸出(在solidity Web編譯器中)如下所示:
tag 2 function test() returns (strin... JUMPDEST function test() returns (strin... PUSH 0 contract Test {\n function ... PUSH 60 contract Test {\n function ... MSTORE string PUSH C0 return "foobar" PUSH 40 contract Test {\n function ... MSTORE return "foobar" PUSH 6 return "foobar" PUSH 80 string SWAP1 return "foobar" DUP2 return "foobar" MSTORE return "foobar" PUSH 666F6F6261720000000000000000000000000000000000000000000000000000 return "foobar" PUSH A0 return "foobar" MSTORE return "foobar" PUSH 20 string PUSH C0 return "foobar" SWAP1 function test() returns (strin... DUP2 function test() returns (strin... MSTORE function test() returns (strin... PUSH 6 return "foobar" PUSH E0 function test() returns (strin... DUP2 function test() returns (strin... SWAP1 function test() returns (strin... MSTORE function test() returns (strin... DUP2 return "foobar" SWAP1 return "foobar" PUSH 100 function test() returns (strin... SWAP1 function test() returns (strin... PUSH A0 return "foobar" SWAP1 return "foobar" DUP1 return "foobar" DUP4 function test() returns (strin... DUP2 return "foobar" DUP5 return "foobar" PUSH 0 contract Test {\n function ... PUSH 4 function test() returns (strin... PUSH 12 function test() returns (strin... CALL function test() returns (strin... POP POP DUP2 function test() returns (strin... MLOAD function test() returns (strin... PUSH FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF NOT AND function test() returns (strin... SWAP1 function test() returns (strin... SWAP2 function test() returns (strin... MSTORE function test() returns (strin... POP POP PUSH 40 contract Test {\n function ... MLOAD function test() returns (strin... PUSH 120 function test() returns (strin... DUP2 function test() returns (strin... SWAP1 function test() returns (strin... SUB function test() returns (strin... SWAP3 function test() returns (strin... POP SWAP1 function test() returns (strin... POP RETURN
我可以看到字元串的十六進製版本及其長度很早就被寫入記憶體。然後它做了很多奇怪的事情,並發出一個用很少的氣體來解決“4”的呼叫,據我所知。乙太坊黃皮書說地址 4 的合約實現了身份功能,在這種情況下呼叫這似乎完全沒有意義。
為什麼這樣做是為了看起來非常簡單的“回報”?
在與 Gitter 上的 Solidity 開發人員討論時,這一點很明確:Solidity 使用身份函式作為一種廉價的
memcpy
操作,而優化器目前還不夠聰明,無法意識到它可以將字元串文字作為整體載入到記憶體中。返回值。因此,它將字元串載入到記憶體中,使用標識函式將其 memcpy 到返回位置,然後將其返回。
彙編程式碼包括創建標識為一的合約所需的所有功能,即合約必須是可辨識的。實際的“測試”函式並未使用彙編程式碼中的所有函式。