contract.set 不是函数

Posted

技术标签:

【中文标题】contract.set 不是函数【英文标题】:contract.set is not a function 【发布时间】:2021-08-10 04:38:24 【问题描述】:

我正在学习以太坊开发,我下载了 react truffle suit,然后尝试更改一些代码以将字符串插入区块链,然后回显它。 但我有一个错误,上面写着:未处理的拒绝(TypeError):

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;

这里是声明 set 函数的合约:

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;
    

【问题讨论】:

【参考方案1】:

您代码中的这一行使用Truffle 包的语法:

await contract.set(this.state.newValue, from: accounts[0]);

但您的代码仅导入 web3js(不是 Truffle)并且似乎在其他地方正确使用它。

在 web3js 中,您需要使用 contract 对象的 methods 属性(与您在 contract.methods.get() 中使用的相同)。以及send() 函数(接受具有from 属性的对象)发送事务而不是调用。

应该是这样的

await contract.methods.set(this.state.newValue).send(from: accounts[0]);

注意:Web3js 和 Truffle 是两个独立的包,彼此无关。但两者都可以用来与智能合约进行交互。

【讨论】:

以上是关于contract.set 不是函数的主要内容,如果未能解决你的问题,请参考以下文章

错误:在调用 Multicall Contract ethereum 的聚合函数时发送交易需要签名者

解决“function call to a non-contract account“问题

关于Typescript - HTMLElement上使用append / prepend函数的问题

在非 Spring 项目中运行 Spring Cloud Contract 测试

然后函数不执行

CakePHP redirect函数