0

I'm fairly new to Solidity and coding overall. I'm going through a Udemy course and I ran into an error which I can't find the solution for. I deployed a contract on the Sepolia test network from which I call function that deployes a new contract, but when I try to deploy it I get the error.

this is the error:

Transaction has been reverted by the EVM:
 {"blockHash":"0x908e501f7cb2e9975ed81fb64fcc51aa9fd8f923a3fad80d9f97c78c40a6de4a",
"blockNumber":"4410294",
"cumulativeGasUsed":"9720319",
"effectiveGasPrice":"69769822991",
"from":"0xe4aa30452696f6b2e8e89f228b7bfa742a232725",
"gasUsed":"21110",
"logs":[],
"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"status":"0",
"to":"0x082e650e19d6748175984209bbbf06bf7b10b569",
"transactionHash":"0xbbd3dc6723c35176647243115985a1e9deab3af006c7468da6482190842f8d34",
"transactionIndex":"53",
"type":"2"}

This is the code, and the function that failes is createCampaign() in the first contract, which is already deployed in the network:

pragma solidity ^0.4.17;

contract CampaignFactory {
    address[] public deployedCampaigns;

    function createCampaign(uint256 minimum) public {
        address newCampaign = new Campaign(minimum, msg.sender);
        deployedCampaigns.push(newCampaign);
    }

    function getDeployedCampaigns() public view returns (address[]) {
        return deployedCampaigns;
    }
}

contract Campaign {
    struct Request {
        string description;
        uint256 value;
        address recipient;
        bool complete;
        uint256 approvalsCount;
        mapping(address => bool) approvals;
    }

    Request[] public requests;
    address public manager;
    uint256 public minimumContribution;
    mapping(address => bool) public approvers;
    uint256 public approversCount;

    modifier restricted() {
        require(msg.sender == manager);
        _;
    }

    function Campaign(uint256 minimum, address creator) public {
         manager = creator;
        minimumContribution = minimum;
    }

    function contribute() public payable {
        require(msg.value > minimumContribution);

        if (!approvers[msg.sender]) {
        approvers[msg.sender] = true;
        approversCount++;
        }
    }

    function createRequest(
        string description,
        uint256 value,
        address recipient
    ) public restricted {
        Request memory newRequest = Request({
            description: description,
            value: value,
            recipient: recipient,
            complete: false,
            approvalsCount: 0
        });
        requests.push(newRequest);
    }

    function approveRequest(uint256 index) public {
        Request storage request = requests[index];
        require(approvers[msg.sender]);
        require(!request.approvals[msg.sender]);

        request.approvals[msg.sender] = true;
        request.approvalsCount++;
    }

    function finalizeRequest(uint256 index) public restricted {
        Request storage request = requests[index];
        require(!request.complete);
        require(request.approvalsCount > approversCount / 2);

        request.complete = true;
        request.recipient.transfer(request.value);
    }
}

This is the what the page looks like along with the react and next code:

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

class CampaignNew extends Component {
  state = {
    minimumContribution: '',
    errorMessage: '',
    loading: false,
  };

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

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

    try {
      const accounts = await web3.eth.getAccounts();
      await factory.methods
        .createCampaign(this.state.minimumContribution)
        .send({
          from: accounts[0],
          gas:'10000000'
        });
        Router.pushRoute('/');
    } catch (err) {
      this.setState({ errorMessage: err.message });
    }
    this.setState({ loading: false });
  };

  render() {
    return (
      <Layout>
        <h3>Create a Campaign</h3>
        <Form onSubmit={this.onSubmit} error={!!this.state.errorMessage}>
          <Form.Field>
            <label>Minimum Contribution</label>
            <Input
              label="wei"
              placeholder="Minimum Contribution is set in Ether"
              labelPosition="right"
              value={this.state.minimumContribution}
              onChange={(event) =>
                this.setState({ minimumContribution: event.target.value })
              }
            />
          </Form.Field>

          <Message error header="Oops!" content={this.state.errorMessage} />
          <Button primary loading={this.state.loading}>
            Create!
          </Button>
        </Form>
      </Layout>
    );
  }
}

export default CampaignNew;
13
  • You don't send any hex data to call a function but send eth value, so you would need a fallback or receive function. Else try calling a function at the contract which is payable and designed to handle the msg.value. Like 0xd7bb99ba (contribute()). May I also ask if it is a direct copy of the code above or if you changed any function names in the deployed version?
    – Maka
    Oct 2, 2023 at 17:51
  • Yes ofc. what do you need me tho send exactly, do you want the abi? Apart from that, can you explain again what I did wrong? I'm having a bit of a hard time understanding.
    – Arad11222
    Oct 2, 2023 at 18:22
  • I don't need you to send anything, is just that deploying the Campaign contract on remix, setting minimum to 100, an then calling 0xd7bb99ba, with a value of 100 or more works. But calling your contract with 0xd7bb99ba and a value above still caused a revert in my simulation, which made me wonder if you had a different name for the function. The issue is you are just directly transferring eth to the contract, which isn't allowed by default, you need to use a function that accepts eth. Did you try to call the contribute() function at your contract rather than directly transferring the eth?
    – Maka
    Oct 2, 2023 at 18:51
  • I didn't change any function names, the contract is exactly the same. When it comes to deploying the contract I never tried calling contribute(). I'll see if it works and I'll update
    – Arad11222
    Oct 2, 2023 at 19:09
  • 1
    I was just able to fix it. Apparently it was a web3 bug between that, Metamask and the client app. Now it all works fine, thank you so much for the help!
    – Arad11222
    Oct 2, 2023 at 22:57

1 Answer 1

0

The createCampaign function from CampaignFactory contract must be payable, the new keyword is used to create a smart contract, therefore it involves paying some ETH.

1
  • 1
    It turned out to be a bug between the version of "web3" that was installed to Metamask and the client app. I changed the dependencies and installed a different version and it all worked again just fine. I'll add that I didn't change the createCampaign() function to payable, I left it the same.
    – Arad11222
    Oct 2, 2023 at 23:30

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.