5

I have a simple contract that I built a small webapplication with. The contract is as follows:

contract MyContract {
    address public creator;

    function MyContract() {
        creator = msg.sender;
    }

    function reject() {
        selfdestruct(creator);
    }

    function send(address target, uint256 amount) {
        if (!target.send(amount)) throw;
    }
       function destroy(address target) {

        selfdestruct(0x0000000000000000000000000000000000000000);
    }
}

This always worked - I'm using MetaMask to sign the payments and inintiate the contracts. Since a week or something, I'm getting an error in my console from Web3: Cannot send value to non-payable constructor

I then started to Google around, and found out about a function needed to be payable and that there should be a fallback function in my contract. So I customized my contract a bit, this is what I have now:

pragma solidity ^0.4.9;

contract Oursurance {
    address public creator;
    uint x;

    function() payable { x = 1; }

    function Oursurance() payable {
        creator = msg.sender;
    }

    function reject() payable {
        selfdestruct(creator);
    }

    function send(address target, uint256 amount) payable {
        if (!target.send(amount)) throw;
    }

    function destroy(address target) payable {
        selfdestruct(0x0000000000000000000000000000000000000000);
    }
}

I know not every function should be payable, but just to be sure I have added it to everything. Just need it to be working again.

I am still getting this error with the above (edited) contract.

4

A little explanation. I renamed "reject" to "kill" and removed payable from the functions I don't imagine should have it.

There are two ways to inject funding into the contract:

  1. When deploying the contract, add value. You can do that through meta.mask as you deploy the contract.
  2. After it's deployed, you can send Ether to the contract's address in the same way you would send ETH to your other wallet. No function named needed. The unnamed (fallback) function, which is payable, will run.

You can also trigger the fallback from JavaScript web3.eth.sendTransaction({from: me, to: contract, value: amount}) or from another contract with contractAddress.send(amount). The contract is going to execute the fallback function when no function is specified, or when the function specified doesn't exist.

I added an event emitter to the fallback function to show how you can use the fallback for something useful. For consistency, I dropped it into the constructor as well, and added a similar event for send().

We can safely say the "necessary accounting" (logs in this case) is performed for all funds that arrive and depart this contract. Nothing will sneak in through functions like send() that aren't designed to process receipts.

pragma solidity ^0.4.9;
contract Oursurance {

  address public creator;

  event LogFundsReceived(address sender, uint amount);
  event LogFundsSent(address receiver, uint amount);

  function() payable {
    LogFundsReceived(msg.sender, msg.value);
  }

  function Oursurance() payable {
    creator = msg.sender;
    LogFundsReceived(msg.sender, msg.value);
  }

  function kill() {
    selfdestruct(creator);
  }

  function send(address target, uint256 amount) {
    if (!target.send(amount)) throw;
    LogFundsSent(target, amount);
  }

}

Hope it helps.

  • Within the function, could contract see how much ether did it received? Is msg.value equivalent to that? @Rob Hitchens – alper Apr 13 '17 at 0:41
  • 1
    @Avatar Yes, msg.value will reliably give you the value transferred in Wei. It's a uint256. – Rob Hitchens - B9lab Apr 13 '17 at 10:49

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.