Good day all, I am learning Solidity, and I came up with this issue while deploying my contract yesterday.
So I can deploy it correctly, and the calls to the readonly function getVotes()
seem to work ok.
When I deploy it on test net, and use tronBox (in a browser environment)
const tronWeb = window.tronWeb;
const contractAddress = 'TFBP2xBhYTb2hNrLep5UpFW1a2DZ5AP4yY';
let contract;
try {
contract = await tronWeb.contract().at(contractAddress);
} catch(e) {
console.error(`error loDING CONTRACT ${contractAddress}`);
throw e
}
//
//
try {
let votes = await contract.getVotes().call();
console.log(`Loading All votes from TRON `, votes);
} catch(e) {
console.error(`error getting votes`, votes);
throw e
}
try {
const txId = await contract.voteBooks([35, 36], [3, 4]).send()
console.log(`Check tx on the explorer: https://shasta.tronscan.org/#/transaction/${txId}`);
} catch(e) {
console.error(`error voting`, e);
throw e
}
The 3d try/catch block doesnāt throw any error, and the console log shows check tx on the explorer:
When I go check it out, the transaction failed, and I cannot find any debug information that could help me figure out what is going on, and why it failed. So I am turning to the TRON experts out there that eat solidity at breakfast, and can spot bugs effortlessly while doing cardio.
Here is the contract on Shasta: TRONSCAN | TRON BlockChain Explorer | ę³¢åŗåŗåé¾ęµč§åØ
I cannot seem to explore why the transaction failed, and I am quite stuck.
Here is the contract source code:
pragma solidity >=0.7.0 <0.9.0;
uint8 constant ILLEGAL = 1;
uint8 constant POOR = 2;
uint8 constant OK = 3;
uint8 constant GREAT = 4;
struct BookVote {
bool initialized;
uint8 classification;
}
struct UserVotes {
mapping(uint256 => BookVote) data;
bool initialized;
}
contract BookVotes {
// user Data
address[] all_addresses;
mapping(address => UserVotes) user_votes;
// all Data
uint256[] public ids;
// map[id] index
mapping(uint256 => uint256) public idsIndex;
uint256[] public illegal;
uint256[] public ok;
uint256[] public poor;
uint256[] public great;
constructor() {
ids.push(0);
}
function addGlobalVote(uint256 bookId, uint8 cl) public {
if (idsIndex[bookId] == 0) {
ids.push(bookId);
illegal.push(0);
ok.push(0);
poor.push(0);
great.push(0);
idsIndex[bookId] = ids.length - 1;
}
uint index = idsIndex[bookId];
if (cl == GREAT) {
great[index]++;
} else if (cl == OK) {
ok[index]++;
} else if (cl == POOR) {
poor[index]++;
} else if (cl == ILLEGAL) {
illegal[index]++;
}
}
function removeGlobalVote(uint256 bookId, uint8 cl) private {
require(idsIndex[bookId] > 0, "cannot remove vote for book");
uint index = idsIndex[bookId];
if (cl == GREAT) {
great[index]--;
} else if (cl == OK) {
ok[index]--;
} else if (cl == POOR) {
poor[index]--;
} else if (cl == ILLEGAL) {
illegal[index]--;
}
}
function voteBooks(uint256[] memory bookIds, uint8[] memory classifications) public {
if (user_votes[msg.sender].initialized == false) {
all_addresses.push(msg.sender);
user_votes[msg.sender].initialized = true;
for (uint i = 0; i < bookIds.length; i++) {
user_votes[msg.sender].data[bookIds[i]].initialized = true;
user_votes[msg.sender].data[bookIds[i]].classification = classifications[i];
}
} else {
// user is already in the mapping
for (uint i = 0; i < bookIds.length; i++) {
uint8 cl = classifications[i];
uint256 book = bookIds[i];
if (user_votes[msg.sender].data[book].initialized) {
// book has already been voted upon in the past
if (cl != user_votes[msg.sender].data[book].classification) {
// the book classification has been updated
// TODO: Runs allVotes
removeGlobalVote(book, cl);
}
user_votes[msg.sender].data[book].classification = cl;
} else {
user_votes[msg.sender].data[book].classification = cl;
user_votes[msg.sender].data[book].initialized = true;
}
addGlobalVote(book, cl);
}
}
}
function getVotes() public view returns (uint256[] memory, uint256[] memory, uint256[] memory, uint256[] memory, uint256[] memory) {
return (ids, illegal, poor, ok, great);
}
}