localgreenchain/lib/blockchain/PlantBlock.ts
Claude 1e14a700c7
Implement LocalGreenChain: Plant Cloning Blockchain System
This commit implements a complete blockchain-based plant tracking system
that preserves lineage across clones, seeds, and all plant offspring while
connecting growers through geographic proximity.

Features implemented:
- Custom blockchain with proof-of-work consensus
- Plant registration and cloning with lineage tracking
- Geographic discovery to find nearby plants and growers
- Integration with plants.net API for plant identification
- Comprehensive web UI for plant management
- RESTful API endpoints for all operations
- Network statistics and visualization

Core Components:
- lib/blockchain/: PlantBlock, PlantChain, and blockchain manager
- lib/services/: plants.net API and geolocation services
- pages/api/plants/: REST API endpoints for all operations
- pages/: Frontend UI pages for registration, exploration, and lineage

Technical Details:
- TypeScript for type safety
- Next.js for server-side rendering
- Tailwind CSS for responsive design
- JSON file-based blockchain storage
- Haversine distance calculations for geolocation
- OpenStreetMap integration for geocoding

This system enables large-scale adoption by:
- Making plant lineage tracking accessible to everyone
- Connecting local communities through plant sharing
- Providing immutable proof of plant provenance
- Supporting unlimited generations of plant propagation
- Scaling from individual growers to global networks

Documentation includes comprehensive README with:
- Quick start guide
- API reference
- Architecture details
- Scaling recommendations
- Use cases for various audiences
- Roadmap for future enhancements
2025-11-16 05:11:55 +00:00

106 lines
2.3 KiB
TypeScript

import crypto from 'crypto';
import { PlantData, BlockData } from './types';
/**
* PlantBlock - Represents a single block in the plant blockchain
* Each block contains data about a plant and its lineage
*/
export class PlantBlock {
public index: number;
public timestamp: string;
public plant: PlantData;
public previousHash: string;
public hash: string;
public nonce: number;
constructor(
index: number,
timestamp: string,
plant: PlantData,
previousHash: string = ''
) {
this.index = index;
this.timestamp = timestamp;
this.plant = plant;
this.previousHash = previousHash;
this.nonce = 0;
this.hash = this.calculateHash();
}
/**
* Calculate the hash of this block using SHA-256
*/
calculateHash(): string {
return crypto
.createHash('sha256')
.update(
this.index +
this.previousHash +
this.timestamp +
JSON.stringify(this.plant) +
this.nonce
)
.digest('hex');
}
/**
* Mine the block using proof-of-work algorithm
* Difficulty determines how many leading zeros the hash must have
*/
mineBlock(difficulty: number): void {
const target = Array(difficulty + 1).join('0');
while (this.hash.substring(0, difficulty) !== target) {
this.nonce++;
this.hash = this.calculateHash();
}
console.log(`Block mined: ${this.hash}`);
}
/**
* Convert block to JSON for storage/transmission
*/
toJSON(): BlockData {
return {
index: this.index,
timestamp: this.timestamp,
plant: this.plant,
previousHash: this.previousHash,
hash: this.hash,
nonce: this.nonce,
};
}
/**
* Create a PlantBlock from JSON data
*/
static fromJSON(data: BlockData): PlantBlock {
const block = new PlantBlock(
data.index,
data.timestamp,
data.plant,
data.previousHash
);
block.hash = data.hash;
block.nonce = data.nonce;
return block;
}
/**
* Verify if this block is valid
*/
isValid(previousBlock?: PlantBlock): boolean {
// Check if hash is correct
if (this.hash !== this.calculateHash()) {
return false;
}
// Check if previous hash matches
if (previousBlock && this.previousHash !== previousBlock.hash) {
return false;
}
return true;
}
}