World Conquest Chronicles

World Conquest Chronicles

go-blockchain, v1.4

The library that implements models and algorithms of blockchain.

Add merging the blockchain model with another one.

Change Log

  • models:
    • blockchain:
      • operations:
        • merging with another blockchain:
          • selecting a fork based on a maximal total difficulty;
          • with automatic deleting orphan blocks;
  • storages:
    • operations:
      • creation from a block group;
  • additionally:
    • return nil instead empty array from loaders.MemoryLoader.LoadBlocks() method;
    • copy the loaded blocks in the storages.MemoryStorage.LoadBlocks() method;
    • fix the unit tests:
      • add the missed tests without blocks;
      • add the tests with checking pointers for the storages.MemoryStorage.LoadBlocks() method;
    • examples:
      • add the example with merging the blockchain model with another one.

Features

  • models:
    • block data:
      • operations:
        • conversion to a string;
        • comparison for equality with another block data;
      • wrappers:
        • wrapper that adds support for the following operations to those block data that cannot do them:
          • conversion to a string:
            • implementation of the fmt.Stringer interface;
            • implementation of the encoding.TextMarshaler interface;
          • comparison for equality with another block data;
    • block:
      • storing:
        • timestamp;
        • block data;
        • hash;
        • previous hash;
      • operations:
        • creation (using a proofer);
        • getting merged data;
        • comparison for equality with another block;
        • self-validation (using a proofer);
    • genesis block:
      • based on a usual block without a previous hash;
    • block group:
      • storing:
        • group of blocks;
      • operations:
        • self-validation (using a proofer):
          • modes:
            • as a full blockchain;
            • as a blockchain chunk;
          • takes into account a prepended chunk;
          • allows empty block groups;
        • validation of the last block (using a proofer):
          • modes:
            • as a full blockchain;
            • as a blockchain chunk;
        • search of differences between two block groups:
          • returns lengths of different prefixes of the compared block groups;
          • based on a hash table index;
        • calculating a total difficulty of blocks;
    • block group loaders:
      • loading block groups via the external interface;
      • automatically saving the loaded block groups to a storage;
      • search of differences between two block group loaders:
        • loads and compares only one block chunk from every block group loader;
      • wrappers:
        • chunk validating loader:
          • automatically validates the loaded block group as a blockchain chunk;
        • last block validating loader:
          • automatically validates the last block from the loaded block group;
          • automatically preloads the next block group to perform the above validation;
        • memoizing loader:
          • remembers loaded block groups;
          • restricts the quantity of the remembered block groups:
            • stores the loaded block groups in the LRU cache;
      • kinds:
        • memory loader:
          • loading blocks from the block group;
    • blockchain:
      • storing:
        • storage;
        • last block;
      • operations:
        • creation:
          • loading the last block from the storage;
          • when the storage is empty (optional):
            • creation a genesis block using a proofer;
            • storing the genesis block to the storage;
        • loading block groups from the storage;
        • adding a block:
          • creation a block using a proofer;
          • storing the block to the storage;
        • merging with another blockchain:
          • selecting a fork based on a maximal total difficulty;
          • with automatic deleting orphan blocks;
  • proofers:
    • operations:
      • block hashing;
      • block difficulty calculating;
      • block validation;
    • kinds:
      • proof of work:
        • based on the Hashcash algorithm;
        • additional storing in a block (in a hash actually):
          • nonce;
          • target bit;
        • difficulty is defined as an inverse target bit;
  • storages:
    • operations:
      • creation from a block group;
      • loading block groups;
      • loading the last block;
      • storing a block;
      • storing a block group (optional);
      • deleting a block;
      • deleting a block group (optional);
    • wrappers:
      • wrapper that adds support for the following operations to those storages that cannot do them:
        • storing a block group;
        • deleting a block group;
    • kinds:
      • memory storage:
        • storing blocks in memory.

Examples

blockchain.Blockchain.Merge():

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "time"

    blockchain "github.com/thewizardplusplus/go-blockchain"
    "github.com/thewizardplusplus/go-blockchain/proofers"
    "github.com/thewizardplusplus/go-blockchain/storing"
    "github.com/thewizardplusplus/go-blockchain/storing/storages"
)

func main() {
    timestamp := time.Date(2006, time.January, 2, 15, 4, 5, 0, time.UTC)
    blockGroupOne := blockchain.BlockGroup{
        {
            Timestamp: timestamp.Add(2*time.Hour + 40*time.Minute),
            Data:      blockchain.NewData("block #1.2"),
            Hash:      "250:0:hash #3.2",
            PrevHash:  "23:0:hash #3.1",
        },
        {
            Timestamp: timestamp.Add(2*time.Hour + 20*time.Minute),
            Data:      blockchain.NewData("block #1.1"),
            Hash:      "250:0:hash #3.1",
            PrevHash:  "23:0:hash #2",
        },
        {
            Timestamp: timestamp.Add(time.Hour),
            Data:      blockchain.NewData("block #0"),
            Hash:      "23:0:hash #2",
            PrevHash:  "23:0:hash #1",
        },
        {
            Timestamp: timestamp,
            Data:      blockchain.NewData("genesis block"),
            Hash:      "23:0:hash #1",
            PrevHash:  "",
        },
    }
    blockchainInstanceOne, err :=
        blockchain.NewBlockchain(nil, blockchain.Dependencies{
            BlockDependencies: blockchain.BlockDependencies{
                Proofer: proofers.ProofOfWork{TargetBit: 248},
            },
            Storage: storing.NewGroupStorage(storages.NewMemoryStorage(blockGroupOne)),
        })
    if err != nil {
        log.Fatalf("unable to create the blockchain #1: %v", err)
    }

    blockGroupTwo := blockchain.BlockGroup{
        {
            Timestamp: timestamp.Add(2 * time.Hour),
            Data:      blockchain.NewData("block #1"),
            Hash:      "23:0:hash #3",
            PrevHash:  "23:0:hash #2",
        },
        {
            Timestamp: timestamp.Add(time.Hour),
            Data:      blockchain.NewData("block #0"),
            Hash:      "23:0:hash #2",
            PrevHash:  "23:0:hash #1",
        },
        {
            Timestamp: timestamp,
            Data:      blockchain.NewData("genesis block"),
            Hash:      "23:0:hash #1",
            PrevHash:  "",
        },
    }
    blockchainInstanceTwo, err :=
        blockchain.NewBlockchain(nil, blockchain.Dependencies{
            BlockDependencies: blockchain.BlockDependencies{
                Proofer: proofers.ProofOfWork{TargetBit: 248},
            },
            Storage: storing.NewGroupStorage(storages.NewMemoryStorage(blockGroupTwo)),
        })
    if err != nil {
        log.Fatalf("unable to create the blockchain #2: %v", err)
    }

    if err := blockchainInstanceOne.Merge(blockchainInstanceTwo, 3); err != nil {
        log.Fatalf("unable to merge the blockchains: %v", err)
    }

    mergedBlocks, _, _ := blockchainInstanceOne.LoadBlocks(nil, 10)
    blocksBytes, _ := json.MarshalIndent(mergedBlocks, "", "  ")
    fmt.Println(string(blocksBytes))

    // Output:
    // [
    //   {
    //     "Timestamp": "2006-01-02T17:04:05Z",
    //     "Data": "block #1",
    //     "Hash": "23:0:hash #3",
    //     "PrevHash": "23:0:hash #2"
    //   },
    //   {
    //     "Timestamp": "2006-01-02T16:04:05Z",
    //     "Data": "block #0",
    //     "Hash": "23:0:hash #2",
    //     "PrevHash": "23:0:hash #1"
    //   },
    //   {
    //     "Timestamp": "2006-01-02T15:04:05Z",
    //     "Data": "genesis block",
    //     "Hash": "23:0:hash #1",
    //     "PrevHash": ""
    //   }
    // ]
}

Repository

Link: https://github.com/thewizardplusplus/go-blockchain/tree/v1.4.0.

Content: code.

License: MIT.