Académique Documents
Professionnel Documents
Culture Documents
Introduction 2
Overview 4
Hands-on 4
Part 3: Get started with Token contracts & Initial Coin Offering 6
Step 1: Setting up the project 7
Step 2: Creating the Code 7
Step 3: Compiling and Deploying the Token Contracts 13
Step 4: Test our Contract 16
1
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
Introduction
As you might have realized by now that there is tremendous buzz about Ethereum smart contracts out
there and as you have already learned from our Blockchain Labs Tech Series of Hands-On. And as you
may recall, a blockchain is a decentralized distributed database that is used to maintain a continuously
growing list of records, called blocks, that is not controlled by a central authority like government or a third
party. Smart technology is deemed to be secure, reliable, world-changing disruptive technology and
overall predict our near-future to be governed through micro-transactions between individuals – that is a
world that is expected to be trustworthy only when we have smart-contracts in all areas of our life”. This is
all certainly true, yet, to a certain extent, as shown in a sample representation of Fig. 1.
Fig. 1
2
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
blockchain itself. And this is what actually makes it so powerful if you think about it. Since it’s so
transparent and runs on a blockchain, it eliminates the need for trust to the third parties. Individuals and
small companies can interact without even knowing each other and feel safe for their funds, because it is
the contract that governs outcome.
To make it even more clear: there is no need for third parties, that would create paper contracts, verify
personalities, make decisions in conflict situations, etc. – that is the contract is right there and it is
automatic. Yes, nowadays technology allows that! With certain limitations, though. Yet it is a great
decentralization already!
Crowdfunding Campaign
Suppose some creative folks are about to create an awesome product, so they need funding to make it
happen at a large scale. How do they get a perfect sponsor? Run a crowdfunding campaign! First they
determine how much money is needed, secondly advertise the idea to the world and showcase the
prototype, and, most importantly, make a promise that anyone investing now would get the product later
proportional to the investment made. We can leverage this thanks to the smart contracts technology!
Sometimes a good idea takes a lot of funds and collective effort. You could ask for donations, but donors
prefer to give to projects they are more certain will get traction and proper funding. This is an example
where a crowdfunding would be ideal: you set up a goal and a deadline for reaching it. If you miss your
goal, the donations are returned, therefore reducing the risk for donors. Since the code is open and
auditable, there is no need for a centralized, trusted platform and therefore the only fees everyone will pay
are just the gas fees.
One of the most important and complex tasks that each project leader faces is the creation of a Crowdsale
contract (the contract). This is a program for creation and distribution (sale) of project’s tokens. The price
of one Crowdsale contract is exactly 1 ETH. This is a complete solution used by a number of projects to
raise funds.
3
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
distribution (sale) of project’s tokens. In this article, we will consider possible ways of creating the contract,
their pros and cons; and also emphasize the simplest and the most reliable ones.
Overview
TestRPC is a simulation of an Ethereum blockchain, which comes with 10 pre-defined Ethereum accounts
and supports mnemonics (that is, one can generate the same set of accounts with the same set of
mnemonics). It does not come with a User Interface as Remix, and we need node console plus the web3
library to interact with this blockchain.
Hands-on
It's no secret - ICOs are all the rage these days. Many new companies are raising millions of dollars by
selling their tokens in crowdsale. If you are reading this article, you are probably pursuing the idea of
developing an ICO. Here you’ll be using the usual tools (testrpc) or Ganache-cli, MetaMask etc. to
complete your hands-on lab.
1. https://www.scribd.com/document/373203852/Step-By-Step-Guide-Installing-Ethereum-Building-
a-Blockchain-on-Ubuntu-16-04-Linux-Server
2. https://www.scribd.com/document/373203852/Step-By-Step-Guide-Installing-Ethereum-Building-
a-Blockchain-on-Ubuntu-16-04-Linux-Server
3. https://www.scribd.com/document/374058743/Step-By-Step-Guide-Building-Deploying-a-Private-
Blockchain-Network-on-Windows
4. https://www.scribd.com/document/375953366/Developing-Smart-Contract-on-Ethereum-
Blockchain-Using-Truffle-Framework
5. https://www.scribd.com/document/376560099/Step-By-Step-Guide-on-Deploying-Revenue-
Sharing-Blockchain-Smart-Contracts-using-Remix-IDE-on-Windows
6. https://www.scribd.com/document/376874686/Step-By-Step-Guide-on-Deploying-Blockchain-
Voting-Smart-Contracts-on-Windows
4
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
• Truffle: A development environment, testing framework and asset pipeline for Ethereum. In other
words, it helps you develop smart contracts, publish them, and test them, among other things. You
can read the docs of the Truffle suite for more informations.
• Ganache: It was called TestRPC before, if you have read a tutorial from a few months ago, chances
are they use TestRPC with Truffle, but it was renamed upon the integration of TestRPC within the
Truffle Suite. What Ganache does is simple, it creates a virtual Ethereum blockchain, and it generates
some fake accounts that we will use during development.
• The Metamask Chrome extension
We will start by using Truffle and Ganache, and then use Truffle with geth and Mist.
Note: there is a GUI for Ganache, but because we are such haxors, we will use the CLI.
Note: these are all the tools that we need to create the front-end of the dapp. There are a lot of
dependencies because we’ll be creating a web application with the latest version of javascript and
React.js.
5
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
Note that we are installing the version 0.20.0 of web3 with web3@0.20.0 because the latest version
of web3, the 1.0 is still in beta and it’s unstable.
npm init –y
Note that OpenZeppelin does not currently follow semantic versioning. You may encounter
breaking changes upon a minor version bump. We recommend pinning the version of OpenZeppelin
you use, as done by the -E (--save-exact) option.
After that, you'll get all the library's contracts in the node_modules/zeppelin-
solidity/contracts folder. You can use the contracts in the library like so:
import 'zeppelin-solidity/contracts/ownership/Ownable.sol';
Security: OpenZeppelin is meant to provide secure, tested and community-audited code, but please
use common sense when doing anything that deals with real money! We take no responsibility for
your implementation decisions and any security problem you might experience.
Part 3: Get started with Token contracts & Initial Coin Offering
Here we are going to use some contracts from OpenZeppelin. There is no need to reinvent the wheel, so
we can just use safe and proven patterns built by world-class experts and verified by OpenZeppelin.
6
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
$ truffle init
Once the command finishes you will see the following directory structure:
contracts/
migrations/
test/
truffle.js
truffle-config.js
Note: as the name suggests, all your Solidity source files go inside contracts/ directory. After you
compile your files for the first time, you can see a build/ directory which contains all your compiled
code.
3. Now use npm to initialize the project by running the following command:
$ npm init
Note: at the time of writing, we used zeppelin-solidity@1.8.0. The above command should install the
zeppelin-solidity package inside node_modules. You can find the token & ICO contracts
inside "node_modules/zeppelin-solidity/contracts" directory. We'll import these from our
own solidity code.
import "zeppelin-solidity/contracts/token/MintableToken.sol";
7
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
6. First step is to create the token contract, under the contracts directory.
$ nano contracts/HashnodeToken.sol
import 'zeppelin-solidity/contracts/token/MintableToken.sol';
As you may have guessed, we are just extending MintableToken provided by zeppelin-solidity
package. MintableTokenitself inherits ERC20 token contract (find it inside zeppelin-
solidity/contracts/token/ directory). So, the end result is that our new token HashnodeToken is an
ERC20 token.
Note: MintableToken means that the total supply of the token starts with 0 and increases as people
purchase the tokens in the crowdsale. If you decide to create 100 tokens and sell 60 of them in
crowdsale, the supply will increase up to 60 (as people pay ETH and buy the tokens). Once the
crowdsale is over, 40 more tokens will be minted making the total supply 100.
Feel free to change the above code and supply appropriate values for name and symbol. It's
recommended to set the decimals to 18 in order to be standard compliant.
7. Now that our ERC20 token is ready, let's proceed to code our crowdsale contract. Create the file
contracts/HashnodeCrowdsale.sol and paste the following content:
nano contracts/HashnodeCrowdsale.sol
node_modules/zeppelin-solidity/contracts/crowdsale/CappedCrowdsale.sol'
and
node_modules/zeppelin-solidity/contracts/crowdsale/RefundableCrowdsale.sol'
import './HashnodeToken.sol';
import 'zeppelin-solidity/contracts/crowdsale/CappedCrowdsale.sol';
8
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
import 'zeppelin-solidity/contracts/crowdsale/RefundableCrowdsale.sol';
// ICO Stage
// ============
enum CrowdsaleStage { PreICO, ICO }
CrowdsaleStage public stage = CrowdsaleStage.PreICO; // By default it's Pre Sale
// =============
// Token Distribution
// =============================
uint256 public maxTokens = 100000000000000000000; // There will be total 100
Hashnode Tokens
uint256 public tokensForEcosystem = 20000000000000000000;
uint256 public tokensForTeam = 10000000000000000000;
uint256 public tokensForBounty = 10000000000000000000;
uint256 public totalTokensForSale = 60000000000000000000; // 60 HTs will be sold
in Crowdsale
uint256 public totalTokensForSaleDuringPreICO = 20000000000000000000; // 20 out
of 60 HTs will be sold during PreICO
// ==============================
// Events
event EthTransferred(string text);
event EthRefunded(string text);
// Constructor
// ============
function HashnodeCrowdsale(uint256 _startTime, uint256 _endTime, uint256 _rate,
address _wallet, uint256 _goal, uint256 _cap) CappedCrowdsale(_cap)
FinalizableCrowdsale() RefundableCrowdsale(_goal) Crowdsale(_startTime, _endTime,
_rate, _wallet) public {
require(_goal <= _cap);
}
// =============
// Token Deployment
// =================
9
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
CrowdsaleStage _stage;
if (uint(CrowdsaleStage.PreICO) == value) {
_stage = CrowdsaleStage.PreICO;
} else if (uint(CrowdsaleStage.ICO) == value) {
_stage = CrowdsaleStage.ICO;
}
stage = _stage;
if (stage == CrowdsaleStage.PreICO) {
setCurrentRate(5);
} else if (stage == CrowdsaleStage.ICO) {
setCurrentRate(2);
}
}
// Token Purchase
// =========================
function () external payable {
uint256 tokensThatWillBeMintedAfterPurchase = msg.value.mul(rate);
if ((stage == CrowdsaleStage.PreICO) && (token.totalSupply() +
tokensThatWillBeMintedAfterPurchase > totalTokensForSaleDuringPreICO)) {
msg.sender.transfer(msg.value); // Refund them
EthRefunded("PreICO Limit Hit");
return;
}
10
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
buyTokens(msg.sender);
if (stage == CrowdsaleStage.PreICO) {
totalWeiRaisedDuringPreICO = totalWeiRaisedDuringPreICO.add(msg.value);
}
}
require(!isFinalized);
uint256 alreadyMinted = token.totalSupply();
require(alreadyMinted < maxTokens);
token.mint(_teamFund,tokensForTeam);
token.mint(_ecosystemFund,tokensForEcosystem);
token.mint(_bountyFund,tokensForBounty);
finalize();
}
// ===============================
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
The code is pretty self-explanatory and is well commented. Let me outline a few important points:
• Our crowdsale contract inherits CappedCrowdsale and RefundableCrowdsale (supplied by
zeppelin-solidity) and therefore has a goal and a hard cap. If the contract isn't able to raise a
certain minimum amount of ETH during the crowdsale, the ETH amounts will be refunded to
the investors. Similarly, the contract will not be able to raise more than a specific amount of
ETH due to a hard cap.
• Total 100 tokens will be created by the end of the crowdsale. Out of 100, 60 will be sold in the
crowdsale. Once the crowdsale is over, rest 40 tokens will be (minted and) divided among
three wallets such as teamFund, ecosystemFund and bountyFund.
• The crowdsale has two stages: PreICO and ICO. You can change the stage and update rate
variable to offer extra discounts during presale. As per the above crowdsale contract 1 ETH
can buy 5 tokens in PreICO and just 2 tokens in public sale. So, the early investors get extra
discounts. Note: Max 20 tokens will be sold in PreICO.
• When PreICO is live, the incoming ETH amounts are immediately transferred to the
beneficiary wallet (supplied while deploying the contract). However, in the public sale the
raised ETH amounts are sent to a refund vault. If the crowdsale reaches its goal, the funds
are transferred to the beneficiary wallet. Otherwise, investors are allowed to claim refunds
(check zeppelin-solidity/contracts/crowdsale/RefundVault.sol).
• You have to call finish() to close the crowdsale. This is where remaining tokens are minted
and distributed among various reserved funds. Note: Any unsold tokens are added to the
ecocystem fund.
module.exports = {
networks: {
development: {
host: "localhost",
port: 8545,
gas: 6500000,
network_id: "5777"
}
},
solc: {
optimizer: {
enabled: true,
runs: 200
}
}
};
10. Next, go on (you may need to create it) to the file migrations/2_HashnodeCrowdsale.js and
modify it to this:
cd migrations
12
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
nano 2_HanshnodeCrowdsale.js
module.exports = function(deployer) {
const startTime = Math.round((new Date(Date.now() - 86400000).getTime())/1000);
// Yesterday
const endTime = Math.round((new Date().getTime() + (86400000 * 20))/1000); //
Today + 20 days
deployer.deploy(HashnodeCrowdsale,
startTime,
endTime,
5,
"0x75b67ad7705fbe440c3d6e1b308a581183cea458", // Replace this wallet address
with the last one (10th account) from Ganache UI. This will be treated as the
beneficiary address.
2000000000000000000, // 2 ETH
500000000000000000000 // 500 ETH
);
};
1. Start TestRPC
9. Open two terminals, on terminal 1, start the TestRPC:
$ testrpc
EthereumJS TestRPC v6.0.3 (ganache-core: 2.0.2)
Available Accounts
==================
(0) 0x2377b69895039cc4b04950aeba2068f0855c6c75
(1) 0x6fa8fa7d660463600f0839c1661983a2984d38ff
(2) 0x0928baabdd60e6c617c46dcf31b654775d08faef
(3) 0xbfbbc66a115aedfa294b66cc7c9e3e7480957e9b
(4) 0xacae8ffc5011be365ba0eb49160093facc0aaa52
(5) 0xe78c6b168c115e39fcaf9663d8cb9edffdf556ab
(6) 0x5efe7397edb26510633c8dab82bfaa9cbe9fd312
(7) 0x99a8a06d0068bca1c76ee4d3e1cf70e9995078e5
(8) 0x84c04e530fcbcebb8bfd38712f728743252d3a04
(9) 0x75b67ad7705fbe440c3d6e1b308a581183cea458
Private Keys
==================
(0) ded40af96542ea9916c97c13927bdf14eade07ab5aae735074683da8994b3b0c
(1) a206d748778d023a9622d0a9a367926ed0093de14ce1768315fca3ec5764ad12
(2) 7857148c7e51b15fd2218185a9eb41414b7e6e1b44112bb15a2665460c2c5ae0
(3) 921f838bcd0a656d5811f6b54dccf64114533b8b0609310ac75dfbaf1e2e3f17
(4) 616d256ca11b32d46e8f840031a29cddedfab3cb5b67aa39213f9cc16ea9bd20
(5) 530b4f33b880d8306f220220a97ec52b9251c4131bb4600d665fc113924a8eea
(6) ebddacacfc2baa03658d0b79fb10e124cb4bd2c8d5f84d59c374fa246c1f13e3
(7) e52931d70a66e4130f0ff8063dd65afab7cb35eab4d3ef6cb7c3174bebda586e
13
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
(8) 3fdee951549e417093c24877d7578dfd07b6dfbea715d52ed67e61dc088cb2b8
(9) 82c9fb061361f9ad18b0e6f87a7d5cc6e6773af6bc700789646a5f3898b6750f
HD Wallet
==================
Mnemonic: horn convince peasant science build ocean narrow vehicle fragile
glare right crisp
Base HD Path: m/44'/60'/0'/0/{account_index}
Listening on localhost:8545
Note: it will run testrpc. Which we are using for our development needs.
Note: we need to do the above modification so that we can set the crowdsale start date to yesterday
while deploying. Otherwise, you have to provide a future date as the crowdsale start date which will be
difficult to test.
The above code keeps our contract ready for deployment with the following settings:
• startTime is yesterday
• endTime is startTime + 20 days
• Current rate is 5 i.e. 1 ETH can buy 5 HTs
• "0x75b67ad7705fbe440c3d6e1b308a581183cea458" is the beneficiary wallet. You should
replace this with the 10th wallet address (usually the last one) from Ganache UI. If you
choose a different wallet from ganache, the last test case will fail! (Can you find out the
reason?)
• Goal is 2 ETH and hard cap is 500 ETH
$ truffle compile
module.exports = {
networks: {
development: {
host: "localhost",
port: 7545,
14
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
gas: 6500000,
network_id: "5777"
}
},
solc: {
optimizer: {
enabled: true,
runs: 200
}
}
};
Note: Ganache (installed earlier) is running on port 7545. The above code configures the local
blockchain (Ganache) details and registers with truffle.
13. Now it's time to compile, deploy and test our code.
$ truffle compile
Fig. 2
Next, let’s check out our build folder. Here we can see all the build artifacts of the contracts we used,
from ERC20 to Mintable token and HashnodeCrwodsale. Build artifacts are stored in JSON files,
which contain the name of the contract, Application Binary Interface definition (ABI), unlinked binary
sting, which will be used by Ethereum Virtual Machine, and some other info.
15
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
$ truffle migrate
Using network 'development'.
Note: if you happen to look at the testrpc tab you will see that the contract was deployed successfully.
$ truffle test
If the tests are successful, you should see something like this:
16
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
Fig. 3
Note: that "truffle test" command automatically compiles and deploys your contracts before
running the tests.
16. Congrats! You have verified your contract on your local machine.
17. You’re done with this section and this Hands-On lab.
2. Click Import Existing DEN. In the box marked Wallet Seed, enter the mnemonic that was displayed
when launching Ganache.
Warning: Do not use this mnemonic on the main Ethereum network (mainnet). Make sure that you set
the network to "Private Network" (use the "Custom RPC" setting). See below for details.
17
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
Fig. 4
3. Enter the Mnemonic 12 words and the password below that and click OK.
Fig. 5
From testrpc (ganache-cli) we have: MetaMask seed phrase:
Mnemonic: horn convince peasant science build ocean narrow vehicle fragile
glare right crisp
18
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
4. Now we need to connect MetaMask to the blockchain created by Ganache. Click the menu that shows
"Main Network" and select Custom RPC.
Fig. 6
5. In the box titled "New RPC URL" enter http://127.0.0.1:8545 and click Save.
6. The network name at the top will switch to say "Private Network". Click the left-pointing arrow next to
"Settings" to close out of the page and return to the Accounts page.
Fig. 7
19
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
Note 1: now that we've connected MetaMask to Ganache, you'll be taken to the accounts screen.
Each account created by Ganache is given 100 ether. The first account should have less than the
others because that account supplies the gas for smart contract deployment. Since you've deployed
your smart contract to the network, this account paid for it.
Note 2: you an now create new accounts. To do so, click the account icon in the upper-right to create
new accounts, the first 10 of which will correspond to the 10 accounts displayed when you launched
Ganache, continue until you can create all the 10 accounts from testrpc.
Fig. 8a
Fig. 8b
20
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
8. To buy some test Ether click on "Buy" button in MetaMask. It'll take you to a faucet where you can
request some test ETH. We'll need this to pay our transaction fees while deploying the contract.
Fig. 9
Note: from the truffle migration we can note the crowdsale address, which we can use
Fig. 10
Contact address: "0x079bfc42cc846b33a5cb2ecc9fbed6251cecc112"
9. Let’s send 1 Ether from account 4 to Account 1. To do so, follow the Fig. 11 (a) to (e).
21
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
Fig. 11
10. Finally, you should observe that there is reduction in the ether that Account 4 holds, and addition in
Account 1, see Fig. 12
22
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org
Global Open Versity Writing and Testing Real world Crowsale Contracts on Ethereum v1.0
Fig. 12
11. Congratulation. You’re done with this section and this lab.
Warning: you should not actually release your ICO with the code found here. It is for demo purposes
only. But it is a good start.
The Ethereum community grows by the day and though there are not many tools out there yet, the ones
such as Truffle and Zeppelin Solidity do a great job at improving developer’s experience.
-----------------------------------------------
Kefa Rabah is the Founder of The Lake Institute. Kefa is knowledgeable in several fields of Science &
Technology, Information Security Compliance, Blockchain Technology, Distributed Ledger Technology
(DLT) and Project Management, and Renewable Energy Systems. He is also the founder of Global Open
Versity, a place to enhance your educating and career goals using the latest innovations and
technologies.
23
April 2007, Kefa Rabah, Global Open Versity, Vancouver Canada
www.globalopenversity.org