Solidity

松露測試因“錯誤:返回錯誤:處理事務時出現 VM 異常:還原”而失敗 - 我該如何調試它?

  • March 16, 2021

我正在使用 truffle、ganache AppImage 來執行個人區塊鏈,並擁有 2 個solidity 智能合約Migrations.solPassportManager.sol

我正在執行松露測試,Error: Returned error: VM Exception while processing transaction: revert所以我猜測我部署的契約有問題,在我部署的程式碼中出現了異常。

我該如何調試呢?

我沒有使用 Remix,我不想在我的工具箱中添加更多工具。到目前為止,只有鬆露、甘納許和我的文本編輯器,我想保持簡單。

在 JavaScript 上執行我的測試只在 Ganache 上創建了 4 個塊(4 個事務),而這 4 個塊中沒有一個經過測試truffle debug <tx-id>會帶來任何有用的資訊——其中一個 txes 返回用於部署的字節碼PassportManager.sol(由於某種原因,每次都會發生這種情況!)和其他 3 都與Migrations.sol.

這是測試和程式碼,只是為了讓您知道發生了什麼:

function addIDFileToPassport(address passport_id, bytes32 id_file) public returns (address, bytes32, uint) {
       Passport storage p = user_passports[passport_id]; //Passport is a struct I've declared earlier, like so:
       /* struct Passport { 
               string flair_name;
               mapping(bytes32 => uint) identity_files;
               bytes32[] identity_files_LUT;
      
       }*/
       require(p.controller == msg.sender);
       p.identity_files_LUT.push(id_file);
       p.identity_files[id_file] = 1;
       return (p.controller, p.identity_files_LUT[p.identity_files_LUT.length - 1], p.identity_files[id_file]);
   }

和失敗的測試:

/* Other tests above */
it("should add an identity file sha256 hash to a controlled passport", () => {
       let this_address = accounts[0];
       let doc_hash = "0x21f3a9de43f07d855f49b946a10c30df432e8af95311435f77daf894216dcd41";
       //let hex_doc_hash = web3.utils.asciiToHex(doc_hash);
       //console.log(hex_doc_hash);
       //let hexArray_doc_hash = web3.utils.hexToBytes(doc_hash);
       //console.log(hexArray_doc_hash);
       //console.log(web3.utils.utf
       
   return PassportManager.deployed()
       .then(instance => {
           meta = instance;
           return meta.addIDFileToPassport.call(this_address, doc_hash);
       })
       .then(returned_tuple => {
           assert.equal(returned_tuple[0], this_address, "Passport controller, passed and returned by PassportManager.addIDFileToPassport(), should match!");
           assert.equal(returned_tuple[1], doc_hash, "Document hash (bytes32), passed and returned by PassportManager.addIDFileToPassport(), should match!");
           assert.equal(returned_tuple[2], 1, "Trust score of newly added doc_hash should be 1!");
       });
   });

為將來提出這個問題的任何人回答並結束我自己的問題:

  1. 程式碼“繁榮”在我的智能合約中,從 VM 異常錯誤和revert事情就可以看出。我養成了在solidity 中臨時將錯誤日誌添加到我的require()語句中的習慣,因此我設法跟踪它在哪里中斷。因此,請務必require(foo == true, "foo shouldn't be false!");嘗試和跟踪事物。
  2. 我的問題是太累了,無法閱讀整個 truffle+ganache 文件。在 truffle 測試中,呼叫不會對區塊鏈進行持久更改(不要問我如何,但它們似乎是事務的干執行),所以我的第一個測試沒有留下任何東西。為了使更改在測試之間保持不變,我實際上需要向我的 ganache 區塊鏈發送適當的交易。

這使得我的更改從測試 1 持續到測試 2,並且我設法通過了測試。

我所做的是:

  • 空執行我的測試call()並測試返回的結果(因為事務實際上並不返回結果,它們返回一個 tx id,你必須手動調試它)
  • 如果呼叫一切順利,我會通過直接呼叫該方法進行適當的交易(在我的情況下,我從meta.initPassport.call("John Doe");meta.initPassport("John Doe", {from: accounts[0]});- 簡單,對吧?我猜不是。關於那個特殊的第二個參數的更多資訊(在我的契約上,initPassport()只需要1 個參數,但我們在 test.js 中的事務上傳遞 2)可以在這裡找到:https ://www.trufflesuite.com/docs/truffle/getting-started/interacting-with-your-contracts#making-a-交易
  • 我的交易對我已部署(遷移)的合約留下了持久的更改,因此我繼續進行測試 2,並在那裡進行呼叫或交易。但至少在測試 2 中,我現在可以測試以前的條件和結果!

引用自:https://ethereum.stackexchange.com/questions/94692