OSDN Git Service

modify general config (#257)
[bytom/vapor.git] / common / address.go
1 package common
2
3 import (
4         "bytes"
5         "errors"
6         "fmt"
7         "strings"
8
9         "github.com/vapor/common/bech32"
10         "github.com/vapor/consensus"
11 )
12
13 var (
14         // ErrChecksumMismatch describes an error where decoding failed due
15         // to a bad checksum.
16         ErrChecksumMismatch = errors.New("checksum mismatch")
17
18         // ErrUnknownAddressType describes an error where an address can not
19         // decoded as a specific address type due to the string encoding
20         // begining with an identifier byte unknown to any standard or
21         // registered (via chaincfg.Register) network.
22         ErrUnknownAddressType = errors.New("unknown address type")
23
24         // ErrAddressCollision describes an error where an address can not
25         // be uniquely determined as either a pay-to-pubkey-hash or
26         // pay-to-script-hash address since the leading identifier is used for
27         // describing both address kinds, but for different networks.  Rather
28         // than assuming or defaulting to one or the other, this error is
29         // returned and the caller must decide how to decode the address.
30         ErrAddressCollision = errors.New("address collision")
31
32         // ErrUnsupportedWitnessVer describes an error where a segwit address being
33         // decoded has an unsupported witness version.
34         ErrUnsupportedWitnessVer = errors.New("unsupported witness version")
35
36         // ErrUnsupportedWitnessProgLen describes an error where a segwit address
37         // being decoded has an unsupported witness program length.
38         ErrUnsupportedWitnessProgLen = errors.New("unsupported witness program length")
39 )
40
41 // Address is an interface type for any type of destination a transaction
42 // output may spend to.  This includes pay-to-pubkey (P2PK), pay-to-pubkey-hash
43 // (P2PKH), and pay-to-script-hash (P2SH).  Address is designed to be generic
44 // enough that other kinds of addresses may be added in the future without
45 // changing the decoding and encoding API.
46 type Address interface {
47         // String returns the string encoding of the transaction output
48         // destination.
49         //
50         // Please note that String differs subtly from EncodeAddress: String
51         // will return the value as a string without any conversion, while
52         // EncodeAddress may convert destination types (for example,
53         // converting pubkeys to P2PKH addresses) before encoding as a
54         // payment address string.
55         String() string
56
57         // EncodeAddress returns the string encoding of the payment address
58         // associated with the Address value.  See the comment on String
59         // for how this method differs from String.
60         EncodeAddress() string
61
62         // ScriptAddress returns the raw bytes of the address to be used
63         // when inserting the address into a txout's script.
64         ScriptAddress() []byte
65
66         // IsForNet returns whether or not the address is associated with the
67         // passed bytom network.
68         IsForNet(*consensus.Params) bool
69 }
70
71 // encodeSegWitAddress creates a bech32 encoded address string representation
72 // from witness version and witness program.
73 func encodeSegWitAddress(hrp string, witnessVersion byte, witnessProgram []byte) (string, error) {
74         // Group the address bytes into 5 bit groups, as this is what is used to
75         // encode each character in the address string.
76         converted, err := bech32.ConvertBits(witnessProgram, 8, 5, true)
77         if err != nil {
78                 return "", err
79         }
80
81         // Concatenate the witness version and program, and encode the resulting
82         // bytes using bech32 encoding.
83         combined := make([]byte, len(converted)+1)
84         combined[0] = witnessVersion
85         copy(combined[1:], converted)
86         bech, err := bech32.Bech32Encode(hrp, combined)
87         if err != nil {
88                 return "", err
89         }
90
91         // Check validity by decoding the created address.
92         version, program, err := decodeSegWitAddress(bech)
93         if err != nil {
94                 return "", fmt.Errorf("invalid segwit address: %v", err)
95         }
96
97         if version != witnessVersion || !bytes.Equal(program, witnessProgram) {
98                 return "", fmt.Errorf("invalid segwit address")
99         }
100
101         return bech, nil
102 }
103
104 // DecodeAddress decodes the string encoding of an address and returns
105 // the Address if addr is a valid encoding for a known address type.
106 //
107 // The bytom network the address is associated with is extracted if possible.
108 // When the address does not encode the network, such as in the case of a raw
109 // public key, the address will be associated with the passed defaultNet.
110 func DecodeAddress(addr string, param *consensus.Params) (Address, error) {
111         // Bech32 encoded segwit addresses start with a human-readable part
112         // (hrp) followed by '1'. For Bytom mainnet the hrp is "bm", and for
113         // testnet it is "tm". If the address string has a prefix that matches
114         // one of the prefixes for the known networks, we try to decode it as
115         // a segwit address.
116         oneIndex := strings.LastIndexByte(addr, '1')
117         if oneIndex > 1 {
118                 prefix := addr[:oneIndex+1]
119                 if IsBech32SegwitPrefix(prefix, param) {
120                         witnessVer, witnessProg, err := decodeSegWitAddress(addr)
121                         if err != nil {
122                                 return nil, err
123                         }
124
125                         // We currently only support P2WPKH and P2WSH, which is
126                         // witness version 0.
127                         if witnessVer != 0 {
128                                 return nil, ErrUnsupportedWitnessVer
129                         }
130
131                         // The HRP is everything before the found '1'.
132                         hrp := prefix[:len(prefix)-1]
133
134                         switch len(witnessProg) {
135                         case 20:
136                                 return newAddressWitnessPubKeyHash(hrp, witnessProg)
137                         case 32:
138                                 return newAddressWitnessScriptHash(hrp, witnessProg)
139                         default:
140                                 return nil, ErrUnsupportedWitnessProgLen
141                         }
142                 }
143         }
144         return nil, ErrUnknownAddressType
145 }
146
147 // IsBech32SegwitPrefix returns whether the prefix is a known prefix for segwit
148 // addresses on any default or registered network.  This is used when decoding
149 // an address string into a specific address type.
150 func IsBech32SegwitPrefix(prefix string, params *consensus.Params) bool {
151         return strings.ToLower(prefix) == params.Bech32HRPSegwit+"1"
152 }
153
154 // decodeSegWitAddress parses a bech32 encoded segwit address string and
155 // returns the witness version and witness program byte representation.
156 func decodeSegWitAddress(address string) (byte, []byte, error) {
157         // Decode the bech32 encoded address.
158         _, data, err := bech32.Bech32Decode(address)
159         if err != nil {
160                 return 0, nil, err
161         }
162
163         // The first byte of the decoded address is the witness version, it must
164         // exist.
165         if len(data) < 1 {
166                 return 0, nil, fmt.Errorf("no witness version")
167         }
168
169         // ...and be <= 16.
170         version := data[0]
171         if version > 16 {
172                 return 0, nil, fmt.Errorf("invalid witness version: %v", version)
173         }
174
175         // The remaining characters of the address returned are grouped into
176         // words of 5 bits. In order to restore the original witness program
177         // bytes, we'll need to regroup into 8 bit words.
178         regrouped, err := bech32.ConvertBits(data[1:], 5, 8, false)
179         if err != nil {
180                 return 0, nil, err
181         }
182
183         // The regrouped data must be between 2 and 40 bytes.
184         if len(regrouped) < 2 || len(regrouped) > 40 {
185                 return 0, nil, fmt.Errorf("invalid data length")
186         }
187
188         // For witness version 0, address MUST be exactly 20 or 32 bytes.
189         if version == 0 && len(regrouped) != 20 && len(regrouped) != 32 {
190                 return 0, nil, fmt.Errorf("invalid data length for witness "+
191                         "version 0: %v", len(regrouped))
192         }
193
194         return version, regrouped, nil
195 }
196
197 // AddressWitnessPubKeyHash is an Address for a pay-to-witness-pubkey-hash
198 // (P2WPKH) output. See BIP 173 for further details regarding native segregated
199 // witness address encoding:
200 // https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
201 type AddressWitnessPubKeyHash struct {
202         hrp            string
203         witnessVersion byte
204         witnessProgram [20]byte
205 }
206
207 // NewAddressWitnessPubKeyHash returns a new AddressWitnessPubKeyHash.
208 func NewAddressWitnessPubKeyHash(witnessProg []byte, param *consensus.Params) (*AddressWitnessPubKeyHash, error) {
209         return newAddressWitnessPubKeyHash(param.Bech32HRPSegwit, witnessProg)
210 }
211
212 // newAddressWitnessPubKeyHash is an internal helper function to create an
213 // AddressWitnessPubKeyHash with a known human-readable part, rather than
214 // looking it up through its parameters.
215 func newAddressWitnessPubKeyHash(hrp string, witnessProg []byte) (*AddressWitnessPubKeyHash, error) {
216         // Check for valid program length for witness version 0, which is 20
217         // for P2WPKH.
218         if len(witnessProg) != 20 {
219                 return nil, errors.New("witness program must be 20 bytes for p2wpkh")
220         }
221
222         addr := &AddressWitnessPubKeyHash{
223                 hrp:            strings.ToLower(hrp),
224                 witnessVersion: 0x00,
225         }
226
227         copy(addr.witnessProgram[:], witnessProg)
228
229         return addr, nil
230 }
231
232 // EncodeAddress returns the bech32 string encoding of an
233 // AddressWitnessPubKeyHash.
234 // Part of the Address interface.
235 func (a *AddressWitnessPubKeyHash) EncodeAddress() string {
236         str, err := encodeSegWitAddress(a.hrp, a.witnessVersion,
237                 a.witnessProgram[:])
238         if err != nil {
239                 return ""
240         }
241         return str
242 }
243
244 // ScriptAddress returns the witness program for this address.
245 // Part of the Address interface.
246 func (a *AddressWitnessPubKeyHash) ScriptAddress() []byte {
247         return a.witnessProgram[:]
248 }
249
250 // IsForNet returns whether or not the AddressWitnessPubKeyHash is associated
251 // with the passed bitcoin network.
252 // Part of the Address interface.
253 func (a *AddressWitnessPubKeyHash) IsForNet(param *consensus.Params) bool {
254         return a.hrp == param.Bech32HRPSegwit
255 }
256
257 // String returns a human-readable string for the AddressWitnessPubKeyHash.
258 // This is equivalent to calling EncodeAddress, but is provided so the type
259 // can be used as a fmt.Stringer.
260 // Part of the Address interface.
261 func (a *AddressWitnessPubKeyHash) String() string {
262         return a.EncodeAddress()
263 }
264
265 // Hrp returns the human-readable part of the bech32 encoded
266 // AddressWitnessPubKeyHash.
267 func (a *AddressWitnessPubKeyHash) Hrp() string {
268         return a.hrp
269 }
270
271 // WitnessVersion returns the witness version of the AddressWitnessPubKeyHash.
272 func (a *AddressWitnessPubKeyHash) WitnessVersion() byte {
273         return a.witnessVersion
274 }
275
276 // WitnessProgram returns the witness program of the AddressWitnessPubKeyHash.
277 func (a *AddressWitnessPubKeyHash) WitnessProgram() []byte {
278         return a.witnessProgram[:]
279 }
280
281 // Hash160 returns the witness program of the AddressWitnessPubKeyHash as a
282 // byte array.
283 func (a *AddressWitnessPubKeyHash) Hash160() *[20]byte {
284         return &a.witnessProgram
285 }
286
287 // AddressWitnessScriptHash is an Address for a pay-to-witness-script-hash
288 // (P2WSH) output. See BIP 173 for further details regarding native segregated
289 // witness address encoding:
290 // https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
291 type AddressWitnessScriptHash struct {
292         hrp            string
293         witnessVersion byte
294         witnessProgram [32]byte
295 }
296
297 // NewAddressWitnessScriptHash returns a new AddressWitnessPubKeyHash.
298 func NewAddressWitnessScriptHash(witnessProg []byte, param *consensus.Params) (*AddressWitnessScriptHash, error) {
299         return newAddressWitnessScriptHash(param.Bech32HRPSegwit, witnessProg)
300 }
301
302 // newAddressWitnessScriptHash is an internal helper function to create an
303 // AddressWitnessScriptHash with a known human-readable part, rather than
304 // looking it up through its parameters.
305 func newAddressWitnessScriptHash(hrp string, witnessProg []byte) (*AddressWitnessScriptHash, error) {
306         // Check for valid program length for witness version 0, which is 32
307         // for P2WSH.
308         if len(witnessProg) != 32 {
309                 return nil, errors.New("witness program must be 32 bytes for p2wsh")
310         }
311
312         addr := &AddressWitnessScriptHash{
313                 hrp:            strings.ToLower(hrp),
314                 witnessVersion: 0x00,
315         }
316
317         copy(addr.witnessProgram[:], witnessProg)
318
319         return addr, nil
320 }
321
322 // EncodeAddress returns the bech32 string encoding of an
323 // AddressWitnessScriptHash.
324 // Part of the Address interface.
325 func (a *AddressWitnessScriptHash) EncodeAddress() string {
326         str, err := encodeSegWitAddress(a.hrp, a.witnessVersion,
327                 a.witnessProgram[:])
328         if err != nil {
329                 return ""
330         }
331         return str
332 }
333
334 // ScriptAddress returns the witness program for this address.
335 // Part of the Address interface.
336 func (a *AddressWitnessScriptHash) ScriptAddress() []byte {
337         return a.witnessProgram[:]
338 }
339
340 // IsForNet returns whether or not the AddressWitnessScriptHash is associated
341 // with the passed bytom network.
342 // Part of the Address interface.
343 func (a *AddressWitnessScriptHash) IsForNet(param *consensus.Params) bool {
344         return a.hrp == param.Bech32HRPSegwit
345 }
346
347 // String returns a human-readable string for the AddressWitnessScriptHash.
348 // This is equivalent to calling EncodeAddress, but is provided so the type
349 // can be used as a fmt.Stringer.
350 // Part of the Address interface.
351 func (a *AddressWitnessScriptHash) String() string {
352         return a.EncodeAddress()
353 }
354
355 // Hrp returns the human-readable part of the bech32 encoded
356 // AddressWitnessScriptHash.
357 func (a *AddressWitnessScriptHash) Hrp() string {
358         return a.hrp
359 }
360
361 // WitnessVersion returns the witness version of the AddressWitnessScriptHash.
362 func (a *AddressWitnessScriptHash) WitnessVersion() byte {
363         return a.witnessVersion
364 }
365
366 // WitnessProgram returns the witness program of the AddressWitnessScriptHash.
367 func (a *AddressWitnessScriptHash) WitnessProgram() []byte {
368         return a.witnessProgram[:]
369 }
370
371 // Sha256 returns the witness program of the AddressWitnessPubKeyHash as a
372 // byte array.
373 func (a *AddressWitnessScriptHash) Sha256() *[32]byte {
374         return &a.witnessProgram
375 }