4

I am in the final stages of developing an application that is similar to https://www.ethereum.org/crowdsale, however, when I click on the create button, my Metamask modal is not popping up to ask me if I want to approve or reject the transaction.

This is my pages/campaigns/requests/new.js file where this is all taking place:

import React, { Component } from "react";
import { Form, Button, Message, Input } from "semantic-ui-react";
import Campaign from "../../../ethereum/campaign";
import web3 from "../../../ethereum/web3";
import { Link, Router } from "../../../routes";
import Layout from "../../../components/Layout";

class RequestNew extends Component {
  state = {
    value: "",
    description: "",
    recipient: ""
  };

  static async getInitialProps(props) {
    const address = props.query;

    return { address };
  }

  onSubmit = async event => {
    event.preventDefault();

    const campaign = Campaign(this.props.address);
    const { description, value, recipient } = this.state;

    try {
      const accounts = await web3.eth.getAccounts();
      await campaign.methods
        .createRequest(description, web3.utils.toWei(value, "ether"), recipient)
        .send({ from: accounts[0] });
    } catch (err) {}
  };

  render() {
    return (
      <Layout>
        <h3>Create a Request</h3>
        <Form onSubmit={this.onSubmit}>
          <Form.Field>
            <label>Description</label>
            <Input
              value={this.state.description}
              onChange={event =>
                this.setState({ description: event.target.value })
              }
            />
          </Form.Field>

          <Form.Field>
            <label>Value in Ether</label>
            <Input
              value={this.state.value}
              onChange={event => this.setState({ value: event.target.value })}
            />
          </Form.Field>

          <Form.Field>
            <label>Recipient</label>
            <Input
              value={this.state.recipient}
              onChange={event =>
                this.setState({ recipient: event.target.value })
              }
            />
          </Form.Field>

          <Button primary>Create!</Button>
        </Form>
      </Layout>
    );
  }
}

export default RequestNew;

This is my ethereum/campaign.js file:

import web3 from './web3';
import Campaign from './build/Campaign.json';

export default address => {
  return new web3.eth.Contract(JSON.parse(Campaign.interface), address);
};

This is my ethereum/web3.js file:

import Web3 from 'web3';

let web3;

if (typeof window !== 'undefined' && typeof window.web3 !== 'undefined') {
  // we are in the browser and metamask is running
  web3 = new Web3(window.web3.currentProvider);
} else {
  // we are on the server *OR* the user is not running metamask
  const provider = new Web3.providers.HttpProvider(
    'https://rinkeby.infura.io/abc123'
  );
  web3 = new Web3(provider);
}

export default web3;

Can anybody see where I missed a step? I am not getting any errors of any sort, just not getting the behavior thats expected when creating a transaction with the Create button which is for Metamask modal to pop up.

So I decided to add some error handling in my try/catch block:

onSubmit = async event => {
    event.preventDefault();

    const campaign = Campaign(this.props.address);
    const { description, value, recipient } = this.state;

    this.setState({ loading: true, errorMessage: "" });

    try {
      const accounts = await web3.eth.getAccounts();
      await campaign.methods
        .createRequest(description, web3.utils.toWei(value, "ether"), recipient)
        .send({ from: accounts[0] });

      Router.pushRoute(`/campaigns/${this.props.address}/requests`);
    } catch (err) {
      this.setState({ errorMessage: err.message });
    }

    this.setState({ loading: false });
  };

render() {
    return (
      <Layout>
        <h3>Create a Request</h3>
        <Form onSubmit={this.onSubmit} error={!!this.state.errorMessage}>
          <Form.Field>
            <label>Description</label>
            <Input
              value={this.state.description}
              onChange={event =>
                this.setState({ description: event.target.value })
              }
            />
          </Form.Field>

          <Form.Field>
            <label>Value in Ether</label>
            <Input
              value={this.state.value}
              onChange={event => this.setState({ value: event.target.value })}
            />
          </Form.Field>

          <Form.Field>
            <label>Recipient</label>
            <Input
              value={this.state.recipient}
              onChange={event =>
                this.setState({ recipient: event.target.value })
              }
            />
          </Form.Field>

And sure enough when I tried creating a request again I was able to see the following error message render to the screen:

This contract object doesn't have address set yet, please set an address first

I am not sure how I do not have an address set yet on this contract object.

1
  • In case somebody still stuck. Try login metamask on diff net and then back to target net. in my case I clicked on ganache nd then rospnet. And it worked May 21, 2022 at 16:09

4 Answers 4

3

"This contract object doesn't have address set yet" -- This error can also occur if the address you have assigned is incorrect; it doesn't exist, or you pasted in the txhash instead of the contract address.

1

I found the culprit in my code, instead of this:

static async getInitialProps(props) {
    const address = props.query;

    return { address };
  }

I need to have it like this:

static async getInitialProps(props) {
    const { address } = props.query;

    return { address };
  }
1
  • 1
    You're allowed to accept your own answer for the win. You can also edit the title and content so it might show up in a search when someone else has a similar issue. Thanks for posting this resolution to the question. Apr 18, 2019 at 2:43
0

I ran into this same issue when running a react truffle box, compiler 0.7.0.

After using

truffle develop

I forgot to actually migrate the contract. I'm only a few days into learning but I enjoyed the lesson.

Perhaps those who find themselves here will avoid this mistake :)

0

I also faced the same error. I figured out, the following code was written:

const campaign = Campaign(props.query.address);

But I forgot to add the await keyword, which is required as web3 takes time in creating the campaign object for us. Following is the corrected code:

const campaign = await Campaign(props.query.address);

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.