2. What's an ICO/Token Lunch?
◈ Initial Coin Offering
◈ A fundraising tool that trades future cryptocoins in exchange for
cryptocurrencies.
◈ Case
⬥ Basic Attention Token
(USD 35 million in 24 seconds)
⬥ Status
(USD 100 million in 1 hour)
2
3. Why ICO/Token Lunch?
◈ For company
⬥ The company can raise funds
⬥ The value of the token will change with the company's future development
◈ For investors
⬥ Use the token in exchange for product use rights
⬥ Sell the token, earn the spread from it
3
4. ERC-20 Token Standard
◈ ERC-20 defines a common list of rules for all Ethereum tokens to
follow.
◈ ERC-20 will allow dapps and wallets to handle tokens across
multiple interfaces/dapps.
4
6. Create your own ethereum token
◈ Inherit Standard Token
◈ Basic Parameters
// A Plan Coin
string public name = "A Plan Coin";
string public symbol = "APC";
uint8 public decimals = 18;
// Crowdsale details
address public beneficiary; // Company addres
uint256 public minAmount = 10 ether;
uint256 public maxAmount = 95279487 ether;
uint256 public minAcceptedAmount = 40 finney; // 1/25 ether
contract APCToken is Owned, StandardToken { . . . }
6
7. Create your own ethereum token (cont.)
◈ Exchange Rate Parameters
◈ Solidity Time Unit
// Eth to APC rate
uint256 public rateAngelMinutes = 650;
uint256 public rateFirstMinutes = 550;
uint256 public rateSecondMinutes = 475;
uint256 public rateThirdMinutes = 425;
uint256 public rateLastMinutes = 400;
uint256 public rateAngelMinutesEnd = 1 minutes;
uint256 public rateFirstMinutesEnd = 2 minutes;
uint256 public rateSecondMinutesEnd = 3 minutes;
uint256 public rateThirdMinutesEnd = 4 minutes;
uint256 public rateLastMinutesEnd = 5 minutes;
1 == 1 seconds , 1 minutes == 60 seconds , 1 hours == 60 minutes
1 days == 24 hours , 1 weeks == 7 days , 1 years == 365 days
7
8. Create your own ethereum token (cont.)
◈ Modifiers
enum Stages {
InProgress,
Ended,
Withdrawn,
Proposed,
Accepted
}
/* Throw if at stage other than current stage */
modifier atStage(Stages _stage) {
if (stage != _stage) {
Throw;
}
_;
}
/* Access is restricted to owner */
modifier onlyOwner() {
if (msg.sender != owner) throw;
_;
}
/* Throw if sender is not beneficiary */
modifier onlyBeneficiary() {
if (beneficiary != msg.sender) {
Throw;
}
_;
}
8
9. Create your own ethereum token (cont.)
◈ Payment Methods
function () atStage(Stages.InProgress) payable {
if (now < start) {
throw;
}
if (now > end) {
throw;
}
// Enforce min amount
if (msg.value < minAcceptedAmount) {
throw;
}
createTokens();
}
function createTokens() payable {
uint256 tokens = toAPC();
totalSupply += tokens;
balances[msg.sender] += tokens;
raised += msg.value;
deposit[msg.sender] = msg.value;
// Notify listners
Transfer(msg.sender, owner, msg.value);
Transfer(owner, msg.sender, tokens);
}
function toAPC() payable returns (uint256 amount){
// Convert `eth to APC using the current rate
} 9
10. Create your own ethereum token (cont.)
◈ Withdraw Methods
/* Function to end the crowdsale */
function endCrowdsale() atStage(Stages.InProgress)
{
// Crowdsale not ended yet
if (now < end) {
throw;
}
stage = Stages.Ended;
}
/** Unlocks the token irreversibly so that the
transfering of value is enabled*/
function unlock() onlyOwner returns (bool
success) {
locked = false;
return true;
}
/* Transfer to the company address */
function withdraw() onlyBeneficiary
atStage(Stages.Ended) {
// Confirm that minAmount is raised
if (raised < minAmount) {
throw;
}
0;
uint256 amountToSend = raised;
if (!beneficiary.send(amountToSend)) {
throw;
}
stage = Stages.Withdrawn;
}
10
11. Create your own ethereum token (cont.)
◈ Refund Methods
function refund() atStage(Stages.Ended) {
// Only allow refunds if minAmount is not raised
if (raised >= minAmount) throw;
uint256 receivedAmount = deposit[msg.sender];
uint256 tokenAmount = balances[msg.sender];
deposit[msg.sender] = 0;
balances[msg.sender] = 0;
totalSupply -= tokenAmount;
raised -= receivedAmount;
if (receivedAmount > 0 && !msg.sender.send(receivedAmount)) {
deposit[msg.sender] = receivedAmount;
balances[msg.sender] = tokenAmount;
totalSupply += tokenAmount;
raised += receivedAmount;
}
} 11
12. Create your own ethereum token (cont.)
◈ Block number condition
function APCToken(address _beneficiary, uint256
_start, uint256 _end) {
beneficiary = _beneficiary;
balances[msg.sender] = 0;
totalSupply = 0;
locked = true;
start = _start;
end = _end;
}
12
function () atStage(Stages.InProgress) payable {
if (block.number < start) throw;
if (block.number > end) throw;
// Enforce min amount
if (msg.value < minAcceptedAmount) {
throw;
}
createTokens();
}