During my development process, I've spotted differences between calling function in my contract from script and from dApp. Whole thing is done on hardhat local network.
Script call:
eth_call
Contract call: Contract#earningInfo
From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
To: 0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0
dApp call:
eth_sendTransaction
Contract call: Contract#earningInfo
Transaction: 0xf58da19368c9aa20c9c33d4177af0efb8c08fd9bcbc59cdfd9c9abcb09742bc2
From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
To: 0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0
Value: 0 ETH
Gas used: 23242 of 23242
Block #6: 0x4389bde0717095ed768297b51425d805d99358f985592e3027f21d9ec1585280
This of course has some effects on the response itself. While first call (script) is returning plain response - second call(dApp) is returning me transactionInfo, which I probably can turn into receipt adn get Event from there, but... I think, that I miss something. Contract itself is a view, without nested calls:
function earningInfo(address account, uint256[] calldata _nftIds) external view returns (uint256[1] memory info) {
uint256 earned = 0;
for (uint i = 0; i < _nftIds.length; i++) {
Stake memory staked = vault[_nftIds[i]];
require(staked.owner == account, "not an owner");
uint256 stakedAt = staked.timestamp;
earned += tokensPerDay * 1 ether * (block.timestamp - stakedAt) / 86400;
}
return [earned];
}
Call from dApp:
export const stakingEarningInfoQueryForTokens = async (userAddress: string, tokenIds: number[]): Promise<any> => {
console.log('calling earning info', userAddress, tokenIds);
const { contract } = await getProvider(chain, address, abi);
return contract.earningInfo(userAddress, tokenIds);
};
And getProvider function:
export const getProvider = async (chain: string, address: string, abi: string[] ) => {
const provider = new JsonRpcProvider(rpc[chain].rpcUrl);
const signer = await provider.getSigner();
const contract = new Contract(address, abi, signer);
return {
provider,
signer,
contract
};
};
I don't have to confirm this transaction in wallet (MetaMask).
Follow up question might be - is the only difference between eth_call and eth_sendTransaction is that the latter one is executed on the chain - therefore it cost money + different response type? :)