A web and terminal blockchain implementation in Python from scratch
- Peer-to-Peer network with decentralized communication
- Public/private key-based account system
- Digital signature verification
- Selectable consensus mechanism - PoW, PoS, PoA
- Smart contract deployment
- IPFS integration
- Persistent storage
- Malicious node to test security
- Command line & web interface
A blockchain is a decentralized, distributed digital ledger where data is stored in blocks linked together in a chain
- A block is made of list of transactions
Since, there is no central authority, network is formed in a peer-to-peer fashion.
Blockchain involves transactions in a trustless environment. So there is need for a mechanism to ensure integrity of the chain. There comes the need of consensus mechanisms. Each consensus mechanism ensures integrity of the chain in their own way.
- Nodes compete to solve a cryptographic puzzle
- The winner gets to add the next block to the chain
- Nodes run vrf to generate vrf output and vrf proof to simulate a lottery system
- The winner of the lottery gets to generate the block.
- A limited set of trusted nodes(authorities) validate and create new blocks
- A smart contract is like a digital agreement written in code
- It sits on the blockchain and runs automatically when certain rules are met
Blockchains are not designed for storing large amount of data. That's where IPFS comes in.
- It's a decentralized file storage system
- Each file is identified by its content
- A unique hash called CID(Content Identifiers) is generated based on the content(Files with same content will have same CID)
- IPFS uses a Distributed Hash Table(DHT), similar to BitTorrent's Kademlia DHT
- When you request a CID, your node queries the DHT to ask "Which peers are providing this CID?"
- Nodes that have previously announced that CID to the DHT will be returned as providers
- Your node then directly connects to those providers via IPFS's peer-to-peer transport protocols(libp2p)
Each node contains its own set of
- Known peers list (members of the network)
- Client connections (connection established by your node to other nodes)
- Server connections (connection established by other nodes to your node)
- Wallet (acts as your account in the network)
- Transaction pool (contains all transactions pending to be mined)
- Chain (personal copy of the blockchain)
Each account contains
- Private key
- Public key
Transactions are of 3 types
-
Coin Transaction - To transfer money
- Timestamp
- Public key of the sender
- Public key of the receiver
- Transaction amount
-
Deploy Transaction - To deploy contract
- Timestamp
- Public key of the sender
- Contract code
- Deploy charge
-
Invoke Transaction - To invoke contract
- Timestamp
- Public key of the sender
- Contract ID
- Function name
- Arguments
- New state
- Invoke charge
Each block contains
- Timestamp
- List of transactions
- Hash of previous block
- Current block hash
- Miner info
- List of files
- Client: Sends ping
- Server: Receives ping → sends pong
- Client: Receives pong → Sends peer info (information about itself)
- Server: Receives peer info → adds it to its known peers (if not already present) → sends back known_peers (list of all nodes it knows)
- Client: Receives known_peers → adds new peers to its own known_peers → requests the chain
- Server: Receives chain request → sends its current chain
- Client: Receives the chain → replaces its own if the length of new chain is longer than the current one
If the total number of nodes in the network is less than 10, it forms a mesh network. If the node count exceeds 9, Gossip-based Random Peer Sampling is used
- Each node maintains a list of 8 connected peers
- At regular intervals, a node drops one connection and connects to a new, previously unconnected peer from the known peers list
- This prevents network congestion by limiting the number of connections per node
- It also prevents sub-network formation by randomly switching connections
Implemented Using: python websockets, asyncio
Users can select their prefered consensus mechanism from the list of three available
- A new block is mined every 30 secs, if there are pending transactions in the transaction pool
- Mining nodes collect transactions into a block
- Node that first finds a valid hash gets the chance to mine
- Difficulty is set to 5. That means, a valid hash is the one which starts with five zeroes
- Nonce is incremented until finding a valid hash
- Once mined, the block is broadcasted to the network
- All nodes validate the block before adding it to their chain
- One node is mined every epoch
- The timings are synchronized between peers based on the time since last block was created
- Each node can stake a certain amount of their cryptocurrency in order to run vrf.
- VRF is a verifiable random function. The stakers generate a vrf proof and vrf output
- If the vrf output generated by a node is less than (max value of vrf output) * (amount staked by this node/total amount staked by all nodes), then
- This node wins the lottery and create a block. (Notice that the greater the amount staked the greater the chance of winning the lottery)
- VRF Proof is used to check whether the one who claims to win the lottery actually generated the vrf output from the correct seed
- If node attempts double signing their stake is slashed.
- If multiple nodes win and creates blocks then the chain is forked.
- We use the heaviest chain rule to arrive at a consensus. (i.e the chain with the most amount staked is the valid chain)
- Initially, admin, the one who started the chain is the only miner
- Admin can add or remove miners
- Each block can be mined only by the assigned miner
- If that miner is inactive, mining will be handed over to the next miner
In this project
- Smart Contracts are written in python
- Users can write their own smart contracts and deploy
- Users can also invoke the deployed contract using their deployed address
- They run inside a sandboxed environment with time limit, memory limit and operation limit
Implemented Using: RestrictedPython, multiprocessing
IPFS is integrated as a wrapper for the existing IPFS network. IPFS hashes of the user uploaded files are stored in the blocks. Other users can use this to download the file.
Implemented Using: IPFS
Persistent storage is implemented to enable nodes to reconnect to the network using there previous network data
- To test the security and robustness of our networks we created a malicious node that attempts
- Generate invalid transactions (amt>account balance or amount<=0)
- Double Sign
- We have tested our blockchain networks using this malicious nodes to verify that our protocols are working and that our network is functional
- We have debeloped a web interface for people uncomfortable with a CLI
- We used hypercorn to run flask as an ASGI so that we can run the event loop
- necessary to run our blockchain network's nodes.
- We use react on the frontend and flask(ASGI) + Hypercorn in the backend
python 3.10+pip(python package manager)venv(for creating virtual environment)
Clone project into your local machine
git clone https://github.com/Rahan-M/BlockChain_Prototype.gitEnter into the project folder
cd BlockChain_PrototypeCreate and activate virtual environment
python -m venv venv
venv\Scripts\activateInstall dependencies
pip install -r requirements.txtStart terminal app
python start_peer.pyInstall frontend dependencies
cd webApp\flask_app\frontend
npm installBuild react app
npm run buildStart web app
cd ..\..
python run.py --port 5000Open browser and visit http://0.0.0.0:5000