I have a simple smart contract code for a test ether faucet. It needs 100 wei initially to deploy:
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
);
}
}
I created the compile script using the standard practice and the code compiles fine without error. I also have it log the ABI which looks good (and it exactly matches the ABI Remix outputs when I compile it on 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;
After compiling, I deploy the smart contract and log the address it has been deployed to. It compiles without error. I am POSITIVE my sepolia Infura end point is correct and has worked fine on other projects.
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();
I get the below error in the console when I hook up the address to the front end. There is nothing wrong with the frontend code. It has to do with the way the contract is being deployed...Seems like the infura endpoint is not opertaing correctly?
App.js:21 Error fetching contract data: AbiError: Parameter decoding error: Returned values aren't valid, did it run Out of Gas? You might also see this error if you are not using the correct ABI for the contract you are retrieving data from, requesting data from a block number that does not exist, or querying a node which is not fully synced.
When I lookup the contract in Remix (the one I deployed using the deploy.js script), all values return as 0. Remix image here
The contract should deploy just like it does in Remix. The identical code deploys in Remix (using the Remix internal tools) without issue.
Infura does not support making
eth_sendTransactionmethod (which is used when you need to sign a transaction, like yourfaucetDripfunction).To sign a transaction, a private key is required. Since Infura provides no support for key management, such transactions are not supported.
If you need to use Infura, what you can instead do is use
eth_sendRawTransaction. Using this, you can create a transaction, get it signed using your private key, and then share transaction payload and signature to Infura.So you can do something like: