Error: invalid BigNumber value (argument="value", value={"value":"25000000000000000"}, code=INVALID_ARGUMENT, version=bignumber/5.5.0) - ethereum

I have tried changing the values from 0.025 ether to 1 ether then also its showing the same error.
Also, I have tried with the rational number like 1/8 still not working.
LOOKED into some answers but they didn't resolve the error.
I have the same code in other project and it's working over there.
Error Which I received
Uncaught (in promise) Error: invalid BigNumber value (argument="value", value={"value":"25000000000000000"}, code=INVALID_ARGUMENT, version=bignumber/5.5.0)
Could not get the stack frames of error: TypeError: Cannot read properties of null (reading 'length')
Image of the Error
Here is my Code for the Listing Price
uint256 listingPrice = 0.025 ether ; // Here ether is denoting the MATIC
function getListingPrice() public view returns (uint256) {
return listingPrice;
}
Here is the Code for fetching the value in UI
async function putItem(url) {
const web3Modal = new Web3Modal();
const connection = await web3Modal.connect();
const provider = new ethers.providers.Web3Provider(connection);
const signer = provider.getSigner();
const { royalty } = formInput;
//NFT Contract
let contract = new ethers.Contract(nftAddress, NFT.abi, signer);
//minting the certificate
let transaction = await contract.createToken(url);
//waiting for the minting transaction to finish
let tx = await transaction.wait();
let event = tx.events[0];
let value = event.args[2];
let tokenId = value.toNumber(); //Token Id Of the NFT
console.log(tokenId)
//NFT Market Contract
contract = new ethers.Contract(nftMarketAddress, NFTMarket.abi, signer);
//fetching listing price from the contract
let listingPrice = await contract.getListingPrice();
listingPrice = listingPrice.toString();
//listing the certificate.
transaction = await contract.createMarketItem(
nftAddress,
tokenId,
{ value: (listingPrice) },
royalty,
index
);
//waiting for the transaction to complete
await transaction.wait();
console.log("completed")
//navigate back to home page
}
If any more detail required, please comment.

It looks like you're trying to send an object as the parameter { value: (listingPrice) }
This should probably be written as either an array of parameters or just the listingPrice
//listing the certificate.
transaction = await contract.createMarketItem(
nftAddress,
tokenId,
listingPrice,
royalty,
index
);
Source: https://docs.ethers.io/v5/api/contract/contract/#contract-functionsSend

For my case I needed to add .toString() to the BigNumber before passing it to the contract.
async changePayoutAmount_ether(amount_ether) {
let amount_wei = new BigNumber(amount_ether).shiftedBy(18).toString()
await this.state.pcrContract.methods.setPayoutAmount(amount_wei).send({from: this.state.account}).then(console.log)
}
Also for anyone troubleshooting, note that there are at least two BigNumber libraries: I believe this error comes from this one but be careful if you're reading docs from the ethers.js one because the syntax for the constructors is different.

I got this error as well. In my case, I forgot to update the ABI.

You can use the following module:
import converter form "ethereum-uint-converter"
And if you want to know more detail, click here.

I think this is the issue:
transaction = await contract.createMarketItem(
nftAddress,
tokenId,
{ value: (listingPrice) },
royalty,
index
);
{ value: (listingPrice) }, is supposed to be object that represents the amount of money you are sending along side the transaction and it should be the last parameter in the function. Because looks like you are creating an NFT market item and you have to pay the price of listing.
Since you are creating an nft, looks like you have a const { royalty } = formInput. I believe you wanted to send the nft price instead of { value: (listingPrice) }. so your transaction should be like this
transaction = await contract.createMarketItem(
nftAddress,
tokenId,
// I assume you want to send the nft price here from form
priceFromForm,
royalty,
index,
// this should be the last parameter
{ value: (listingPrice) }
);

Related

Reading smart contract function - what am I doing wrong?

I'm trying to read total supply from this smart contract, I have checked the ABI and the read does not require arguments. Why am I getting this error?
Imported the ABI from Etherscan with a valid API key
Connected Infura node with valid api.
Please help. I'm new!
Error:
Error: call revert exception [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (method="TOTAL_SUPPLY()", data="0x", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.7.0)
reason: null,
code: 'CALL_EXCEPTION',
method: 'TOTAL_SUPPLY()',
data: '0x',
errorArgs: null,
errorName: null,
errorSignature: null,
address: '0xFc7a5BD22dFc48565D6f04698E566Dd0C71d3155',
args: [],
transaction: {
data: '0x902d55a5',
to: '0xFc7a5BD22dFc48565D6f04698E566Dd0C71d3155',
from: '0xa9519a76981489Cf44a6b1023C53EA674B9365fB'
}
}
CODE:
const ethers = require("ethers");
async function main() {
// make an API call to the ABIs endpoint
const response = await fetch('https://api.etherscan.io/api?module=contract&action=getabi&address=0x31Cd7378715174e2c5Bd7EDF9984c9bC2A9209Eb&apikey=xxx');
const data = await response.json();
let abi = data.result;
/*console.log(abi);*/
// creating a new Provider, and passing in our node URL
const node = "https://mainnet.infura.io/v3/xxx";
const provider = new ethers.providers.JsonRpcProvider(node);
// initiating a new Wallet, passing in our private key to sign transactions
let privatekey = "xxx";
let wallet = new ethers.Wallet(privatekey, provider);
// print the wallet address
console.log("Using wallet address " + wallet.address);
// specifying the deployed contract address
let contractaddress = "0xFc7a5BD22dFc48565D6f04698E566Dd0C71d3155";
// initiating a new Contract
let contract = new ethers.Contract(contractaddress, abi, wallet);
console.log("Using contract address " + contract.address);
// calling the "retrieve" function to read the stored value
let supply = await contract.TOTAL_SUPPLY();
console.log("Value stored in contract is " + supply.toString());
You're retrieving ABI of address 0x31Cd7378715174e2c5Bd7EDF9984c9bC2A9209Eb on the Ethereum mainnet.
Your ethers provider correctly connects to the Ethereum mainnet.
But then it's trying to interact (call function TOTAL_SUPPLY()) with contract on address 0xFc7a5BD22dFc48565D6f04698E566Dd0C71d3155.
Since there's no contract on the 0xFc... address on the Ethereum mainnet, the call fails.
Have u tried web3client.app.
You can test any abi methods across 500+ chains in any smart contracts.
Identify which network your contract resides and do test it out.
It has code generate feature that lets you to easily get a bug free high quality code

Is there any way to convert dollar to ether while making transaction using Ethereum payment as well as from dollar to Solana in Web3.js?

I am integrating payment transaction for two blockchains , ethereum and solana using Web3.js. But how to automatically convert the dollar price to Ethereum and Solana respectively?
Ethereum payment code
----------------------------------
const amountEth=0.00001
Web3.eth.sendTransaction({
to: paymentAddress,
value: Web3.toWei(amountEth, 'ether')
}, (err, transactionId)=>{
if(err){
}else{
}
})
Solana Payment Code
-------------------------
var transaction = new solanaWeb3.Transaction().add(
solanaWeb3.SystemProgram.transfer({
fromPubkey: resp.publicKey,
toPubkey: recieverWallet,
lamports: 0.00000000001 * solanaWeb3.LAMPORTS_PER_SOL,
}),
);
Assets value in dollar are kinda real-world data, you need to go through one of the following options,
1 - Define a state variable to store the current rate (i.e SOL/USD or ETH/USD) in your code and update it periodically by your own, which is not really a good way.
2 - Using Oracles like Chainlink price feed which is available on both Ethereum and Solana
Using either of options, you then need to have a public method in your contract to return the current rate and call it in your frontend UI to set the price before user submits the transaction.
Chainlink price feed is one solution. Another solution is you write code in the front-end. This is a react hook example.
import useSWR from "swr"
const coingeckoURL = "https://api.coingecko.com/api/v3/coins/ethereum?localization=false&tickers=false&community_data=false&developer_data=false&sparkline=false"
export const ITEM_PRICE = 15
const fetcher = async url => {
const res = await fetch(url)
const json = await res.json()
// console.log(json) to see the api result
return json.market_data.current_price.usd ?? null
}
export const useItemPriceInEth = () => {
const { data, ...rest } = useSWR(
coingeckoURL,
fetcher,
{ refreshInterval: 1000 }
)
// The nullish coalescing operator (??) is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined, and otherwise returns its left-hand side operand.
const perItem = (data && (ITEM_PRICE / Number(data)).toFixed(6)) ?? null
return { eth: { data, perItem, ...rest}}
}

Ethers.js event listeners - Expected behavior for many getLogs/chainId/blocknumber requests?

I'm building a minting site that requires me to check the number of NFTs minted and display that number in real time to the user.
At first I was just making a request every few seconds to retrieve the number, but then I figured I could use an event listener to cut down on the requests, as people would only be minting in short bursts.
However, after using the event listener, the volume of requests has gone way up. Looks like it is constantly calling blockNumber, chainId, and getLogs. Is this just how an event listener works under the hood? Or do am I doing something wrong here?
This is a next js API route and here is the code:
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import { ethers } from 'ethers'
import { contractAddress } from '../../helpers'
import type { NextApiRequest, NextApiResponse } from 'next'
import abi from '../../data/abi.json'
const NEXT_PUBLIC_ALCHEMY_KEY_GOERLI =
process.env.NEXT_PUBLIC_ALCHEMY_KEY_GOERLI
let count = 0
let lastUpdate = 0
const provider = new ethers.providers.JsonRpcProvider(
NEXT_PUBLIC_ALCHEMY_KEY_GOERLI,
'goerli'
)
const getNumberMinted = async () => {
console.log('RUNNING NUMBER MINTED - MAKING REQUEST', Date.now())
const provider = new ethers.providers.JsonRpcProvider(
NEXT_PUBLIC_ALCHEMY_KEY_GOERLI,
'goerli'
)
const contract = new ethers.Contract(contractAddress, abi.abi, provider)
const numberMinted = await contract.functions.totalSupply()
count = Number(numberMinted)
lastUpdate = Date.now()
}
const contract = new ethers.Contract(contractAddress, abi.abi, provider)
contract.on('Transfer', (to, amount, from) => {
console.log('running event listener')
if (lastUpdate < Date.now() - 5000) {
getNumberMinted()
}
})
export default function handler(req: NextApiRequest, res: NextApiResponse) {
try {
res.setHeader('Content-Type', 'application/json')
res.status(200).json({ count })
} catch (err) {
res
.status(500)
.json({ error: 'There was an error from the server, please try again' })
}
}
If you use the AlchemyProvider or directly the StaticJsonRpcProvider (which ApchemyProvider inherits) you will eliminate the chainId calls; those are used to ensure the network hasn’t changed, but if you using a third-party service, like Alchemy or INFURA, this isn’t a concern which is why the StaticJsonRpcProvider exists. :)
Then every pollingInterval, a getBlockNumber is made (because this is a relatively cheap call) to detect when a new block occurs; when a new block occurs, it uses the getLogs method to find any logs that occurred during that block. This minimizes the number of expensive getLogs method.
You can increase or decrease the pollingInterval to trade-off latency for server resource cost.
And that’s how events work. :)
Does that make sense?

Web3JS contract call returning a different value than direct contract call with remix

I have a contract deployed onchain:
function getNonces(bytes32 _hashWalletSig, uint256[] calldata _dataTypes)
public
view
virtual
returns (uint8[] memory, bytes32[] memory)
{
...
}
If I point the remix editor to this contract and call the getNonce() function directly with the parameters:
0xa58d6abf78c9492df62daf0e251c6af49d5101eaadf2c4786e277a8da97f9f73 and [0]
I get my expected result.
However, I have a frontend application using Web3Js that attempts to call the getNonce function but I'm getting a completely different value (i.e. 0x00000000) which indicates that nothing is found:
export const getBlockchainStatus = async (walletSignature: string): Promise<boolean> => {
const MainContract = new web3.eth.Contract(
Ky0xMainAbi as AbiItem[],
CONTRACT_ADDRESS,
);
const hashwalletSig = ethers.utils.keccak256(walletSignature);
console.log('hashwalletSig:', hashwalletSig);
const response = await MainContract.methods.getNonces(hashwalletSig, ['0']).call();
console.log('response', response[1][0]);
return response[1][0] !== '0x0000000000000000000000000000000000000000000000000000000000000000';
};
The hashWalletSig matches the original value that I passed into the remix editor.
Can someone tell me what I'm doing wrong in Web3JS?

Unable to make a token transfer

I'm trying to simply transfer tokens from one address to another on ropsten but i keep getting this error
Returned error: The method eth_sendTransaction does not exist/is not available
this is the code:
const cacheAddress_ = "0xDD963fCdD32ccC802470CdB85A634dE8A47E9257"
const circulationAddress_ = "0x2dA320D8efF599f11Fe575124020743c9c2E8088"
var web3 = new Web3(new Web3.providers.HttpProvider("https://ropsten.infura.io/v3/API_KEY"))
async function transfer() {
const contract = new web3.eth.Contract(lvn.ABI, lvn.address)
const block = await contract.methods.transfer(circulationAddress_, new BigNumber(10**9*10**18)).send({ from: cacheAddress_ })
const circulationBalance = await contract.methods.balanceOf(circulationAddress_).call()
const cacheBalance = await getCacheBalance()
console.log({ circulationBalance, cacheBalance })
}
transfer()
I know it's not a problem with infura, Infura definitely exposes the necessary API's for making transactions. I've tried on a local node with rinkeby and i get the same problem. This is not a duplicate of this question because the same error occurs with web3.eth.personal.unlockAccount still comes up as unavailable (same error as above).
Any help with this would be greatly appreciated.
One solve might be to sign the token transfer if anybody knows how to do that (i know how to sign a regular eth transaction but not a token transfer)