0

I'm trying to compile something that mirror a pattern like this and getting the following error from remix:

"browser/ballot.sol:26:3: DeclarationError: Function with same name and arguments defined twice. constructor() public { ^ (Relevant source part starts here and spans across multiple lines). browser/ballot.sol:31:3: Other declaration is here: function() public payable {} ^--------------------------^"

the code (if I comment out the second fallback function, it works):

pragma solidity ^0.4.0;

contract C {

  address public owner; 
  address public creator;

  constructor (address _creator) public {
    owner = tx.origin;
    creator = _creator;
  }

  function() public payable {}

  function printOwner() public view returns(address h) {
      h = owner;
  }

}

//factory contract for C
contract CFactory {
  address public owner;
  address public currentContractAddress;

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

  //function() public payable {}

  function test1() public returns(address){
    C c = new C(currentContractAddress);
    return c.printOwner();
  }

}
1

The problem is it doesn't compile.

constructor. This is wrong. In solc 0.4.22 you can say function constructor() but is new (today) so I used the more traditional "same name as contract" method.

tx.orgin is a security risk, so changed to msg.sender with a pass-through pattern.

pragma solidity ^0.4.17;

contract C {

  address public owner; 
  address public creator;

  function C(address _creator, address _owner) public {
    owner = _owner;
    creator = _creator;
  }

  function() public payable {}

  function printOwner() public view returns(address h) {
      h = owner;
  }

}

//factory contract for C
contract CFactory {
  address public owner;
  address public currentContractAddress;

  function CFactory() public {
    owner = msg.sender;
    currentContractAddress = address(this);
  }

  //function() public payable {}

  function test1() public returns(address){
    C c = new C(currentContractAddress, msg.sender);
    return c.printOwner();
  }

}

Hope it helps.

  • Thanks, I see that it works using old syntax. Remix tells me to use constructor() as it is explained on the docs solidity.readthedocs.io/en/v0.4.22/contracts.html. Is it going to work if I would use only one payable fallback function? I used the tx.origin only to set the owner at creation time, I wouldn't use it to check privileges in functions, is it going to be a security flaw anyway? – cAos Apr 17 '18 at 17:08
  • Possibly I'm mistaken about the new constructor syntax. tx.origin is always a security risk on the "do not use" list. The way I refactored replicates what you had before, exactly as intended, without the risk. I'm not sure what you're trying to do with the payable fallback. Contract C simply swallows funds with no way to withdraw them. It's hard to say where you're going with this. – Rob Hitchens Apr 17 '18 at 17:23
  • Both contracts will contain a payable function and a withdraw and/or selfdestruct function. I could actually remove the payable function from the contract with no problem. But now I'm wondering about the error I've described before, I would like to know If I misunderstood something about how the crontracts and fallback function work – cAos Apr 17 '18 at 17:31
  • I think you need to restate it as a new question. – Rob Hitchens Apr 17 '18 at 17:37
  • 1
    I know probably I've been unclear. The issue comes from the fact that constructor() and function() get translated to the same hash so they have to have different parameters. At this point I'm not sure if this is an unexpected behavior or it has been made up on purpose. I'll go without the fallback function given that in my case it is not relevant – cAos Apr 17 '18 at 21:29

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.