我有一个用于测试以太水龙头的简单智能合约代码。初始部署需要 100 wei:
pragma solidity ^0.8.21;
contract EthRiver {
address public owner;
uint public drip;
uint public totalDonations;
mapping (address => uint) public lastDrip;
uint public dripInterval;
constructor() payable {
owner = msg.sender;
require(msg.value >= 100, "Initial balance for the Faucet must be greater than or equal to 10,000 wei");
}
function faucetDrip( address payable inputAddress) public payable {
dripInterval = 180;
drip = 10;
if(lastDrip[inputAddress]==0){
lastDrip[inputAddress] = block.timestamp;
} else {
require (block.timestamp >= lastDrip[inputAddress] + dripInterval, "Address can only receive drip once every 3 minutes");
}
inputAddress.transfer(drip);
lastDrip[inputAddress] = block.timestamp;
}
function faucetDonate() public payable {
require(msg.value > 0, "Donation amount must be greater than zero");
totalDonations += msg.value;
}
function getFaucetSummary() public view returns (uint, uint) {
return (
address(this).balance,
totalDonations
);
}
}
我使用标准实践创建了编译脚本,代码编译良好,没有错误。我还让它记录了看起来不错的 ABI(当我在 Remix 上编译它时,它与 ABI Remix 输出完全匹配):
const path = require("path");
const fs = require("fs");
const solc = require("solc");
const contractPath = path.resolve(__dirname, "contracts", "ethrivercontract.sol");
const source = fs.readFileSync(contractPath, 'utf8');
const input = {
language: "Solidity",
sources: {
"ethrivercontract.sol": {
content: source,
},
},
settings: {
metadata: {
useLiteralContent: true
},
outputSelection: {
"*": {
"*": ["*"]
}
}
}
};
const output = JSON.parse(solc.compile(JSON.stringify(input)));
const contractABI = output.contracts['ethrivercontract.sol']['EthRiver'].abi;
console.log('Contract ABI:', JSON.stringify(contractABI, null, 4));
module.exports = output.contracts["ethrivercontract.sol"].EthRiver;
编译后,我部署智能合约并记录其已部署到的地址。它编译没有错误。我确信我的 sepolia Infura 端点是正确的,并且在其他项目上运行良好。
const HDWalletProvider = require('@truffle/hdwallet-provider');
const { Web3 } = require('web3');
const { abi, evm } = require("./compile");
const provider = new HDWalletProvider({
mnemonic: {
phrase: ' 12 word phrase'
},
providerOrUrl: 'https://sepolia.infura.io/v3/xxxxxxxxxxxxxxxxxxxxxxxxxxx'
});
const web3 = new Web3(provider);
const deploy = async () => {
const accounts = await web3.eth.getAccounts();
console.log('Attempting to deploy from account', accounts[0]);
const result = await new web3.eth.Contract(abi)
.deploy({ data: "0x" + evm.bytecode.object })
.send({ gas: '10000000', from: accounts[0], value:'100' });
console.log('Contract deployed to', result.options.address);
provider.engine.stop();
};
deploy();
当我将地址连接到前端时,我在控制台中收到以下错误。前端代码没有任何问题。这与合约的部署方式有关...似乎 infura 端点运行不正确?
App.js:21 获取合约数据时出错:AbiError:参数解码错误:返回值无效,是否耗尽了 Gas?如果您没有为从中检索数据的合约使用正确的 ABI、从不存在的区块号请求数据或查询未完全同步的节点,您也可能会看到此错误。
当我在 Remix 中查找合约(我使用 deploy.js 脚本部署的合约)时,所有值都返回为 0。
合约应该像在 Remix 中一样部署。相同的代码在 Remix 中部署(使用 Remix 内部工具)没有问题。
Infura 不支持制作
eth_sendTransaction
方法(当您需要签署交易时使用该方法,如您的 faucetDrip
函数)。
要签署交易,需要私钥。由于 Infura 不支持密钥管理,因此不支持此类交易。
如果您需要使用Infura,您可以使用
eth_sendRawTransaction
。使用此功能,您可以创建交易,使用您的私钥对其进行签名,然后将交易负载和签名共享给 Infura。
eth_sendRawTransaction
提交预签名交易以广播到以太坊网络。
https://docs.infura.io/networks/ethereum/json-rpc-methods/eth_sendrawtransaction