I'm using truffle, the ganache AppImage to run a personal blockchain, and have 2 solidity smart contracts Migrations.sol
and PassportManager.sol
I'm running a truffle test and getting Error: Returned error: VM Exception while processing transaction: revert
so I'm guessing something's wrong with my deployed contract, something is throwing an exception in my deployed code.
How can I debug this?
I'm not using Remix and I'd hate to add MORE tools to my toolbox. Just truffle, ganache and my text editor so far, and I'd like to keep it simple.
Running my tests on JavaScript only creates 4 blocks (4 transactions) on Ganache, and none of those 4, tested with truffle debug <tx-id>
brings up any useful info – one of the txes returns the bytecode for deploying PassportManager.sol
(which happens every time for some reason!) and the other 3 all have something to do with Migrations.sol
.
Here's the tests and code just so you know what's up:
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]);
}
And the failing test:
/* 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!");
});
});
Best Answer
To answer and close my own question for anyone coming up on it in the future:
revert
thing. I got into the habit of temporarily adding error logging to myrequire()
statements inside solidity, so I managed to track where it was breaking. So, do userequire(foo == true, "foo shouldn't be false!");
to try and track things.That made my changes persist from test 1 to test 2, and I managed to get passing tests.
What I did was:
call()
and test returned results (because Transactions don't actually return results, they return a tx id and you gotta debug that manually)meta.initPassport.call("John Doe");
tometa.initPassport("John Doe", {from: accounts[0]});
- simple, right? I guess not. More info on that special second parameter (on my contract,initPassport()
only takes 1 parameter, but we pass 2 on the transaction inside test.js) can be found here: https://www.trufflesuite.com/docs/truffle/getting-started/interacting-with-your-contracts#making-a-transaction