1 package chaincfg
2 3 import (
4 "strings"
5 6 "github.com/p9c/p9/pkg/chainhash"
7 )
8 9 // String returns the hostname of the DNS seed in human-readable form.
10 func (d DNSSeed) String() string {
11 return d.Host
12 }
13 14 // Register registers the network parameters for a Bitcoin network. This may error with ErrDuplicateNet if the network
15 // is already registered (either due to a previous Register call, or the network being one of the default networks).
16 // Network parameters should be registered into this package by a main package as early as possible. Then, library
17 // packages may lookup networks or network parameters based on inputs and work regardless of the network being standard
18 // or not.
19 func Register(params *Params) (e error) {
20 if _, ok := registeredNets[params.Net]; ok {
21 return ErrDuplicateNet
22 }
23 registeredNets[params.Net] = struct{}{}
24 pubKeyHashAddrIDs[params.PubKeyHashAddrID] = struct{}{}
25 scriptHashAddrIDs[params.ScriptHashAddrID] = struct{}{}
26 hdPrivToPubKeyIDs[params.HDPrivateKeyID] = params.HDPublicKeyID[:]
27 // // A valid Bech32 encoded segwit address always has as prefix the human-readable part for the given net followed by
28 // // '1'.
29 // bech32SegwitPrefixes[params.Bech32HRPSegwit+"1"] = struct{}{}
30 return nil
31 }
32 33 // mustRegister performs the same function as Register except it panics if there is an error. This should only be called
34 // from package init functions.
35 func mustRegister(params *Params) {
36 if e := Register(params); E.Chk(e) {
37 panic("failed to register network: " + e.Error())
38 }
39 }
40 41 // IsPubKeyHashAddrID returns whether the id is an identifier known to prefix a pay-to-pubkey-hash address on any
42 // default or registered network. This is used when decoding an address string into a specific address type. It is up to
43 // the caller to check both this and IsScriptHashAddrID and decide whether an address is a pubkey hash address, script
44 // hash address, neither, or undeterminable (if both return true).
45 func IsPubKeyHashAddrID(id byte) bool {
46 _, ok := pubKeyHashAddrIDs[id]
47 return ok
48 }
49 50 // IsScriptHashAddrID returns whether the id is an identifier known to prefix a pay-to-script-hash address on any
51 // default or registered network. This is used when decoding an address string into a specific address type. It is up to
52 // the caller to check both this and IsPubKeyHashAddrID and decide whether an address is a pubkey hash address, script
53 // hash address, neither, or undeterminable (if both return true).
54 func IsScriptHashAddrID(id byte) bool {
55 _, ok := scriptHashAddrIDs[id]
56 return ok
57 }
58 59 // IsBech32SegwitPrefix returns whether the prefix is a known prefix for segwit addresses on any default or registered
60 // network. This is used when decoding an address string into a specific address type.
61 func IsBech32SegwitPrefix(prefix string) bool {
62 prefix = strings.ToLower(prefix)
63 _, ok := bech32SegwitPrefixes[prefix]
64 return ok
65 }
66 67 // HDPrivateKeyToPublicKeyID accepts a private hierarchical deterministic extended key id and returns the associated
68 // public key id. When the provided id is not registered, the ErrUnknownHDKeyID error will be returned.
69 func HDPrivateKeyToPublicKeyID(id []byte) ([]byte, error) {
70 if len(id) != 4 {
71 return nil, ErrUnknownHDKeyID
72 }
73 var key [4]byte
74 copy(key[:], id)
75 pubBytes, ok := hdPrivToPubKeyIDs[key]
76 if !ok {
77 return nil, ErrUnknownHDKeyID
78 }
79 return pubBytes, nil
80 }
81 82 // newHashFromStr converts the passed big-endian hex string into a chainhash.Hash. It only differs from the one
83 // available in chainhash in that it panics on an error since it will only (and must only) be called with hard-coded,
84 // and therefore known good, hashes.
85 func newHashFromStr(hexStr string) *chainhash.Hash {
86 hash, e := chainhash.NewHashFromStr(hexStr)
87 if e != nil {
88 // Ordinarily I don't like panics in library code since it can take applications down without them having a
89 // chance to recover which is extremely annoying, however an exception is being made in this case because the
90 // only way this can panic is if there is an error in the hard-coded hashes. Thus it will only ever potentially
91 // panic on init and therefore is 100% predictable. loki: Panics are good when the condition should not happen!
92 panic(e)
93 }
94 return hash
95 }
96 func init() {
97 // Register all default networks when the package is initialized.
98 mustRegister(&MainNetParams)
99 mustRegister(&TestNet3Params)
100 mustRegister(&RegressionTestParams)
101 mustRegister(&SimNetParams)
102 }
103