I ran into some trouble with my smartcontract. I want to be able to allocate referral tokens to each person who participated in the ICO referral program. In order to do this, the smart contract must be able to distinguish contributions made and link them to a certain participant. I am looking for a way to let the smart contract create unique contribution addresses for each participant that registers for the ICO. These addresses will receive contributions and immediately transfer them to the "main" contract address, this way knowing each contribution made by each contributor seperately, even if he contributes from multiple wallets. How can i do this?

  • I don't get it, you just want to know WHEN a contributors contributed? Jan 15 '18 at 1:23
  • No, i want to know WHO is the contributor, even if he contributes from 3/4 different addresses. I want a way to create a unique address for each ICO participant, so i know who sends what. Jan 15 '18 at 1:28
  • You cannot assign an address from the smart contract, but you can assign them an ID. Jan 15 '18 at 1:30
  • And how does that work exactly? Jan 15 '18 at 1:31
  • So, just to be clear : A person who wants to contribute signs up on a website, and gets his dashboard. On this dashboard he will get a referral link and can see the amount of people who signed up through that link, and next he will see the total amount of all contributions made by those people. I need to know how i can distinguish these contributors, by giving each of them a contribution address of which the smart contract will know who it is. Otherwise, there is no way of knowing who contributed what. Jan 15 '18 at 1:32

According to the comments in the OP:

You cannot assig na new address to a sender while in a smart contract. Moreover, inside the contract, there is new way for you to know what address belongs to you. Moreover, this is only my point of view, user send ether from where they want, usualy from only one account. Its their responsability to send from where they want, not ours.

But, even if you manage to identify users, I would create a mapping with a uint as a key and a mapping as a value. This other mapping would be the list of addresses user sent ether from. This way, you are able to identify addresses.

  • And what if i make receiver contracts for each participant and a seperate accumulation contract which accumulates all the amounts of the receiver contracts? How would i trigger this receiver contract to automatically send each contribution to the accumulation contract? Jan 15 '18 at 1:57
  • Contracts to handle contracts to... ? Do you have any idea how much this will cost you (or the sender)? A lot of money. In solidity, make things simple, not complicated, or you will lose a lot of money. Jan 15 '18 at 2:39
  • How would you suggest me to do it then? Jan 15 '18 at 14:04

You have to have two contracts: Main and Reciever. Main contract which will have a function to create an instance of a Receiver contract and register this instance in mapping to make sure we are going to receive payments only from valid Receivers.

Receiver contract will implement default payable fallback function which transfer any value to the main contract. There is only small amount of gas which can be used by default payable function when ETH is being send so you may ask your users to call special function to make their payments. I called it PayTransfer. Working code, tested on Remix is below. To test it you have to:

  1. Create Main Contract
  2. Call AddReceiver function in Main contract.
  3. New Receiver address will be displayed in Event NewReceiver and also in public variable lastReceiver.
  4. Then you have to make a payemnt to receiver contract. In remix you can attach PaymentReceiver contract to the address you got in previous step. Use At Address button.

  5. Once payment is done you can check your Main contract balance, Receiver Balance and Receiver contribution value to the main contract using functions as follows:

    • MyBalance
    • ReceiverBalance
    • ReceiverContribution

In case default payable fallback function will not work ( works on Remix ) you can either ask your clients to call PayTransfer function to make their payments or modify fallback function not to transfer msg.value to Main contract and use RetrievePayment function to transfer ETH to your main contract ( you will have to pay for gas in this case ).

Hope this helps.

pragma solidity ^0.4.24;

contract PaymentReceiver {

    Main public main;

    function () payable {

    function PayTransfer() public payable {

    function RetreivePayment() public {
    constructor() public {
        main = Main( msg.sender);

contract Main {

    event NewReceiver(address receiver);
    event ReceivedPayment(address receiver, uint256 value);
    mapping(address => uint256) contributions;
    mapping (address=>bool) validReceiver;
    address public lastReceiver;

    function ReceivePayment() public payable {
        require (validReceiver[msg.sender]);
        contributions[msg.sender] = contributions[msg.sender] + msg.value;
        emit ReceivedPayment(msg.sender,msg.value);


    function AddReceiver() public {
        PaymentReceiver receiver = new PaymentReceiver();
        validReceiver[address(receiver)] = true;
        lastReceiver = address(receiver);
        emit NewReceiver(receiver);

    function MyBalance() public view  returns (uint) {

    return address(this).balance;


    function ReceiverBalance(address receiver) public view returns (uint256) {
        return address(receiver).balance;

    function ReceiverContribution(address receiver) public view returns (uint256) {
        return contributions[address(receiver)];


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.