17
Develop your first Dapp!
Interested in Blockchain technology, but don't find a reliable source to get started?
You have come to the right place. In this article, we'll learn how to develop a complete decentralized website (Dapp) from scratch.
We will be writing a Lottery contract that will allow people to participate in the lottery. The lottery manager will pick a lottery winner and all the lottery amount will eventually get transferred to the winner. Sounds interesting, right? So, let's get started!
To develop a dapp, we first need to write an Ethereum Smart Contract using Solidity which we'll deploy on the blockchain network.
We'll be using Remix IDE for writing, debugging, and interacting locally with the Smart Contract.
Note: To follow along, refer to this contract.
Let's write our first smart contract. Head on to the Remix IDE and navigate to the Storage.sol file in the Contracts folder as shown.
Delete the existing code from the Storage.sol file and follow along.
Specify the Solidity version for our code by adding the code below.
pragma solidity ^0.4.17;
Now, let's get started with the Contract.
contract Lottery {
}
Firstly, we have used the contract
keyword to declare a Contract named Lottery, followed by the curly braces, where we'll write our Contract.
Now, declare two variables namely manager
of datatype address
and players
of datatype address[]
. In Solidity, the address
datatype is used to store the wallet address.
address public manager;
address[] public players;
Following, declare a Lottery()
function. As this function has the same name as the Contract name, it will eventually work as a constructor.
function Lottery() public {
manager = msg.sender;
}
This function will execute automatically when anyone deploys the Contract. We have used the public
keyword after the function name which will make the function's visibility public and let anyone call the function.
In this function, we are setting the caller of the function as the manager. As a result, the user who will deploy this Contract will be recognized as the manager of the contract.
In our case, you will the renowned manager of the Contract as you are going to deploy it.
After that, declare an enter()
function.
function enter() public payable {
require(msg.value > .01 ether);
players.push(msg.sender);
}
This function will let anyone enter our lottery. Apart from the public
keyword, we have used the payable
keyword. It specifies that this function will require some amount of ethers to execute. So, whoever wants to enter our lottery, needs to pay a specified amount of ether, which also seems necessary, right? This ether will get stored as the Contract's ether in our Contract.
In the enter()
function, we have written require(msg.value > .01 ether);
. Here, msg.value
denotes the amount of ether the user sends along with the function. It specifies that to enter our Lottery, the caller of the function must send ethers more than 0.01 ether and if the caller fulfills the specified condition, then only he is welcomed in the contract by pushing the caller's address to the players
array.
Following the enter()
function, comes the random()
function.
function random() private view returns (uint) {
return uint(keccak256(block.difficulty, now, players));
}
Yes, you are getting it right. This function will return a random number which will help the manager in picking a random winner among the entered players. Solidity does not have a native random
method, thus we have to define our own.
But let's discuss what are these private
, view
, and returns
keywords following the function name.
private
-> This keyword is the opposite of thepublic
keyword. By using theprivate
keyword, we are blocking public access to this function. As a result of which, this function can't be called from outside of the contract, even by the manager, and can only be called from inside of the Contract.
view
-> It will restrict the modification of the data of our Contract and will only allow reading our Contract data.
returns
-> It specifies that our function will return some data. Following it, we have written(uint)
which specifies that our function will return data of typeuint
. (uint stands for unsigned integer).
If you want to know more about the Solidity datatypes, then go to this page.
After random()
comes the pickWinner()
function, which will let the manager pick the winner of our Lottery.
function pickWinner() public restricted {
uint index = random() % players.length;
players[index].transfer(this.balance);
players = new address[](0);
}
Here, we have used a new keyword namely restricted
after the public
keyword.
What does this restricted
keyword specify? Well, we'll talk about this keyword after the upcoming function.
In the pickWinner()
function, we are initializing the index
variable of type uint to store the array index of the winning player, which is obtained by the shown operation. This operation will return a random number from 0 to players.length() -1
.
After getting the index
, we are transferring all the contract's ether to the address at the players[index]
. Followed by resetting the players
variable to an empty array, so that we can now accept entries for a new lottery.
After pickWinner()
, comes the restricted()
modifier.
modifier restricted() {
require(msg.sender == manager);
_;
}
Modifier is a special keyword that allows you to control the behavior of your smart contract functions. We have seen the use case of modifier in pickWinner()
function. By using modifier, all the conditions specified in the modifier will also be applicable for the function in which it is used.
In restricted()
modifier, we have specified the condition require(msg.sender == manager);
which specifies that sender must be the manager of the Contract.
After that, we have written _;
, which will execute all the function code after this.
Lastly comes the player()
function, which returns the players
array.
function getPlayers() public view returns (address[]) {
return players;
}
Getting bored of the theoretical thing, right? So, let's deploy our contract and start interacting with it.
Navigate to the deploy and run transactions panel on the Remix IDE. In this panel, make sure, your ENVIRONMENT is set to JavaScript VM as shown.
Similarly, select Lottery-Contracts under the CONTRACT tab. Now, click Deploy.
After Successfully deploying your Contract, you can see all the variables and methods of our Lottery contract in a Graphical form as shown below.
Clicking each of these buttons, allow us to interact with our Contract.
On clicking the manager button, you should get your current address. You can verify that address with your current address in the ACCOUNT tab below the ENVIRONMENT tab as shown below.
You can also change your current account, by selecting another account from the ACCOUNT tab. Now, enter the lottery from this new account.
Note: You can check the status of your transaction by expanding the panel from the bottom as shown below.
Now, click the getPlayers button, you should get an empty array. Surprised to see an empty array despite entering the lottery?
In reality, our enter function was failed. This was because we have required a minimum value of 0.01 ether to enter our lottery.
Now, under the VALUE tab, change the unit to ether from Wei and enter value 1. Now, again click the enter button and then click getPlayers button again. Now you should see your current address.
Finally, click the pickWinner button. Before clicking, ensure that your address is the same as the manager's address, by selecting from the ACCOUNT tab. After picking the winner, you can verify that the ether in any of the player's addresses is again 100 and now the players
array is also empty.
That's all! Woohoo! You just wrote and deployed your first Smart Contract on the test network.
To integrate React web app with your Smart Contract, you can follow next tutorial.
17