Skip to content
This repository was archived by the owner on Feb 22, 2025. It is now read-only.

bitmark archive

Sean Moss-Pultz edited this page Feb 22, 2025 · 3 revisions

Below is a complete document that details the Bitmark blockchain archival process, including an overview of the system, the Merkle tree generation, on-chain registration, and how to verify data authenticity.


Bitmark Blockchain Archive

Introduction

The Bitmark blockchain archival process ensures that all historical blockchain data remains permanently preserved and independently verifiable, even after the network is discontinued. This guarantees that provenance records for digital assets registered on Bitmark remain accessible forever.

Why This Matters

The Bitmark blockchain was created to establish digital property rights by recording ownership and provenance immutably. As we transition the network into a read-only archival state, we ensure that:

  • All past transactions and ownership records remain verifiable.
  • No reliance on Bitmark’s infrastructure is required to check past records.
  • Collectors, artists, and researchers can independently confirm provenance.

How the Archive Works

The full history of the Bitmark blockchain—including block headers, transaction records, and asset registrations—has been securely preserved using decentralized, trustless methods:

  • MerkleRegistry Smart Contract: The Merkle root of the archived blockchain is permanently stored in a public Ethereum contract, allowing for on-chain verification of any past record.
  • Bitcoin OP_RETURN: The same Merkle root is embedded in a Bitcoin transaction, providing an immutable, censorship-resistant timestamp.
  • IPFS Storage: All raw blockchain data, including transaction history, Merkle proofs, and full JSON exports, is stored on IPFS for open access.

This dual-chain approach ensures redundancy, longevity, and resistance to censorship, making it possible for anyone, even decades from now, to cryptographically verify the history of Bitmark transactions.


Overview

The archival process involves the following key steps:

  • Discontinuing the Blockchain & Read-Only Mode:
    The Bitmark blockchain is discontinued and switched to a read-only mode, meaning no new blocks can be submitted. This mode is ideal for archiving because it prevents any further modifications to the chain.

  • Immutable Data Storage:
    The complete blockchain data (from the genesis block up to block 279813) is archived and uploaded to IPFS. This decentralized file storage system ensures the data remains immutable and publicly accessible.

  • Merkle Tree for Data Verification:
    To create a compact and secure representation of the blockchain data, we leverage the Merkle tree concept. In our implementation, each block’s digest (i.e., block hash) is used as a leaf in the tree. This allows anyone to verify that a specific block is part of the archive by checking its corresponding Merkle proof.

  • On-Chain Registration:
    An Ethereum smart contract acts as an on-chain immutable registry. The Merkle root (representing the entire Bitmark blockchain) is registered with this contract, providing a publicly accessible and tamper-proof record of the archived data.

  • Bitcoin OP_RETURN Registration:
    To further reinforce the integrity of this archive, the same Merkle root is embedded in a Bitcoin OP_RETURN transaction. This provides an immutable timestamp on Bitcoin, ensuring that even if Ethereum changes, the data remains provable.


Why Bitcoin OP_RETURN?

While Ethereum allows structured on-chain storage and smart contract verification, Bitcoin’s OP_RETURN serves as an immutable timestamp that secures the integrity of the archived data on the most decentralized blockchain.

Key Benefits of OP_RETURN:

  • Censorship-resistant timestamp: Bitcoin has the longest and most secure chain history, ensuring that the archive is immutably recorded.
  • Blockchain redundancy: By using both Ethereum and Bitcoin, we prevent reliance on a single network.
  • Long-term accessibility: Bitcoin’s simple data storage method (OP_RETURN) ensures that the record can be retrieved and verified decades from now.

Together, Ethereum and Bitcoin create a trustless, tamper-proof mechanism for verifying the history of Bitmark transactions.


1. Merkle Tree Generation

The first step in the archival process is generating a Merkle tree from all the block digests. We use the OpenZeppelin Merkle Tree library for this purpose. The process is as follows:

Steps

  1. Collect Block Digests:
    Every block’s hash (32 bytes) is collected and ordered by block number (starting with the genesis block).

  2. Generate the Merkle Tree:
    These block digests are used as the leaves of a standard Merkle tree. The resulting tree outputs a single Merkle root representing the entire dataset.

  3. Output Files:
    Two files are produced:

    • tree.json: Contains the full Merkle tree structure.
    • proof.json: Contains the Merkle proof for each leaf, which can later be used to verify the authenticity of individual blocks.

Code Example

import { StandardMerkleTree } from './dist/standard.js';
import fs from 'fs';

// List of block digests (example values)
const values = [
  ['0x0012af8f437cc0b4358df93f317129747ab3cf3cf0795530decd01eb39f7935c'],
  ['0x1868c17aefd307550819d4cdb4bc89394e19368da76e3c56f593fcf003265e00'],
  ['0xae60a58d61eb62035a4dc5a1b3688b3f3bcef5c07ed61de56dafbe8eca040200'],
  ['0x94d1e9f462f513df92a12c91c073f42cd4ecc92a4b22a611b8c673e384d97d00'],
  ['0x8013783e15e60b9a65f2d1c93ac18579b82b7eb701448f2d809ecffcd3723000'],
  // ... add all block digests in order
];

// Generate the Merkle tree using the block digests
const tree = StandardMerkleTree.of(values, ['bytes32']);

console.log('Merkle Root:', tree.root);

// Save the full tree structure to tree.json
fs.writeFileSync('tree.json', JSON.stringify(tree.dump()));

// Generate the Merkle proofs for each block digest and save to proof.json
const proofs = [];
for (const [i, v] of tree.entries()) {
  const proof = tree.getProof(i);
  proofs.push({ [v]: proof });
}
fs.writeFileSync('proof.json', JSON.stringify(proofs));

After running the code, the generated Merkle root is:

0x00f2f7ffb0f1ece2814c1ee7b3be0bfd68f03b206d2dc885064d96d82569eb6a

These files are then merged into a unified Merkle Proof File.


2. Registering the Merkle Tree on Ethereum

To permanently record the Merkle root on-chain, we deploy an Ethereum smart contract that functions as an immutable registry. This ensures that anyone can later verify the authenticity of the archived blockchain data.

Registration Process

  1. Set Up the Provider & Signer:
    Configure an Ethereum provider (e.g., via Infura, Alchemy, or a local node) and create a signer using your private key.

  2. Define the Contract Details:
    The contract’s ABI includes the external function registerMerkleRoot with the parameters: _merkleRoot, _proofURI, and _metadataURI.

  3. Send the Transaction:
    The Merkle root, along with the URIs for the proof file and metadata, is submitted to the smart contract. Once the transaction is confirmed, the Merkle root is permanently recorded on-chain.

Code Example

const { ethers } = require("ethers");

// --- 1. Set Up the Provider ---
const provider = new ethers.providers.JsonRpcProvider("http://localhost:8545");

// --- 2. Set Up the Signer ---
// Replace with your Ethereum private key
const privateKey = "0xYOUR_PRIVATE_KEY_HERE";
const wallet = new ethers.Wallet(privateKey, provider);

// --- 3. Define the Contract ABI and Address ---
const contractAddress = "0x8Dae078b56ec37cdf4B71CffAc21572cCE8873eD";
const abi = [
  "function registerMerkleRoot(bytes32 _merkleRoot, string _proofURI, string _metadataURI) external"
];

// Create a contract instance connected to the wallet (signer)
const contract = new ethers.Contract(contractAddress, abi, wallet);

// --- 4. Define the Function Parameters ---
const _merkleRoot = "0x00f2f7ffb0f1ece2814c1ee7b3be0bfd68f03b206d2dc885064d96d82569eb6a";
const _proofURI   = "ipfs://QmUTivb8fhJyNF1MvPXU1swyc8Eonf9eTeVm7uxPkiKaxK";
const _metadataURI = "ipfs://QmQeLXYbeB5kzoZQhLwoRhSaXAovc6Kp9didBasVDRuVHe";

// --- 5. Build, Sign, and Send the Transaction ---
async function registerMerkleRootTx() {
  try {
    const txResponse = await contract.registerMerkleRoot(_merkleRoot, _proofURI, _metadataURI);
    console.log("Transaction sent! Hash:", txResponse.hash);
    
    // Optionally wait for confirmation
    const receipt = await txResponse.wait();
    console.log("Transaction confirmed in block", receipt.blockNumber);
  } catch (error) {
    console.error("Error sending transaction:", error);
  }
}

registerMerkleRootTx();

After the transaction is sent, you can view its details on Etherscan by using the transaction hash. This transaction represents a Bitmark Blockchain Archive registration on Ethereum.


3. Verifying Archived Bitmark Data

Even after the Bitmark blockchain is decommissioned, you can verify any past Bitmark record using the archival data stored on Ethereum and Bitcoin. This ensures that provenance records remain independently accessible.


1️. Verify via Ethereum Smart Contract

To confirm that a specific Bitmark record was included in the archived blockchain:

  1. Check the Ethereum contract:

    • Open the MerkleRegistry smart contract.
    • Call the function getMerkleEntryByRoot (0x42e7e55f), using the input: 0x00f2f7ffb0f1ece2814c1ee7b3be0bfd68f03b206d2dc885064d96d82569eb6a.
    • Validate that the returned data includes:
      • Merkle Root: 0x00f2f7ffb0f1ece2814c1ee7b3be0bfd68f03b206d2dc885064d96d82569eb6a
      • Merkle Proof: ipfs://QmUTivb8fhJyNF1MvPXU1swyc8Eonf9eTeVm7uxPkiKaxK
      • Blockchain Archive: ipfs://QmQeLXYbeB5kzoZQhLwoRhSaXAovc6Kp9didBasVDRuVHe
      • Registrant: 0x1d05cf6c6BEb0c869851BFdb9510D4E44E855ad6
  2. Find your block hash::

    • Locate your Bitmark registration details (e.g., transaction ID or asset fingerprint).
    • Search the IPFS-hosted archive for your asset.
  3. Retrieve the Merkle Proof:

    • Look up your block digest in the Merkle Proof File.
    • Identify your block leaf index in the values section and locate the proof leaves within the proof section based on your block digest.
  4. Validate data authenticity:

    • Open the MerkleRegistry smart contract.
    • Call the function verifyLeafByRoot (0xe905f981), using the following parameters:
      • root – The Merkle root.
      • leaf – Your block leaf.
      • proof – The proof leaves array.
    • Verify that the result is true.

2️. Verify via Bitcoin OP_RETURN

Bitcoin does not support smart contracts, and storing data within Bitcoin transactions is limited, making it challenging to embed structured information. The Bitmark blockchain Archival Data must include the following components to ensure authenticity and integrity:

  • Merkle Root (32 bytes): Represents the root of a Merkle Tree, summarizing all the data in a cryptographic structure.
  • Merkle Proof File: Used for verification, proving that specific data exists within the tree.
  • Metadata File: Represents the entire blockchain dataset, providing necessary details.

Since the Merkle Root is 32 bytes and IPFS CIDs (used to reference the Merkle Proof File and Metadata File) typically use SHA-256 hashes, which are also 32 bytes each (though they may be larger in some cases), the total storage requirement is at least 96 bytes.. However, Bitcoin’s OP_RETURN field, which allows embedding data in transactions, is limited to 80 bytes, making it insufficient for direct storage of all components.

To maintain data integrity within Bitcoin’s constraints, a more efficient approach is used:

Instead of storing all data directly, a SHA-256 hash of the message is stored in OP_RETURN. The message follows a specific format:

Merkle Root|Merkle Proof URI|Metadata URI

This structure allows verification of the archival data while staying within Bitcoin's storage limitations. The Merkle Proof and Metadata can still be retrieved externally via the provided URIs, ensuring that the entire dataset remains accessible and verifiable.

To validate that the same Merkle root is timestamped on Bitcoin:

  1. Find the OP_RETURN transaction:

  2. Check the stored hash:

    • Extract the OP_RETURN data from the transaction.
    • Ensure it matches the hash 95083bd32d4d5d6dfef286b1b6c5608a2398d467a5fdcb07047b7f6ccb74cfed

3️ Cross-check Ethereum & Bitcoin

For ultimate proof of authenticity, confirm that:

  • The SHA-256 hash generated from the Merkle root on Ethereum, following the pattern above, matches the OP_RETURN hash on Bitcoin.
  • The Merkle Proof File contains the block digest linked to your Bitmark record.

By performing these checks, you can independently verify that a Bitmark asset was part of the blockchain’s history, even after Bitmark itself is no longer running.


Example Verification Steps (For Developers)

For those who prefer to verify records programmatically, you can use the following methods:

Check Ethereum Merkle Root

Call the Ethereum RPC to retrieve the MerkleEntry:

curl -X POST \
-H "Content-Type: application/json" \
--data '{
 "jsonrpc": "2.0",
 "id": 6119061042218438,
 "method": "eth_call",
 "params": [
   {
     "from": "0x0000000000000000000000000000000000000000",
     "data": "0x42e7e55f00f2f7ffb0f1ece2814c1ee7b3be0bfd68f03b206d2dc885064d96d82569eb6a",
     "to": "0x8dae078b56ec37cdf4b71cffac21572cce8873ed"
   },
   "latest"
 ]
}' \
https://mainnet.infura.io/v3/<INFURA_API_KEY>

A successful response looks like:

{
 "jsonrpc": "2.0",
 "id": 6119061042218438,
 "result": "0x000000000000000000000000000000000000000000000000000000000000002000f2f7ffb0f1ece2814c1ee7b3be0bfd68f03b206dc885064d96d82569eb6a00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000001000000000000000000000000001d05cf6c6beb0c869851bfdb9510d4e44e855ad600000000000000000000000000000000000000000000000000000067ad6f8300000000000000000000000000000000000000000000000000000000000035697066733a2f2f516d55546976623866684a794e46314d76505855317377796338456f6e6639655465566d377578506b6b61784b00000000000000000000000000000000000000000000000000000000000000000000000000000000000035697066733a2f2f5d51654c5859626542356b7a6f5a51684c776f5268536158416f7663364b70396469644261735644527556486500000000000000000000"
}

Retrieve the Contract ABI from Etherscan

curl \
https://api.etherscan.io/api?module=contract&action=getabi&address=0x8dae078b56ec37cdf4b71cffac21572cce8873ed&apikey=<YOUR_API_KEY>

Use the retrieved ABI to parse the MerkleEntry from the response.


Retrieve OP_RETURN from Bitcoin

Using a Bitcoin RPC or block explorer API: Use Etherscan to obtain the contract ABI:

curl -X GET "https://blockchain.info/rawtx/a0c4b6b683b703d15e76705d2c008f0ce6f460a2b65b251b0887d453bfcf6878"

Then, extract the OP_RETURN field and ensure it matches the Ethereum-stored Merkle root hash.


Conclusion

The Bitmark blockchain archival process ensures that all historical transactions remain verifiable, immutable, and accessible, even after the blockchain itself is shut down.

By leveraging multiple decentralized systems, we have established a trustless, independent verification method:

  • Ethereum Smart Contract: The Merkle root of all archived Bitmark transactions is stored on Ethereum, allowing verification through a publicly accessible contract.
  • Bitcoin OP_RETURN: The same Merkle root is embedded in a Bitcoin transaction, providing a censorship-resistant timestamp that ensures data integrity across blockchains.
  • IPFS Archival: The full Bitmark blockchain data, including block digests, transaction records, and Merkle proofs, is permanently stored on IPFS.

Together, these methods eliminate reliance on a single blockchain while preserving the history of Bitmark as a permanent, verifiable record of digital provenance.

Why This Matters

The Bitmark blockchain was built to enable true ownership of digital assets, and this archival effort ensures that those ownership records will always be accessible and verifiable. Whether you are:

  • An artist or collector verifying provenance,
  • A researcher studying early blockchain property systems, or
  • A developer interested in historical cryptographic proofs,

this archival method guarantees that Bitmark's history remains intact—forever.


Next Steps & Community Involvement

Developers & Researchers:

  • Access the full archive and verification scripts on GitHub.
  • Contribute to ongoing efforts to improve trustless verification methods.

Artists & Collectors:

  • Learn how to verify past Bitmark registrations in our Step-by-Step Guide.
  • Reach out with any questions about how to retrieve and validate your records.

General Public & Media:

  • Follow our official announcement for more details.
  • Help spread awareness about digital provenance preservation.

Final Thought

The digital world evolves, but provenance is forever. By integrating Ethereum, Bitcoin, and IPFS, we have ensured that the legacy of Bitmark persists beyond its operational lifetime, safeguarding digital property rights for years to come.

Explore, Verify, and Preserve. The history of Bitmark is now yours to keep.