I have a contract that does the following:
- It maintains a list of items, which stores the name, id, sold status etc.
- I have a function,
createItem
, which creates these items and requires the name of the item. - I have a function,
purchaseItem
, this function sets the items[_id].sold = true.
pragma solidity >=0.4.22 <0.9.0;
contract TradeCoin {
uint public count = 0;
struct Item {
uint id;
string name;
bool sold;
uint unit;
address seller;
address buyer;
}
constructor() {
createItem('Bedframe', '1');
createItem('Gaming Chair', '1');
createItem('Dining Table', '1');
}
mapping(uint => Item) public items;
function createItem(string memory _name, uint _unit) public {
count++;
items[count] = Item(count, _name, false, _unit, msg.sender, address(0));
}
function buyItem() public {
}
function purchaseItem(uint _id) public {
items[_id].sold = true;
}
}
Problem:
I am able to call createItem, but I am unable to call purchaseItem in the truffle console.
This is the error I am getting back which isn't very helpful
truffle(development)> Uncaught Error: Returned error: VM Exception while processing transaction: revert
at evalmachine.<anonymous>
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
data: {
'0xbad383e14adc1990474ef7426b3b9948601896f605094db59979153102f379d5': { error: 'revert', program_counter: 98, return: '0x' },
stack: 'RuntimeError: VM Exception while processing transaction: revert\n' +
' at Function.RuntimeError.fromResults (/tmp/.mount_ganachwOodBT/resources/static/node/node_modules/ganache-core/lib/utils/runtimeerror.js:94:13)\n' +
' at BlockchainDouble.processBlock (/tmp/.mount_ganachwOodBT/resources/static/node/node_modules/ganache-core/lib/blockchain_double.js:627:24)\n' +
' at runMicrotasks (<anonymous>)\n' +
' at processTicksAndRejections (internal/process/task_queues.js:93:5)',
name: 'RuntimeError'
},
hijackedStack: 'Error: Returned error: VM Exception while processing transaction: revert\n' +
' at Object.ErrorResponse (/home/jennifer/.nvm/versions/node/v17.1.0/lib/node_modules/truffle/build/webpack:/node_modules/web3-core-helpers/lib/errors.js:28:1)\n' +
' at /home/jennifer/.nvm/versions/node/v17.1.0/lib/node_modules/truffle/build/webpack:/node_modules/web3/node_modules/web3-core-requestmanager/lib/index.js:302:1\n' +
' at /home/jennifer/.nvm/versions/node/v17.1.0/lib/node_modules/truffle/build/webpack:/packages/provider/wrapper.js:107:1\n' +
' at XMLHttpRequest.request.onreadystatechange (/home/jennifer/.nvm/versions/node/v17.1.0/lib/node_modules/truffle/build/webpack:/node_modules/web3/node_modules/web3-providers-http/lib/index.js:98:1)\n' +
' at XMLHttpRequestEventTarget.dispatchEvent (/home/jennifer/.nvm/versions/node/v17.1.0/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:1)\n' +
' at XMLHttpRequest.exports.modules.996763.XMLHttpRequest._setReadyState (/home/jennifer/.nvm/versions/node/v17.1.0/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:208:1)\n' +
' at XMLHttpRequest.exports.modules.996763.XMLHttpRequest._onHttpResponseEnd (/home/jennifer/.nvm/versions/node/v17.1.0/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:318:1)\n' +
' at IncomingMessage.<anonymous> (/home/jennifer/.nvm/versions/node/v17.1.0/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:289:47)\n' +
' at IncomingMessage.emit (node:events:402:35)\n' +
' at IncomingMessage.emit (node:domain:537:15)\n' +
' at endReadableNT (node:internal/streams/readable:1340:12)\n' +
' at processTicksAndRejections (node:internal/process/task_queues:83:21)'
}
I know that items[0] exist because I created that in the constructor. I was even able to get items[0]. I tried to recreate this in Remix, I can call purchaseItem without any issue.
I thought maybe the deployed contract is out of sync, so I tried deploying it multiple times and I know it does get updated. Because if I changed the parameter of purchaseItem to 0 parameter, it throws an error saying that purchaseItem has 0 arguments but 1 was given
.
I then made an even simpler function called buyItem
, which does nothing. Even that is throwing this error. This makes me think it's not an issue with the function itself but how it's being called?
Details on Migration/Test
1_initial_migration.js
/* eslint-disable no-undef */
const Migrations = artifacts.require("Migrations");
module.exports = function (deployer) {
deployer.deploy(Migrations);
};
1_deploy_contracts.js
/* eslint-disable no-undef */
const TradeCoin = artifacts.require("./TradeCoin.sol");
module.exports = function(deployer) {
deployer.deploy(TradeCoin);
}
Here is how the Transaction shows up in Gnache
It also appears that it's not an out-of-gas issue, which some people suggested could cause this error sometimes.
Truffle Config
module.exports = {
contracts_build_directory: "./src/contracts/",
networks: {
development: {
host: "127.0.0.1", // Localhost (default: none)
port: 7545, // Standard Ethereum port (default: none)
network_id: "*", // Any network (default: none)
},
// Set default mocha options here, use special reporters etc.
mocha: {
// timeout: 100000
},
// Configure your compilers
compilers: {
solc: {
version: "0.8.10", // Fetch exact version from solc-bin (default: truffle's version)
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
settings: { // See the solidity docs for advice about optimization and evmVersion
optimizer: {
enabled: true,
runs: 200
},
evmVersion: "byzantium"
}
}
},
};
Truffle Debugger Output I also tried stepping through the code using Truffle Debugger. It appears that there are 38 steps. And it fails on the 38th. I am not really sure what the instructions do and why after DUP1, it would do revert.
What could the issue be? Any advice on where I should look for debugging. Thanks for the help.