# Project GameNet
The internet has transformed the way we communicate, allowing us to connect with people from all over the world in real time. With the help of RSA, we can even communicate privately, enabling us to engage in activities that were once impossible.
*Like playing chess with anyone in the world :grin:*
However, for some applications, participants need to maintain private data and perform computations on it(for example maintaining bank balances, playing poker, sealed bid auctions, etc). Unfortunately, trusting anyone on the internet can be challenging, this led to the rise of trusted Centralized entities, such as governments or corporations with brand value, which everybody has to trust with their data.
###### Web 2.0, the current model of the internet, relies on centralized servers to maintain all user's private data. While this model works, it has significant limitations. For example, it requires users to trust the centralized entity, and this trust comes at a cost. If the incentives of the centralized entity do not align with the users' interests, the system can break down leading to the exploitation of users. Furthermore, centralized entities can easily become targets for hackers and malicious actors, putting user data at risk.
Recent advancements in cryptography, such as zero-knowledge proofs (zk-proofs) and fully homomorphic encryption (FHE), offer new possibilities for maintaining private states in a P2P network. Public blockchains also provide a platform for trust without the need for centralized entities. Combining these technologies allows us to explore decentralized solutions for computations on private data without relying on centralized entities.
*One way to explore the potential applications, is through gaming.*
> Gaming is a leading indicator on up-and-coming technologies. Games are a technically demanding yet relatively low-stakes environment to explore scalability and usability problems early in a technology platform's lifecycle: --- [gupsheep](https://gubsheep.mirror.xyz/nsteOfjATPSKH0J8lRD0j2iynmvv_C8i8eb483UzcTM)
#### The aim of GameNet
The dream is to enable playing any multiplayer game over a p2p network that scales with the number of players and with guaranteed security(no player can cheat and get an unfair advantage). The project proposes a way to do this where players only need to trust the security (*immutability and censorship resistance*) of a decentralized public blockchain.
#### Potential benefits
It also lends itself well to the push towards onchain gaming, But it's also extremely scalable as the majority of the interactions can happen off-chain(over p2p) only falling back to on-chain when necessary.
Unlike traditional online games, where game devs need to run expensive servers and pass on the cost to users. Here one only needs a relay network and it might lead to new kinds of game economy and the game can truly be owned by the community rather than a corporation controlling and updating the rules.
*Similar to an offline game like chess, once the creator of the game has formalized the rules, anyone who wants can play the game by simply following the rules, the creator doesn't need to do anything else, (like paying a "trusted" middle-man to host the game for others to play).*
# Architecture
Games can be thought of as a **[state machine](https://developer.mozilla.org/en-US/docs/Glossary/State_machine)**. A game starts with an initial state, then players update the game state according to the rules of the game to ultimately reach a final state(s).
Some games are turn based or only the player whose turn it is can update the **Game State**.
#### GameState
Games like chess are complete information but there also exist incomplete information games like battleship, dark chess etc. So game states can be divided into different types
- public(**pub**)
- private(**pvt_X**) visible to a particular player 'X'
- hidden (visible to no one)
#### playerMove
State Transition Function or **playerMove** uses player inputs to update the current game state. Depending on the type of states used to calculate playerMove, games can be classified into different types.
#### Common game types
- **playerMove** depends on **pub** :
*chess*, *ludo*...
- **playerMoveA** depends on **pub**, **pvt_A** :
*Battleship*,...
can be solved using zkps
- **playerMoveA** depends on **pub**, **pvt_A**, **pvt_B** :
*Dark* *chess*,
only zkp is not sufficient, PSI can be used in some cases, a solution using FHE will be more general.
- **playerMoveA** depends on **pub**, **hidden** :
*poker*(the unrevealed deck of cards can be thought of hidden)
## Phase 1
Only focuses on 2-player, incomplete information games with no hidden states, and the players can only update their private state without relying on the opponent's private state.
The games will be turn-based, with Player A making the first move followed by Player B. Public state (**PubSt**) will include a counter(**step**) which starts from 0. So Player A can only update game states(make moves) when `step % 2 == 0` and vice versa.
```mermaid
sequenceDiagram
Note over A,B: all messages will be digitally signed.
Note left of A: PubSt0<br/> A_PvSt0<br/>
A->>B: hash(A_PvSt0)
B->>A: hash(B_PvSt0)
Note right of B: PubSt_0<br/> B_PvSt0<br/> hash(A_PvSt0)
Note left of A: Move 1<br/> PubSt0 >> PubSt1<br/> A_PvSt0 >> A_PvSt1 <br/> hash(B_PvSt0)
A->>B: PubSt1, hash(A_PvSt1) <br/>Proof of correct state transition
Note right of B: Move 2<br/> PubSt1 >> PubSt2<br/> B_PvSt0 >> B_PvSt1 <br/> hash(A_PvSt1)
B->>A: PubSt2, hash(B_PvSt1) <br/>Proof of correct state transition
Note left of A: Move 3<br/> PubSt2 >> PubSt3<br/> A_PvSt1 >> A_PvSt2 <br/> hash(B_PvSt1)
A->>B: PubSt3, hash(A_PvSt2) <br/>Proof of correct state transition
```
### State transition proofs
With recursive zk proofs we can prove that the game was played according to rules.
>State~N-1~ => State~N~ is correct and proofOf(State~N-2~ => State~N-1~ is correct and proofOf(.....))
= Proof of all the State transitions are correct from the innitial state
For 2 player games with alternate turns, the circuits will also check that the **step** counter is incremented correctly and the move is signed by the Correct Player.
TODO Explore,
- [ ] Recursive Proofs with circom https://github.com/nalinbhardwaj/Nova-Scotia
- [ ] Recursive Proofs with mina's snarkyjs,
The problem with recursion is that prooving a proof uses lot of constrains and so proofing time. compared to the game logic, which may be simple.
Can it be done without recursion?
What if the Player sends only the proofOf(State~N-1~ => State~N~)? with State~N-1~ being a public input one can easily verify that the correct state is used apart from verifying the proof.
A bad actor can try to use a wrong **fromState** with correct transition, so now the zk proof is correct but the chain of state transitions is broken. which the zk-verifier cannot catch. But since all messages need to be signed one can proof to a Smart Contract that the opponent cheated by using a incorrect **State**. But how will the contract verify which is the correct state? the contract may only know the innitial state.
Solution using,
1. resursion: proof that State~N~ comes from State~0~ and we have the intermidiate state transition proofs
2. checkpointing: If a state is signed by both players, it means both of them agree on that state being correct.
With recursion the **Contract** contract implementation becomes much simpler as with just one verifier the contract can verify the whole game was played correctly.
Possible Attack Surface:
Attacker playing both sides to produce unrealistic situations like(both players winning). One may by controlling both palyers, playing 2 games in parallel. So giving points/tropy to a player with most win where players themselfs do the match making is no good. With a decentralized fair matchmaking this can be prevented.
### Referee Contract
In a 2 party system its impossible to come to a consensus if one decides to violate game rules, So this contract will be responsible to punish the violators. It will also be responsible to enfore time contrains(*forceMove*) when one player abandons the game halfway.
So to start a game the player will need to have some staked collateral that they value more than winning the game. Moreover the same collateral can be reused as long as the player continues to play the game. A collateral can be both economic and social (Player can be issues SBTs for storing game progress and other stats so players a not incentivised in creating multiple accounts).
```solidity
interface Referee {
function forceMove(State..., OpponentAddr, Proof) external;
function forceMoveReply(NewState..., Proof) external;
function claimWin() external;
function startGame(OpponentAddr) external;
function depositCollateral() external payable;
function setProxy(proxyAddress) external;
}
```
#### **proxyAddress**: *For security and easy of use*
With wallets like metamask signing anything needs a lot of user interaction and time which is fine for defi but for games we can pop metamask for every message. So we need the frontend client to sign messages on the users behalf. But asking for the privat e key of a user's wallet is a security risk. With **proxyAddress**, the private key of the address is stored in the frontend client and if the private key gets compromised the only that game session is affected and no funds are lost from the main wallet. Users can update the proxyAddr at any time between games.