Greetings BlockDAG community,

Today, we’re diving into the groundbreaking offchain implementation of Proof of Work (PoW) using a Directed Acyclic Graph (DAG) for our blockchain. This innovative approach promises to enhance scalability and performance like never before. But that’s not all! We also have an exhilarating update on the X1 Miner application – we’re kickstarting the development of new modules that will take user engagement to the next level. Stay tuned for all the thrilling details!

Key Features of BlockDAG

Concurrent Block Addition: Multiple blocks can be added simultaneously, reducing bottlenecks.
 

  • Enhanced Scalability: The DAG structure handles higher transaction volumes more efficiently than traditional blockchains.
  • Robust Security: Utilizes PoW to secure the network and validate transactions.

Offchain Implementation Overview

1. Data Structure
In BlockDAG, each block contains transactions and references to one or more previous blocks (parents). This structure allows blocks to be added in parallel.

struct Block {
id: String,
data: String,
nonce: u64,
parent_ids: Vec<String>,
hash: String,
}

2. Adding a Block
To add a block to the BlockDAG:
 

  • Create a Block: Generate a new block with references (parent IDs) to one or more previous blocks.
  • Proof of Work: Calculate a nonce that satisfies a PoW puzzle.

fn create_block(data: &str, parent_ids: Vec<String>, difficulty: u32) -> Block {
   let mut nonce = 0;
   loop {
       let hash_input = format!(“{}{}{:?}”, data, nonce, parent_ids);
       let hash = calculate_hash(&hash_input);
       if hash.starts_with(&”0″.repeat(difficulty as usize)) {
           return Block {
id: generate_id(),
data: data.to_string(),
nonce,
parent_ids,
hash,
};
}
nonce += 1;
}
}

3. Proof of Work Calculation
The PoW puzzle involves finding a nonce such that the hash of the block data and nonce has a certain number of leading zeros, indicating the difficulty.

fn calculate_hash(input: &str) -> String {
   use sha2::{Sha256, Digest};
   let mut hasher = Sha256::new();
hasher.update(input);
   format!(“{:x}”, hasher.finalize())
}

Mathematically, the PoW can be described as:H(data+nonce)<targetwhere H is the hash function, and the target is derived from the difficulty level.4. Validating Blocks
To validate a block:
 

  • Verify PoW: Check that the hash meets the PoW requirement.
  • Check Parent Blocks: Ensure all referenced parent blocks exist and are valid.

fn validate_block(block: &Block, difficulty: u32, blockdag: &HashMap<String, Block>) -> bool {
   let hash_input = format!(“{}{}{:?}”, block.data, block.nonce, block.parent_ids);
   let hash = calculate_hash(&hash_input);
   if !hash.starts_with(&”0″.repeat(difficulty as usize)) {
       return false;
}
   for parent_id in &block.parent_ids {
       if !blockdag.contains_key(parent_id) {
           return false;
}
}
   true
}

Offchain Implementation


Offchain Storage
Blocks in the BlockDAG can be stored offchain to enhance scalability and reduce on-chain storage requirements. Offchain storage involves keeping the bulk of the data on external servers or distributed storage systems, while critical block references and hashes remain on-chain for validation.Data Availability
Offchain data must be readily available for validation and retrieval. This can be achieved through:
 

  • Decentralized Storage Systems: Using platforms like IPFS or Filecoin to store block data.
  • Offchain Databases: Utilizing traditional databases or distributed ledgers to manage and retrieve block information.

Proof of Existence
To ensure the integrity of offchain data, proofs of existence can be used. A common approach is to store a Merkle root or hash of the offchain data on-chain. This allows any part of the data to be verified against the stored hash.
 

struct OffchainBlock {
id: String,
merkle_root: String,
parent_ids: Vec<String>,
hash: String,
}

Synchronization
Nodes must synchronize offchain data to ensure consistency. This involves:
 

  • Data Replication: Ensuring multiple copies of offchain data are available across the network.
  • Validation Protocols: Implementing protocols for nodes to verify the integrity and validity of offchain data.

Example Workflow
 

  • Block Creation: A miner creates a block with specific data and references to previous blocks.
  • Nonce Calculation: The miner calculates a nonce that solves the PoW puzzle.
  • Offchain Storage: The block data is stored offchain, and a proof (hash or Merkle root) is recorded on-chain.
  • Block Submission: The miner submits the block and proof to the network.
  • Validation: Nodes validate the block by verifying the PoW and checking the parent blocks and the offchain proof.
  • Inclusion in BlockDAG: Once validated, the block is added to the BlockDAG.

Mathematical FormulasProof of Work (PoW)
The PoW algorithm requires solving a hash puzzle:
H(data+nonce)<target
 

  • Hash Function H: A cryptographic hash function like SHA-256.
  • Nonce: A variable that miners adjust to find a valid hash.
  • Target: A value that determines the difficulty of the PoW puzzle. The lower the target, the higher the difficulty.

Difficulty Adjustment
The target can be dynamically adjusted based on network conditions to maintain a consistent level of difficulty. This can be done using a formula such as:

\text{new_target} = \frac{\text{old_target} \times \text{time_expected}}{\text{time_taken}}

X1 Miner: App store approval and kickstarting other modules

We have resubmitted the new build for approval to both the Apple App Store and the Google Play Store. We eagerly await their final validation and approval to publish the app. Meanwhile, we have kickstarted the development of other modules to enhance user engagement in the X1 application. These include the leaderboard, community section, airdrops portal, and much more.