@dignetwork/proof-of-work
v0.1.3
Published
A high-performance Bitcoin-compatible proof of work library for Node.js, built with Rust and NAPI bindings. This library provides efficient mining capabilities using Bitcoin's target-based difficulty system with double SHA-256 hashing.
Readme
Proof of Work
A high-performance Bitcoin-compatible proof of work library for Node.js, built with Rust and NAPI bindings. This library provides efficient mining capabilities using Bitcoin's target-based difficulty system with double SHA-256 hashing.
Features
- Bitcoin-Compatible: Uses Bitcoin's target-based difficulty system with double SHA-256 hashing
- High Performance: Written in Rust for maximum mining efficiency
- Asynchronous Mining: Non-blocking proof of work computation that won't freeze your application
- Cancellable Operations: Start mining with ability to cancel anytime using handles
- Progress Tracking: Real-time progress monitoring with attempt counts and timing
- Unlimited Attempts: Mine until solution is found (unless explicitly limited)
- Nonce Verification: Verify that a nonce meets difficulty requirements
- Standardized Verification: Consensus-critical verification with algorithm version validation
- Difficulty Analysis: Calculate difficulty levels from hash values
- Security Features: Tamper-resistant verification with algorithm immutability
- Cross-platform Support: Builds for Windows, macOS, and Linux
- Multiple Architectures: Supports x64 and ARM64 architectures
- TypeScript Support: Full TypeScript definitions included
Installation
npm install @dignetwork/proof-of-workQuick Start
const { computeProofOfWorkAsync } = require('@dignetwork/proof-of-work')
async function mine() {
const entropySeed = Buffer.from('my_plot_entropy_seed', 'utf-8')
const difficulty = 1.0 // Bitcoin difficulty (1.0 = easiest)
// Start mining (returns immediately with a handle)
const handle = computeProofOfWorkAsync(entropySeed, difficulty)
// Set up Ctrl+C handling for cancellation
process.on('SIGINT', () => {
console.log('\nCancelling mining...')
handle.cancel()
process.exit(0)
})
// Wait for completion
while (!handle.isCompleted() && !handle.hasError()) {
console.log(`Mining... attempts: ${handle.getAttempts()}`)
await new Promise(resolve => setTimeout(resolve, 1000))
}
if (handle.hasError()) {
console.log('Mining failed:', handle.getError())
} else {
const result = handle.getResult()
console.log('Solution found!')
console.log('Nonce:', result.nonce)
console.log('Hash:', result.hash)
console.log('Attempts:', result.attempts)
console.log('Time:', result.time_ms, 'ms')
}
}
mine().catch(console.error)API Reference
Main Functions
computeProofOfWorkAsync(entropySeed, difficulty, maxAttempts?, logAttempts?, doubleSha?): ProofOfWorkHandle
Computes proof of work asynchronously using Bitcoin's target-based difficulty system. Returns immediately with a handle for cancellation and progress tracking.
Parameters:
entropySeed(Buffer): The entropy seed (plotId) to bind the work todifficulty(number): Bitcoin-style difficulty level (1.0 = easiest, higher = harder)maxAttempts(number, optional): Maximum attempts before giving up (default: unlimited)logAttempts(boolean, optional): Whether to log each hash attempt (default: false)doubleSha(boolean, optional): Whether to use double SHA-256 like Bitcoin (default: true)
Returns: ProofOfWorkHandle for cancellation and progress tracking
verifyProofOfWork(entropySeed, nonce, difficulty, doubleSha?): boolean
Verifies that a nonce produces a hash that meets the Bitcoin difficulty target.
Parameters:
entropySeed(Buffer): The entropy seed that was usednonce(number): The nonce to verifydifficulty(number): The required difficulty leveldoubleSha(boolean, optional): Whether to use double SHA-256 (default: true)
Returns: true if the nonce is valid for the given difficulty
verifyProofOfWorkStandardized(entropySeed, nonce, difficulty, expectedVersion?, doubleSha?): boolean
CONSENSUS CRITICAL: Standardized verification with algorithm validation. This function verifies both the proof of work AND the algorithm compatibility.
Parameters:
entropySeed(Buffer): The entropy seed that was usednonce(number): The nonce to verifydifficulty(number): The required difficulty levelexpectedVersion(number, optional): Expected algorithm version (default: current)doubleSha(boolean, optional): Whether to use double SHA-256 (default: true)
Returns: true if the nonce is valid AND algorithm is correct
Security Note: Use this function for network consensus validation. It validates algorithm version compatibility and prevents tampering.
Utility Functions
difficultyToTargetHex(difficulty): string
Convert a Bitcoin-style difficulty to the corresponding target value as hex.
Parameters:
difficulty(number): The difficulty level
Returns: The target as a hex string
hashToDifficulty(hash): number
Calculate the difficulty that a given hash would satisfy.
Parameters:
hash(Buffer): The hash to analyze (32 bytes)
Returns: The difficulty level this hash would satisfy
Consensus & Security Functions
getAlgorithmVersion(): number
Get the current difficulty algorithm version. This version number is part of the network consensus.
Returns: The algorithm version number
getAlgorithmSpec(): string
Get the algorithm specification hash. This hash identifies the exact algorithm implementation.
Returns: The algorithm specification identifier
getAlgorithmParameters(): AlgorithmParameters
Get the standardized difficulty algorithm parameters. These parameters are part of the network consensus.
Returns: Algorithm parameters object containing:
version(number): Algorithm version numberspecHash(string): Algorithm specification hashbaseZeroBits(number): Base number of zero bits for difficulty 1.0logMultiplier(number): Logarithmic multiplier for difficulty scalingmaxZeroBits(number): Maximum allowed zero bits
ProofOfWorkHandle Methods
The handle returned by computeProofOfWorkAsync provides these methods:
cancel(): void
Cancels the running proof of work computation.
isCancelled(): boolean
Returns true if the computation has been cancelled.
isCompleted(): boolean
Returns true if the computation has found a valid solution.
hasError(): boolean
Returns true if there was an error (cancelled or max attempts reached).
getError(): string | null
Returns the error message if there was an error, or null if no error.
getResult(): ProofOfWorkResult | null
Returns the result if computation completed successfully, or null if not completed.
getAttempts(): bigint
Returns the current number of attempts made (approximate).
getProgress(): ProofOfWorkProgress
Returns detailed progress information (attempts, elapsed time, etc.).
getDifficulty(): number
Returns the difficulty level for this computation.
Result Types
ProofOfWorkResult
nonce(bigint): The nonce that was foundhash(string): The resulting hash as hex stringattempts(bigint): Number of attempts madetime_ms(number): Time taken in millisecondsdifficulty(number): The difficulty that was satisfiedtarget(string): The target that was used (as hex string)
ProofOfWorkProgress
attempts(bigint): Current number of attemptsnonce(bigint): Current nonce being testedelapsed_ms(number): Time elapsed in millisecondsattempts_per_second(number): Estimated attempts per second
TypeScript Usage
import {
computeProofOfWorkAsync,
verifyProofOfWork,
verifyProofOfWorkStandardized,
getAlgorithmVersion,
getAlgorithmParameters,
hashToDifficulty,
ProofOfWorkResult,
ProofOfWorkHandle,
AlgorithmParameters
} from '@dignetwork/proof-of-work'
async function mineWithTypes(): Promise<void> {
const entropySeed = Buffer.from('my_plot_entropy_seed', 'utf-8')
const difficulty = 2.0
const handle: ProofOfWorkHandle = computeProofOfWorkAsync(entropySeed, difficulty)
// Wait for completion with proper typing
const waitForCompletion = async (handle: ProofOfWorkHandle): Promise<ProofOfWorkResult> => {
while (!handle.isCompleted() && !handle.hasError()) {
await new Promise(resolve => setTimeout(resolve, 100))
}
if (handle.hasError()) {
throw new Error(handle.getError() || 'Unknown error')
}
const result = handle.getResult()
if (!result) {
throw new Error('No result available')
}
return result
}
const result: ProofOfWorkResult = await waitForCompletion(handle)
// Standard verification
const isValid: boolean = verifyProofOfWork(
entropySeed,
Number(result.nonce),
difficulty
)
// Standardized verification (recommended for networks)
const isStandardValid: boolean = verifyProofOfWorkStandardized(
entropySeed,
Number(result.nonce),
difficulty
)
// Check algorithm parameters
const params: AlgorithmParameters = getAlgorithmParameters()
console.log(`Algorithm version: ${params.version}`)
console.log(`Algorithm spec: ${params.specHash}`)
console.log('Mining completed, valid:', isValid)
console.log('Consensus valid:', isStandardValid)
}Difficulty System
This library uses Bitcoin's target-based difficulty system:
- Difficulty 1.0: Easiest level, requires 8 leading zero bits in hash
- Difficulty 2.0: Requires 12 leading zero bits
- Difficulty 4.0: Requires 16 leading zero bits (2 zero bytes)
- Higher difficulties: Exponentially more difficult
The difficulty directly corresponds to how computationally expensive it is to find a valid nonce.
Security & Consensus
This library implements a consensus-critical verification system to prevent tampering and ensure network compatibility.
Algorithm Standardization
- Version 1 Specification:
DIG_POW_V1_SMOOTH_LOG_DIFFICULTY_2024 - Formula:
zero_bits = 8 + log2(difficulty) * 2 - Immutable Parameters: All difficulty calculation parameters are locked constants
- Version Validation: Algorithm version must match across all network participants
Security Guarantees
- Tamper Detection: Algorithm spec hash prevents silent modifications
- Version Enforcement: Mismatched versions are rejected automatically
- Consensus Compliance: All parameters are immutable constants
- Network Compatibility: Ensures identical verification across nodes
- Upgrade Safety: Algorithm changes require coordinated hard forks
Usage for Network Consensus
// For production networks: Always use standardized verification
const isValid = verifyProofOfWorkStandardized(entropySeed, nonce, difficulty)
// Check algorithm compatibility
const version = getAlgorithmVersion() // Returns: 1
const spec = getAlgorithmSpec() // Returns: "DIG_POW_V1_SMOOTH_LOG_DIFFICULTY_2024"
// Validate all proofs with version checking
function validateNetworkProof(entropySeed, nonce, difficulty) {
return verifyProofOfWorkStandardized(entropySeed, nonce, difficulty, 1)
}Network Upgrade Process
To change the difficulty algorithm:
- Define new algorithm version (e.g., version 2)
- Update consensus parameters and spec hash
- Coordinate hard fork across all network participants
- Validate version compatibility on peer connections
Performance Tips
- Use appropriate difficulty levels: Start with 1.0-4.0 for testing
- Monitor progress: Use the handle to track mining progress
- Set reasonable limits: Use
maxAttemptsfor time-critical applications - Handle cancellation: Always provide a way to cancel long-running operations
Development
Prerequisites
Setup
# Clone and install dependencies
git clone <repository-url>
cd proof-of-work
npm install
# Build the native module
npm run build
# Run tests
npm testProject Structure
proof-of-work/
├── src/
│ └── lib.rs # Rust implementation with NAPI bindings
├── __test__/
│ └── index.spec.mjs # Test suite
├── npm/ # Platform-specific native binaries
├── .github/workflows/ # CI/CD pipeline
├── Cargo.toml # Rust configuration
├── package.json # Node.js configuration
└── index.d.ts # TypeScript definitionsCI/CD & Publishing
This project uses GitHub Actions for:
- Cross-platform builds (Windows, macOS, Linux)
- Multiple architectures (x64, ARM64)
- Automated testing
- npm publishing based on commit messages
License
MIT
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Make your changes and add tests
- Ensure all tests pass (
npm test) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
