如何從合約呼叫中獲取合約的返回值?
如果合約確實返回了一些東西,(無論是字元串還是
return true/return false
)如何獲得它的返回值?我的意思是返回值儲存在哪裡?在 的情況下是否需要使用
RETURNDATACOPY
或值是否在堆棧上return true/return false
?如果它在堆棧上,如何知道合約退出是因為執行中的問題(如恢復或耗盡氣體)還是因為執行成功返回 false ?當然,我是在知道站點或返回值的類型時說的,因此
RETURNDATASIZE
不需要使用。我不想要一個 Solidity 或 Vyper 的答案,而是想知道事情在底層是如何工作的。
這裡有一堆問題,我將嘗試解開。
1.如何獲取它的返回值?
當合約在 EVM 中終止時,它處於暫停狀態,表示為
H
。這種停止狀態採用三個可能的值:
()
當執行需要停止而沒有返回值時- 空集,讓我們
None
在需要繼續執行時呼叫它(offset, length)
或對應於返回值的兩個數字的列表約定是 for
offset
,length
以對應於記憶體中mem[offset, offset + length - 1]
與返回數據對應的字節。2、返回值存放在哪裡?
您的問題是返回數據如何到達那裡?好吧,通常編譯後的合約會在終止前用所需的數據填充機器記憶體。
3. 有必要使用
RETURNDATACOPY
嗎?
RETURNDATACOPY
實際上是針對一個契約呼叫另一個契約並需要從另一個契約收集返回數據的特殊情況。從概念上講,當另一個合約被呼叫時,父合約可以訪問一個被呼叫的變數output
或mu_o
黃紙符號中的返回數據。的目標是將數據從目前記憶體
RETURNDATACOPY
中複製出來,以便可以返回。mu_o``mu_m
4. 如果在棧上,如何知道合約是否因為執行問題而退出?
因此,如上所述,返回數據在終止合約之前儲存在記憶體中。還有其他方法可以理解合約是如何停止的,特別是停止狀態、異常停止功能等。
5、呼叫後返回父合約的數據在哪裡?
在記憶中。
CALL
這是黃皮書中定義的摘錄。如您所見,輸出數據保存在記憶體中,然後
mu_o
作為指向記憶體中該部分的簡寫/指針引入。