-
Notifications
You must be signed in to change notification settings - Fork 3
/
block.go
85 lines (73 loc) · 1.97 KB
/
block.go
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
74
75
76
77
78
79
80
81
82
83
84
85
package simpleBlockchain
import (
"encoding/binary"
"encoding/json"
"fmt"
"time"
)
var (
coinbasePrevBlock = []byte{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
}
genesisBlockPrevBlock= []byte{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
}
)
type Block struct {
BlockHeader *BlockHeader `json:"blockheader""`
Transactions []*Transaction `json:"transactions"`
}
func (b Block) newHash() []byte {
bh, _ := b.BlockHeader.Serialize()
return ReverseBytes(DoubleSha256(bh))
}
func CreateGenesisBlock(miner string, data string) *Block {
return MiningNewBlock(miner, genesisBlockPrevBlock, GenesisBits,1, []*Transaction{})
}
func MiningNewBlock(miner string, prevBlock []byte, bits []byte, height int, transactions []*Transaction) *Block{
coinbaseTx := CreateCoinBaseTransaction(miner, fmt.Sprintf("mine by %s at height %d",miner, height))
txs := append([]*Transaction{coinbaseTx}, transactions...)
root := CalculateMerkleRoot(txs)
bh := &BlockHeader{
Version: 0,
PrevBlock: prevBlock,
MerkleRoot: root,
TimeStamp: uint32(time.Now().Unix()),
Bits: binary.LittleEndian.Uint32(bits),
Height: height,
}
block := &Block{
BlockHeader: bh,
Transactions: txs,
}
pow := NewProofOfWork(block)
pow.mining()
newBlockHeader:= copyBlockHeader(pow.block.BlockHeader)
pow.block.BlockHeader = &newBlockHeader
return pow.block
}
func (block Block) Serialize() ([]byte,error) {
bblock, err := json.Marshal(block)
if err != nil {
return nil, err
}
return bblock, nil
}
func DeserializeBlock(data []byte) (*Block,error) {
var blk Block
err := json.Unmarshal(data, &blk)
if err != nil {
return nil, err
}
return &blk, nil
}
func (b Block) String() string {
bs, _ := json.MarshalIndent(b,""," ")
return string(bs) + "\n"
}