OSDN Git Service

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