In this section, we will build a crowdsourcing application using an Ethereum platform. Our crowdsourcing application has the following requirements;
- Register a project that needs funding. The minimum funding amount for a project can’t be changed after the initial setup.
- Multiple funders should be able to fund the project.
- View the status of the funding at any interval.
- Update the status of project as it goes through the process of funding.
- Funding of the project can be closed explicitly. If the funding is closed explicitly, the funders should get their respective amount automatically.
We will create a smart contract that will implement the above use case requirement. To realize our use case, we will create a local private instance of Ethereum, where all functions of the use case will be executed locally.
Setting Ethereum on Local Environment
To set up an Ethereum network on a local environment, you will need to download one of its implementation. We would go with Go Ethereum.
Go Ethereum is an implementation of Ethereum in Go programming language. To get started, download Go Ethereum a.k.a. Geth for your operating system from https://geth.ethereum.org/downloads/. The current version of Geth at the time of writing this book is 1.7.1.
Tip – If you are on a MAC, use the following details to quickly install Ethereum using brew.
$ brew tap ethereum/ethereum
$ brew install ethereum
To bootstrap your private Ethereum network, we need to create a starting block or the first block termed as genesis block. A genesis block is the block that contains configuration details of the Ethereum network. The following JSON file is a sample custom genesis configuration that you will use to bootstrap the Ethereum private network.
{
"config": {
"chainId": 1,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"alloc" : {},
"coinbase" : "0x0000000000000000000000000000000000000000",
"difficulty" : "0x20000",
"extraData" : "",
"gasLimit" : "0x2fefd8",
"nonce" : "0x0000000000000050",
"mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp" : "0x00"
}
The above configuration file named start.json specifies the fields in JSON format that sets up the Ethereum network. Some of the significant fields are difficulty level, gas limit, nonce, mixhash hash values (used for applying PoW), starting block number (i.e., chainId) and so on. You can also bootstrap the network with predefined wallet accounts and ether by specifying it in the alloc field. We will leave the alloc field blank for now, as we will focus on creating accounts and mining ethers locally as part of our application.
In the next section we will create the above genesis block and set up a local Ethereum network. To get started, download the project from the GitHub repository – https://github.com/enterprise-blockchain-book/first-edition.git.
Note – For more details on genesis block, refer to https://github.com/ethereum/go-ethereum/wiki/Private-network
Creating Genesis Block
As a first step, we will bootstrap a local Ethereum network by creating the genesis block using the above described start.json file. You can follow the below steps:
- Open a terminal or command prompt and navigate to ethereum/setup folder from the downloaded git project. Run the following command:
geth –datadir=./data init start.json
It will create the genesis block in the data folder. You should see a message at the end –“Successfully wrote genesis state”
- Next execute the following command to start a local instance of Ethereum using the data folder created in earlier step.
geth –networkid 999 –ipcpath ~/Library/Ethereum/geth.ipc –rpc –rpcaddr “127.0.0.1” –rpcapi=”db,eth,net,web3,personal,web3″ –rpcport “8545” –datadir=./data –rpccorsdomain “*” console
Note – For windows, use the same command without the ipcpath. –
geth –networkid 999 –rpc –rpcaddr “127.0.0.1” –rpcapi=”db,eth,net,web3,personal,web3″ –rpcport “8545” –datadir=./data –rpccorsdomain “*” console
The following provides the details of the above command line options:
- networkid – The
networkid value of 999 signifies a local environment. There are standard
predefined networkid values from 1 to 5, like 1 for Frontier which connects to
an actual Etherum network, 3 is for Ropsten which is a Test Ethereum
network. Any value other than these
predefined values implies a local instance.
- ipcpath – This is the IPC endpoint file. IPC or interprocess communication allows local processes to communicate with geth using the IPC endpoint.
- rpc – Enable remote procedure call of Geth APIs over HTTP JSON-RPC protocol.
- rpcaddr and rpcport – Specify RPC address and RPC port
- rpcapi – List of Geth APIs that would be enabled over RPC port
- datadir – The data directory for the databases.
- rpccorsdomain – Comma-separated list of domains from which to accept cross-origin requests from the browser. A value of “*” implies accept a request from all domains. Our web application will use XMLHttpRequest to interact with Ethereum node using RPC protocol.
- o console – This would start the geth node instance and open the console.
Note – To view all command line options, kindly visit https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options.
After you execute the command, you would see the below set of messages being printed on the console, denoting IPC endpoint and RPC-HTTP location of the Ethereum node, along with the Geth JavaScript console welcome message. Let’s refer to the said console as ‘geth console’, and we would reference this later in this chapter. You can also see some modules loaded at the end. We will use one of the module web3 API to invoke certain useful functions.
“INFO [08-15|17:55:27] IPC endpoint opened: /Users/Navveen/Library/Ethereum/geth.ipc
INFO [08-15|17:55:27] HTTP endpoint opened: http://127.0.0.1:8545
Welcome to the Geth JavaScript console!
instance: Geth/v1.6.1-stable-021c3c28/darwin-amd64/go1.8.3 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0”
Creating Main Account
In this section, we would create our first account using geth console. Follow the steps below:
- On the geth console prompt, let’s create an account by invoking the web3 API personal.newAccount() method. You can replace ‘password’ by the password of your choice..
> web3.personal.newAccount(“password”)
You will see the following public address and keystore location of the account. The first account is designated as the main account (a.k.a. etherbase) by default. This is the default address where the mining reward (i.e., ether) would be credited.
“0x42d187a0fce3392e853770d360e850f2ea1681bc”
> INFO [08-15|18:00:47] New wallet appeared url=keystore:///Users/Navveen/Downlo… status=Locked
- You can view the list of accounts, by using the web3 API method personal.listAccounts() as shown below
> web3.personal.listAccounts
The above method will display the public address of the main account.
[“0x42d187a0fce3392e853770d360e850f2ea1681bc”]
- Next, you would get the balance associated with the main account as
> web3.fromWei(eth.getBalance(eth.coinbase));
0
The getBalance() method returns 0, which is as expected as we do yet have any ethers in the account.
Creating Miners
In this section, we would start mining locally to add ethers to the main account. Follow the steps below:
- Open a new terminal or command prompt and type in the following command to connect to existing Ethereum geth node instance over IPC port that we had set up earlier. We will provide the path to the existing IPC endpoint location to the ‘geth attach’ command. Upon running the command it will open up the console. Let’s refer to this console as ‘geth sub-console’; we would reference this later in the chapter.
geth attach ~/Library/Ethereum/geth.ipc
Note – For windows, use the same command without specifying the ipc path as shown below. If you recall earlier while starting the geth instance we did not specify ipc path for windows.
geth attach
You should see the following message –
instance: Geth/v1.6.1-stable-021c3c28/darwin-amd64/go1.8.3
coinbase: 0x42d187a0fce3392e853770d360e850f2ea1681bc
at block: 0 (Thu, 01 Jan 1970 05:30:00 IST)
datadir: /Users/Navveen/Downloads/ethereum/setup/data
modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
- On the prompt, enter the following command
> miner.start(2)
This will start mining on the geth console. On the geth console, you should see the messages “committed new block” being printed. The value of 2 signifies the number of threads. It means the command will spawn two threads to perform mining in parallel. You can specify any number of threads. Please note that threads are expensive resources and therefore specifying large number of threads will take up more system memory.
You can stop the mining after 30 minutes, and you should have enough ethers in the main account. To stop mining, execute the following command
> miner.stop()
- Go back to the geth console and type in the following to get the balance of the main account.
> web3.fromWei(eth.getBalance(eth.coinbase));
You would see ethers in your account. For the crowdfunding application, we would need around 2000 ethers. So, make sure you have enough ethers; else you can start the mining process again by issuing commands in geth sub-console as described earlier.
With the main account setup with enough ether balance, next we will create additional accounts using the Ethereum Wallet application. We will also deploy and execute our smart contract using the said application.
Installing Ethereum Wallet
Ethereum Wallet provides a graphical interface to create and manage accounts and execute smart contracts. You can download the Ethereum Wallet for your operating system from the Download section at https://github.com/ethereum/mist/releases
Next, open the Ethereum Wallet, and this should connect to your running local Ethereum instance. You should see a message – Private NET on the application window as shown below. It effectively means the wallet is connected to the running local instance. Click on Launch Application.
You should see an Account Overview screen as shown in the figure below. The Accounts section contains the Main Account (etherbase) that we created earlier, along with the ether balance that was mined locally.
Creating Accounts
Next, we would create sample accounts for our crowdsourcing application. We will create total of three accounts, two funder accounts and one beneficiary account for which the money is being raised.
Earlier we created the main account using the Web3 APIs; this option provides an alternate way to create accounts using the wallet interface.
For creating accounts, click on the Add Account link. Enter the password for the account and confirm it. Next screen would display the password key files for your account and its path. If you plan to use your account on other machines or phones, you can simply import this key files to get access to your account.
Note – A pair of keys, a private key, and a public address defines every account in Ethereum. If you lose the key file, you will lose access to your account. So make sure to backup this key file when running in a production environment. The key file is available in Ethereum node’s data directory. For Mac, this is located at ~/Library/Ethereum, for Linux – ~/.ethereum and for windows at C:\Users\%username%\%appdata%\Roaming\Ethereum.
The key file is a hidden file; so make sure you have enabled the appropriate option to view the hidden files.
Click on the newly created account. On the account details page, click on Account 2 and rename it as Funder1. The following figure shows the details of Funder1 account.
Now, click on the copy address link located on the right side. A warning window will be displayed as the account is on private network, click copy anyway.
Next, click on Transfer Ether and Tokens. On the Send tab, select From as the Main Account (Etherbase), and the To field should be populated with the address of the Funder1 account. If not, paste the address that you copied in the earlier step. Enter amount as 1000. If you click on Show More Options, you can specify the fee you are willing to pay for executing this transaction in the blockchain network. You can also select a higher fee for faster processing of the transaction. Since this is a private network, drag the fee slider to Faster. The following figure shows the Send tab with these details. Click Send.
On the Send transaction window, specify the account password to confirm the transaction. In this page, you would see the gas price, the estimated consumption fee in ethers from earlier selected option and the maximum fee, which you are willing to pay for the transaction.
If you go to Wallets tab and scroll down to Latest Transactions section, you would see a transaction entry for the above record and confirmation block counts (0 of 12.). To invoke this transaction, the miner needs to be started, as they would execute the transaction and commit the block. Start the miner again in the geth sub-console using the command miner.start(2) as described earlier and you would see the confirmation block count progressively increasing as shown in the figure below.
Once the confirmation count reaches 12 of 12, the block would be added to the blockchain. If you click on it, you can view the transaction details and block number mined for this transaction.
Note – The number of confirmations is the number of new blocks (in a sequence) that is appended to a block of transaction. The 12 number implies, 12 new blocks were appended to the block that contains your transaction. Once the confirmation is reached, the transaction block is committed. The confirmation is required to ensure a secure block is being committed to the blockchain and avoid orphaned blocks. The orphaned block occurs when two miners produce blocks at the same time. However, some public Ethereum network might require many blocks for confirmation based on their use cases, which implies it might even take hour(s) for a single block to be committed. For more details, refer to this excellent article from Vitalik Buterin at https://blog.ethereum.org/2015/09/14/on-slow-and-fast-block-times/
Similarly, create another account called Funder2 and transfer 500 ethers from Main Account. For the beneficiary account, create an account and call it as ProjectAI. We will transfer the funds to ProjectAI account now using smart contract. Copy the address of ProjectAI account, as we would need this later once we deploy the contract. The following image shows the snapshot of all the accounts created so far along with its balance in ethers.
In the next article, we would create the smart contract,