4

I want to create a simple smart contract for registration of users to a competition where when users can pay to contract and 2 ethers will deduct from his account. But when I'm trying to do so on my local ganache blockchain,only gas price is being deducted.

But I'm confused on how to accept payments from ethereum network accounts to the contract.

Help me..

Here's the code

pragma solidity >=0.4.22;

contract dCoders {
    // variables
    // storing contract_amount collected for the event
    address public owner;
    uint public regFee;

    mapping (address => uint) public balance; 

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

    event reg(address indexed _from);

    // register a user in the event
    function register() payable public {
        // emit reg(_sender, owner, regFee);

        balance[msg.sender] -= regFee;
        balance[address(this)] += regFee;   

        emit reg(msg.sender);
    }

    // distribute the amount collected to winners

    // register a sponser in the event
}
2
  • Implement function() payable external. Commented Jan 16, 2019 at 18:02
  • still same issue
    – Hrishabh
    Commented Jan 16, 2019 at 18:14

3 Answers 3

5
pragma solidity >=0.4.22;

contract dCoders {
 //variables
 //storing contract_amount collected for the event
 address public owner;
 uint public regFee;

 mapping (address => uint) public balance; 

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

  event reg(address indexed _from);

  //register a user in the event
 function register() payable external {
 require(msg.value == 2 ether);
 balance[address(this)] += regFee;     
 emit reg(msg.sender); 
 }

 //distribute the amount collected to winners

  //register a sponser in the event

  }

Assuming that at the moment you need to draft only, here it is.

1) you do not need to decrement any balance for your user: it is done automatically when he sends ethers to you and you accept them. The “balance” mapping is a local-to-your contract variable only. It is written by you in order to be readed by you

2) you can call your function “register” or you can avoid to name it.

function () payable external {
...
}

In this way your user must send 2 ether to the contract without calling nothing. This way he can use any wallet to do it.

Just to help you to start... 😉

4
  • I followed your steps ,but now when I'm trying to pay to the contract address using metamask.it gives following error: LERT: [ethjs-rpc] rpc error with payload {"id":4029074856048,"jsonrpc":"2.0","params":["0xf866028502540be40082520894157d16b9fa8f87912d5afded5586799de1c6007a8080822d46a0f597fa7f1ee73a94ebd6f3ff300f6439d6d6cdc5a054b0a763be623666a91c26a0361b13d5c633a1729d046be4cf957528d92b28be703c177f0d7fc4df53af033a"],"method":"eth_sendRawTransaction"} Error: VM Exception while processing transaction: out of gas ....I'm using ganache
    – Hrishabh
    Commented Jan 16, 2019 at 19:31
  • Use Remix-ide in JavaScript VM mode. Reintroduce Ganache after a complete successful test.
    – Rick Park
    Commented Jan 16, 2019 at 19:55
  • Got it,the problem was with gas limit....
    – Hrishabh
    Commented Jan 16, 2019 at 20:22
  • 1
    I suggest you to develop on Remix just in order not to have to manage this kind of problems when developing the structure of the code. Please mark as answered the question.
    – Rick Park
    Commented Jan 16, 2019 at 20:24
5

Accepting payments in Ethere only requires a function with a payable keyword.

As Rick mentioned, easiest way is to have a fallback function (without function name) which is executed whenever someone sends Ethers to the contract - that way they don't need to call any function directly and they can just use a regular Ether sending transaction without knowing anything of the contract's functions.

Otherwise your usage of balance is rather..wrong. If I understand you correctly, you want to store the amount of Ethers each user has sent. In that case you probably want to change the line to: balance[msg.sender] = msg.value;. If you store it with address(this) you will not have the sender's address stored anywhere.

If, on the other hand, you are simply trying to store the amount of Ethers received with the line, then you can just remove it. You can always find out how much Ethers a contract has without explicit functionality for it. So two things are automatic: 1) Reducing Ethers from sender 2) Incrementing Ethers in contract.

1
  • I agree with Lauri. Even if in that a way you can say to be able to know how much funds has been collected in total, not being dependent from the possible withdrawal, it is possible to say that to use a mapping with one key only (the address of the contract is a constant once deployed) is wrong because a simple uint is enough!
    – Rick Park
    Commented Jan 16, 2019 at 22:48
2

The user sends a transaction to the contract function. This transaction includes a value which is ether funds, and data which selects the function to run and passes in arguments.

On the contract side, you need the function to be payable and you can inspect the amount of money received with the message to confirm it is exactly what you need.

If it's okay to proceed, then register your user, do the accounting and emit an event.

The OP didn't reveal any details about what happens after registration, so some guesswork about what to do. Importantly, all funds from all sources rest in the contract's balance without any help from us. It may be important to know the sources of those funds (who sent how much) and this is where the balances mapping helps. It is not funds. It's accounting (data) about the funds.

pragma solidity 0.4.22;

contract dCoders {

    address public owner;
    uint public regFee;

    mapping (address => uint) public balances; 

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

    event LogRegistration(address from);

    // User sends 2 ether to this function
    function register() payable public{

        require(msg.value == regFee);
        balances[msg.sender] += msg.value; // track contributions by user    
        emit LogRegistration(msg.sender);
    }

}

Hope it helps.

0

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.