CROWDSALE

Raising funds from friends without a third party

Crowdfinding

Do you have a really good idea? It is remarkable, but rather large sums are necessary for its realization. There is a small chance that many people would like your idea and they would like to support it. The trust to you as to the performer who will be able to realize this idea correctly and in time will be very important for clients. The YOC platform is perfect for these purposes. You have an opportunity to create a completely transparent contract in which you will specify the time of achievement your purpose. At the same time in case of success, you receive all funds which investors are ready to enclose in your project, in case of failure is necessary to follow the undertaken obligations, investors with guarantee will get the refund.

TOKENS AND DAOS

We will show an example as it is possible to create perfect Crowdfinding, at the same time we will be able to solve two main difficulties: how rewards are managed and kept, and how the money is spent after the funds are raised.

In the majority of present Crowdfinding projects where the funds raised for implementation of the project stored in the central invariable database. Such the investors who weren't in time to make investments until the termination of the company in any way won't be able to participate in the project anymore, and those who has already enclosed the logician can't return the money back except, how to earn the promised reward. In our case we can create the contract, having placed it on the Yocoin platform. This contract will trace all funds arriving from investors and give them a token in exchange which in a consequence will be extinguished by exchange for goods or serviced. The investor can store this token himself, waiting for successful implementation of the project and then to exchange it. Or for example, it can be sold or exchanged for a token of other project, at the same time all obligations for exchange of the released token of a product or service pass to the new buyer. The investor has an opportunity to receive the funds back in case of unsuccessful execution of this project.

We realized DAO which, will be able to operate expenditure of the raised funds. At the same time implementation of the similar management scheme of crowdsale or crowd equity itself is very valuable product. Such realization allows to create a better management of assets and as a result increases probability of a successful completion of all project. Now, create a shareholder association. We are going to use the address of the token we just created as the Shares Address, a minimum quorum of 10, and 1500 minutes (25 hours) as the voting time. Deploy this contract and save the address.

THE CODE

Copy this code and let's create the crowdsale:


pragma solidity ^0.4.16;

interface token {
    function transfer(address receiver, uint amount);
}

contract Crowdsale {
    address public beneficiary;
    uint public fundingGoal;
    uint public amountRaised;
    uint public deadline;
    uint public price;
    token public tokenReward;
    mapping(address => uint256) public balanceOf;
    bool fundingGoalReached = false;
    bool crowdsaleClosed = false;

    event GoalReached(address recipient, uint totalAmountRaised);
    event FundTransfer(address backer, uint amount, bool isContribution);

    /**
     * Constrctor function
     *
     * Setup the owner
     */
    function Crowdsale(
        address ifSuccessfulSendTo,
        uint fundingGoalInEthers,
        uint durationInMinutes,
        uint etherCostOfEachToken,
        address addressOfTokenUsedAsReward
    ) {
        beneficiary = ifSuccessfulSendTo;
        fundingGoal = fundingGoalInEthers * 1 ether;
        deadline = now + durationInMinutes * 1 minutes;
        price = etherCostOfEachToken * 1 ether;
        tokenReward = token(addressOfTokenUsedAsReward);
    }

    /**
     * Fallback function
     *
     * The function without name is the default function that is called whenever anyone sends funds to a contract
     */
    function () payable {
        require(!crowdsaleClosed);
        uint amount = msg.value;
        balanceOf[msg.sender] += amount;
        amountRaised += amount;
        tokenReward.transfer(msg.sender, amount / price);
        FundTransfer(msg.sender, amount, true);
    }

    modifier afterDeadline() { if (now >= deadline) _; }

    /**
     * Check if goal was reached
     *
     * Checks if the goal or time limit has been reached and ends the campaign
     */
    function checkGoalReached() afterDeadline {
        if (amountRaised >= fundingGoal){
            fundingGoalReached = true;
            GoalReached(beneficiary, amountRaised);
        }
        crowdsaleClosed = true;
    }


    /**
     * Withdraw the funds
     *
     * Checks to see if goal or time limit has been reached, and if so, and the funding goal was reached,
     * sends the entire amount to the beneficiary. If goal was not reached, each contributor can withdraw
     * the amount they contributed.
     */
    function safeWithdrawal() afterDeadline {
        if (!fundingGoalReached) {
            uint amount = balanceOf[msg.sender];
            balanceOf[msg.sender] = 0;
            if (amount > 0) {
                if (msg.sender.send(amount)) {
                    FundTransfer(msg.sender, amount, false);
                } else {
                    balanceOf[msg.sender] = amount;
                }
            }
        }

        if (fundingGoalReached && beneficiary == msg.sender) {
            if (beneficiary.send(amountRaised)) {
                FundTransfer(beneficiary, amountRaised, false);
            } else {
                //If we fail to send the funds to beneficiary, unlock funders balance
                fundingGoalReached = false;
            }
        }
    }
}

CODE HIGHLIGHTS

Notice that in the Crowdsale function (the one that is called upon contract creation), how the variables deadline and funding Goal are set:


pragma solidity ^0.4.16;

interface token {
    function transfer(address receiver, uint amount);
}

Those are some of the special keywords in solidity that help you code, allowing you to evaluate some things like 1 yoc == 1000 finney or 2 days == 48 hours. Inside the system all YOC amounts are kept in wei, the smallest divisible unit of yoc. The code above converts the funding goal into wei by multiplying it by 1,000,000,000,000,000,000 (which is what the special keyword yoc converts into). The next line creates a timestamp that is exactly X minutes away from today by also using a combination of the special keywords now and minutes. For more global keywords, check the solidity documentation on Globally available variables.

The following line will instantiate a contract at a given address:


interface token {
    function transfer(address receiver, uint amount);
}

Notice that the contract understands what a token is because we defined it earlier by starting the code with:


pragma solidity ^0.4.16;

This doesn't fully describe how the contract works or all the functions it has. It describes only the ones which the contract needs: a token is a contract with a transfer function, and we have one at this address.

HOW TO USE

Go to contracts and then deploy contract:

  • Put the address of the organization you just created in the field if successful, send to.

  • Put 250 yocs as the funding goal

  • If you are just doing it for a test or demonstration, put the crowdsale duration as 3-10 minutes, but if you are really raising funds you can put a larger amount, like 45,000 (31 days).

  • The yoc cost of each token should be calculated based on how many tokens you are putting up for sale (a maximum of how many you added as "initial supply" of your token on the previous step). In this example, put 5 yocs.

  • The address of the token you created should be added to the token reward address

Put a gas price, click deploy and wait for your crowdsale to be created. Once the crowdsale page is created, you now need to deposit enough gifts, so it can pay the rewards back. Click the address of the crowdsale, then deposit and send 50 gadgets to the crowdsale.

I have 100 gadgets. Why not sell them all?

This is a very important point. The crowdsale we are building will be completely controlled by the token holders. This creates the danger that someone controlling 50%+1 of all the tokens will be able to send all the funds to themselves. You can try to create special code on the association contract to prevent these hostile takeovers, or you can instead have all the funds sent to a simple address. To simplify we are simply selling off half of all the gadgets: if you want to further decentralize this, split the remaining half between trusted organizations.

RAISE FUNDS

Once the crowdsale has all the necessary tokens, contributing to it is easy and you can do it from any Yocoin wallet: just send funds to it. You can see the relevant code bit here:


function () {
    require(!crowdsaleClosed);
    uint amount = msg.value;
    // ...

The unnamed function is the default function executed whenever a contract receives yoc. This function will automatically check if the crowdsale is active, calculate how many tokens the caller bought and send the equivalent. If the crowdsale has ended or if the contract is out of tokens the contract will throw meaning the execution will be stopped and the yoc sent will be returned (but all the gas will be spent).

This has the advantage that the contract prevents falling into a situation that someone will be left without their yoc or tokens. We would also self destruct the contract after the crowdsale ended in a previous version of this contract: this would mean that any transaction sent after that moment would lose their funds. We prevent anyone losing money by creating a fallback function that throws when the sale is over.

The contract has a safe Withdrawal() function, without any parameters, that can be executed by the beneficiary to access the amount raised or by the funders to get back their funds in the case of a failed fundraise.

Extending the crowdsale

WHAT IF THE CROWDSALE OVERSHOOTS ITS TARGET?

In our code, only two things can happen: either the crowdsale reaches its target or it doesn't. Since the token amount is limited, it means that once the goal has been reached no one else can contribute. But the history of crowdfunding is full of projects that overshoot their goals in much less time than predicted or that raised many times over the required amount.

UNLIMITED CROWDSALE

So, we are going to modify our project slightly. Instead of sending a limited set of tokens, the project actually creates a new token out of thin air whenever someone sends them yoc. Firstly, we need to create a Mintable token.

Then modify the crowdsale to rename all mentions of transfer to mint Token:


contract token { function mintToken(address receiver, uint amount){  } }
// ...
    function () {
        // ...
        tokenReward.mintToken(msg.sender, amount / price);
        // ...
    }

Once you published the crowdsale contract, get its address and go into your Token Contract to execute a Change Ownership function. This will allow your crowdsale to call the Mint Token function as much as it wants.

Warning: This opens you to the danger of hostile takeover. At any point during the crowdsale anyone who donates more than the amount already raised will be able to control the whole pie and steal it. There are many strategies to prevent that, but implementing will be left as an exercise to the reader:

  • Modify the crowdsale when a token is bought. You can send the same quantity of tokens to the founder's account so that they always control 50% of the project
  • Modify the Organization to create a veto power to some trusted third party that could stop any hostile proposal
  • Modify the token to allow a central trusted party to freeze token accounts as verification is required and that there isn't any single entity controlling a majority of them

SCHEDULING A CALL

Yocoin contracts are passive. They can only do something once they have been activated. Fortunately, there are some third party community services that provide a service for you: the Yocoin Alarm Clock is an open marketplace where anyone can receive yoc to execute scheduled calls or pay yoc to schedule them. This tutorial will be using the 0.6.0 version of the Alarm service. Documentation for this version available here.

First, you need to add the contract to your watchlist. Go to your Contracts tab and then Watch contract (not deploy contract): Give the name "Yocoin Alarm Clock", use 0xe109EcB193841aF9dA3110c80FDd365D1C23Be2a as address (the icon should look like a green eyed creature) and add this code as the JSON Interface:


contract token { function mintToken(address receiver, uint amount){  } }
// ...
    function () {
        // ...
        tokenReward.mintToken(msg.sender, amount / price);
        // ...
    }

Tip: if you are on the test net, use the address 0xb8Da699d7FB01289D4EF718A55C3174971092BEf instead

Click on the green icon that you just added and then choose a function called the Write to contract title. There will be multiple Schedule Call functions, choose the first one, that only has three fields:

  • contractAddress will be the address of the deployed crowdsale contract.
  • abiSignature will be 0x01cb3b20. You can figure out the signature for any function by trying to execute them but in the confirmation window, instead of typing your password, copy the code in the Data field. The function signature is the first 10 characters in bold.
  • targetBlock is the block number in which you want the function to be executed, read below to calculate an estimation.

The crowdsale contract specifies a deadline using a timestamp, but the Alarm clock currently schedules calls based on block numbers. We need to compute a block number that is going to be probabilistically past the deadline since yocoin has a block time of approximately 17 seconds. We can do this with the formula current_block_number + duration_in_minutes * 60 / 17 + buffer where buffer is a number of blocks that is sufficiently larger that you can rely on it occurring after the crowdsale deadline. For short crowdsales less than a day in duration a buffer of 200 blocks should be sufficient. For durations closer to 30 days, you should probably pick a number closer to 5,000.

You can use the following chart for rough estimates for how many blocks to add to the current block to compute the target Block.

  • 1 hour duration (60 minutes): 212 blocks
  • 1 day duration (1440 minutes): 5082 blocks
  • 1 week duration (10,800 minutes): 38,117 blocks
  • 1 month duration (44,640 minutes): 157,553 blocks

On the Send field, you need to send enough yoc to pay the transaction fee, plus some more to pay the scheduler. Any extra money sent will be refunded, so sending at least 0.25 yoc will probably keep you on the safe side.

After that, just press execute and your call will be scheduled. There are no guarantees that someone will actually execute it, so you should check back after the deadline has passed to be sure.

Improve this page

What's next?

Create a democratic autonomous organization

You’ve developed your idea and secured funds. What’s the next step? You have to hire managers, to find a trustworthy CFO to manage the accounts, to run board meetings and do a bunch of paperwork.

You can simply leave this work to an Yocoin contract. It collects proposals from your backers and submit them through a completely transparent voting process.

One of the advantages having a robot running your organization is that it is immune to any outside influence. It’s guaranteed to execute only what it was programmed to. You'll be able to provide services with a 100% uptime guarantee, because the Yocoin network is decentralized.

YOU CAN DEVELOP:

  • A virtual organization where members vote for taking any decision
  • A transparent association based on shareholder voting
  • Your own country with an unchangeable constitution
  • A better delegative democracy