Skip to content

Commit c9b3ae0

Browse files
committed
current to week of july 9 2021
1 parent 4adb89f commit c9b3ae0

File tree

15 files changed

+309
-1
lines changed

15 files changed

+309
-1
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
venv
22
.DS_Store
33
.env
4-
08_Getting_MoralisData
4+
08_Getting_MoralisData
5+
__pycache__
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/bash
2+
brownie networks add Arbitrum arbitrum_rinkeby host='https://speedy-nodes-nyc.moralis.io/f9c80ab8c7ec06447269db5c/arbitrum/testnet' name='Arbitrum Rinky' chainid=421611 explorer='https://rinkeby-explorer.arbitrum.io/#/'

09_guess_number_vrf/.gitattributes

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.sol linguist-language=Solidity
2+
*.vy linguist-language=Python

09_guess_number_vrf/.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
__pycache__
2+
.history
3+
.hypothesis/
4+
build/
5+
reports/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity 0.6.6;
3+
4+
import "smartcontractkit/[email protected]/contracts/src/v0.6/VRFConsumerBase.sol";
5+
6+
/* Contract Guess Number
7+
Contract should support multiple guess the number games.
8+
Creator of games should risk an ammounts of tokens to start a new game.
9+
A secret number is established during game creation by calling chainlink
10+
The secret number should be between 1-100.
11+
Each guess of the number in a game will cost an amount of tokens
12+
Each game should allow only 10 guesses, once the tenth guess is made
13+
the game will expire and the funds will go to the game creator.
14+
Whoever makes the right guess will win the balance of the game.
15+
Once the right guess is made a game should not allow people to play.
16+
Once a game makes a payment 1% of the amount will go to the contract creator as a fee. */
17+
18+
contract GuessNumber is VRFConsumerBase {
19+
using SafeMathChainlink for uint256;
20+
21+
uint256 private constant ROLL_IN_PROGRESS = 1000;
22+
bytes32 private s_keyHash;
23+
uint256 private s_fee;
24+
25+
event Dice_rolled(bytes32 indexed requestId, uint256 indexed roller);
26+
event Game_created(address indexed owner, uint256 game_index, uint256 time);
27+
event Game_served(bytes32 indexed requestId, uint256 indexed game_id);
28+
event Game_solved(address indexed solver, uint256 game_index, uint256 time);
29+
event Game_expired(address indexed creator, uint256 game_index, uint256 time);
30+
31+
struct game {
32+
address game_owner;
33+
uint256 secret_number;
34+
uint256 game_balance;
35+
uint256 guess_count;
36+
bool is_active;
37+
}
38+
39+
uint256 curr_id;
40+
41+
mapping (bytes32 => uint256) private rolls;
42+
mapping (uint256 => game) game_index;
43+
44+
address payable contract_owner;
45+
46+
constructor(address vrfCoordinator, address link, bytes32 keyHash, uint256 fee)
47+
public
48+
VRFConsumerBase(vrfCoordinator, link)
49+
{
50+
s_keyHash = keyHash;
51+
s_fee = fee;
52+
contract_owner = msg.sender;
53+
curr_id = 0;
54+
}
55+
56+
function create_game() public payable returns(bool){
57+
require (msg.value == 0.0001*(10**18), "You should pay 0.0001 tokens to create game");
58+
game_index[curr_id].game_owner = msg.sender;
59+
game_index[curr_id].game_balance = msg.value;
60+
game_index[curr_id].guess_count = 0;
61+
rollDice(curr_id, curr_id+10);
62+
curr_id = curr_id + 1;
63+
emit Game_created(msg.sender,curr_id-1, block.timestamp);
64+
}
65+
66+
function rollDice(uint256 game_id, uint256 seed) public returns (bytes32 requestId) {
67+
require(LINK.balanceOf(address(this)) >= s_fee, "Not enough LINK to pay fee");
68+
require(game_index[game_id].secret_number == 0, "Already served");
69+
requestId = requestRandomness(s_keyHash, s_fee, seed);
70+
rolls[requestId] = game_id;
71+
game_index[game_id].secret_number = ROLL_IN_PROGRESS;
72+
emit Dice_rolled(requestId, game_id);
73+
}
74+
75+
function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
76+
uint256 served_game = rolls[requestId];
77+
uint256 d10Value = randomness.mod(100).add(1);
78+
game_index[served_game].secret_number = d10Value;
79+
game_index[served_game].is_active = true;
80+
emit Game_served(requestId, served_game);
81+
}
82+
83+
function play_game(uint256 game_id, uint256 guessed_number) public payable returns (bool) {
84+
require (msg.value == 0.00001*(10**18), "you must payh 0.00001 tokens to play");
85+
require (guessed_number >= 1 && guessed_number<= 100, "Guessed number should be within 1 to 100");
86+
require (game_index[game_id].is_active == true);
87+
game_index[game_id].game_balance = game_index[game_id].game_balance + msg.value;
88+
game_index[game_id].guess_count = game_index[game_id].guess_count + 1;
89+
address payable player = payable(msg.sender);
90+
address payable creator = payable(game_index[game_id].game_owner);
91+
if (guessed_number == game_index[game_id].secret_number) {
92+
player.transfer((game_index[game_id].game_balance * 99) / 100);
93+
contract_owner.transfer(game_index[game_id].game_balance / 100);
94+
game_index[game_id].game_balance = 0;
95+
game_index[game_id].is_active = false;
96+
emit Game_solved(msg.sender, game_id, block.timestamp);
97+
}
98+
else {
99+
if (game_index[game_id].guess_count == 10){
100+
creator.transfer((game_index[game_id].game_balance * 99) / 100);
101+
contract_owner.transfer(game_index[game_id].game_balance / 100);
102+
game_index[game_id].game_balance = 0;
103+
game_index[game_id].is_active = false;
104+
emit Game_expired(game_index[game_id].game_owner, game_id, block.timestamp);
105+
}
106+
}
107+
}
108+
109+
function get_game_balance(uint256 game_id) public view returns(uint256) {
110+
return game_index[game_id].game_balance;
111+
}
112+
113+
function get_game_guesses(uint256 game_id) public view returns(uint256) {
114+
return game_index[game_id].guess_count;
115+
}
116+
117+
function is_game_active (uint game_id) public view returns (bool) {
118+
return game_index[game_id].is_active;
119+
}
120+
121+
122+
// the functions below are for pure testing purposes these should be deleted to actually make this a dApp
123+
function get_game_number_test(uint256 game_id) public view returns(uint256) {
124+
return game_index[game_id].secret_number;
125+
}
126+
127+
function cancelGame(uint256 game_id) public returns (bool){
128+
require(msg.sender == game_index[game_id].game_owner);
129+
address payable creator = payable(msg.sender);
130+
creator.transfer(game_index[game_id].game_balance);
131+
game_index[game_id].game_balance = 0;
132+
return true;
133+
}
134+
}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from brownie import accounts, GuessNumber
2+
from dotenv import load_dotenv
3+
import os
4+
5+
def main():
6+
load_dotenv()
7+
account = accounts.load(os.environ['DEPLOY_ACCOUNT'])
8+
GuessNumber.deploy(os.environ['VRF_BSC'],os.environ['LINK_BSC'],os.environ['KEY_HASH_BSC'], 0.1*(10**18),{'from':account})
9+
deployments = len(GuessNumber)
10+
print(f"number of deployments {deployments}, address of last deployment {GuessNumber[deployments-1].address}")
11+
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from brownie import accounts, GuessNumber
2+
from dotenv import load_dotenv
3+
import os
4+
5+
def main():
6+
load_dotenv()
7+
account = accounts.load(os.environ['DEPLOY_ACCOUNT'])
8+
GuessNumber.deploy(os.environ['VRF_ETH'],os.environ['LINK_ETH'],os.environ['KEY_HASH_ETH'], 0.1*(10**18),{'from':account})
9+
deployments = len(GuessNumber)
10+
print(f"number of deployments {deployments}, address of last deployment {GuessNumber[deployments-1].address}")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from brownie import accounts, GuessNumber
2+
from dotenv import load_dotenv
3+
import os
4+
5+
def main():
6+
load_dotenv()
7+
account = accounts.load(os.environ['DEPLOY_ACCOUNT'])
8+
GuessNumber.deploy(os.environ['VRF_POLY'],os.environ['LINK_POLY'],os.environ['KEY_HASH_POLY'], 0.0001*(10**18),{'from':account})
9+
deployments = len(GuessNumber)
10+
print(f"number of deployments {deployments}, address of last deployment {GuessNumber[deployments-1].address}")
11+

10_Flask_Dapp/Readme.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# README
2+
1. For this project you need flask.
3+
2. From your virtual environment run pip install flask
4+
3. Done

10_Flask_Dapp/app.py

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from flask import Flask, render_template
2+
3+
app = Flask(__name__)
4+
5+
@app.route('/')
6+
def index():
7+
return render_template("index.html")
8+
9+
if __name__ == "__main__":
10+
app.run()

10_Flask_Dapp/run.py

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from app import app
2+
3+
if __name__ == "__main__":
4+
app.run()

10_Flask_Dapp/static/js/logic.js

+31
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

10_Flask_Dapp/templates/index.html

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{% extends "templates/base_template.html" %}
2+
{% block title %}Your Dapp{% endblock %}
3+
{% block head%}
4+
{% endblock %}
5+
{% block main %}
6+
7+
<div class="container">
8+
<div class="row">
9+
<div class="col">
10+
<h1>Connect to Play</h1>
11+
<hr>
12+
<div class="mb-3">
13+
<div class="form-group">
14+
<div class="input-group mb-3">
15+
<input id="username" type="text" class="form-control" placeholder="Username" aria-label="Username" aria-describedby="basic-addon1">
16+
</div>
17+
<div class="input-group mb-3">
18+
<input id="useremail" type="text" class="form-control" placeholder="Email" aria-label="Email" aria-describedby="basic-addon1">
19+
</div>
20+
</div>
21+
<div>
22+
<button class="btn btn-primary" id="submit" onclick="login();">Connect MetaMask</button>
23+
</div>
24+
<hr>
25+
<div class="form-group">
26+
<div class="input-group mb-3">
27+
<input disabled = "true" id="gameid" type="text" class="form-control" placeholder="Input Game ID" aria-label="Game ID" aria-describedby="basic-addon1">
28+
</div>
29+
<div>
30+
<button disabled = "true" class="btn btn-primary" id="balance" onclick="game_balance();">Get Game Balance</button>
31+
</div>
32+
<hr>
33+
<div class="input-group mb-3">
34+
<input disabled = "true" id="gamebalance" type="text" class="form-control" placeholder="Game Balance" aria-label="Email" aria-describedby="basic-addon1">
35+
</div>
36+
</div>
37+
</div>
38+
</div>
39+
</div>
40+
</div>
41+
42+
{% endblock %}
43+
{% block script %}
44+
<script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
45+
<script src="https://unpkg.com/moralis/dist/moralis.js"></script>
46+
<script src="{{ url_for('static', filename='js/logic.js') }}"></script>
47+
{% endblock %}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<!--Head Content-->
5+
<title>{% block title %}{% endblock %}</title>
6+
<!-- Required meta tags -->
7+
<meta charset="UTF-8">
8+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
9+
{% block links %}
10+
<!-- Import the Bootstrap stylesheet -->
11+
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
12+
{% endblock %}
13+
</head>
14+
<body>
15+
<nav class="navbar navbar-expand-lg navbar-light bg-light mb-3">
16+
<a class="navbar-brand" href="/">Guess The Number</a>
17+
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
18+
<span class="navbar-toggler-icon"></span>
19+
</button>
20+
</nav>
21+
<main>
22+
{% block main %}{% endblock %}
23+
</main>
24+
{% block script %}
25+
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
26+
{% endblock %}
27+
</body>
28+
</html>

10_Flask_Dapp/views.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import app
2+
from flask import render_template
3+
from flask import request, redirect, jsonify, make_response
4+
import json
5+
6+
@app.route('/')
7+
def index():
8+
return render_template("index.html")

0 commit comments

Comments
 (0)