为什么交易要消耗gas来实现公共视图功能?

Lup*_*lol 0 javascript ethereum solidity web3js

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

\n

部署的智能合约

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

交易代码 JavaScript

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

交易:https://ropsten.etherscan.io/tx/0x8ce3a288072809a804adac2206dc566dfb3eb3ddba3330bcb52ca6be71963b71

\n

Pet*_*jda 5

有两种与智能合约交互的方式。一笔交易(读写,需要 Gas 费)和一次调用(只读,无 Gas 费)。

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

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