arnaucube
arnaucube/slowlorisdbPublic Self-hosted repository
slowlorisdb/node/node.go
node/node.goRaw
  1package node
  2
  3import (
  4	"crypto/ecdsa"
  5	"time"
  6
  7	"github.com/arnaucube/slowlorisdb/core"
  8)
  9
 10type Node struct {
 11	PrivK      *ecdsa.PrivateKey
 12	Addr       core.Address
 13	Bc         *core.Blockchain
 14	Miner      bool // indicates if the node is running as a miner
 15	PendingTxs []core.Tx
 16}
 17
 18func NewNode(privK *ecdsa.PrivateKey, bc *core.Blockchain, isMiner bool) (*Node, error) {
 19	addr := core.AddressFromPrivK(privK)
 20
 21	node := &Node{
 22		PrivK:      privK,
 23		Addr:       addr,
 24		Bc:         bc,
 25		Miner:      isMiner,
 26		PendingTxs: []core.Tx{},
 27	}
 28	return node, nil
 29}
 30
 31func (node *Node) Sign(m []byte) (*core.Signature, error) {
 32	return core.Sign(node.PrivK, m)
 33}
 34
 35func (node *Node) SignBlock(block *core.Block) error {
 36	block.CalculateHash()
 37	sig, err := core.Sign(node.PrivK, block.Hash[:])
 38	if err != nil {
 39		return err
 40	}
 41	block.Signature = sig.Bytes()
 42	return nil
 43}
 44
 45func (node *Node) AddToPendingTxs(tx core.Tx) {
 46	node.PendingTxs = append(node.PendingTxs, tx)
 47}
 48
 49func (node *Node) BlockFromPendingTxs() (*core.Block, error) {
 50	block, err := node.NewBlock(node.PendingTxs)
 51	if err != nil {
 52		return nil, err
 53	}
 54	block.PrevHash = node.Bc.LastBlock.Hash
 55	err = block.CalculatePoW(node.Bc.Difficulty)
 56	if err != nil {
 57		return nil, err
 58	}
 59	err = node.SignBlock(block)
 60	if err != nil {
 61		return nil, err
 62	}
 63	block.CalculateHash()
 64
 65	return block, nil
 66}
 67
 68func (node *Node) NewBlock(txs []core.Tx) (*core.Block, error) {
 69	block := &core.Block{
 70		Height:    node.Bc.GetHeight() + 1,
 71		PrevHash:  node.Bc.LastBlock.Hash,
 72		Txs:       txs,
 73		Miner:     core.Address{},
 74		MinerPubK: &node.PrivK.PublicKey,
 75		Timestamp: time.Now(),
 76		Nonce:     0,
 77		Hash:      core.Hash{},
 78		Signature: []byte{},
 79	}
 80	block.CalculateHash()
 81	err := node.SignBlock(block)
 82	if err != nil {
 83		return nil, err
 84	}
 85	return block, nil
 86}
 87
 88func (node *Node) CreateGenesis(pubK *ecdsa.PublicKey, amount uint64) (*core.Block, error) {
 89	// pubK is the wallet where the first coins will be created
 90	// amount is the amount of coins that will be created
 91
 92	in := core.Input{
 93		TxId:  core.GenesisHashTxInput,
 94		Vout:  0,
 95		Value: amount,
 96	}
 97	var ins []core.Input
 98	ins = append(ins, in)
 99
100	out := core.Output{
101		Value: amount,
102	}
103	var outs []core.Output
104	outs = append(outs, out)
105
106	tx := core.Tx{
107		From:       &ecdsa.PublicKey{},
108		To:         pubK,
109		InputCount: uint64(0),
110		Inputs:     []core.Input{},
111		Outputs:    outs,
112		Signature:  []byte{},
113	}
114
115	// calculate TxId
116	// tx.CalculateTxId()
117	tx.TxId = core.GenesisHashTxInput
118	// sign transaction
119
120	var txs []core.Tx
121	txs = append(txs, tx)
122
123	block := &core.Block{
124		Height:    node.Bc.LastBlock.Height + 1,
125		PrevHash:  node.Bc.LastBlock.Hash,
126		Txs:       txs,
127		Miner:     node.Addr,
128		MinerPubK: &node.PrivK.PublicKey,
129		Timestamp: time.Now(),
130		Nonce:     uint64(0),
131		Hash:      core.Hash{},
132		Signature: []byte{},
133	}
134
135	block.CalculateHash()
136	err := node.SignBlock(block)
137	if err != nil {
138		return nil, err
139	}
140	return block, nil
141}