Solidity
從 Node.JS 應用程序正確處理要求/斷言失敗錯誤?
我的智能合約中有一個 getter 函式,它返回靜態定義的字元串數組中的字元串值之一。進入該函式後,它使用 . 對傳入索引進行邊界檢查
require()
。如果邊界檢查失敗,在我使用Web3.js進行呼叫的 Node.JS 應用程序中會發生什麼?會拋出 Javascript 錯誤嗎?我會得到 NULL 回來嗎?如果有人有一篇好的文章或網路資源展示了處理來自 Web3.JS 呼叫的錯誤的正確方法,這些錯誤導致在智能合約端觸發斷言或要求操作,請分享。
這是我的智能合約程式碼:
pragma solidity ^0.4.23; import "github.com/OpenZeppelin/zeppelin-solidity/contracts/ownership/Ownable.sol"; contract VideoDummyData is Ownable{ // Constructor, MUST be public. constructor() public { // Unused. } // Array of sample video IDs. string[3] m_aryVideoIds = ["ZUSPD9zOyJs", "4nqJiBRNQuw", "PLcxE4UkJt0"]; // Return one of the sample video IDs. function getVideoIdAt (uint ndx) public view returns(string) { // Bounds check on the desired index. require(ndx < m_aryVideoIds.length); return m_aryVideoIds[ndx]; } }
由於您正在呼叫一個
view
函式,因此第一個回調或多或少會立即出錯。目前可以返回錯誤
require(expression, "error msg");
挑戰是在 Web3 和 Node.js 中進一步訪問此消息。
同時,您可以在承諾的程式碼中使用
try
和.catch()
,例如松露合約抽象。你不會知道確切的原因,但你可以根據契約的要求來推斷它。
希望能幫助到你。
一旦你呼叫/發送方法得到恢復,你在 express/nodejs 程式碼中得到以下響應的任何原因。
{ "data": { "0x926192b712005c4eab709b7f7e1718435b6f2117580360b73e7601a439feffcd": { "error": "revert", "program_counter": 383, "return": "0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000165468697320496420616c72656164792065786973747300000000000000000000", "reason": "This Id already exists" }, "stack": "RuntimeError: VM Exception while processing transaction: revert This Id already exists\n at Function.RuntimeError.fromResults (C:\\Program Files\\WindowsApps\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\app\\resources\\static\\node\\node_modules\\ganache-core\\lib\\utils\\runtimeerror.js:94:13)\n at BlockchainDouble.processBlock (C:\\Program Files\\WindowsApps\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\app\\resources\\static\\node\\node_modules\\ganache-core\\lib\\blockchain_double.js:627:24)\n at processTicksAndRejections (internal/process/task_queues.js:93:5)", "name": "RuntimeError" } }
現在在這裡我們需要向使用者顯示適當的消息,以便使用者可以理解我們可以使用下面的程式碼。從回复的響應中獲取原因。在 nodeJS/expressjs 程式碼中使用以下程式碼….
try { await myContract.methods.foo().send(); } catch (e) { const data = e.data; const txHash = Object.keys(data)[0]; const reason = data[txHash].reason; console.log(reason); }