Documentation
¶
Index ¶
- Variables
- func FindDifferences(leftLoader Loader, rightLoader Loader, chunkSize int) (leftDifferences BlockGroup, rightDifferences BlockGroup, err error)
- type Block
- func NewBlock(data Data, prevBlock Block, dependencies BlockDependencies) Blockdeprecated
- func NewBlockEx(ctx context.Context, params NewBlockExParams) (Block, error)
- func NewGenesisBlock(data Data, dependencies BlockDependencies) Blockdeprecated
- func NewGenesisBlockEx(ctx context.Context, params NewGenesisBlockExParams) (Block, error)
- type BlockDependencies
- type BlockGroup
- func (blocks BlockGroup) Difficulty(proofer Proofer) (int, error)
- func (blocks BlockGroup) FindDifferences(anotherBlocks BlockGroup) (leftIndex int, rightIndex int, hasMatch bool)
- func (blocks BlockGroup) IsLastBlockValid(prevBlock *Block, validationMode ValidationMode, proofer Proofer) error
- func (blocks BlockGroup) IsValid(prependedChunk BlockGroup, validationMode ValidationMode, proofer Proofer) error
- type Blockchain
- func (blockchain *Blockchain) AddBlock(data Data) errordeprecated
- func (blockchain *Blockchain) AddBlockEx(ctx context.Context, data Data) error
- func (blockchain Blockchain) LoadBlocks(cursor interface{}, count int) (blocks BlockGroup, nextCursor interface{}, err error)
- func (blockchain *Blockchain) Merge(loader Loader, chunkSize int) error
- type Clock
- type Data
- type DataComparer
- type Dependencies
- type GroupStorage
- type Loader
- type NewBlockExParams
- type NewBlockchainExParams
- type NewGenesisBlockExParams
- type Proofer
- type Storage
- type Stringer
- type TextMarshaler
- type ValidationMode
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrEmptyStorage = errors.New("empty storage")
ErrEmptyStorage ...
var ErrEqualDifficulties = errors.New("equal difficulties")
ErrEqualDifficulties ...
var ErrNoMatch = errors.New("no match")
ErrNoMatch ...
Functions ¶
func FindDifferences ¶ added in v1.4.0
func FindDifferences(leftLoader Loader, rightLoader Loader, chunkSize int) ( leftDifferences BlockGroup, rightDifferences BlockGroup, err error, )
FindDifferences ...
Types ¶
type Block ¶
Block ...
Example ¶
timestamp := time.Date(2006, time.January, 2, 15, 4, 5, 0, time.UTC)
blockDependencies := blockchain.BlockDependencies{
// use the custom clock function to get the same blocks
Clock: func() time.Time {
timestamp = timestamp.Add(time.Hour)
return timestamp
},
Proofer: proofers.ProofOfWork{
TargetBit: 248,
},
}
genesisBlock, err := blockchain.NewGenesisBlockEx(
context.Background(),
blockchain.NewGenesisBlockExParams{
Dependencies: blockDependencies,
Data: blockchain.NewData("genesis block"),
},
)
if err != nil {
log.Fatalf("unable to create a new genesis block: %s", err)
}
blocks := []blockchain.Block{genesisBlock}
for i := 0; i < 5; i++ {
block, err := blockchain.NewBlockEx(
context.Background(),
blockchain.NewBlockExParams{
Dependencies: blockDependencies,
Data: blockchain.NewData(fmt.Sprintf("block #%d", i)),
PrevBlock: mo.Some(blocks[len(blocks)-1]),
},
)
if err != nil {
log.Fatalf("unable to create a new block: %s", err)
}
blocks = append(blocks, block)
}
blocksBytes, _ := json.MarshalIndent(blocks, "", " ")
fmt.Println(string(blocksBytes))
Output: [ { "Timestamp": "2006-01-02T16:04:05Z", "Data": "genesis block", "Hash": "248:225:00e26abd9974fcdea4b32eca43c9dc5c67fffa8efd53cebffa9b049fd6c2bb36", "PrevHash": "" }, { "Timestamp": "2006-01-02T17:04:05Z", "Data": "block #0", "Hash": "248:198:0058f5dae6ca3451801a276c94862c7cce085e6f9371e50d80ddbb87c1438faf", "PrevHash": "248:225:00e26abd9974fcdea4b32eca43c9dc5c67fffa8efd53cebffa9b049fd6c2bb36" }, { "Timestamp": "2006-01-02T18:04:05Z", "Data": "block #1", "Hash": "248:15:002fc891ad012c4a89f7b267a2ec1767415c627ff69b88b90a93be938b026efa", "PrevHash": "248:198:0058f5dae6ca3451801a276c94862c7cce085e6f9371e50d80ddbb87c1438faf" }, { "Timestamp": "2006-01-02T19:04:05Z", "Data": "block #2", "Hash": "248:136:003c7def3d467a759fad481c03cadbd62e62b2c5dbc10e4bbb6e1944c158a8be", "PrevHash": "248:15:002fc891ad012c4a89f7b267a2ec1767415c627ff69b88b90a93be938b026efa" }, { "Timestamp": "2006-01-02T20:04:05Z", "Data": "block #3", "Hash": "248:65:00d5800e119abe44d89469c2161be7f9645d7237697c6d14b4a72717893582fa", "PrevHash": "248:136:003c7def3d467a759fad481c03cadbd62e62b2c5dbc10e4bbb6e1944c158a8be" }, { "Timestamp": "2006-01-02T21:04:05Z", "Data": "block #4", "Hash": "248:173:00b6863763acd6ec77ca3521589d8e68c118efe855657d702783e8e6aee169a9", "PrevHash": "248:65:00d5800e119abe44d89469c2161be7f9645d7237697c6d14b4a72717893582fa" } ]
func NewBlock
deprecated
func NewBlock( data Data, prevBlock Block, dependencies BlockDependencies, ) Block
NewBlock ...
Deprecated: Use NewBlockEx instead.
func NewBlockEx ¶ added in v1.4.1
func NewBlockEx(ctx context.Context, params NewBlockExParams) (Block, error)
NewBlockEx ...
func NewGenesisBlock
deprecated
func NewGenesisBlock(data Data, dependencies BlockDependencies) Block
NewGenesisBlock ...
Deprecated: Use NewGenesisBlockEx instead.
func NewGenesisBlockEx ¶ added in v1.4.1
func NewGenesisBlockEx( ctx context.Context, params NewGenesisBlockExParams, ) (Block, error)
NewGenesisBlockEx ...
func (Block) IsValidGenesisBlock ¶
IsValidGenesisBlock ...
type BlockDependencies ¶
BlockDependencies ...
type BlockGroup ¶
type BlockGroup []Block
BlockGroup ...
Example ¶
timestamp := time.Date(2006, time.January, 2, 15, 4, 5, 0, time.UTC)
blockChunks := []blockchain.BlockGroup{
// chunk #0
{
{
Timestamp: timestamp.Add(6 * time.Hour),
Data: blockchain.NewData("block #4"),
Hash: "248:" +
"173:" +
"00b6863763acd6ec77ca3521589d8e68c118efe855657d702783e8e6aee169a9",
PrevHash: "248:" +
"65:" +
"00d5800e119abe44d89469c2161be7f9645d7237697c6d14b4a72717893582fa",
},
{
Timestamp: timestamp.Add(5 * time.Hour),
Data: blockchain.NewData("block #3"),
Hash: "248:" +
"65:" +
"00d5800e119abe44d89469c2161be7f9645d7237697c6d14b4a72717893582fa",
PrevHash: "248:" +
"136:" +
"003c7def3d467a759fad481c03cadbd62e62b2c5dbc10e4bbb6e1944c158a8be",
},
},
// chunk #1
{
{
Timestamp: timestamp.Add(4 * time.Hour),
Data: blockchain.NewData("block #2"),
Hash: "248:" +
"136:" +
"003c7def3d467a759fad481c03cadbd62e62b2c5dbc10e4bbb6e1944c158a8be",
PrevHash: "248:" +
"15:" +
"002fc891ad012c4a89f7b267a2ec1767415c627ff69b88b90a93be938b026efa",
},
{
Timestamp: timestamp.Add(3 * time.Hour),
Data: blockchain.NewData("block #1"),
Hash: "248:" +
"15:" +
"002fc891ad012c4a89f7b267a2ec1767415c627ff69b88b90a93be938b026efa",
PrevHash: "248:" +
"198:" +
"0058f5dae6ca3451801a276c94862c7cce085e6f9371e50d80ddbb87c1438faf",
},
},
// chunk #2
{
{
Timestamp: timestamp.Add(2 * time.Hour),
Data: blockchain.NewData("block #0"),
Hash: "248:" +
"198:" +
"0058f5dae6ca3451801a276c94862c7cce085e6f9371e50d80ddbb87c1438faf",
PrevHash: "248:" +
"225:" +
"00e26abd9974fcdea4b32eca43c9dc5c67fffa8efd53cebffa9b049fd6c2bb36",
},
{
Timestamp: timestamp.Add(time.Hour),
Data: blockchain.NewData("genesis block"),
Hash: "248:" +
"225:" +
"00e26abd9974fcdea4b32eca43c9dc5c67fffa8efd53cebffa9b049fd6c2bb36",
PrevHash: "",
},
},
}
var prependedChunk blockchain.BlockGroup
proofer := proofers.ProofOfWork{TargetBit: 248}
for index, blockChunk := range blockChunks {
validationMode := blockchain.AsBlockchainChunk
if index == len(blockChunks)-1 {
validationMode = blockchain.AsFullBlockchain
}
err := blockChunk.IsValid(prependedChunk, validationMode, proofer)
if err != nil {
log.Fatalf("chunk #%d is incorrect: %v", index, err)
}
prependedChunk = blockChunk
}
fmt.Println("all chunks are correct")
Output: all chunks are correct
func (BlockGroup) Difficulty ¶ added in v1.4.0
func (blocks BlockGroup) Difficulty(proofer Proofer) (int, error)
Difficulty ...
func (BlockGroup) FindDifferences ¶ added in v1.4.0
func (blocks BlockGroup) FindDifferences(anotherBlocks BlockGroup) ( leftIndex int, rightIndex int, hasMatch bool, )
FindDifferences ...
func (BlockGroup) IsLastBlockValid ¶
func (blocks BlockGroup) IsLastBlockValid( prevBlock *Block, validationMode ValidationMode, proofer Proofer, ) error
IsLastBlockValid ...
func (BlockGroup) IsValid ¶
func (blocks BlockGroup) IsValid( prependedChunk BlockGroup, validationMode ValidationMode, proofer Proofer, ) error
IsValid ...
type Blockchain ¶
type Blockchain struct {
// contains filtered or unexported fields
}
Blockchain ...
Example ¶
timestamp := time.Date(2006, time.January, 2, 15, 4, 5, 0, time.UTC)
blockDependencies := blockchain.BlockDependencies{
// use the custom clock function to get the same blocks
Clock: func() time.Time {
timestamp = timestamp.Add(time.Hour)
return timestamp
},
Proofer: proofers.ProofOfWork{
TargetBit: 248,
},
}
blockchainInstance, err := blockchain.NewBlockchainEx(
context.Background(),
blockchain.NewBlockchainExParams{
Dependencies: blockchain.Dependencies{
BlockDependencies: blockDependencies,
Storage: storing.NewGroupStorage(&storages.MemoryStorage{}),
},
GenesisBlockData: mo.Some(blockchain.NewData("genesis block")),
},
)
if err != nil {
log.Fatalf("unable to create a new blockchain: %v", err)
}
const blockCount = 5
for i := 0; i < blockCount; i++ {
if err := blockchainInstance.AddBlockEx(
context.Background(),
blockchain.NewData(fmt.Sprintf("block #%d", i)),
); err != nil {
log.Fatalf("unable to add a new block: %v", err)
}
}
addedBlocks, _, _ := blockchainInstance.LoadBlocks(nil, blockCount+1)
blocksBytes, _ := json.MarshalIndent(addedBlocks, "", " ")
fmt.Println(string(blocksBytes))
Output: [ { "Timestamp": "2006-01-02T21:04:05Z", "Data": "block #4", "Hash": "248:173:00b6863763acd6ec77ca3521589d8e68c118efe855657d702783e8e6aee169a9", "PrevHash": "248:65:00d5800e119abe44d89469c2161be7f9645d7237697c6d14b4a72717893582fa" }, { "Timestamp": "2006-01-02T20:04:05Z", "Data": "block #3", "Hash": "248:65:00d5800e119abe44d89469c2161be7f9645d7237697c6d14b4a72717893582fa", "PrevHash": "248:136:003c7def3d467a759fad481c03cadbd62e62b2c5dbc10e4bbb6e1944c158a8be" }, { "Timestamp": "2006-01-02T19:04:05Z", "Data": "block #2", "Hash": "248:136:003c7def3d467a759fad481c03cadbd62e62b2c5dbc10e4bbb6e1944c158a8be", "PrevHash": "248:15:002fc891ad012c4a89f7b267a2ec1767415c627ff69b88b90a93be938b026efa" }, { "Timestamp": "2006-01-02T18:04:05Z", "Data": "block #1", "Hash": "248:15:002fc891ad012c4a89f7b267a2ec1767415c627ff69b88b90a93be938b026efa", "PrevHash": "248:198:0058f5dae6ca3451801a276c94862c7cce085e6f9371e50d80ddbb87c1438faf" }, { "Timestamp": "2006-01-02T17:04:05Z", "Data": "block #0", "Hash": "248:198:0058f5dae6ca3451801a276c94862c7cce085e6f9371e50d80ddbb87c1438faf", "PrevHash": "248:225:00e26abd9974fcdea4b32eca43c9dc5c67fffa8efd53cebffa9b049fd6c2bb36" }, { "Timestamp": "2006-01-02T16:04:05Z", "Data": "genesis block", "Hash": "248:225:00e26abd9974fcdea4b32eca43c9dc5c67fffa8efd53cebffa9b049fd6c2bb36", "PrevHash": "" } ]
func NewBlockchain
deprecated
func NewBlockchain( genesisBlockData Data, dependencies Dependencies, ) (*Blockchain, error)
NewBlockchain ...
Deprecated: Use NewBlockchainEx instead.
func NewBlockchainEx ¶ added in v1.4.1
func NewBlockchainEx( ctx context.Context, params NewBlockchainExParams, ) (*Blockchain, error)
NewBlockchainEx ...
func (*Blockchain) AddBlock
deprecated
func (blockchain *Blockchain) AddBlock(data Data) error
AddBlock ...
Deprecated: Use [AddBlockEx] instead.
func (*Blockchain) AddBlockEx ¶ added in v1.4.1
func (blockchain *Blockchain) AddBlockEx(ctx context.Context, data Data) error
AddBlockEx ...
func (Blockchain) LoadBlocks ¶ added in v1.3.2
func (blockchain Blockchain) LoadBlocks(cursor interface{}, count int) ( blocks BlockGroup, nextCursor interface{}, err error, )
LoadBlocks ...
func (*Blockchain) Merge ¶ added in v1.4.0
func (blockchain *Blockchain) Merge(loader Loader, chunkSize int) error
Merge ...
Example ¶
blockDependencies := blockchain.BlockDependencies{
Clock: time.Now,
Proofer: proofers.ProofOfWork{
TargetBit: 248,
},
}
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:" +
"57:" +
"02988cf0f90c7771e726245c71416c6c376a2a473e90f3d0a7ba9787af421b34",
PrevHash: "250:" +
"7:" +
"031d530789698389a084fd7a32e4b315d59fb0791a7b22ac4dce90be5a030eb5",
},
{
Timestamp: timestamp.Add(2*time.Hour + 20*time.Minute),
Data: blockchain.NewData("block #1.1"),
Hash: "250:" +
"7:" +
"031d530789698389a084fd7a32e4b315d59fb0791a7b22ac4dce90be5a030eb5",
PrevHash: "240:" +
"25578:" +
"0000d382b7d47324d79ba6178449f9ebbd08a20412c2fa548a32f6ad217f6ce9",
},
{
Timestamp: timestamp.Add(time.Hour),
Data: blockchain.NewData("block #0"),
Hash: "240:" +
"25578:" +
"0000d382b7d47324d79ba6178449f9ebbd08a20412c2fa548a32f6ad217f6ce9",
PrevHash: "240:" +
"73021:" +
"00004a15cf538f5e4d3592c68ee4ac6dd3d3b99d7fa5effcd75fe07c58eb213e",
},
{
Timestamp: timestamp,
Data: blockchain.NewData("genesis block"),
Hash: "240:" +
"73021:" +
"00004a15cf538f5e4d3592c68ee4ac6dd3d3b99d7fa5effcd75fe07c58eb213e",
PrevHash: "",
},
}
blockchainInstanceOne, err := blockchain.NewBlockchainEx(
context.Background(),
blockchain.NewBlockchainExParams{
Dependencies: blockchain.Dependencies{
BlockDependencies: blockDependencies,
Storage: storing.NewGroupStorage(
storages.NewMemoryStorage(blockGroupOne),
),
},
GenesisBlockData: mo.None[blockchain.Data](),
},
)
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: "240:" +
"885:" +
"0000afa95e15291e5d6e7b5454292841114904f4d4b81c8187e838b7fe7d7b25",
PrevHash: "240:" +
"25578:" +
"0000d382b7d47324d79ba6178449f9ebbd08a20412c2fa548a32f6ad217f6ce9",
},
{
Timestamp: timestamp.Add(time.Hour),
Data: blockchain.NewData("block #0"),
Hash: "240:" +
"25578:" +
"0000d382b7d47324d79ba6178449f9ebbd08a20412c2fa548a32f6ad217f6ce9",
PrevHash: "240:" +
"73021:" +
"00004a15cf538f5e4d3592c68ee4ac6dd3d3b99d7fa5effcd75fe07c58eb213e",
},
{
Timestamp: timestamp,
Data: blockchain.NewData("genesis block"),
Hash: "240:" +
"73021:" +
"00004a15cf538f5e4d3592c68ee4ac6dd3d3b99d7fa5effcd75fe07c58eb213e",
PrevHash: "",
},
}
blockchainInstanceTwo, err := blockchain.NewBlockchainEx(
context.Background(),
blockchain.NewBlockchainExParams{
Dependencies: blockchain.Dependencies{
BlockDependencies: blockDependencies,
Storage: storing.NewGroupStorage(
storages.NewMemoryStorage(blockGroupTwo),
),
},
GenesisBlockData: mo.None[blockchain.Data](),
},
)
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": "240:885:0000afa95e15291e5d6e7b5454292841114904f4d4b81c8187e838b7fe7d7b25", "PrevHash": "240:25578:0000d382b7d47324d79ba6178449f9ebbd08a20412c2fa548a32f6ad217f6ce9" }, { "Timestamp": "2006-01-02T16:04:05Z", "Data": "block #0", "Hash": "240:25578:0000d382b7d47324d79ba6178449f9ebbd08a20412c2fa548a32f6ad217f6ce9", "PrevHash": "240:73021:00004a15cf538f5e4d3592c68ee4ac6dd3d3b99d7fa5effcd75fe07c58eb213e" }, { "Timestamp": "2006-01-02T15:04:05Z", "Data": "genesis block", "Hash": "240:73021:00004a15cf538f5e4d3592c68ee4ac6dd3d3b99d7fa5effcd75fe07c58eb213e", "PrevHash": "" } ]
type DataComparer ¶ added in v1.4.0
DataComparer ...
type Dependencies ¶
type Dependencies struct {
BlockDependencies
Storage GroupStorage
}
Dependencies ...
type GroupStorage ¶
type GroupStorage interface {
Storage
StoreBlockGroup(blocks BlockGroup) error
DeleteBlockGroup(blocks BlockGroup) error
}
GroupStorage ...
type Loader ¶
type Loader interface {
LoadBlocks(cursor interface{}, count int) (
blocks BlockGroup,
nextCursor interface{},
err error,
)
}
Loader ...
type NewBlockExParams ¶ added in v1.4.1
type NewBlockExParams struct {
Dependencies BlockDependencies
Data Data
PrevBlock mo.Option[Block]
}
NewBlockExParams ...
type NewBlockchainExParams ¶ added in v1.4.1
type NewBlockchainExParams struct {
Dependencies Dependencies
GenesisBlockData mo.Option[Data]
}
NewBlockchainExParams ...
type NewGenesisBlockExParams ¶ added in v1.4.1
type NewGenesisBlockExParams struct {
Dependencies BlockDependencies
Data Data
}
NewGenesisBlockExParams ...
type Proofer ¶
type Proofer interface {
Hash(block Block) string
HashEx(ctx context.Context, block Block) (string, error)
Validate(block Block) error
Difficulty(hash string) (int, error)
}
Proofer ...
type Storage ¶
type Storage interface {
Loader
LoadLastBlock() (Block, error)
StoreBlock(block Block) error
DeleteBlock(block Block) error
}
Storage ...
type TextMarshaler ¶ added in v1.4.0
type TextMarshaler interface {
encoding.TextMarshaler
}
TextMarshaler ...
It's used only for mock generating.
type ValidationMode ¶
type ValidationMode int
ValidationMode ...
const ( AsFullBlockchain ValidationMode = iota AsBlockchainChunk )
...