1

I'm getting a weird error while compiling a contract in Solidity, I think it's because I'm using Solidity v0.5.0 and it was written with a previous version. Here's the code:

pragma solidity ^0.4.2;

contract Migrations {
    address public owner;
    uint public last_completed_migration;

    modifier restricted() {
        if (msg.sender == owner) _;
    }

    function Migrations() {
         owner = msg.sender;
    }

    function setCompleted(uint completed) restricted {
        last_completed_migration = completed;
    }

    function upgrade(address new_address) public restricted {
        Migrations upgraded = Migrations(new_address);
        upgraded.setCompleted(last_completed_migration);
    }
}

To be specific the compiler returns:

TypeError: Name has to refer to a struct, enum or contract.
    Migrations upgraded = Migrations(new_address);

underling the first appearance of Migrations.

Where's the problem in this?

  • 1
    If you're using Solidity 0.5.0, then why does your code begin with pragma solidity ^0.4.2? – goodvibration Jan 29 at 17:28
  • Because when I first studied this code that was the version being used. I know have changed it v0.5.0 but the error stays – AndreaCRD Jan 29 at 17:34
  • It does not matter. ^ means “after or equal this compiler version”. So 0.5.0 is fine – Rick Park Jan 29 at 17:35
  • P.s.: after you changed using constructor, use at least a pragma solidity ^0.4.24 or so... 😉 – Rick Park Jan 29 at 17:42
2

There are other issues to get a clean compile with 0.5.0.

Here is an untested hack that compiles cleanly. I feel like I should point out that Migrations should always compile with the corresponding Truffle that created it (using truffle init), so this sort of hack shouldn't be necessary.

pragma solidity 0.5.0;

contract Migrations {

    address public owner;
    uint public last_completed_migration;

    modifier restricted() {
        if (msg.sender == owner) _;
    }

    constructor() public {
        owner = msg.sender;
    }

    function setCompleted(uint completed) public restricted {
        last_completed_migration = completed;
    }

    function upgrade(address new_address) public restricted {
        Migrations upgraded = Migrations(new_address);
        upgraded.setCompleted(last_completed_migration);
    }
}

Hope it helps.

  • This works, thanks. Only problem now is that I'm getting: TypeError: Event invocations have to be prefixed by "emit". votedEvent(_candidateId); ^----------------------^ which is a method called in another contract – AndreaCRD Jan 29 at 17:44
  • You'll have minor issues with all of your contracts. The visibility of constructors and other functions, for example. Needs public where the old code might be silent on the matter. Constructor names, emit, etc. See here: solidity.readthedocs.io/en/v0.5.0/050-breaking-changes.html – Rob Hitchens - B9lab Jan 29 at 17:52
  • Man: we helped a lot, but please do not ask here without reading the docs! It is not a good habit! Good luck, anyway! – Rick Park Jan 29 at 18:40
0

Simply change the

function Migrations...

with

constructor...

In 0.5.0 there is no more the use of a function with the same name of the contract as constructor

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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