I can't work out what i'm doing wrong here. Why can't i get a simple uint to return from my contract when running using hardhat tests?
Contract.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import 'hardhat/console.sol';
import "@openzeppelin/contracts/access/AccessControl.sol";
contract Contract is AccessControl {
using SafeMath for uint256;
constructor() {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
function doIt() public returns (uint256) {
console.log("Returning 1 from contract");
return 1;
}
}
Test.js
const { expect, assert } = require("chai");
const { ethers, upgrades } = require("hardhat");
describe("Contract", function () {
let acontract;
beforeEach(async function () {
// Deploying contract
const aContract = await ethers.getContractFactory("Contract");
acontract = await aContract.deploy();
await acontract.deployed();
console.log(`Contract deployed to ${acontract.address}`);
});
describe("test contract", function () {
it("doIt", async function () {
console.log(JSON.stringify(await acontract.doIt()));
});
});
});
Output:
npx hardhat test test-test/test.js
Contract
test contract
Contract deployed to 0x5FbDB2315678afecb367f032d93F642f64180aa3
Returning 1 from contract
{"hash":"0x2e7cd7d48db5bf437d117ca6c2de3d067c4299fba02b55b69d7a0037a01de74f","type":2,"accessList":[],"blockHash":"0xb15cbb79171f086b59bfa277aa643510022bc787098c4e3a77309c939ae36885","blockNumber":2,"transactionIndex":0,"confirmations":1,"from":"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266","gasPrice":{"type":"BigNumber","hex":"0x6978bc25"},"maxPriorityFeePerGas":{"type":"BigNumber","hex":"0x3b9aca00"},"maxFeePerGas":{"type":"BigNumber","hex":"0x9756ae4a"},"gasLimit":{"type":"BigNumber","hex":"0x01bad458"},"to":"0x5FbDB2315678afecb367f032d93F642f64180aa3","value":{"type":"BigNumber","hex":"0x00"},"nonce":1,"data":"0xb29f0835","r":"0x1c77fabb8795afe562dd6772bd3c26db9b73f94d0be5774dfc3488a3a1e6d299","s":"0x30a98924f50a02f6f06698edf29b14d1be2f3fddea60cba276a4e60a3198e33d","v":0,"creates":null,"chainId":31337}
✓ doIt
Any help appreciated. Thanks
Best Answer
When you call a non view/pure function, ethers creates and signs a transaction. Ethers then returns the transaction data and not the value returned by your solidity function (the value is actually encoded in the transaction hash). You can get the returned value by:
view
if it does not change the state of the contract, or topure
if it does not access state variablesA more detailed explanation is available here