Solidity
松露測試因“錯誤:返回錯誤:處理事務時出現 VM 異常:還原”而失敗 - 我該如何調試它?
我正在使用 truffle、ganache AppImage 來執行個人區塊鏈,並擁有 2 個solidity 智能合約
Migrations.sol
和PassportManager.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!"); }); });
為將來提出這個問題的任何人回答並結束我自己的問題:
- 程式碼“繁榮”在我的智能合約中,從 VM 異常錯誤和
revert
事情就可以看出。我養成了在solidity 中臨時將錯誤日誌添加到我的require()
語句中的習慣,因此我設法跟踪它在哪里中斷。因此,請務必require(foo == true, "foo shouldn't be false!");
嘗試和跟踪事物。- 我的問題是太累了,無法閱讀整個 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 中,我現在可以測試以前的條件和結果!