9 "github.com/bytom/common/bech32"
10 "github.com/bytom/consensus"
14 // ErrChecksumMismatch describes an error where decoding failed due
16 ErrChecksumMismatch = errors.New("checksum mismatch")
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")
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")
32 // ErrUnsupportedWitnessVer describes an error where a segwit address being
33 // decoded has an unsupported witness version.
34 ErrUnsupportedWitnessVer = errors.New("unsupported witness version")
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")
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
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.
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
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
66 // IsForNet returns whether or not the address is associated with the
67 // passed bytom network.
68 IsForNet(*consensus.Params) bool
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)
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)
91 // Check validity by decoding the created address.
92 version, program, err := decodeSegWitAddress(bech)
94 return "", fmt.Errorf("invalid segwit address: %v", err)
97 if version != witnessVersion || !bytes.Equal(program, witnessProgram) {
98 return "", fmt.Errorf("invalid segwit address")
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.
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
116 oneIndex := strings.LastIndexByte(addr, '1')
118 prefix := addr[:oneIndex+1]
119 if consensus.IsBech32SegwitPrefix(prefix, param) {
120 witnessVer, witnessProg, err := decodeSegWitAddress(addr)
125 // We currently only support P2WPKH and P2WSH, which is
126 // witness version 0.
128 return nil, ErrUnsupportedWitnessVer
131 // The HRP is everything before the found '1'.
132 hrp := prefix[:len(prefix)-1]
134 switch len(witnessProg) {
136 return newAddressWitnessPubKeyHash(hrp, witnessProg)
138 return newAddressWitnessScriptHash(hrp, witnessProg)
140 return nil, ErrUnsupportedWitnessProgLen
144 return nil, ErrUnknownAddressType
147 // decodeSegWitAddress parses a bech32 encoded segwit address string and
148 // returns the witness version and witness program byte representation.
149 func decodeSegWitAddress(address string) (byte, []byte, error) {
150 // Decode the bech32 encoded address.
151 _, data, err := bech32.Bech32Decode(address)
156 // The first byte of the decoded address is the witness version, it must
159 return 0, nil, fmt.Errorf("no witness version")
165 return 0, nil, fmt.Errorf("invalid witness version: %v", version)
168 // The remaining characters of the address returned are grouped into
169 // words of 5 bits. In order to restore the original witness program
170 // bytes, we'll need to regroup into 8 bit words.
171 regrouped, err := bech32.ConvertBits(data[1:], 5, 8, false)
176 // The regrouped data must be between 2 and 40 bytes.
177 if len(regrouped) < 2 || len(regrouped) > 40 {
178 return 0, nil, fmt.Errorf("invalid data length")
181 // For witness version 0, address MUST be exactly 20 or 32 bytes.
182 if version == 0 && len(regrouped) != 20 && len(regrouped) != 32 {
183 return 0, nil, fmt.Errorf("invalid data length for witness "+
184 "version 0: %v", len(regrouped))
187 return version, regrouped, nil
190 // AddressWitnessPubKeyHash is an Address for a pay-to-witness-pubkey-hash
191 // (P2WPKH) output. See BIP 173 for further details regarding native segregated
192 // witness address encoding:
193 // https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
194 type AddressWitnessPubKeyHash struct {
197 witnessProgram [20]byte
200 // NewAddressWitnessPubKeyHash returns a new AddressWitnessPubKeyHash.
201 func NewAddressWitnessPubKeyHash(witnessProg []byte, param *consensus.Params) (*AddressWitnessPubKeyHash, error) {
202 return newAddressWitnessPubKeyHash(param.Bech32HRPSegwit, witnessProg)
205 // newAddressWitnessPubKeyHash is an internal helper function to create an
206 // AddressWitnessPubKeyHash with a known human-readable part, rather than
207 // looking it up through its parameters.
208 func newAddressWitnessPubKeyHash(hrp string, witnessProg []byte) (*AddressWitnessPubKeyHash, error) {
209 // Check for valid program length for witness version 0, which is 20
211 if len(witnessProg) != 20 {
212 return nil, errors.New("witness program must be 20 bytes for p2wpkh")
215 addr := &AddressWitnessPubKeyHash{
216 hrp: strings.ToLower(hrp),
217 witnessVersion: 0x00,
220 copy(addr.witnessProgram[:], witnessProg)
225 // EncodeAddress returns the bech32 string encoding of an
226 // AddressWitnessPubKeyHash.
227 // Part of the Address interface.
228 func (a *AddressWitnessPubKeyHash) EncodeAddress() string {
229 str, err := encodeSegWitAddress(a.hrp, a.witnessVersion,
237 // ScriptAddress returns the witness program for this address.
238 // Part of the Address interface.
239 func (a *AddressWitnessPubKeyHash) ScriptAddress() []byte {
240 return a.witnessProgram[:]
243 // IsForNet returns whether or not the AddressWitnessPubKeyHash is associated
244 // with the passed bitcoin network.
245 // Part of the Address interface.
246 func (a *AddressWitnessPubKeyHash) IsForNet(param *consensus.Params) bool {
247 return a.hrp == param.Bech32HRPSegwit
250 // String returns a human-readable string for the AddressWitnessPubKeyHash.
251 // This is equivalent to calling EncodeAddress, but is provided so the type
252 // can be used as a fmt.Stringer.
253 // Part of the Address interface.
254 func (a *AddressWitnessPubKeyHash) String() string {
255 return a.EncodeAddress()
258 // Hrp returns the human-readable part of the bech32 encoded
259 // AddressWitnessPubKeyHash.
260 func (a *AddressWitnessPubKeyHash) Hrp() string {
264 // WitnessVersion returns the witness version of the AddressWitnessPubKeyHash.
265 func (a *AddressWitnessPubKeyHash) WitnessVersion() byte {
266 return a.witnessVersion
269 // WitnessProgram returns the witness program of the AddressWitnessPubKeyHash.
270 func (a *AddressWitnessPubKeyHash) WitnessProgram() []byte {
271 return a.witnessProgram[:]
274 // Hash160 returns the witness program of the AddressWitnessPubKeyHash as a
276 func (a *AddressWitnessPubKeyHash) Hash160() *[20]byte {
277 return &a.witnessProgram
280 // AddressWitnessScriptHash is an Address for a pay-to-witness-script-hash
281 // (P2WSH) output. See BIP 173 for further details regarding native segregated
282 // witness address encoding:
283 // https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
284 type AddressWitnessScriptHash struct {
287 witnessProgram [32]byte
290 // NewAddressWitnessScriptHash returns a new AddressWitnessPubKeyHash.
291 func NewAddressWitnessScriptHash(witnessProg []byte, param *consensus.Params) (*AddressWitnessScriptHash, error) {
292 return newAddressWitnessScriptHash(param.Bech32HRPSegwit, witnessProg)
295 // newAddressWitnessScriptHash is an internal helper function to create an
296 // AddressWitnessScriptHash with a known human-readable part, rather than
297 // looking it up through its parameters.
298 func newAddressWitnessScriptHash(hrp string, witnessProg []byte) (*AddressWitnessScriptHash, error) {
299 // Check for valid program length for witness version 0, which is 32
301 if len(witnessProg) != 32 {
302 return nil, errors.New("witness program must be 32 bytes for p2wsh")
305 addr := &AddressWitnessScriptHash{
306 hrp: strings.ToLower(hrp),
307 witnessVersion: 0x00,
310 copy(addr.witnessProgram[:], witnessProg)
315 // EncodeAddress returns the bech32 string encoding of an
316 // AddressWitnessScriptHash.
317 // Part of the Address interface.
318 func (a *AddressWitnessScriptHash) EncodeAddress() string {
319 str, err := encodeSegWitAddress(a.hrp, a.witnessVersion,
327 // ScriptAddress returns the witness program for this address.
328 // Part of the Address interface.
329 func (a *AddressWitnessScriptHash) ScriptAddress() []byte {
330 return a.witnessProgram[:]
333 // IsForNet returns whether or not the AddressWitnessScriptHash is associated
334 // with the passed bytom network.
335 // Part of the Address interface.
336 func (a *AddressWitnessScriptHash) IsForNet(param *consensus.Params) bool {
337 return a.hrp == param.Bech32HRPSegwit
340 // String returns a human-readable string for the AddressWitnessScriptHash.
341 // This is equivalent to calling EncodeAddress, but is provided so the type
342 // can be used as a fmt.Stringer.
343 // Part of the Address interface.
344 func (a *AddressWitnessScriptHash) String() string {
345 return a.EncodeAddress()
348 // Hrp returns the human-readable part of the bech32 encoded
349 // AddressWitnessScriptHash.
350 func (a *AddressWitnessScriptHash) Hrp() string {
354 // WitnessVersion returns the witness version of the AddressWitnessScriptHash.
355 func (a *AddressWitnessScriptHash) WitnessVersion() byte {
356 return a.witnessVersion
359 // WitnessProgram returns the witness program of the AddressWitnessScriptHash.
360 func (a *AddressWitnessScriptHash) WitnessProgram() []byte {
361 return a.witnessProgram[:]
364 // Sha256 returns the witness program of the AddressWitnessPubKeyHash as a
366 func (a *AddressWitnessScriptHash) Sha256() *[32]byte {
367 return &a.witnessProgram