6f6abef1d6
In this commit, we introduce the concept of scopes for individual key managers. Each scope will lock down a key manager to a particular purpose and coin type within the BIP0043 hierarchy. Each scope will also have a set address type schema. This schema will be consulted when creating addresses for a particular scoped key manager. Finally, we introduce 3 new default scopes: * BIP 44 * BIP 84 * BIP 49++ (BIP49 but uses p2wkh for change addresses)
124 lines
4.2 KiB
Go
124 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,
|
|
},
|
|
}
|
|
)
|
|
|