2

I'm working on making a React frontend for my smart contract, but I'm having problems connecting it into my React code.

Here are the relevant portions of my code:

import TruffleContract from 'truffle-contract'

...

class App extends Component {
  constructor(props) {
    super(props);

    // Initialize MetaMask plugin
    this.web3 = new Web3();
    const isMetaMaskEnabled = () => !!window.web3;

    if (!isMetaMaskEnabled()) {
      alert('Add the Metamask pluging to your browser to continue');
      return;
    }

    if (window.ethereum) {
      window.web3 = new Web3(window.ethereum)
      try {
        // Request account access if needed
        window.ethereum.enable().then(() => {
          console.log("Accounts now exposed")
        }).catch((error) => {
          console.log(error)
        })
      } catch(error) {
        // User denied account access
        console.log(error).then(() => {
          console.log("unable to obtain MetaMask Account")
        })
      }
    } else if (window.web3) {
      window.web3 = new Web3(window.web3.currentProvider).then(() => {
        console.log("Accounts always exposed")
      }).catch((error) => {
        console.log(error)
      })
    } else {
      console.log("Non-Ethereum browser detected. You should consider trying MetaMask!")
    }

    this.web3.eth.net.getNetworkType()
    .then(function(netID) {
      while (netID !== 'main') {
        // alert('Select Main Ethereum Network in MetaMask')
      }
    });

    this.state = {
      ...
      uAddress: '0x0'
    }

    this.users = TruffleContract(Users);
    this.users.setProvider(window.web3.currentProvider)

    this.users = this.users.bind(this)
  }

  componentDidMount() {
    this.users.deployed().then((instance) => {
      this.setState( {uAddress: instance.address} )
    })
  }

When I try to call deployed() on this.users, I'm getting the error,

TypeError: this.users.deployed is not a function

I know there have been similar questions asked, but they create a contract instance using the abi and contract address, and not using the TruffleContract method. I want to know if it's possible to get this way to work.

4
  • Why would you need this.users = this.users.bind(this)?
    – ivicaa
    Commented Jan 10, 2019 at 22:28
  • I'm planning on passing it into a child component. Is this the right way to do it? Commented Jan 11, 2019 at 1:51
  • @JarethRader Normally .bind() is used for functions not objects.
    – Ismael
    Commented Jan 11, 2019 at 5:47
  • I'm not sure what I did, but it's working now. And I did remove this.users = this.users.bind(this). Commented Jan 12, 2019 at 7:10

1 Answer 1

0

In case anyone comes here looking for an answer, I've figured it out.

I changed how I instance my contract. I create a separate js file to store an object with all the contract data;

module.exports = {
  address: "(Your-Contract-Address-Goes_here)",
  abi: [
    {
     (Your-Contract-ABI-goes-here)
    }
  ]
}

then to create the instance, I get Web3 and use the web3.eth.Contract method;

const Web3 = require("web3");
const web3 = new Web3(
  new Web3.providers.HttpProvider(
    "https://rinkeby.infura.io/v3/(You-Infura-Secret-Goes-Here)"
  )
);

const Contract = require("Path-To-Contract");
const contractInstance = new web3.eth.Contract(
  Contract.abi,
  Contract.address
);

Now you should be able to make calls to your contract using the web3 api like so,

let data = contract.method.Contract_Method.call(Any-Varibles-Go-Here).encodeABI();
web3.eth.sendTransaction(data [,callback]);

Sending write methods is a little different, and using Infura will also actually require you to sign your own transaction and use web3.eth.sendSignedTransaction() but I won't elaborate on that here. If you're using Metamask, or I assume Dapper although I haven't tried it, it will work the way I have explained about. Metamask will sign transactions you send on their own nodes I believe which is why this works, but Infura will not sign transactions on their nodes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.