Following a tutorial on Solidity and am working on the front end and end up getting hit with this error
It won't let me fetch the greeting but I can set the greeting everything else works except for the fetch greeting, it won't let me see it even if I set the greeting to something else I can't see it in the console only the error here is the Solidity tutorial
Here is my solidity code
pragma solidity ^0.8.4;
import "hardhat/console.sol";
contract Greeter {
string greeting;
constructor(string memory _greeting) {
console.log("Deploying a Greeter with greeting:", _greeting);
greeting = _greeting;
}
function greet() public view returns (string memory) {
return greeting;
}
function setGreeting(string memory _greeting) public {
console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
greeting = _greeting;
}
}
And here is my react code:
import './App.css';
import { useState } from 'react';
import { ethers } from 'ethers'
import Greeter from './artifacts/contracts/Greeter.sol/Greeter.json'
// Update with the contract address logged out to the CLI when it was deployed
const greeterAddress = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
function App() {
// store greeting in local state
const [greeting, setGreetingValue] = useState()
// request access to the user's MetaMask account
async function requestAccount() {
await window.ethereum.request({ method: 'eth_requestAccounts' });
}
// call the smart contract, read the current greeting value
async function fetchGreeting() {
if (typeof window.ethereum !== 'undefined') {
const provider = new ethers.providers.Web3Provider(window.ethereum)
const contract = new ethers.Contract(greeterAddress, Greeter.abi, provider)
try {
const data = await contract.greet()
console.log('data: ', data)
} catch (err) {
console.log("Error: ", err)
}
}
}
// call the smart contract, send an update
async function setGreeting() {
if (!greeting) return
if (typeof window.ethereum !== 'undefined') {
await requestAccount()
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner()
const contract = new ethers.Contract(greeterAddress, Greeter.abi, signer)
const transaction = await contract.setGreeting(greeting)
await transaction.wait()
fetchGreeting()
}
}
return (
<div className="App">
<header className="App-header">
<button onClick={fetchGreeting}>Fetch Greeting</button>
<button onClick={setGreeting}>Set Greeting</button>
<input onChange={e => setGreetingValue(e.target.value)} placeholder="Set greeting" />
</header>
</div>
);
}
export default App;
Any advice would help thx
You need insert the attribute value
value = {greeting}
in the input:
<input onChange={e => setGreetingValue(e.target.value)}
placeholder="Introduce uno nuevo"
value={greeting}
/>
Also initialize with two quotes useState ():
const [greeting, setGreetingValue] = useState ('')
You will probably now have a issue with the metamask nonce, which will tell you that it is too high like message error like this:
Nonce too high. Expected nonce to be 1 but got 2
You will reset account in metamask, or import a new account.
Related
Help me to get fetch information from blockchain and display in the browser. i want know how to call this thirdweb functions in react.
Below code is a solidity code used to create a user in our system.
function createUser(string memory _userId, string memory _fName, string memory _lName, string memory _mobile, string memory _dob, uint256 _age, string memory _nationality, string memory _gender) public {
if(!chkexisitinguserId(_userId)){
users[_userId] = User(_fName, _lName, _mobile, _dob, _age,_nationality,_gender);
noofUser++;
allUserId[k] = _userId;
k++;
}
}
function getUser(string memory _userId) public view returns (string memory, string memory, string memory, string memory, uint256, string memory, string memory) {
User memory user = users[_userId];
return (user.fName, user.lName, user.mobile, user.dob, user.age, user.nationality, user.gender);
}
The below code is thirdweb libary code to interact with smart contract. The below code is stored in refer.js file.
import { useContract, useContractWrite } from "#thirdweb-dev/react";
export default function Component() {
const { contract } = useContract("0xBB417720eBc8b76AdeAe2FF4670bbc650C3E791f");
const { mutateAsync: createUser, isLoading } = useContractWrite(contract, "createUser")
const call = async () => {
try {
const data = await createUser([ "John0312", "John", "s", "8090890367", "03-11-2000", 20, "India", "M" ]);
console.info("contract call successs", data);
} catch (err) {
console.error("contract call failure", err);
}
}
}
export default function Component() {
const { contract } = useContract("0xBB417720eBc8b76AdeAe2FF4670bbc650C3E791f");
const { data, isLoading } = useContractRead(contract, "getUser", _userId)
}
The smart contract is deployed in thirdweb and trying to access it. I am stuck at how to call this "call" async function from app.js.
import React, { useEffect } from 'react'
function App(){
const handleclick = async (e) => {
await call();
}
return (
<button onClick={handleclick}>click me</button>
)
}
export default App
it generates error like undefined function call().
I would create a new hook (useCall.js) who's job is simply to instantiate the useContract and useContractWrite hooks, then define the call() method for you to use in any component.
In this example, call() is the only thing returned from the hook. It's wrapped inside useCallback to ensure it's only defined when createUser is defined.
export default function useCall() {
const { contract } = useContract("0xBB417720eBc8b76AdeAe2FF4670bbc650C3E791f");
const { mutateAsync: createUser, isLoading } = useContractWrite(contract, "createUser")
const call = React.useCallback(async () => {
try {
const data = await createUser([ "John0312", "John", "s", "8090890367", "03-11-2000", 20, "India", "M" ]);
console.info("contract call successs", data);
} catch (err) {
console.error("contract call failure", err);
}
}, [createUser]);
return call;
}
Now inside of any component you can use the hook and get the call() function:
import useCall from './useCall';
export default function Component() {
const call = useCall();
useEffect(() => {
(async () => {
await call();
})();
}, []);
}
I created a simple CRA app to figure out how to use the Phantom wallet to make Solana transactions(I still don't know If that is even possible). I referenced two Stackoverflow questions source and source and came up with a somewhat working code as in the airdrop is working perfectly fine but the main transaction is not.
This is my code:
import "./App.css";
import { useEffect, useState } from "react";
const web3 = require("#solana/web3.js");
function App() {
const [provider, setProvider] = useState(null);
const [walletKey, setWalletKey] = useState(null);
const getProvider = () => {
if ("solana" in window) {
const provider = window.solana;
if (provider.isPhantom) {
return provider;
}
}
};
const connectWallet = async () => {
const provider = getProvider();
if (provider) {
try {
const response = await provider.connect();
const pubKey = await provider.publicKey;
console.log(pubKey);
setProvider(provider);
setWalletKey(response.publicKey.toString());
} catch (err) {
// { code: 4001, message: 'User rejected the request.' }
}
}
};
useEffect(() => connectWallet, []);
const airDropSol = async (connection, publicKey) => {
try {
const airdropSignature = await connection.requestAirdrop(
publicKey,
web3.LAMPORTS_PER_SOL
);
const latestBlockHash = await connection.getLatestBlockhash();
// Confirming that the airdrop went through
await connection.confirmTransaction({
blockhash: latestBlockHash.blockhash,
lastValidBlockHeight: latestBlockHash.lastValidBlockHeight,
signature: airdropSignature,
});
console.log("Airdropped");
} catch (error) {
console.error(error);
}
};
async function transferSOL() {
//Changes are only here, in the beginning
const phantomProvider = provider;
if (!phantomProvider) {
console.log("No provider found", phantomProvider);
}
const pubKey = await phantomProvider.publicKey;
console.log("Public Key: ", pubKey);
// Establishing connection
var connection = new web3.Connection(web3.clusterApiUrl("devnet"));
// I have hardcoded my secondary wallet address here. You can take this address either from user input or your DB or wherever
var recieverWallet = new web3.PublicKey(
"Wallet Key I want to send SOL to here"
);
// Airdrop some SOL to the sender's wallet, so that it can handle the txn fee
airDropSol(connection, pubKey);
console.log("WORKED 1");
const transaction = new web3.Transaction();
const instructions = web3.SystemProgram.transfer({
fromPubkey: pubKey,
toPubkey: recieverWallet,
lamports: web3.LAMPORTS_PER_SOL, //Investing 1 SOL. Remember 1 Lamport = 10^-9 SOL.
});
transaction.add(instructions);
console.log("WORKED 2");
// Setting the variables for the transaction
transaction.feePayer = pubKey;
let blockhashObj = await connection.getLatestBlockhash();
transaction.recentBlockhash = blockhashObj.blockhash;
const signature = await phantomProvider.signAndSendTransaction(
connection,
transaction,
[pubKey]
);
await connection.confirmTransaction(signature);
console.log(signature);
}
return (
<div className="App">
<header className="App-header">
<h2>Tutorial: Connect to Phantom Wallet</h2>
{provider && walletKey && <p>Connected account {walletKey}</p>}
{provider && walletKey && <button onClick={transferSOL}>TEST</button>}
{!provider && (
<p>
No provider found. Install{" "}
Phantom Browser extension
</p>
)}
</header>
</div>
);
}
export default App;
This is the error generated in and I don't know how to fix it. Can anyone help? Error in browser console
Also when I run npm start this error in vcode console also gets shown.
All I want to do is simply send SOL from one phantom wallet to another like sending money in real life, I have spent alot of time trying to figure this out someone please point out the problem and help
Use #solana/web3.js version 1.30.2
New versions form web3 libraries need some dependencies and webpack configurations.
You can use a code I'm sharing:-
Refer my code on this link
With Webpack 5 you need to polyfill Buffer.
Here is a tutorial on how to do so https://viglucci.io/how-to-polyfill-buffer-with-webpack-5
And here is an example of a webpack config of a Solana dApp UI made with CRA https://github.com/Bonfida/serverless-merch/blob/master/ui/config-overrides.js
I want to call a payable function in a smart contract I deployed, but it does not work. This is the error I am getting:
Error: Returned error: The method eth_sendTransaction does not exist/is not available
The answer I could find is to just use a private key, because infura does not cater this method, however I want the user to sign the transaction to the smart contract with MetaMask.
This is my code:
export async function helloworld() {
const rpcURL =
"https://ropsten.infura.io/v3/KEY";
const web3 = new Web3(rpcURL);
let provider = window.ethereum;
if (typeof provider !== "undefined") {
provider
.request({ method: "eth_requestAccounts" })
.then((accounts) => {
selectedAccount = accounts[0];
console.log(`Selected account is ${selectedAccount}`);
})
.catch((err) => {
console.log(err);
return;
});
window.ethereum.on("accountsChanged", function (accounts) {
selectedAccount = accounts[0];
console.log(`Selected account changed to ${selectedAccount}`);
});
}
const networkId = await web3.eth.net.getId();
const thecontract = new web3.eth.Contract(
simpleContractAbi,
"0x50A404efF9A057900f87ad0E0dEfA0D485931464"
);
isInitialized = true;
investit(thecontract, selectedAccount);
}
and this is the code that actually throws the error:
export const investit = async (thecontract, selectedAccount) => {
if (!isInitialized) {
await helloworld();
}
thecontract.methods
.invest()
.send({ from: selectedAccount, value: 10000 })
.catch(function (err) {
console.log(err);
});
};
I am completely lost, since if I use the normal window.ethereum.request (https://docs.metamask.io/guide/sending-transactions.html#example) to send a transaction, metamask opens up and I can sign it. With the contract call it simply does not work.
Do you know the reason? How can I fix this?
This must be the issue. you are just passing an url:
const rpcURL ="https://ropsten.infura.io/v3/KEY";
instead:
const web3 = new Web3(new Web3.providers.HttpProvider("https://ropsten.infura.io/v3/KEY"))
eth_sendTransaction requires you holding the private key to sign the transaction before broadcasting it to the network. Infura doesn’t maintain any private keys. In order to send a transaction, you need to sign the transaction on your end with your private key.
The way you check providers is not correct. window.ethereum is also a provider which is provided by metamask. provider itself is meaningless, it has to be injected into the new Web3().
I was trying to make a to-do list using react as my front-end and solidity as my backend. I used Truffle and Ganache to test it. I successfully set up the private blockchain and imported multiple accounts from Ganache. However, whenever I use method.call() in my react app, it throws the following error:
index.js:298 Uncaught (in promise) 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.
at ABICoder.push../node_modules/web3-eth-abi/lib/index.js.ABICoder.decodeParametersWith (index.js:298)
at ABICoder.push../node_modules/web3-eth-abi/lib/index.js.ABICoder.decodeParameters (index.js:285)
at Contract.push../node_modules/web3-eth-contract/lib/index.js.Contract._decodeMethodReturn (index.js:470)
at Method.outputFormatter (index.js:760)
at Method.push../node_modules/web3-core-method/lib/index.js.Method.formatOutput (index.js:147)
at sendTxCallback (index.js:523)
at cb (util.js:689)
at Item.push../node_modules/process/browser.js.Item.run (browser.js:153)
at drainQueue (browser.js:123)
I have no idea what I am doing wrong. I checked the abi and contract address, but they all seem to be correct. Could anyone please tell me what causes the error and how I can fix it?
Here is my solidity and react code:
Solidity (contract):
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
pragma experimental ABIEncoderV2;
contract Todolist {
string[][] lists;
mapping (address => uint) public ownerToListId;
mapping (address => bool) ownerHasList;
function addToList(string calldata item) external{
if (!ownerHasList[msg.sender]) {
// newList = newList.push(item);
lists.push([item]);
ownerToListId[msg.sender] = lists.length - 1;
} else {
lists[ownerToListId[msg.sender]].push(item);
}
}
function getList() external view returns(string[] memory) {
return lists[ownerToListId[msg.sender]];
}
}
React (app.js) :
import React, { useState } from "react";
import Web3 from "web3";
import { todolistAbi } from "./abi/abis";
import "./App.css";
const web3 = new Web3(Web3.givenProvider);
const contractAddr = "0x75e4f59aBA61e780Accf573Ce632C2f31B534056";
const TodolistContract = new web3.eth.Contract(todolistAbi, contractAddr);
function App() {
const [list, setList] = useState(["placeholder"]);
// const [getNumber, setGetNumber] = useState(0x00);
const [itemToAdd, setItemToAdd] = useState("");
const getList = async () => {
const list = await TodolistContract.methods.getList().call();
console.log(list);
setList(list.map((item) => <li>{item}</li>));
};
const addToList = async () => {
const accounts = await window.ethereum.enable();
const account = accounts[0];
const gas = await TodolistContract.methods
.addToList(itemToAdd)
.estimateGas();
await TodolistContract.methods
.addToList(itemToAdd)
.send({ from: account, gas });
console.log("a");
await getList();
};
return (
<div className='App'>
<header className='App-header'>
<div>
<ul>{list}</ul>
</div>
<br />
<input type='text' onChange={(e) => setItemToAdd(e.target.value)} />
<button onClick={addToList} type='button'>
get the list!
</button>
</header>
</div>
);
}
export default App;
truffle-config.js:
module.exports = {
networks: {
development: {
host: "127.0.0.1", // Localhost (default: none)
port: 7545, // Standard Ethereum port (default: none)
network_id: "*", // Any network (default: none)
from: "0xfbfaf75dea69c388f45d20d5aab7b947072d8416",
gas: 18000000,
},
},
mocha: {
},
compilers: {
solc: {
version: "0.6.0",
},
},
};
I am having the error when I call getList function in react...
"const list = await TodolistContract.methods.getList().call();"
function getList() external view returns(string[] memory) {
return lists[ownerToListId[msg.sender]];
}
when you call this function on react side, you have to send account and values. Who is calling this function? caller of this function should be manager, msg.sender.
I'm trying to connect a NodeJs server to a solidity contract thats been migrated to a local blockchain and then call the methods on this class via javascript. However, the code returns an error stating that getGreeting() is not defined.
I'm very new Solidity and JavaScript (background in C and Java) so I feel like I'm overlooking something really simple?
My question is how to get it to work and find the method and return "Hello, World!" to the terminal?
My development environment is:
Truffle v5.1.10 (core: 5.1.10)
Solidity - 0.4.25 (solc-js)
Node v12.14.1
Web3.js v1.2.1
Below is the code I'm working on:
// import our compiled JSON
const contractJSON = require("./build/contracts/Hello.json");
const contract = require("#truffle/contract");
const Web3 = require('web3');
// create instance of ganache-cli provider
const web3 = new Web3("http://localhost:9545");
var Hello = contract(contractJSON);
Hello.setProvider(web3);
// if contract is deployed return instance of it and store in app variable
let app = Hello.deployed().then((instance) =>{
return instance;
}).catch(function(error) {
return error;
});
// call a method on our contract via javascript
app.getGreeting().then(() => {
console.log(app);
});
For context the Solidity contract is as follows:
pragma solidity >=0.4.0 <0.7.0;
contract Hello {
string greeting;
constructor() public {
greeting = "Hello, World!";
}
function getGreeting() public view returns (string memory) {
return greeting;
}
function setGreeting(string memory _greeting) public {
greeting = _greeting;
}
}
For those of you who view this in the future the issue was that I imported the provider incorrectly according to the #truffle/contract documentation here. Also, forgot to fulfill the second promise. Therefore the answer to this solution as of the time of writing is as follows:
const provider = new Web3.providers.HttpProvider("http://localhost:9545");
let Hello = contract(contractJSON);
Hello.setProvider(provider);
Hello.deployed().then((instance) => {
deployed = instance;
return instance.getGreeting();
}).then((result) => {
console.log(result);
}).catch((error) => {
console.log(error);
});
Many thanks to #blex for the assistance.
Your are calling the function "getGreeting()" on the Promise object and not on the contract instance.
// import our compiled JSON
const contractJSON = require("./build/contracts/Hello.json");
const contract = require("#truffle/contract");
const Web3 = require('web3');
// create instance of ganache-cli provider
const web3 = new Web3("http://localhost:9545");
var Hello = contract(contractJSON);
Hello.setProvider(web3);
(async () => {
// Get Contract Instance
let app = await Hello.deployed();
// Call Function
const response = await app.getGreeting();
console.log(response);
})()