-
Notifications
You must be signed in to change notification settings - Fork 0
/
commontypes.go
203 lines (142 loc) · 4.83 KB
/
commontypes.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
package common
import (
"bytes"
"crypto/ecdsa"
"crypto/elliptic"
"encoding/hex"
"encoding/json"
"errors"
"github.com/SummerCash/go-summercash/crypto"
)
// Address - []byte wrapper for addresses
type Address [AddressLength]byte
// Hash - []byte wrapper for hashes
type Hash [HashLength]byte
// AddressSpace - given address-space (e.g. 0x000-0x123)
type AddressSpace struct {
Addresses []Address `json:"addresses"` // Addresses in address space
ID Hash `json:"ID"` // AddressSpace identifier
}
var (
// ErrDuplicateAddress - error definition describing two addresses of equal value
ErrDuplicateAddress = errors.New("duplicate address")
)
const (
// AddressLength - max addr length
AddressLength = 20
// HashLength - max hash length
HashLength = 32
)
/* BEGIN EXPORTED METHODS */
/*
BEGIN ADDRESS METHODS
*/
// NewAddress - initialize new address
func NewAddress(privateKey *ecdsa.PrivateKey) (Address, error) {
var address Address // Init buffer
marshaledPublicKey := elliptic.Marshal(privateKey.PublicKey, privateKey.PublicKey.X, privateKey.PublicKey.Y) // Marshal public key
marshaledPublicKey = append([]byte("0x"), marshaledPublicKey...) // Prepend prefix
copy(address[:], marshaledPublicKey) // Copy marshaled
return address, nil // Return public key
}
// PublicKeyToAddress - initialize new address with given public key
func PublicKeyToAddress(publicKey *ecdsa.PublicKey) Address {
var address Address // Init buffer
marshaledPublicKey := elliptic.Marshal(publicKey, publicKey.X, publicKey.Y) // Marshal public key
marshaledPublicKey = append([]byte("0x"), marshaledPublicKey...) // Prepend prefix
copy(address[:], marshaledPublicKey) // Copy marshaled
return address // Return public key
}
// StringToAddress - convert string to address
func StringToAddress(s string) (Address, error) {
var address Address // Init buffer
decoded, err := hex.DecodeString(s[2:]) // Decode string
if err != nil { // Check for errors
return Address{}, err // Return found error
}
copy(address[:], append([]byte("0x"), decoded...)) // Copy decoded
return address, nil // Return address
}
// Bytes - convert given address to bytes
func (address Address) Bytes() []byte {
return address[:] // Return byte val
}
// String - convert given address to string
func (address Address) String() string {
noPrefix := address[2:] // Remove duplicate 0x prefix
enc := make([]byte, len(noPrefix)*2+2) // Init encoder buffer
copy(enc, "0x") // Copy prefix
hex.Encode(enc[2:], noPrefix[:]) // Encode given byte array
return string(enc) // Return string val
}
/*
END ADDRESS METHODS
*/
/*
BEGIN HASH METHODS
*/
// NewHash - initialize hash from byte array
func NewHash(b []byte) Hash {
var hash Hash // Init buffer
if string(crypto.Sha3(b[0:2])) != string(crypto.Sha3(MemPrefix)) { // Check no mem prefix
b = append([]byte("0x"), b...) // Prepend 0x
}
copy(hash[:], b[:HashLength]) // Copy byte val, trim to max hash length
return hash // Return init hash
}
// StringToHash - convert string to hash
func StringToHash(s string) (Hash, error) {
var hash Hash // Init buffer
decoded, err := hex.DecodeString(s[2:]) // Decode string
if err != nil { // Check for errors
return Hash{}, err // Return found error
}
copy(hash[:], decoded) // Copy decoded
return hash, nil // Return hash
}
// Bytes - convert given hash to bytes
func (hash Hash) Bytes() []byte {
return hash[:] // Return bytes representation
}
// String - convert given hash to string
func (hash Hash) String() string {
enc := make([]byte, len(hash)*2+2) // Init encoder buffer
copy(enc, "0x") // Copy prefix
hex.Encode(enc[2:], hash[:]) // Encode given byte array
return string(enc) // Return string val
}
/*
END HASH METHODS
*/
/*
BEGIN ADDRESS-SPACE METHODS
*/
// NewAddressSpace - initialize address space
func NewAddressSpace(originAddresses []Address) (*AddressSpace, error) {
for x, address := range originAddresses { // Iterate through addresses
if x != 0 && address == originAddresses[x-1] { // Check for duplicate
return &AddressSpace{}, ErrDuplicateAddress // Return error
}
}
addressSpace := &AddressSpace{ // Init space
Addresses: originAddresses,
}
hash := crypto.Sha3(addressSpace.Bytes()) // Hash
(*addressSpace).ID = NewHash(hash) // Set ID
return addressSpace, nil // Return initialized
}
// Bytes - convert given address-space to bytes
func (addressSpace *AddressSpace) Bytes() []byte {
buffer := new(bytes.Buffer) // Init buffer
json.NewEncoder(buffer).Encode(*addressSpace) // Serialize space
return buffer.Bytes() // Return serialized
}
// String - convert given address-space to string
func (addressSpace *AddressSpace) String() string {
marshaled, _ := json.MarshalIndent(*addressSpace, "", " ") // Marshal address-space
return string(marshaled) // Return marshaled
}
/*
END ADDRESS-SPACE METHODS
*/
/* END EXPORTED METHODS */