You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
2.9 KiB

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