Check the last release (v0.5.0)
This project is a Blockchain-Based Credential Verification System, and it's main objective to enhance the security and privacy when it comes to digital credentials. By using the Blockchain technology we assure that the data won't be changed (immutable), decentralized and hashed in the blockchain so it won't be reviled to anyone.
The system will act as a verifier that checks if a specific user owns a specific credential, this way the system won't store any credentials or user's personal information, applying the decentralization mechanism to ensure that the customer has his own information not the system.
A peer is a single computer or "node" that acts as both client and a server at the same time. Unlike a traditional setup where a client talks to a big central computer, in a P2P network, every participant has equal status and responsibilities.
The ledger is not a built-in feature of the library itself, but rather a data structure implemented inside the Node class to store the blockchain.
The library facilitates the connection between peers, but the ledger is the actual storage container for the CHID records.
During the "Verifying" path, the ledger acts as the reference point for the system:
-
Querying: When a user requests verification, the system searches the ledger for a matching
CHIDhash. -
Ownership Check: The ledger provides the "proof" (the stored hash) that the system needs to perform the
DECOwnershipCheckagainst the user'sHID.
Node(host, port, id=None): Creates the node.- Usage: Uses the
BlockchainAddressto set the host and port.
- Usage: Uses the
start(): Spawns a background thread to listen for other nodesconnect_with_node(host, port): Outbounds connection.- The system node uses this to join the blockchain network.
The networking functionality is done by the Network class which inherits the Node class to act as a peer.
-
broadcast(data): Sends a dictionary to all connected peers.- Used to broadcast a
newBlockafter a successful registration.
- Used to broadcast a
-
send(node, data): Sends data to one specific peer.- Used by a blockchain node to send a specific
CHIDback to the requester.
- Used by a blockchain node to send a specific
The library is event-driven. You don't pull data; you "react" to it by overriding these methods in the system.
node_message(self, connected_node, data) This is the most important function for the project. It is triggered whenever any data arrives, and the incoming data are handled by the Interaction class, that takes the Payload object.
- Parameters:
connected_node: The node object that sent the message.data: The dictionary containing the custom protocol (e.g.,action,childHash). This is where theif/elifstatements to handle Registration, Querying, or Verification Responses.
outbound_node_connected(self, connected_node): Gets triggered when an outbound node is connected to the network.
inbound_node_connected(self, connected_node): Runs when a node is connected to the network.
inbound_node_disconnected(self, connected_node): Runs when a connected node, is disconnected.
- Privacy: raw credentials remain off-chain and with the holder.
- Immutability: on-chain CHIDs are tamper-evident.
- Decentralization: blockchain acts as a shared ledger for references, not as a credential store.
- Holder (User): owns credentials and proves possession.
- Issuer (Authority): verifies real-world claims and issues credentials.
- Verifier (System): checks on-chain references to confirm ownership.
CHID (Credential Holder Identifier) is a compact reference stored on-chain:
CHID = "HID:CID:AUTHID"HID— Holder ID (derived from holder Credential)CID— Credential ID (derived from credential data)AUTHID— Authority/Issuer ID
All IDs are deterministic hashes (e.g., SHA-256) generated by the system when actors/credentials are created or approved.
- Issuance: Authority verifies a holder and approves a credential.
- CHID generation: system derives HID, CID, AUTHID and computes CHID.
- On-chain registration: CHID is stored on the blockchain as a reference.
Prerequisites: Python 3.11+.
pip install -e . -r requirements.txtcd source
python main.pymain.py starts a node on P2P port 8000; its HTTP API listens on the P2P port plus 10000 (http://localhost:18000, Swagger UI at /docs). The first start creates and mines the genesis block in storage/.
In Python code, create a Verchain instance and choose either startup entry point:
from core.verchain import Verchain
verchain = Verchain("Blockchain", "localhost", 8000, isBootstrap=False)
verchain.start() # Start the P2P network; the API starts during initialization
# or: verchain.cli.start() # CLI entry point; CLI commands are being addedThe node's HTTP server is managed by VerchainAPI; API and CLI processing is handled by the VerchainProcessor service.
The credential is uploaded as a PDF. Only hashes are stored on-chain.
curl -X POST http://localhost:18000/register \
-F "user.name=Alice" -F "user.nationalNumber=123456" -F "user.phone=5551234" \
-F "user.age=24" -F "user.email=alice@example.com" -F "user.birth=2002-01-01" \
-F "credential.documentID=101" \
-F "issuer.name=JPUF" -F "issuer.issuerID=3423" \
-F "credential.document=@diploma.pdf;type=application/pdf"Upload the same PDF with the same IDs:
curl -X POST http://localhost:18000/check \
-F "username=Alice" -F "userID=123456" -F "documentID=101" \
-F "issuer=JPUF" -F "issuerID=3423" \
-F "document=@diploma.pdf;type=application/pdf"
# "APPROVED"A changed file or a wrong documentID returns 404 (Credential-not-found). See docs/API.md for every endpoint and response.
settings.yml controls the mining difficulty, the upload limit and the performance mode. SAFE re-validates the whole chain on every insert; FAST validates only the new block.
Bug reports, issues and pull requests are welcome. Follow standard fork-and-PR workflow.
Specify the project license in LICENSE file.
- Maintainer: Bashar Mithan
- Contact email: basharmithan@gmail.com
- System CLI.