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.

79 lines
1.4 KiB

  1. package core
  2. import (
  3. "crypto/ecdsa"
  4. "encoding/json"
  5. log "github.com/sirupsen/logrus"
  6. )
  7. var GenesisHashTxInput = HashBytes([]byte("genesis"))
  8. type Input struct {
  9. TxId Hash
  10. Vout int // index of the output from the TxId
  11. Value uint64
  12. }
  13. type Output struct {
  14. Value uint64
  15. }
  16. // Tx holds the data structure of a transaction
  17. type Tx struct {
  18. TxId Hash
  19. From *ecdsa.PublicKey
  20. To *ecdsa.PublicKey
  21. InputCount uint64
  22. Inputs []Input
  23. Outputs []Output
  24. Signature []byte
  25. }
  26. func (tx *Tx) Bytes() []byte {
  27. // TODO add parser, to use minimum amount of bytes
  28. b, _ := json.Marshal(tx)
  29. return b
  30. }
  31. func (tx *Tx) CalculateTxId() {
  32. h := HashBytes(tx.Bytes())
  33. tx.TxId = h
  34. }
  35. func NewTx(from, to *ecdsa.PublicKey, in []Input, out []Output) *Tx {
  36. tx := &Tx{
  37. From: from,
  38. To: to,
  39. InputCount: uint64(len(in)),
  40. Inputs: in,
  41. Outputs: out,
  42. Signature: []byte{},
  43. }
  44. tx.CalculateTxId()
  45. return tx
  46. }
  47. // CheckTx checks if the transaction is consistent
  48. func CheckTx(tx *Tx) bool {
  49. // check that inputs == outputs
  50. totalIn := 0
  51. for _, in := range tx.Inputs {
  52. // check that inputs are not empty, to avoid spam tx
  53. if in.Value == uint64(0) {
  54. return false
  55. }
  56. totalIn = totalIn + int(in.Value)
  57. }
  58. totalOut := 0
  59. for _, out := range tx.Outputs {
  60. totalOut = totalOut + int(out.Value)
  61. }
  62. if totalIn != totalOut {
  63. log.Info("totalIn != totalOut")
  64. return false
  65. }
  66. // TODO check signature
  67. return true
  68. }