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.

141 lines
2.9 KiB

  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) Sign(m []byte) (*core.Signature, error) {
  26. return core.Sign(node.PrivK, m)
  27. }
  28. func (node *Node) SignBlock(block *core.Block) error {
  29. block.CalculateHash()
  30. sig, err := core.Sign(node.PrivK, block.Hash[:])
  31. if err != nil {
  32. return err
  33. }
  34. block.Signature = sig.Bytes()
  35. return nil
  36. }
  37. func (node *Node) AddToPendingTxs(tx core.Tx) {
  38. node.PendingTxs = append(node.PendingTxs, tx)
  39. }
  40. func (node *Node) BlockFromPendingTxs() (*core.Block, error) {
  41. block, err := node.NewBlock(node.PendingTxs)
  42. if err != nil {
  43. return nil, err
  44. }
  45. block.PrevHash = node.Bc.LastBlock.Hash
  46. err = block.CalculatePoW(node.Bc.Difficulty)
  47. if err != nil {
  48. return nil, err
  49. }
  50. err = node.SignBlock(block)
  51. if err != nil {
  52. return nil, err
  53. }
  54. block.CalculateHash()
  55. return block, nil
  56. }
  57. func (node *Node) NewBlock(txs []core.Tx) (*core.Block, error) {
  58. block := &core.Block{
  59. Height: node.Bc.GetHeight() + 1,
  60. PrevHash: node.Bc.LastBlock.Hash,
  61. Txs: txs,
  62. Miner: core.Address{},
  63. MinerPubK: &node.PrivK.PublicKey,
  64. Timestamp: time.Now(),
  65. Nonce: 0,
  66. Hash: core.Hash{},
  67. Signature: []byte{},
  68. }
  69. block.CalculateHash()
  70. err := node.SignBlock(block)
  71. if err != nil {
  72. return nil, err
  73. }
  74. return block, nil
  75. }
  76. func (node *Node) CreateGenesis(pubK *ecdsa.PublicKey, amount uint64) (*core.Block, error) {
  77. // pubK is the wallet where the first coins will be created
  78. // amount is the amount of coins that will be created
  79. in := core.Input{
  80. TxId: core.GenesisHashTxInput,
  81. Vout: 0,
  82. Value: amount,
  83. }
  84. var ins []core.Input
  85. ins = append(ins, in)
  86. out := core.Output{
  87. Value: amount,
  88. }
  89. var outs []core.Output
  90. outs = append(outs, out)
  91. tx := core.Tx{
  92. From: &ecdsa.PublicKey{},
  93. To: pubK,
  94. InputCount: uint64(0),
  95. Inputs: []core.Input{},
  96. Outputs: outs,
  97. Signature: []byte{},
  98. }
  99. // calculate TxId
  100. // tx.CalculateTxId()
  101. tx.TxId = core.GenesisHashTxInput
  102. // sign transaction
  103. var txs []core.Tx
  104. txs = append(txs, tx)
  105. block := &core.Block{
  106. Height: node.Bc.LastBlock.Height + 1,
  107. PrevHash: node.Bc.LastBlock.Hash,
  108. Txs: txs,
  109. Miner: node.Addr,
  110. MinerPubK: &node.PrivK.PublicKey,
  111. Timestamp: time.Now(),
  112. Nonce: uint64(0),
  113. Hash: core.Hash{},
  114. Signature: []byte{},
  115. }
  116. block.CalculateHash()
  117. err := node.SignBlock(block)
  118. if err != nil {
  119. return nil, err
  120. }
  121. return block, nil
  122. }