I am learning Ethereum development, I downloaded the react truffle suit and then tried to change some code to insert a string into the blockchain and then echo it. But I have an error which says: Unhandled Rejection (TypeError): contract.set is not a function
App.js:
import React, { Component } from "react";
import SimpleStorageContract from "./contracts/SimpleStorage.json";
import getWeb3 from "./getWeb3";
import "./App.css";
class App extends Component {
state = { storageValue: "", web3: null, accounts: null, contract: null, newValue: "" };
componentDidMount = async () => {
try {
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
// Get network provider and web3 instance.
const web3 = await getWeb3();
// Use web3 to get the user's accounts.
const accounts = await web3.eth.getAccounts();
// Get the contract instance.
const networkId = await web3.eth.net.getId();
const deployedNetwork = SimpleStorageContract.networks[networkId];
const instance = new web3.eth.Contract(
SimpleStorageContract.abi,
deployedNetwork && deployedNetwork.address,
);
// Set web3, accounts, and contract to the state, and then proceed with an
// example of interacting with the contract's methods.
this.setState({ web3, accounts, contract: instance }, this.runExample);
} catch (error) {
// Catch any errors for any of the above operations.
alert(
`Failed to load web3, accounts, or contract. Check console for details.`,
);
console.error(error);
}
};
handleChange(event) {
this.setState({newValue: event.target.value });
}
async handleSubmit(event) {
event.preventDefault();
const { accounts, contract } = this.state;
await contract.set(this.state.newValue, {from: accounts[0]});
const response = await contract.get();
this.setState({storageValue: response });
}
runExample = async () => {
const { contract } = this.state;
// Get the value from the contract to prove it worked.
const response = await contract.methods.get().call();
// Update state with the result.
this.setState({ storageValue: response });
};
render() {
if (!this.state.web3) {
return <div>Loading Web3, accounts, and contract...</div>;
}
return (
<div className="App">
<h1>Sample</h1>
<div>Text: {this.state.storageValue}</div>
<form onSubmit={this.handleSubmit}>
<input type="text" value={this.state.newValue} onChange={this.handleChange.bind(this)}></input>
<input type="submit" value="Submit"></input>
</form>
</div>
);
}
}
export default App;
Here is the contract which the set function is declared:
SimpleStorage.sol:
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.21 <0.7.0;
contract SimpleStorage {
string storedData;
constructor(string memory x) public {
storedData = x;
}
function set(string memory x) public {
storedData = x;
}
function get() public view returns (string memory) {
return storedData;
}
}
This line in your code uses syntax of the Truffle package:
But your code only imports web3js (not Truffle) and seems to be using it correctly in other places.
In web3js, you need to use the
methods
property (same as you're using incontract.methods.get()
) of thecontract
object. As well as thesend()
function (that accepts the object with thefrom
property) to send a transaction instead of a call.So it should be
Note: Web3js and Truffle are two separate packages, not related to each other. But both can be used to interact with smart contracts.