-
Notifications
You must be signed in to change notification settings - Fork 2
/
Blockchain.ts
73 lines (56 loc) · 1.91 KB
/
Blockchain.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import { Block, fromBlockObject, BlockType } from './Block';
import { SigPublicKey, NTRUPublicKey } from './Keys';
import { StorageId } from './Storage';
export enum AssetSymbol {
TXL = 'TXL',
BTC = 'BTC',
}
export class Blockchain {
id: StorageId;
leafId: StorageId | undefined;
publicSig: SigPublicKey;
publicNtru: NTRUPublicKey | undefined;
assetSymbol: AssetSymbol;
blocks: Block[] = [];
constructor(publicSig: SigPublicKey, publicNtru?: NTRUPublicKey, symbol?: AssetSymbol) {
this.publicSig = publicSig;
this.publicNtru = publicNtru;
this.assetSymbol = symbol || AssetSymbol.TXL;
}
addBlock(block: Block): void {
this.blocks.push(block);
}
leaf(): Block | undefined {
const prevs = this.blocks.map(block => block.prev).filter(prev => !!prev);
return this.blocks.find(block => prevs.indexOf(block.signature) === -1);
}
openingBlock(): Block | undefined {
if (!Array.isArray(this.blocks)) {
return;
}
return this.blocks.filter(block => block.type === BlockType.OPENING && !block.prev).pop();
}
}
export function fromBlockchainObject(obj: any) {
const chain = new Blockchain(obj.publicSig, obj.publicNtru, obj.assetSymbol);
chain.blocks = obj.blocks.map(deserializeBlock);
return chain;
}
export function deserializeBlock(block: object): Block {
return fromBlockObject(block);
}
export function isBlockchain(val: any): boolean {
if (!val) return false;
// Ducktyping: maybe extend check with more fields
return Array.isArray(val.blocks);
}
export function isBlockchainRecord(val: any): boolean {
if (!val) return false;
const fields = Object.getOwnPropertyNames(val);
// an empty record is a valid record..
if (fields.length === 0) return true;
// test the first object if it is a blockchain
// if so the val behaves like a Record<string, Blockchain>
const testFirstChain = fields[0];
return isBlockchain(val[testFirstChain]);
}