为什么事务消耗公共视图函数的gas ?



我在Ropsten以太坊测试网络上部署了以下智能合约,之后我尝试使用@alch/Alchemy -web3 npm包进行交易(是的,我正在使用Alchemy API),但正如你所看到的,我对交易收取了费用。为什么呢?公共视图函数调用不应该花费0 gas吗?

已部署智能合约

// SPDX-Lincense-Identifier: MIT
pragma solidity ^0.8.11;
contract VendingMachine {
address public owner;
mapping(address => uint256) public donutBalances;
constructor() {
owner = msg.sender;
donutBalances[address(this)] = 100;
}
function getVendingMachineBalance() public view returns (uint256) {
return donutBalances[address(this)];
}
function restock(uint amount) public {
require(msg.sender == owner, "Only the owner can restock this machine.");
donutBalances[address(this)] += amount;
}
function purchase(uint amount) public payable {
require(msg.sender == owner, "Only the owner can restock this machine.");
require(donutBalances[address(this)] >= amount, "Not enough donuts in stock to fulfill purchase request.");
require(msg.value >= amount*2 ether, "You must pay at least 2 ether / donut.");
donutBalances[address(this)] -= amount;
donutBalances[msg.sender] += amount;
}  
}

交易码javascript

const { API_URL, METAMASK_ACCOUNT_PRIVATE_KEY, METAMASK_ACCOUNT_PUBLIC_KEY } = process.env;
const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
const web3 = createAlchemyWeb3(`${API_URL}`);
const contractAddress = '0xc7E286A86e4c5b8F7d52fA3F4Fe7D9DE6601b6F9'
const contractAPI = new web3.eth.Contract(contract.abi, contractAddress)
const nonce = await web3.eth.getTransactionCount(METAMASK_ACCOUNT_PUBLIC_KEY, 'latest');
const transaction = {
to: contractAddress, // faucet address to return eth
gas: 500000,
nonce: nonce,
data: contractAPI.methods.getVendingMachineBalance().encodeABI()
// optional data field to send message or execute smart contract
};
const signedTx = await web3.eth.accounts.signTransaction(transaction, METAMASK_ACCOUNT_PRIVATE_KEY)
web3.eth.sendSignedTransaction(signedTx.rawTransaction, function (error, hash) {
if (!error) {
console.log("🎉 The hash of your transaction is: ", hash, "n Check Alchemy's Mempool to view the status of your transaction!");
} else {
console.log("❗Something went wrong while submitting your transaction:", error)
}
});

事务:https://ropsten.etherscan.io/tx/0x8ce3a288072809a804adac2206dc566dfb3eb3ddba3330bcb52ca6be71963b71

与智能合约交互的方式有两种。<<strong>事务/strong>(读写,需要gas费)和调用(只读,无气体)。

你的JS片段发送一个事务。如果你想用一个(无气体)调用来调用getVendingMachineBalance()函数,你可以使用。call() web3js方法。

const contractAPI = new web3.eth.Contract(contract.abi, contractAddress);
const response = await contractAPI.methods.getVendingMachineBalance().call();