6.5 KiB
Executable File
Blockchain Integration Guide
⚠️ Updated direction: this document describes the legacy broad usage (recording every CUD operation of tracked models on-chain). Per
15-ARCHITECTURE.mdand16-NETWORK.md, the blockchain is now scoped to settlement + identity registration + Merkle-root anchoring + attestation hashes + arbitration. Data itself stays off-chain, signed locally. TheBlockchain.jstransaction recording described below remains functional for backward compatibility but is no longer the target model.
Overview
The apxtri blockchain provides decentralized synchronization of critical data across multiple town servers. When enabled, all Create/Update/Delete operations on tracked models are recorded in blocks and broadcast to peer towns.
How It Works
1. Local-First Architecture
- Operations happen immediately on your local server
- Users get instant feedback (no waiting for consensus)
- Blockchain transactions are added after successful local operations
2. Transaction Flow
User Request
↓
Route Handler (e.g., POST /apxtri/pagans)
↓
Odmdb.create(paganItem, role) ← Writes to local filesystem immediately
↓
[Success] → Blockchain.createTransaction('create', 'pagans', paganItem)
↓
Added to pendingTransactions[] in memory
↓
Every 10 minutes → Blockchain.createBlock()
↓
Block signed with PRIVKMAYOR
↓
Broadcast to all peer towns via HTTP POST /apxtri/blockchain/receive
↓
Peers verify signature using town's public key
↓
Peers apply transactions to their local databases
3. Enabled Models
Pagans (routes/pagans.js)
- Create Pagan:
POST /apxtri/pagans→create/pagans - Update Pagan:
DELETE /apxtri/pagans/alias/:alias(soft delete) →update/pagans - Create Person:
PUT /apxtri/person/:tribe→create/persons - Update Person:
PUT /apxtri/person/:tribe→update/persons - Delete Person:
DELETE /apxtri/person/:tribe/:alias→delete/persons
Towns (routes/towns.js)
- Create Town:
POST /apxtri/towns→create/towns - Update Town:
PUT /apxtri/towns/:townId→update/towns - Delete Town:
DELETE /apxtri/towns/:townId→delete/towns - Change Owner:
GET /apxtri/towns/changeowner/:alias→update/towns
Configuration
Required Environment Variables (.env)
# Enable blockchain synchronization
BLOCKCHAIN_CONNECT=true
# Mayor's PGP private key (used to sign blocks)
PRIVKMAYOR="-----BEGIN PGP PRIVATE KEY BLOCK-----
...your private key here...
-----END PGP PRIVATE KEY BLOCK-----"
# Town and nation identifiers
TOWN=farm
NATION=ants
Enable Blockchain in apxtri.js
Add after line 40 in apxtri.js:
if (process.env.BLOCKCHAIN_CONNECT === 'true') {
const Blockchain = require('./models/Blockchain.js');
Blockchain.start();
logger.info("Blockchain synchronization enabled");
}
Requirements for Peer Towns
Each peer town must:
- Have an entry in
/var/lib/apxtowns/data/apxtri/objects/towns/itm/{townId}.json - Include fields:
townId: Unique identifierpubkey: PGP public key for signature verificationdns: Array of domain names (e.g.,["town.example.com"])
- Have accessible endpoint:
POST /apxtri/blockchain/receive
Example town entry:
{
"townId": "wall",
"pubkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n...",
"dns": ["wall-ants.example.com"]
}
How to Add Blockchain to a New Model
Example: Adding blockchain to a hypothetical "Articles" model:
Step 1: Import Blockchain in route file
const Blockchain = require("../models/Blockchain.js");
const blockchainEnabled = process.env.BLOCKCHAIN_CONNECT === 'true';
Step 2: Add transaction after successful operations
// CREATE
const result = await articlesDb.create(articleItem, role);
if (result.status === 200 && blockchainEnabled) {
Blockchain.createTransaction('create', 'articles', articleItem);
}
// UPDATE
const result = await articlesDb.update(articleItem, role);
if (result.status === 200 && blockchainEnabled) {
Blockchain.createTransaction('update', 'articles', articleItem);
}
// DELETE
const result = await articlesDb.delete(articleId, role);
if (result.status === 200 && blockchainEnabled) {
Blockchain.createTransaction('delete', 'articles', { id: articleId });
}
Step 3: Ensure schema has apxid defined
Blockchain.updateLocalData() needs to identify items by their primary key. Make sure your schema has:
{
"apxid": "articleId",
"properties": {
"articleId": { "type": "string" }
}
}
Block Creation Schedule
- Interval: Every 10 minutes (600,000 ms)
- Trigger:
setInterval()inBlockchain.start() - Condition: Only creates block if
pendingTransactions.length > 0
Security
Signature Verification
Each block is signed with the town's private key (PRIVKMAYOR). Peer towns verify:
- Block hash matches calculated hash
- Signature is valid using the validator town's public key
- Validator town exists in the towns database
Access Control
Transactions are applied with admin role:
const role = { xprofils: ['admin'], xalias: 'blockchain' };
This bypasses normal permission checks to ensure network-wide consistency.
Monitoring
Check Blockchain Status
# Dev mode logs
tail -f /var/lib/apxtowns/data/apxtri/logs/apxtri*.log | grep Blockchain
# Prod mode logs
sudo journalctl -f -u apxtri.service | grep Blockchain
Log Messages
[Blockchain] New transaction for {model}: {type}- Transaction added[Blockchain] ✅ New block #{index} created successfully- Block created[Blockchain] Received block from {validator}- Block received from peer[Blockchain] Accepted and stored block from {validator}- Verification passed[Blockchain] Transaction {id} applied successfully- Peer applied transaction
Limitations & Future Improvements
Current State
- ✅ Block creation and broadcasting
- ✅ Signature verification
- ✅ Transaction application
- ❌ Consensus voting (commented out)
- ❌ Block persistence to disk
- ❌ Chain validation on startup
- ❌ Conflict resolution for divergent chains
Recommended Next Steps
- Persist blockchain to disk (
/var/lib/apxtowns/data/apxtri/blockchain/*.json) - Implement consensus voting before finalizing blocks
- Add chain validation on server startup
- Handle network partitions and chain forks
- Add blockchain API endpoints for querying chain state