How do I solve the Smart Contract error "returned values aren't valid"? - ethereum

I am trying to read basic information from a smart contract using web3.js (GRAPH Token):
https://etherscan.io/address/0xc944e90c64b2c07662a292be6244bdf05cda44a7#code
This is my super simple react web3.js setup:
import Web3 from 'web3';
...
useEffect(() => {
const start = async () => {
const web3 = new Web3('https://bsc-dataseed1.binance.org:443')
const abi = [{"inputs":[{"internalType":"uint256","name":"_initialSupply","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"MinterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"MinterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"NewOwnership","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"NewPendingOwnership","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"addMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingGovernor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"uint256","name":"_deadline","type":"uint256"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"removeMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newGovernor","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
const address = '0xc944E90C64B2c07662A292be6244BDf05Cda44a7'
const contract = new web3.eth.Contract(abi, address)
console.log(contract);
const i = await contract.methods.getName().call()
console.log(i); // => ERROR
}
start()
}, [])
And it throws error:
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.
This is a known and misleading error which usually means that the address or the contract abi is invalid but I verified it is correct.
I researched this error for two days but didn't manage to solve this issue... any suggestions?

You're trying to interact with an Ethereum contract, using a BSC (Binance Smart Chain) Web3 provider (in your case https://bsc-dataseed1.binance.org:443). This results in trying to call the getName() function on the BSC address (which doesn't contain any contract).
Ethereum and BSC are different networks, unrelated to each other.
Solution: Use an Ethereum mainnet provider (for example Infura is widely used).

Related

How to get the address of a contract deployed by another contract

-----START EDIT-----
I don't know what I was doing wrong before, but the code below was somehow not working for me, and now is working, and it's exactly the same. I don't know how or what I was missing before, but both this minimal example and the real project I am working on is working now. Obviously I changed something, but I can't figure out what. I just know it's working now. Sorry for the confusion and thanks to everyone for helping.
-----END EDIT-----
I am new to Solidity and am using the Factory pattern for deploying a contract from another contract. I am trying to get the contract address of the deployed contract, but I am running into errors.
I already tried the solution in this question, but I'm getting the following error: Return argument type struct StorageFactory.ContractData storage ref is not implicitly convertible to expected type (type of first return variable) address.
Here is my code:
// START EDIT (adding version)
pragma solidity ^0.8.0;
// END EDIT
contract StorageFactory {
struct ContractData {
address contractAddress; // I want to save the deployed contract address in a mapping that includes this struct
bool exists;
}
// mapping from address of user who deployed new Storage contract => ContractData struct (which includes the contract address)
mapping(address => ContractData) public userAddressToStruct;
function createStorageContract(address _userAddress) public {
// require that the user has not previously deployed a storage contract
require(!userAddressToStruct[_userAddress].exists, "Account already exists");
// TRYING TO GET THE ADDRESS OF THE NEWLY CREATED CONTRACT HERE, BUT GETTING AN ERROR
address contractAddress = address(new StorageContract(_userAddress));
// trying to save the contractAddress here but unable to isolate the contract address
userAddressToStruct[_userAddress].contractAddress = contractAddress;
userAddressToStruct[_userAddress].exists = true;
}
}
// arbitrary StorageContract being deployed
contract StorageContract {
address immutable deployedBy;
constructor(address _deployedBy) {
deployedBy = _deployedBy;
}
}
How can I get this contract address, so I can store it in the ContractData struct? Thanks.
I compiled your contract, deployed it on Remix, and interacted without issue with this setting
pragma solidity >=0.7.0 <0.9.0;
I think you had this in your contract before
userAddressToStruct[_userAddress] = contractAddress;
instead of this
userAddressToStruct[_userAddress].contractAddress = contractAddress;
You can use the following code to get the address of the deployed contract:
address contractAddress;
(contractAddress,) = new StorageContract(_userAddress);
userAddressToStruct[_userAddress].contractAddress = contractAddress;

Automatically pointing contract address to solidity interface

I'm trying to use a interface on remix IDE and my only issue is that I have to copy and paste the contract's address.
Is there a way that I can point it automatically?
ty.
In Remix IDE, you need to copy and paste the newly deployed address manually.
With frameworks, such as Hardhat, you can retrieve the address of the deployed contract in the code and then pass it to the other contract.
In the example below, we're passing the address of First instance to Second's constructor, using the Hardhat JS framework.
const firstFactory = await ethers.getContractFactory("First");
const first = await firstFactory.deploy();
await first.deployed();
const secondFactory = await ethers.getContractFactory("Second");
const second = await secondFactory.deploy(first.address);
await second.deployed();
pragma solidity ^0.8;
contract First {}
contract Second {
constructor(address firstAddress) {}
}

Passing wallet argument in ethers Contract function

I am trying to create an instance of a contract on ethers.
const example = new ethers.Contract(CONTRACT_ADDRESS, contractABI, signer);
I am using a wallet directly instead of getting a signer through metamask ( I am aware of the risks)
Here is my "signer":
const signer = new ethers.Wallet("PRIVATE_KEY");
When i try to execute the code I get:
ethers-5.5.4.esm.min.js:1 Uncaught (in promise) Error: invalid address or ENS name (argument="name", value={"_isSigner":true,"address":"0x92388d12744B418eFac8370B266D31fd9C.....","provider":null}, code=INVALID_ARGUMENT, version=contracts/5.5.0)
Do I have a syntax error? or is this not the correct way to pass a wallet as a signer
I think you might miss your provider there, you'll need to add provider object like this
const url = "RPC Node URL"
const provider = new ethers.providers.JsonRpcProvider(url);
const signer = new ethers.Wallet("PRIVATE_KEY", provider);
Use the right RPC Node network to interact with the right blockchain. You can either use public or private RPC, but for production it is recommended to use private services.
You did not connect to the signer. From docs
// this creates a new contract address
new ethers.Contract( address , abi , signerOrProvider )
// Returns a new instance of the Contract, but connected to providerOrSigner.
contract.connect( providerOrSigner ) ⇒ Contractsource
In your code:
example.connect(signer)

Cannot switch signers with ethers.js for a contract interaction using Hardhat

Hardhat specifies that to use a different account for contract interactions you should use the connect() method, passing it a Signer, as such:
const [owner, addr1] = await ethers.getSigners();
/* ... */
await greeter.connect(addr1).setGreeting("Hello!");
Where greeter is the contract instance.
However, when I use a Signer as they specify to, I get the following error:
Error: invalid address or ENS name (argument="name", value="<SignerWithAddress 0x59F...34C>", code=INVALID_ARGUMENT, version=contracts/5.6.0)
The internet says to use an address, such as this issue suggesting to use something like addr1.address. But when I do, the following error results:
VoidSigner cannot sign transactions (operation="signTransaction", code=UNSUPPORTED_OPERATION, version=abstract-signer/5.6.0)
How can I switch signers/accounts when making contract calls with ethers.js and Hardhat?
The error you get is because you are not passing in the full address object.
Specifically, I get your exact error when I do this:
This does not work, but reproduces your error:
[deployer, account1] = await ethers.getSigners();
address1 = account1.address;
/* ... */
await greeter.connect(address1).setGreeting("Hello!");
This works, however:
[deployer, account1] = await ethers.getSigners();
/* ... */
await greeter.connect(account1).setGreeting("Hello!");
Notice that we do not call ".address" on account1 in the second example.

How to inject Binance Wallet into Web3 instead of Metamask?

I started using Binance Chain Wallet in my dapp, so I can now use:
import { BscConnector } from '#binance-chain/bsc-connector'
export const bsc = new BscConnector({
supportedChainIds: [56, 97] // later on 1 ethereum mainnet and 3 ethereum ropsten will be supported
})
// invoke method on bsc e.g.
await bsc.activate();
await bsc.getAccount();
await bsc.getChainId();
but in API docs it says to do some chain operations I need to iject :
The biggest difference between Binance Chain Wallet and MetaMask is we inject BinanceChain rather than ethereum (or web3) to the web page. So user could keep two extensions at the same time.
BinanceChain.request({method: "eth_sign", params: ["address", "message"])
with metamsk I use
ethereum.request(...)
can you explain to me how to do this?
BinanceChain obj is not declared :)
So I figured out that these steps are necessarily :
// create instance of bsc wallet
const bsc = new BscConnector({
supportedChainIds: [56, 97, 1] // later on 1 ethereum mainnet and 3 ethereum ropsten will be supported
})
// get provider out of this instance:
const bsc_provider = await bsc.getProvider()
provider = new ethers.providers.Web3Provider(bsc_provider)
// from here u can use all binance wallet functions:
provider.provider.switchNetwork('eth-mainnet')
see docs:
binance wallet docs