Skip to content

Commit 894c4c2

Browse files
committed
init
0 parents  commit 894c4c2

19 files changed

+1654
-0
lines changed

Diff for: .gitattributes

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

Diff for: LICENSE

+131
Large diffs are not rendered by default.

Diff for: ReadMe.md

+198
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
# Challenge - Chess on blockchain
2+
3+
This project is about implementation of chess as smart contract on ethereum blockchains.
4+
- The smart contract will define game rules and validation on moves
5+
- Data of pieces such as location on board and promotion status resides on blockchain.
6+
- Player interacts the smart contract to "move" the pieces on the "board"
7+
- Winner will be rewarded the bet from loser
8+
9+
This chanllenge is attempting to overcome to limitations on the Programming Language for smart contract, Solidity. For instant, player will pay the gas when moving pieces on board, speed of the transaction, code size is limited (24KB), etc. To reduce those negative impacts, Smart Contract should be implemented so that:
10+
- Minimize gas
11+
- Make fair interactions (gas paid by both players should be nearly same amount regardless of which pieces to be moved)
12+
- Correctness, Security, Code simplicity
13+
14+
The lastest stats (check how to perform the stats at [tests\performance.py](tests\performance.py)):
15+
16+
|Movement |Gas Used (Black)|Gas Used (White)|
17+
|---------|---------|---------|
18+
|Pawn |97732 |98699 |
19+
|Pawn (2 steps) |99645 |100620 |
20+
|Knight |82119 |83045 |
21+
|Rook |82486 |83412 |
22+
|Bishop |85530 |86452 |
23+
|Queen |84026 |84948 |
24+
|King |69962 |100895 |
25+
26+
|Operation |Gas Used |
27+
|---------|---------|
28+
|Deploy |3681065 |
29+
30+
31+
## About the game
32+
33+
Game Rules:
34+
- Anyone can create board (smart contract) which allows two players
35+
- Anyone can join the board with no/one player. Later player joins as Player Two
36+
- Player One sends certain amount of ETH as bet and defines minimun entry fee (cannot greater than his/her sent bet)
37+
- Player Two joins the game with bet amount >= minimun entry fee
38+
- Players can withdraw the game (loss) and the winner can then collect the bet
39+
- Player can pass the game. If both agree, both can collected back his/her claimed bet. (Gas paid cannot be refund)
40+
41+
Smart Contract should have functions:
42+
- Join game
43+
- Move Pieces (with castling and promotion as normal chess)
44+
- Pass and Withdraw the game
45+
- Collect the bet if win
46+
47+
## Develoment
48+
Here used Brownie and Python for development, testing, contract deployment and client application.
49+
This repo includes a GUI in TKinter as a tool to simulate smart contract client (player).
50+
51+
Below are screenshots for the application:
52+
53+
:::image type="content" source="screens/board.png" alt-text="board":::
54+
55+
:::image type="content" source="screens/menu.png" alt-text="menu":::
56+
57+
To compile the smart contract:
58+
59+
`brownie compile`
60+
61+
To deploy the contract:
62+
63+
`brownie run scripts\deploy.py`
64+
65+
To run the client application:
66+
67+
`brownie run scripts\client.py`
68+
69+
To run the performance script:
70+
`brownie run scripts\stats.py`
71+
72+
To test the cases in folder .\tests\:
73+
74+
`brownie test`
75+
76+
77+
### Limitations
78+
This project is not for putting on production blockchain (No one will pay for such game with real moeny!), but the design is open to extend to that. It takes configuration files .env and brownie-config.yaml for various tunning transaction on blockchain.
79+
80+
## APIs
81+
82+
Public functions defined in smart contract:
83+
```javascript
84+
function ctx()
85+
function GetPiecesInfo() public view returns (string memory)
86+
function JoinGame(uint256 minEntryFee) payable
87+
function MovePiece(PieceID pid, uint8 pos_r, uint8 pos_c, uint256 speccmd)
88+
function Win() public payable
89+
```
90+
91+
### ctx()
92+
```
93+
function ctx()
94+
```
95+
The context of the board on the blockchain. It returns structure:
96+
```c
97+
enum PlayerState {
98+
Normal,
99+
Withdraw,
100+
Pass
101+
}
102+
103+
struct Player {
104+
address player_address;
105+
PlayerState state;
106+
uint256 bet;
107+
}
108+
109+
struct Context {
110+
Player PlayerOne;
111+
Player PlayerTwo;
112+
uint256 fee;
113+
int playerturn;
114+
}
115+
```
116+
117+
- **PlayerOne**: the player one (black) with address, state and the bet in wei. State can be set to withdraw if King is captured. If the state is Withdraw, it means Player Two win.
118+
- **PlayerTwo**: the player one (White) with address, state and the bet in wei. State can be set to withdraw if King is captured. If the state is Withdraw, it means Player One win.
119+
- **fee**: the entry fee to join the game.
120+
- **playerturn**: number of turns of the game. Start with 0 (Black)
121+
122+
### GetPiecesInfo()
123+
124+
```
125+
function GetPiecesInfo() public view returns (string memory)
126+
```
127+
128+
Information of the board in string format:
129+
```json
130+
[(Piece ID, Piece Type, row, column, alive), ...]
131+
```
132+
The lenght of the array is 32 (i.e. 32 pieces).
133+
134+
- **Piece ID**: 0-indexed integer to represent the id of each piece.
135+
```c
136+
enum PieceID {
137+
p1_king, p1_queen, p1_rookl, p1_rookr, p1_bishopl, p1_bishopr, p1_knightl, p1_knightr, p1_pawn1, p1_pawn2, p1_pawn3, p1_pawn4, p1_pawn5, p1_pawn6, p1_pawn7, p1_pawn8,
138+
p2_king, p2_queen, p2_rookl, p2_rookr, p2_bishopl, p2_bishopr, p2_knightl, p2_knightr, p2_pawn1, p2_pawn2, p2_pawn3, p2_pawn4, p2_pawn5, p2_pawn6, p2_pawn7, p2_pawn8
139+
}
140+
```
141+
- **Piece Type**: 0-indexed integer to represnet the type of the piece. It can change if pawn is promoted.
142+
```c
143+
enum PieceType{
144+
king, rook, bishop, queen, knight, pawn
145+
}
146+
```
147+
- **row**: row on the block, which is 0-indexed (i.e. in range of \[0,7\])
148+
- **column**: column on the block, which is 0-indexed (i.e. in range of \[0,7\])
149+
- **alive**: 0 or 1 indicator on whether the piece is captured
150+
151+
152+
### JoinGame()
153+
154+
```
155+
function JoinGame(uint256 minEntryFee) payable
156+
```
157+
158+
Called by client to join the game. It is **Not** the bet which should be set as transaction value when calling this method.
159+
160+
- **minEntryFee**: The amount in wel to define the minimun entry fee of the game. Valid to player one only.
161+
162+
163+
### MovePiece()
164+
165+
```
166+
function MovePiece(PieceID pid, uint8 pos_r, uint8 pos_c, uint256 speccmd)
167+
```
168+
169+
Commands send from player to associate with the board.
170+
171+
- pid: Piece ID defined in the board (smart contract).
172+
- pos_r: row of the target position to move, which is 0-indexed (i.e. in range of \[0,7\])
173+
- pos_c: column of the target position to move, which is 0-indexed (i.e. in range of \[0,7\])
174+
- speccmd: 0-indexed integer for commands such as caslting, pawn promotion. Also include game operations such as Pass and Withdraw.
175+
176+
```c
177+
enum SpecCommand {
178+
Null, Withdraw, Pass, Castle, PromoteToQueen, PromoteToRook, PromoteToBishop, PromoteToKnight
179+
}
180+
```
181+
182+
**Note**:
183+
- If player issues Withdraw, the game will be completed.
184+
- If player A issues Pass, player B can either pass or issues different command to stating no agree to tie the game.
185+
- If player issues Castle, the pid should refer to the rook, not the king.
186+
187+
### Win()
188+
189+
```
190+
function Win() public payable
191+
```
192+
193+
Winner collects the bet from players (player 1's bet plus Player 2's bet) after winning the game. The balance of the smart contract will add to winner's balance and the contract is no longer playable.
194+
195+
196+
## License
197+
198+
[GPL v2](LICENSE)

Diff for: brownie-config.yaml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
dependencies:
2+
- OpenZeppelin/[email protected]
3+
dotenv: .env
4+
networks:
5+
default: development
6+
limits:
7+
gas_limit_deploy:
8+
min: 2
9+
max: 1000000000
10+
gas_limit_tx:
11+
min: 1
12+
max: 1000000000

0 commit comments

Comments
 (0)