125 lines
4.2 KiB
Go
125 lines
4.2 KiB
Go
|
package waddrmgr
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"sync"
|
||
|
|
||
|
"github.com/roasbeef/btcd/btcec"
|
||
|
"github.com/roasbeef/btcd/chaincfg"
|
||
|
"github.com/roasbeef/btcutil"
|
||
|
"github.com/roasbeef/btcutil/hdkeychain"
|
||
|
"github.com/roasbeef/btcwallet/internal/zero"
|
||
|
"github.com/roasbeef/btcwallet/walletdb"
|
||
|
)
|
||
|
|
||
|
// DerivationPath represents a derivation path from a particular key manager's
|
||
|
// scope. Each ScopedKeyManager starts key derivation from the end of their
|
||
|
// cointype hardened key: m/purpose'/cointype'. The fields in this struct allow
|
||
|
// further derivation to the next three child levels after the coin type key.
|
||
|
// This restriction is in the spriti of BIP0044 type derivation. We maintain a
|
||
|
// degree of coherency with the standard, but allow arbitrary derivations
|
||
|
// beyond the cointype key. The key derived using this path will be exactly:
|
||
|
// m/purpose'/cointype'/account/branch/index, where purpose' and cointype' are
|
||
|
// bound by the scope of a particular manager.
|
||
|
type DerivationPath struct {
|
||
|
// Account is the account, or the first immediate child from the scoped
|
||
|
// manager's hardened coin type key.
|
||
|
Account uint32
|
||
|
|
||
|
// Branch is the branch to be derived from the account index above. For
|
||
|
// BIP0044-like derivation, this is either 0 (external) or 1
|
||
|
// (internal). However, we allow this value to vary arbitrarily within
|
||
|
// its size range.
|
||
|
Branch uint32
|
||
|
|
||
|
// Index is the final child in the derivation path. This denotes the
|
||
|
// key index within as a child of the account and branch.
|
||
|
Index uint32
|
||
|
}
|
||
|
|
||
|
// KeyScope represents a restricted key scope from the primary root key within
|
||
|
// the HD chain. From the root manager (m/) we can create a nearly arbitrary
|
||
|
// number of ScopedKeyManagers of key derivation path: m/purpose'/cointype'.
|
||
|
// These scoped managers can then me managed indecently, as they house the
|
||
|
// encrypted cointype key and can derive any child keys from there on.
|
||
|
type KeyScope struct {
|
||
|
// Purpose is the purpose of this key scope. This is the first child of
|
||
|
// the master HD key.
|
||
|
Purpose uint32
|
||
|
|
||
|
// Coin is a value that represents the particular coin which is the
|
||
|
// child of the purpose key. With this key, any accounts, or other
|
||
|
// children can be derived at all.
|
||
|
Coin uint32
|
||
|
}
|
||
|
|
||
|
// String returns a human readable version describing the keypath encapsulated
|
||
|
// by the target key scope.
|
||
|
func (k *KeyScope) String() string {
|
||
|
return fmt.Sprintf("m/%v'/%v'", k.Purpose, k.Coin)
|
||
|
}
|
||
|
|
||
|
// ScopeAddrSchema is the address schema of a particular KeyScope. This will be
|
||
|
// persisted within the database, and will be consulted when deriving any keys
|
||
|
// for a particular scope to know how to encode the public keys as addresses.
|
||
|
type ScopeAddrSchema struct {
|
||
|
// ExternalAddrType is the address type for all keys within branch 0.
|
||
|
ExternalAddrType AddressType
|
||
|
|
||
|
// InternalAddrType is the address type for all keys within branch 1
|
||
|
// (change addresses).
|
||
|
InternalAddrType AddressType
|
||
|
}
|
||
|
|
||
|
var (
|
||
|
// KeyScopeBIP0049Plus is the key scope of our modified BIP0049
|
||
|
// derivation. We say this is BIP0049 "plus", as we'll actually use
|
||
|
// p2wkh change all change addresses.
|
||
|
KeyScopeBIP0049Plus = KeyScope{
|
||
|
Purpose: 49,
|
||
|
Coin: 0,
|
||
|
}
|
||
|
|
||
|
// KeyScopeBIP0084 is the key scope for BIP0084 derivation. BIP0084
|
||
|
// will be used to derive all p2wkh addresses.
|
||
|
KeyScopeBIP0084 = KeyScope{
|
||
|
Purpose: 84,
|
||
|
Coin: 0,
|
||
|
}
|
||
|
|
||
|
// KeyScopeBIP0044 is the key scope for BIP0044 derivation. Legacy
|
||
|
// wallets will only be able to use this key scope, and no keys beyond
|
||
|
// it.
|
||
|
KeyScopeBIP0044 = KeyScope{
|
||
|
Purpose: 44,
|
||
|
Coin: 0,
|
||
|
}
|
||
|
|
||
|
// DefaultKeyScopes is the set of default key scopes that will be
|
||
|
// created by the root manager upon initial creation.
|
||
|
DefaultKeyScopes = []KeyScope{
|
||
|
KeyScopeBIP0049Plus,
|
||
|
KeyScopeBIP0084,
|
||
|
KeyScopeBIP0044,
|
||
|
}
|
||
|
|
||
|
// ScopeAddrMap is a map from the default key scopes to the scope
|
||
|
// address schema for each scope type. This will be consulted during
|
||
|
// the initial creation of the root key manager.
|
||
|
ScopeAddrMap = map[KeyScope]ScopeAddrSchema{
|
||
|
KeyScopeBIP0049Plus: {
|
||
|
ExternalAddrType: NestedWitnessPubKey,
|
||
|
InternalAddrType: WitnessPubKey,
|
||
|
},
|
||
|
KeyScopeBIP0084: {
|
||
|
ExternalAddrType: WitnessPubKey,
|
||
|
InternalAddrType: WitnessPubKey,
|
||
|
},
|
||
|
KeyScopeBIP0044: {
|
||
|
InternalAddrType: PubKeyHash,
|
||
|
ExternalAddrType: PubKeyHash,
|
||
|
},
|
||
|
}
|
||
|
)
|
||
|
|