Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions Lottery.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ contract Lottery {

bool public open;

mapping(uint => mapping(address => bool)) private entered;

constructor () {
owner = msg.sender;
}
Expand Down Expand Up @@ -61,11 +63,10 @@ contract Lottery {
require(msg.value == entryAmount, "Insufficient Funds");

//Check if user is already a player
for(uint i=0; i < players.length; i++){
if (msg.sender == players[i]){
revert reEntry();
}
if(entered[lotteryId][msg.sender]){
revert reEntry();
}
entered[lotteryId][msg.sender] = true;
players.push(msg.sender);
}

Expand Down
91 changes: 47 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,46 @@
# Introduction
# How to generate and work with randomness in Solidity using Witnet

## Introduction
- Randomness is a core functionality for many applications
- Games, trait-based NFTs, and luck-based financial applications rely heavily on randomness
- Welcome! In this tutorial, we are going to learn about random number generation and Working with it
- Welcome! In this tutorial, we are going to learn about random number generation and working with it
---
# Pre requisites
- To understand and utilize this tutorial you need to have the understanding of:
- Basic knowledge of developing smart contracts in Solidity
- Basic experience with Remix IDE
- Working with Celo Alfajores testnet
## Pre requisites
- To get the most out of this tutorial you need to have a basic understanding of:
- Developing smart contracts in Solidity
- Working with the Remix IDE
- Working with the Celo Alfajores testnet
---
# Requirements
## Requirements
- Metamask
- Celo Alfajores testnet
---
# Let's Get started!
## What we are going to build
- A lottery contract where users can join the lottery by paying an entry amount (just like buying a lottery in real life)
- A random winner will be chosen from the players and will be rewarded the entire lottery amount
- The Lottery will be conducted by an owner who would have access to start and end the lottery
- The owner will not have access to the funds
## Let's Get started!

### What we are going to build
- A lottery smart contract where users can join the lottery by paying an entry fee
- A random winner will be chosen amongst the participants and will be rewarded the entire lottery amount
- The Lottery will be conducted by the lottery's owner who would have access to start and end the lottery
- The lottery's owner will not have access to the funds
- The winner will be picked randomly based on the random number generated by an oracle
- Before starting to code, we must understand some basics first
- Before starting to code, we must first understand some basics
- We will be covering
- Randomness and its requirement in blockchain
- Problem with generating on-chain randomness
- About oracles and Random Number Generation
- About Witnet Oracle
- Random number generation contract from Witnet
## Requirement of Randomness
- Use cases of randomness in blockchain applications
- Problems with generating randomness on-chain
- Achieving randomness through oracles
- An Introduction to the WitnetRandomness contract provided by Witnet
### Requirement of Randomness
- Most applications require randomness in some sort
- Let's take for example a gambling contract(like our own), these contracts award people based on luck, and luck is random
- For these luck-based applications to work, the randomness must be tamper-proof so that no one can exploit
- While in the field of blockchain and smart contracts, there are some problems
## Problem with On-Chain Randomness
- However, in the field of blockchain and smart contracts, there are some problems
### Problem with On-Chain Randomness
- When people get started they use randomness by using the block number or the block timestamp
- But everything in the blockchain is deterministic
- This leads to big security concerns where a party can gain an unfair advantage
- The only bypass to this situation is to generate a number through a trusted source that is outside of the blockchain
- Enter Oracles!!
## Oracles and Random Number generation
### Oracles and Random Number generation
- Oracles act as a bridge between smart contracts and the outer world
- Oracles are a reliable source of information
- They allow the blockchain to interact with external data
Expand All @@ -49,14 +51,14 @@
- Through oracles, smart contracts can obtain tamper-proof random numbers
- Every oracle has a different way of generating the randomness
- We are going to learn how to generate a random number using Witnet
## Witnet Oracle
### Witnet Oracle
- Witnet is a multichain oracle that gives smart contract access to real-world information
- It is one of the oracles that are available in the cell network
- Witnet provides us with a contract using which we can call and obtain randomness
- How this work is, nodes from the witnet are randomly selected to generate a random byte that is cryptographically committed
- It is called crowd-witnessing
- To learn more about randomness in witnet - https://docs.witnet.io/smart-contracts/witnet-randomness-oracle
## Using Randomness from witnet
- To learn more about randomness in Witnet - https://docs.witnet.io/smart-contracts/witnet-randomness-oracle
### Using Randomness from Witnet
- Before starting to code our lottery contract, let's understand the randomness functions provided by Witnet
- You can find their code and the explanation here - https://docs.witnet.io/smart-contracts/witnet-randomness-oracle/code-examples

Expand Down Expand Up @@ -96,14 +98,14 @@ contract Witnet {
- It takes around 5 to 10 minutes to generate the random number
- After 5 - 10 minutes, we can call the fetch function to obtain the random number
- This number is generated earlier and it is fetched into the contract whenever you call the fetch function
## Setup
- To make this tutorial as simple as possible, we are going to use only remix to write and test the contract
### Setup
- To make this tutorial as simple as possible, we are going to use only Remix to write and test the contract
- You can also use local development by using your favorite code editor
- You can download the package for the interface of the randomness contract through this command:
npm I witnet-solidity-bridge
- For the rest of us, we are going to use remix IDE
- For the rest of us, we are going to use Remix IDE
- Open up remix IDE and create a new file -> Lottery.sol
## Building the contract
### Building the contract
- If you're curious, the entire code for the contract can be viewed by [CLICKING HERE!](https://github.com/KishoreVB70/Lottery-Tutorial/blob/main/Lottery.sol)
- Before starting to code a project, we must have an outline of all the functionality that will be in the contract
- This contract will behave like a traditional lottery where there is an owner who will start and end the lottery
Expand All @@ -130,7 +132,7 @@ contract Lottery {
```
- As usual, we write the license and the pragma solidity version
- We import the interface for the randomness contract
- We set the address of the randomness contract in Celo alfajores and create the instance of the interface.
- We set the address of the randomness contract hosted on the Celo Alfajores testnet and create the instance of the interface.
---
```
uint256 entryAmount;
Expand All @@ -143,6 +145,8 @@ contract Lottery {
address owner;

bool open;

mapping(uint => mapping(address => bool)) private entered;
```
- Let's look at all the variables we will be going through
- Firstly we have the `entryAmount` so that the players can know the amount
Expand Down Expand Up @@ -210,20 +214,19 @@ contract Lottery {
require(msg.value == entryAmount, "Insufficient Funds");

//Check if user is already a player
for(uint i=0; i < players.length; i++){
if (msg.sender == players[i]){
revert reEntry();
}
if(entered[lotteryId][msg.sender]){
revert reEntry();
}
entered[lotteryId][msg.sender] = true;
players.push(msg.sender);
}
```
- Then we have the join function which is payable and can only be accessed if there is an active lottery(`onlyIfOpen`)
- First, we have a require statement to check if the user has sent the right amount
- Then we perform a check to see if the user is already entered in the lottery
- We have employed a simple for loop which iterated over the `players` array and checks if the caller is already a part of it
- If the caller is already in the array, then the function call is reverted by the custom error
- If not, the player is added to the array
- Then we perform a check to see if the user has already entered in the lottery
- We use a mapping to store a boolean value about whether a user is already participating in the current lottery
- If the caller is already participating in the lottery, then the function call is reverted with a custom error
- If not, the player is added to the array and the entered value of the caller is set to true for the current lottery
---
```
function requestRandomness() external onlyOwner onlyIfOpen{
Expand Down Expand Up @@ -278,22 +281,22 @@ contract Lottery {
- Finally, we emit the `Ended` event to log the information of the lottery Id, winner amount, and the winner's address
- As our contract is handling funds, we implement a receive function
---
## Testing the contract
### Testing the contract
- Finally, we are done coding the contract
- You can find the entire code of the contract by [CLICKING HERE!](https://github.com/KishoreVB70/Lottery-Tutorial/blob/main/Lottery.sol)
- Now we are going to use remix IDE and metamask to deploy the contract to the Celo alfajores network
- I have made a simple video to show you guys the functionality
[![Testing Video](https://i.postimg.cc/ZYFzPrvF/tutorial-yt.jpg)](https://www.youtube.com/watch?v=DPsizPEkZZk "Testing Video")
---
# Conclusion
## Conclusion
- Congratulations!, you have learned another new implementation in the Web3 world
- In this tutorial, we have learned a reliable way to generate random numbers and built a practical contract
---
# What's next
## What's next
- You can use this random number generator to make complex contracts for games
- Explore other oracles and use randomness generator from them
- You can learn more about oracles and access other forms of data they provide
---
# References
## References
- Witnet - https://witnet.io/
- Witnet Randomness - https://docs.witnet.io/intro/tutorials/randomness