Having problem calling a read-only function with ethers - javascript

I have a problem calling a read only function from my frontend. When I try to call it metamask ask me to pay gas fee
and the output of this transaction doesn't have any sense.
The solidity smart contract: https://rinkeby.etherscan.io/address/0xcf781c136ce1534d00db67c4ec488a6c4e01bbef
This is the solidity function : viewregistro
function compile_registro (string memory new_reg) public returns (bool registration){
registro[ultima] = new_reg;
ultima = ultima +1;
registration = true;
return registration;
}
function viewregistro(uint where) public view returns (string memory here){
here = registro[where];
return here;
}
This is the javascript code:
const enable = async () =>{
await window.ethereum.enable();
provider = new ethers.providers.Web3Provider(window.ethereum);
signer = await provider.getSigner();
address = await signer.getAddress();
console.log(provider);
return provider, signer, address
}
const contractConnection2 = async () => {
rank = new ethers.Contract( address_, rankingabi_ ,signer);
console.log(rank);
return rank;
}
const addmember = async() => {
rank.compile_registro("pluto");
}

Related

NFT Mint not load metadata

i'm learning blockchain dev and now i'm trying to mint an NFT, the process is ok but the problem is that metadata are not showed in the wallet or opensea.
This is the contract
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.17;
import '#openzeppelin/contracts/token/ERC721/ERC721.sol';
import '#openzeppelin/contracts/access/Ownable.sol';
import "#openzeppelin/contracts/utils/Counters.sol";
contract NFT is ERC721, Ownable {
uint256 public mintPrice;
uint256 public maxPerWallet;
uint256 public totalSupply;
bool public isPublicMintEnabled;
string internal baseTokenUri;
address payable public withdrawWallet;
mapping (address => uint256) public walletMints;
mapping(uint256 => string) private _tokenURIs;
Counters.Counter private _tokenIds;
using Counters for Counters.Counter;
using Strings for uint256;
constructor() payable ERC721('NFT', 'NFT') {
mintPrice = 0.0004 ether;
maxPerWallet = 3;
// Set withdraw wallet address
}
function setIsPublicMintEnabled(bool isPublicMintEnabled_) external onlyOwner {
isPublicMintEnabled = isPublicMintEnabled_;
}
function setBaseTokenUri(string calldata baseTokenUri_) external onlyOwner {
baseTokenUri = baseTokenUri_;
}
function tokenURI(uint256 tokenId_) public view override returns (string memory) {
require(_exists(tokenId_), 'Token does not exist!');
return string(abi.encodePacked(baseTokenUri, Strings.toString(tokenId_), ".json"));
}
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual
{
_tokenURIs[tokenId] = _tokenURI;
}
function withDraw() external onlyOwner {
(bool success, ) = withdrawWallet.call{ value: address(this).balance } ('');
require(success, 'Withdraw failed');
}
function mint(string memory uri) public payable returns (uint256) {
require(isPublicMintEnabled, 'Mint is not enabled');
require(msg.value == mintPrice, 'Wrong mint value');
require(walletMints[msg.sender] + 1 <= maxPerWallet, 'Exceed max quantity per wallet');
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(msg.sender, newItemId);
_setTokenURI(newItemId, uri);
return newItemId;
}
}
And this is the mint function on the mint website
const mintNFT = async (nft) => {
setMinting(true)
const mintAmount = 1
const isConnected = Boolean(accounts[0])
if (!isConnected) {
alert('Non sei connesso al tuo Wallet')
setMinting(false)
return
}
var nftParsed = JSON.parse(nft.metadata)
if (window.ethereum) {
// Connect to blockchain
const provider = new providers.Web3Provider(window.ethereum)
const signer = provider.getSigner()
const contract = new Contract(
address,
NFT.abi, // Implement
signer
)
const imageFile = await dataUrlToFile(nftParsed.image, "img.png")
const nftstorage = new NFTStorage({ token: NFT_STORAGE_KEY })
const storage = await nftstorage.store({
image: imageFile,
name: nftParsed.name,
description: 'prova'
})
if (storage) {
try {
const response = await contract.mint(storage.url, {
value: ethers.utils.parseEther((0.0004).toString())
})
console.log(response)
} catch (e) {
console.error(e)
alert("Sorry, error while minting your NFT")
setMinting(false)
}
} else {
alert("Mint problems")
setMinting(false)
}
setMinting(false)
}
}
This code convert dataurl (format for nft saved in db) to image
async function dataUrlToFile(dataUrl, fileName) {
const res = await fetch(dataUrl);
const blob = await res.blob();
return new File([blob], fileName, { type: 'image/png' });
}
In first try, i successfully created nft with metadata, but now using a min website seems to be impossible, the time that it worked the image was stored in a directory and not in a dataurl format.
Hope someone can help,
Thanks

Unable to retrieve the Ethereum balance of MetaMask account

const showAccount = document.querySelector('.showAccount');
const showBalance = document.querySelector('.showBalance');
const Web3 = require("web3");
getAccount();
getBalance();
getAccount returns the wallet id
async function getAccount() {
const accounts = await ethereum.request({ method: 'eth_requestAccounts' });
const account = accounts[0];
showAccount.innerHTML = account;
}
getBalance returns undefined instead of the amount of Ether from Metamask
async function getBalance() {
const accounts = await ethereum.request({ method: 'eth_requestAccounts' });
const account = accounts[0];
showBalance.innerHTML = account.balance;
}
Maybe someone knows a good API for retrieving more values than just these two with examples or got a nice video to learn from.
I found the properties for my accounts object: here
I customized your code and now it displays the amount of Ether from the Account:
const showAccount = document.querySelector('.showAccount');
const showBalance = document.querySelector('.showBalance');
getAccount();
loadBalance();
async function getAccount() {
const accounts = await ethereum.request({ method: 'eth_requestAccounts' });
const account = accounts[0];
showAccount.innerHTML = account;
}
function loadBalance(){
web3Provider = null;
contracts = {};
account = '0x0';
const Web3 = require("web3");
const ethEnabled = async () => {
if (window.ethereum) {
await window.ethereum.send('eth_requestAccounts');
window.web3 = new Web3(window.ethereum);
return true;
}
}
if (typeof web3 !== 'undefined') {
// If a web3 instance is already provided by Meta Mask.
web3Provider = web3.currentProvider;
web3 = new Web3(web3.currentProvider);
} else {
// Specify default instance if no web3 instance provided
web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
web3 = new Web3(App.web3Provider);
}
$.getJSON("Market.json", function (market) {
console.log("initializing Market contract")
// Instantiate a new truffle contract from the artifact
contracts.Market = TruffleContract(market);
// Connect provider to interact with contract
contracts.Market.setProvider(web3Provider);
});
$.getJSON("Users.json", function (users) {
console.log("initializing User contract")
// Instantiate a new truffle contract from the artifact
contracts.Users = TruffleContract(users);
// Connect provider to interact with contract
contracts.Users.setProvider(App.web3Provider);
});
var marketInstance;
var userInstance;
var loader = $("#loader");
var content = $("#content");
//loader.show();
content.show();
// Load account data
console.log("loading account data")
var currentAccount;
web3.eth.getCoinbase(function (err, account) {
if (err === null) {
console.log("Your Account: " + account)
account = account;
currentAccount = account;
web3.eth.getBalance(account, function(err, balance) {
if (err === null) { //Note:set id="accountBalance" in your html page
$("#accountBalance").text(web3.fromWei(balance, "ether") + " ETH");
}
});
}
});
}

Communicating with a Smart Contract on BSC over ethers gives -32603 error code

Hello I am new to Smart Contract development, for a few days I try to get this working, but no luck. I hope someone can help me. I try to communicate to a Smart Contract deployed to BSC https://testnet.bscscan.com/address/0x2ED1c3c1Fc6646F321cf546a892684E946435CE9 see the source code below.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "#chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract FundMe {
mapping(address => uint256) public addressToAmountFunded;
address[] public funders;
address public owner;
AggregatorV3Interface internal priceFeed;
uint balance;
// if you're following along with the freecodecamp video
// Please see https://github.com/PatrickAlphaC/fund_me
// to get the starting solidity contract code, it'll be slightly different than this!
constructor(address _priceFeed) {
priceFeed = AggregatorV3Interface(_priceFeed);
owner = msg.sender;
}
function fund() public payable {
uint256 mimimumUSD = 50 * 10**18;
require(
getConversionRate(msg.value) >= mimimumUSD,
"You need to spend more ETH!"
);
addressToAmountFunded[msg.sender] += msg.value;
balance += msg.value;
funders.push(msg.sender);
}
function getVersion() public view returns (uint256) {
return priceFeed.version();
}
function getPrice() public view returns (uint256) {
(, int price, , , ) = priceFeed.latestRoundData();
return uint256(price * 10000000000);
}
// 1000000000
function getConversionRate(uint256 ethAmount)
public
view
returns (uint256)
{
uint256 ethPrice = getPrice();
uint256 ethAmountInUsd = (ethPrice * ethAmount) / 1000000000000000000;
return ethAmountInUsd;
}
function getEntranceFee() public view returns (uint256) {
// mimimumUSD
uint256 mimimumUSD = 50 * 10**18;
uint256 price = getPrice();
uint256 precision = 1 * 10**18;
return (mimimumUSD * precision) / price;
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
function withdraw() public payable onlyOwner {
payable(msg.sender).transfer(balance);
for (
uint256 funderIndex = 0;
funderIndex < funders.length;
funderIndex++
) {
address funder = funders[funderIndex];
addressToAmountFunded[funder] = 0;
}
funders = new address[](0);
}
}
I deployed the smart contract with truffle, with the following migration script
const FundMe = artifacts.require("FundMe");
const BINANCE_BNB_USD_PRICE_FEED = '0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE';
module.exports = async (deployer, network, [defaultAccount]) => {
let priceFeedAddress = BINANCE_BNB_USD_PRICE_FEED
try {
await deployer.deploy(FundMe, BINANCE_BNB_USD_PRICE_FEED, { from: defaultAccount })
} catch (err) {
console.error(err)
}
}
I try to call getPrice() that communicates to chainlink to get the latest price of BNB/USDT.
Here is the Javascript
const getContract = () =>
new Promise(async (resolve, reject) => {
const contract = await fetch('./build/contracts/FundMe.json')
const Contract = await contract.json()
let provider = await detectEthereumProvider()
if (provider) {
await provider.request({ method: 'eth_requestAccounts' })
const networkId = await provider.request({ method: 'net_version' })
provider = new ethers.providers.Web3Provider(provider)
const signer = provider.getSigner()
showAddress(signer)
const contract = new ethers.Contract(
Contract.networks[networkId].address,
Contract.abi,
signer,
)
resolve(contract)
return
}
reject('Install Metamask')
})
const showAddress = async (signer) => {
address = await signer.getAddress()
const connectButton = document.getElementById('connect')
connectButton.innerText = address
}
const getPrice = async (contract) => {
console.log('contract', contract)
const price = await contract.getPrice()
console.log('price', price)
const priceContainer = document.getElementById('price')
priceContainer.innerText = price
}
const init = async () => {
const contract = await getContract()
getPrice(contract)
}
const fundButton = document.getElementById('fund')
fundButton.addEventListener('click', async () => {
const fundMe = await getContract()
})
init()
I get the following error in the browser console and have no idea whats the cause.
Your deploy script passing the 0x056... address as the priceFeed param of the constructor.
So the getPrice() contract function is then trying to call the latestRoundData() on the 0x056... address, expecting a response.
However, your contract is deployed on the testnet, and there's no contract on the 0x056... address on the testnet (link) to return a value, which causes the "main" call to revert.

Cannot figure out why I am getting VM Exception while processing transaction: revert error

I am a beginner in blockchain programming and I am not able to understand why I am getting an error while trying to solidity function using Web3 and Ganache.
const PetList = require('./build/contracts/PetList.json')
const fs = require('fs')
const Web3 = require('web3')
const abi = fs.readFileSync("build/contracts/PetList.json").toString().trim();
// Ganache Blockchain
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:7545"));
web3.eth.net.isListening()
.then(() => console.log('Web3 is connected'))
.catch(e => console.log('Wow. Something went wrong'));
var setUpContract = async function( ){
await web3.eth.net.getId().then((networkId) => {
const networkData = PetList.networks[networkId]
console.log("Setting up contract...")
if(networkData){
return petList = new web3.eth.Contract(PetList.abi, networkData.address)
}
})
acc = await web3.eth.getAccounts()
currentAccount = acc[0]
console.log("Account: ", acc[0])
}
async function start(){
await setUpContract()
await addPet()
}
var addPet = async function(){
console.log(await getPetCount())
return results = await petList.methods.addPet('Zippo', 'Dog').send({from: currectAccount})
}
start()
pragma solidity ^0.5.0;
contract PetList{
uint public petCount = 0;
mapping (uint => Pet) public pets;
struct Pet{
uint id;
string name;
string tag;
}
event PetAdded(
uint id,
string name,
string tag
);
function addPet(string memory _name, string memory _tag) public {
require(bytes(_name).length > 0, "INVALID TAG");
require(bytes(_tag).length > 0, "INVALID NAME");
petCount++;
pets[petCount] = Pet(petCount, _name, _tag);
emit PetAdded(petCount, _name, _tag);
}
}
I also used .send() without any parameters and it gave me an error saying No "from" address specified in neither the given options, nor the default options.
To make a function receive ether you must have a fallback function or add payable modifier
So you can change your code to the following
function addPet(string memory _name, string memory _tag) public payable

Calling a Smart Contract function using Web3

I have the following code to call a smart contract function:
async function addManager(){
const networkId = await web3.eth.net.getId();
var deployedNetwork = MarketplaceArtifact.networks[networkId];
var marketplace = new web3.eth.Contract(
MarketplaceArtifact.abi,
deployedNetwork.address,
);
var address = document.getElementById('addressField').value;
const { AddManager } = marketplace.methods;
const response = await AddManager(address, { from: this.account }).call();
console.log(response);
}
Why is the console.log giving me such a response Shouldn't the call return the return value form the smart contract?

Categories