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.

71 lines
1.5 KiB

  1. package address
  2. import "fmt"
  3. import "bytes"
  4. import "encoding/binary"
  5. import "github.com/deroproject/derosuite/crypto"
  6. type Address struct {
  7. Network uint64
  8. SpendingKey []byte
  9. ViewingKey []byte
  10. //TODO add support for integrated address
  11. }
  12. const ChecksumLength = 4
  13. type Checksum [ChecksumLength]byte
  14. func GetChecksum(data ...[]byte) (result Checksum) {
  15. keccak256 := crypto.Keccak256(data...)
  16. copy(result[:], keccak256[:4])
  17. return
  18. }
  19. func (a *Address) Base58() (result string) {
  20. prefix := make([]byte, 9, 9)
  21. n := binary.PutUvarint(prefix, a.Network)
  22. prefix = prefix[:n]
  23. checksum := GetChecksum(prefix, a.SpendingKey, a.ViewingKey)
  24. result = EncodeDeroBase58(prefix, a.SpendingKey, a.ViewingKey, checksum[:])
  25. return
  26. }
  27. func NewAddress(address string) (result *Address, err error) {
  28. raw := DecodeDeroBase58(address)
  29. // donot compare length to support much more user base and be compatible with cryptonote
  30. if len(raw) < 69 { // 1 byte prefix + 32 byte key + 32 byte key + 4 byte checksum
  31. err = fmt.Errorf("Address is the wrong length")
  32. return
  33. }
  34. checksum := GetChecksum(raw[:len(raw)-4])
  35. if bytes.Compare(checksum[:], raw[len(raw)-4:]) != 0 {
  36. err = fmt.Errorf("Checksum does not validate")
  37. return
  38. }
  39. // parse network first
  40. address_prefix, done := binary.Uvarint(raw)
  41. if done <= 0 {
  42. err = fmt.Errorf("Network could not be parsed in address\n")
  43. return
  44. }
  45. raw = raw[done:]
  46. result = &Address{
  47. Network: address_prefix,
  48. SpendingKey: raw[0:32],
  49. ViewingKey: raw[32:64],
  50. }
  51. return
  52. }