waddrmgr

package
v0.9.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 30, 2019 License: ISC Imports: 20 Imported by: 0

README

waddrmgr

[Build Status] (https://travis-ci.org/btcsuite/btcwallet)

Package waddrmgr provides a secure hierarchical deterministic wallet address manager.

A suite of tests is provided to ensure proper functionality. See test_coverage.txt for the gocov coverage report. Alternatively, if you are running a POSIX OS, you can run the cov_report.sh script for a real-time report. Package waddrmgr is licensed under the liberal ISC license.

Feature Overview

  • BIP0032 hierarchical deterministic keys
  • BIP0043/BIP0044 multi-account hierarchy
  • Strong focus on security:
    • Fully encrypted database including public information such as addresses as well as private information such as private keys and scripts needed to redeem pay-to-script-hash transactions
    • Hardened against memory scraping through the use of actively clearing private material from memory when locked
    • Different crypto keys used for public, private, and script data
    • Ability for different passphrases for public and private data
    • Scrypt-based key derivation
    • NaCl-based secretbox cryptography (XSalsa20 and Poly1305)
  • Scalable design:
    • Multi-tier key design to allow instant password changes regardless of the number of addresses stored
    • Import WIF keys
    • Import pay-to-script-hash scripts for things such as multi-signature transactions
    • Ability to export a watching-only version which does not contain any private key material
    • Programmatically detectable errors, including encapsulation of errors from packages it relies on
    • Address synchronization capabilities
  • Comprehensive test coverage

Documentation

[GoDoc] (http://godoc.org/git.parallelcoin.io/dev/9/walletmain/waddrmgr)

Full go doc style documentation for the project can be viewed online without installing this package by using the GoDoc site here: http://godoc.org/git.parallelcoin.io/dev/9/walletmain/waddrmgr

You can also view the documentation locally once the package is installed with the godoc tool by running godoc -http=":6060" and pointing your browser to http://localhost:6060/pkg/git.parallelcoin.io/dev/9/walletmain/waddrmgr

Installation

$ go get git.parallelcoin.io/dev/9/walletmain/waddrmgr

Package waddrmgr is licensed under the copyfree ISC License.

Documentation

Overview

Package waddrmgr provides a secure hierarchical deterministic wallet address manager.

Overview

One of the fundamental jobs of a wallet is to manage addresses, private keys, and script data associated with them. At a high level, this package provides the facilities to perform this task with a focus on security and also allows recovery through the use of hierarchical deterministic keys (BIP0032) generated from a caller provided seed. The specific structure used is as described in BIP0044. This setup means as long as the user writes the seed down (even better is to use a mnemonic for the seed), all their addresses and private keys can be regenerated from the seed.

There are two master keys which are protected by two independent passphrases. One is intended for public facing data, while the other is intended for private data. The public password can be hardcoded for callers who don't want the additional public data protection or the same password can be used if a single password is desired. These choices provide a usability versus security tradeoff. However, keep in mind that extended hd keys, as called out in BIP0032 need to be handled more carefully than normal EC public keys because they can be used to generate all future addresses. While this is part of what makes them attractive, it also means an attacker getting access to your extended public key for an account will allow them to know all derived addresses you will use and hence reduces privacy. For this reason, it is highly recommended that you do not hard code a password which allows any attacker who gets a copy of your address manager database to access your effectively plain text extended public keys.

Each master key in turn protects the three real encryption keys (called crypto keys) for public, private, and script data. Some examples include payment addresses, extended hd keys, and scripts associated with pay-to-script-hash addresses. This scheme makes changing passphrases more efficient since only the crypto keys need to be re-encrypted versus every single piece of information (which is what is needed for *rekeying*). This results in a fully encrypted database where access to it does not compromise address, key, or script privacy. This differs from the handling by other wallets at the time of this writing in that they divulge your addresses, and worse, some even expose the chain code which can be used by the attacker to know all future addresses that will be used.

The address manager is also hardened against memory scrapers. This is accomplished by typically having the address manager locked meaning no private keys or scripts are in memory. Unlocking the address manager causes the crypto private and script keys to be decrypted and loaded in memory which in turn are used to decrypt private keys and scripts on demand. Relocking the address manager actively zeros all private material from memory. In addition, temp private key material used internally is zeroed as soon as it's used.

Locking and Unlocking

As previously mentioned, this package provide facilities for locking and unlocking the address manager to protect access to private material and remove it from memory when locked. The Lock, Unlock, and IsLocked functions are used for this purpose.

Creating a New Address Manager

A new address manager is created via the Create function. This function accepts a wallet database namespace, passphrases, network, and perhaps most importantly, a cryptographically random seed which is used to generate the master node of the hierarchical deterministic keychain which allows all addresses and private keys to be recovered with only the seed. The GenerateSeed function in the hdkeychain package can be used as a convenient way to create a random seed for use with this function. The address manager is locked immediately upon being created.

Opening an Existing Address Manager

An existing address manager is opened via the Open function. This function accepts an existing wallet database namespace, the public passphrase, and network. The address manager is opened locked as expected since the open function does not take the private passphrase to unlock it.

Closing the Address Manager

The Close method should be called on the address manager when the caller is done with it. While it is not required, it is recommended because it sanely shuts down the database and ensures all private and public key material is purged from memory.

Managed Addresses

Each address returned by the address manager satisifies the ManagedAddress interface as well as either the ManagedPubKeyAddress or ManagedScriptAddress interfaces. These interfaces provide the means to obtain relevant information about the addresses such as their private keys and scripts.

Chained Addresses

Most callers will make use of the chained addresses for normal operations. Internal addresses are intended for internal wallet uses such as change outputs, while external addresses are intended for uses such payment addresses that are shared. The NextInternalAddresses and NextExternalAddresses functions provide the means to acquire one or more of the next addresses that have not already been provided. In addition, the LastInternalAddress and LastExternalAddress functions can be used to get the most recently provided internal and external address, respectively.

Requesting Existing Addresses

In addition to generating new addresses, access to old addresses is often required. Most notably, to sign transactions in order to redeem them. The Address function provides this capability and returns a ManagedAddress.

Importing Addresses

While the recommended approach is to use the chained addresses discussed above because they can be deterministically regenerated to avoid losing funds as long as the user has the master seed, there are many addresses that already exist, and as a result, this package provides the ability to import existing private keys in Wallet Import Format (WIF) and hence the associated public key and address.

Importing Scripts

In order to support pay-to-script-hash transactions, the script must be securely stored as it is needed to redeem the transaction. This can be useful for a variety of scenarios, however the most common use is currently multi-signature transactions.

Syncing

The address manager also supports storing and retrieving a block hash and height which the manager is known to have all addresses synced through. The manager itself does not have any notion of which addresses are synced or not. It only provides the storage as a convenience for the caller.

Network

The address manager must be associated with a given network in order to provide appropriate addresses and reject imported addresses and scripts which don't apply to the associated network.

Errors

All errors returned from this package are of type ManagerError. This allows the caller to programmatically ascertain the specific reasons for failure by examining the ErrorCode field of the type asserted ManagerError. For certain error codes, as documented by the specific error codes, the underlying error will be contained in the Err field.

Bitcoin Improvement Proposals

This package includes concepts outlined by the following BIPs:

BIP0032 (https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
BIP0043 (https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki)
BIP0044 (https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki)

Index

Constants

View Source
const (

	// addresses.
	MaxAccountNum = hdkeychain.HardenedKeyStart - 2 // 2^31 - 2

	// underlying hierarchical deterministic key derivation.
	MaxAddressesPerAccount = hdkeychain.HardenedKeyStart - 1

	// not fit into that model.
	ImportedAddrAccount = MaxAccountNum + 1 // 2^31 - 1

	// ImportedAddrAccountName is the name of the imported account.
	ImportedAddrAccountName = "imported"

	// DefaultAccountNum is the number of the default account.
	DefaultAccountNum = 0

	// branch.
	ExternalBranch uint32 = 0

	// branch.
	InternalBranch uint32 = 1
)
View Source
const (

	// LatestMgrVersion is the most recent manager version.
	LatestMgrVersion = 5
)

Variables

View Source
var (

	// p2wkh change all change addresses.
	KeyScopeBIP0049Plus = KeyScope{
		Purpose: 49,
		Coin:    0,
	}

	// will be used to derive all p2wkh addresses.
	KeyScopeBIP0084 = KeyScope{
		Purpose: 84,
		Coin:    0,
	}

	// it.
	KeyScopeBIP0044 = KeyScope{
		Purpose: 44,
		Coin:    0,
	}

	// created by the root manager upon initial creation.
	DefaultKeyScopes = []KeyScope{
		KeyScopeBIP0049Plus,
		KeyScopeBIP0084,
		KeyScopeBIP0044,
	}

	// 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,
		},
	}
)
View Source
var Break = managerError(ErrCallBackBreak, "callback break", nil)

Break is a global err used to signal a break from the callback function by returning an error with the code ErrCallBackBreak

View Source
var DefaultScryptOptions = ScryptOptions{
	N: 262144,
	R: 8,
	P: 1,
}

DefaultScryptOptions is the default options used with scrypt.

View Source
var Log = cl.NewSubSystem("wallet/addrmgr", ll.DEFAULT)

Log is the logger for the peer package

Functions

func Create

func Create(
	ns walletdb.ReadWriteBucket, seed, pubPassphrase, privPassphrase []byte,
	chainParams *chaincfg.Params, config *ScryptOptions,
	birthday time.Time) error

Create creates a new address manager in the given namespace. The seed must conform to the standards described in hdkeychain.NewMaster and will be used to create the master root node from which all hierarchical deterministic addresses are derived. This allows all chained addresses in the address manager to be recovered by using the same seed.

All private and public keys and information are protected by secret keys derived from the provided private and public passphrases. The public passphrase is required on subsequent opens of the address manager, and the private passphrase is required to unlock the address manager in order to gain access to any private keys and information.

If a config structure is passed to the function, that configuration will override the defaults.

A ManagerError with an error code of ErrAlreadyExists will be returned the address manager already exists in the specified namespace.

func DoUpgrades

func DoUpgrades(
	db walletdb.DB, namespaceKey []byte, pubPassphrase []byte,
	chainParams *chaincfg.Params, cbs *OpenCallbacks) error

DoUpgrades performs any necessary upgrades to the address manager contained in the wallet database, namespaced by the top level bucket key namespaceKey.

func IsError

func IsError(
	err error, code ErrorCode) bool

IsError returns whether the error is a ManagerError with a matching error code.

func UseLogger

func UseLogger(
	logger *cl.SubSystem)

UseLogger uses a specified Logger to output package logging info. This should be used in preference to SetLogWriter if the caller is also using log.

func ValidateAccountName

func ValidateAccountName(
	name string) error

ValidateAccountName validates the given account name and returns an error, if any.

Types

type AccountProperties

type AccountProperties struct {
	AccountNumber    uint32
	AccountName      string
	ExternalKeyCount uint32
	InternalKeyCount uint32
	ImportedKeyCount uint32
}

type AddressType

type AddressType uint8
const (

	// PubKeyHash is a regular p2pkh address.
	PubKeyHash AddressType = iota

	// Script reprints a raw script address.
	Script

	// shouldn't be consulted during historical rescans.
	RawPubKey

	// compatible manner.
	NestedWitnessPubKey

	// type.
	WitnessPubKey
)

type BlockStamp

type BlockStamp struct {
	Height    int32
	Hash      chainhash.Hash
	Timestamp time.Time
}

type CryptoKeyType

type CryptoKeyType byte
const (

	// private keys.
	CKTPrivate CryptoKeyType = iota

	// CKTScript specifies the key that is used for encryption of scripts.
	CKTScript

	// keys.
	CKTPublic
)

Crypto key types.

type DerivationPath

type DerivationPath struct {

	// manager's hardened coin type key.
	Account uint32

	// its size range.
	Branch uint32

	// key index within as a child of the account and branch.
	Index uint32
}

type EncryptorDecryptor

type EncryptorDecryptor interface {
	Encrypt(in []byte) ([]byte, error)
	Decrypt(in []byte) ([]byte, error)
	Bytes() []byte
	CopyBytes([]byte)
	Zero()
}

type ErrorCode

type ErrorCode int
const (

	// set to the underlying error returned from the database.
	ErrDatabase ErrorCode = iota

	// and there is not yet any code written to upgrade.
	ErrUpgrade

	// ManagerError will be set to the underlying error.
	ErrKeyChain

	// error.
	ErrCrypto

	// key type has been selected.
	ErrInvalidKeyType

	// ErrNoExist indicates that the specified database does not exist.
	ErrNoExist

	// ErrAlreadyExists indicates that the specified database already exists.
	ErrAlreadyExists

	// by the maxCoinType constant.
	ErrCoinTypeTooHigh

	// than the max allowed value as defined by the MaxAccountNum constant.
	ErrAccountNumTooHigh

	// manager to be unlocked, was requested on a locked account manager.
	ErrLocked

	// a watching-only account manager.
	ErrWatchingOnly

	// ErrInvalidAccount indicates that the requested account is not valid.
	ErrInvalidAccount

	// the account manager.
	ErrAddressNotFound

	// the account manager.
	ErrAccountNotFound

	// ErrDuplicateAddress indicates an address already exists.
	ErrDuplicateAddress

	// ErrDuplicateAccount indicates an account already exists.
	ErrDuplicateAccount

	// addresses per account have been requested.
	ErrTooManyAddresses

	// This could be for either public or private master keys.
	ErrWrongPassphrase

	// the same network the account manager is configured for.
	ErrWrongNet

	// down to the manager.
	ErrCallBackBreak

	// due to being empty.
	ErrEmptyPassphrase

	// within the database.
	ErrScopeNotFound
)

These constants are used to identify a specific ManagerError.

func (ErrorCode) String

func (e ErrorCode) String() string

String returns the ErrorCode as a human-readable name.

type KeyScope

type KeyScope struct {

	// the master HD key.
	Purpose uint32

	// children can be derived at all.
	Coin uint32
}

func (*KeyScope) String

func (k *KeyScope) String() string

String returns a human readable version describing the keypath encapsulated by the target key scope.

type ManagedAddress

type ManagedAddress interface {

	// Account returns the account the address is associated with.
	Account() uint32

	// Address returns a util.Address for the backing address.
	Address() util.Address

	// AddrHash returns the key or script hash related to the address
	AddrHash() []byte

	// of being part of an address chain.
	Imported() bool

	// use such as a change output of a transaction.
	Internal() bool

	// Compressed returns true if the backing address is compressed.
	Compressed() bool

	// Used returns true if the backing address has been used in a transaction.
	Used(ns walletdb.ReadBucket) bool

	// processing
	AddrType() AddressType
}

type ManagedPubKeyAddress

type ManagedPubKeyAddress interface {
	ManagedAddress

	// PubKey returns the public key associated with the address.
	PubKey() *ec.PublicKey

	// serialized as a hex encoded string.
	ExportPubKey() string

	// have any keys.
	PrivKey() (*ec.PrivateKey, error)

	// serialized as Wallet Import Format (WIF).
	ExportPrivKey() (*util.WIF, error)

	// we don't know exactly how the key was derived.
	DerivationInfo() (KeyScope, DerivationPath, bool)
}

type ManagedScriptAddress

type ManagedScriptAddress interface {
	ManagedAddress

	// Script returns the script associated with the address.
	Script() ([]byte, error)
}

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

func Open

func Open(
	ns walletdb.ReadBucket, pubPassphrase []byte,
	chainParams *chaincfg.Params) (*Manager, error)

Open loads an existing address manager from the given namespace. The public passphrase is required to decrypt the public keys used to protect the public information such as addresses. This is important since access to BIP0032 extended keys means it is possible to generate all future addresses.

If a config structure is passed to the function, that configuration will override the defaults.

A ManagerError with an error code of ErrNoExist will be returned if the passed manager does not exist in the specified namespace.

func (*Manager) ActiveScopedKeyManagers

func (m *Manager) ActiveScopedKeyManagers() []*ScopedKeyManager

ActiveScopedKeyManagers returns a slice of all the active scoped key managers currently known by the root key manager.

func (*Manager) AddrAccount

func (m *Manager) AddrAccount(ns walletdb.ReadBucket,
	address util.Address) (*ScopedKeyManager, uint32, error)

AddrAccount returns the account to which the given address belongs. We also return the scoped manager that owns the addr+account combo.

func (*Manager) Address

func (m *Manager) Address(ns walletdb.ReadBucket,
	address util.Address) (ManagedAddress, error)

Address returns a managed address given the passed address if it is known to the address manager. A managed address differs from the passed address in that it also potentially contains extra information needed to sign transactions such as the associated private key for pay-to-pubkey and pay-to-pubkey-hash addresses and the script associated with pay-to-script-hash addresses.

func (*Manager) Birthday

func (m *Manager) Birthday() time.Time

Birthday returns the birthday, or earliest time a key could have been used, for the manager.

func (*Manager) BlockHash

func (m *Manager) BlockHash(ns walletdb.ReadBucket, height int32) (
	*chainhash.Hash, error)

BlockHash returns the block hash at a particular block height. This information is useful for comparing against the chain back-end to see if a reorg is taking place and how far back it goes.

func (*Manager) ChainParams

func (m *Manager) ChainParams() *chaincfg.Params

ChainParams returns the chain parameters for this address manager.

func (*Manager) ChangePassphrase

func (m *Manager) ChangePassphrase(ns walletdb.ReadWriteBucket, oldPassphrase,
	newPassphrase []byte, private bool, config *ScryptOptions) error

ChangePassphrase changes either the public or private passphrase to the provided value depending on the private flag. In order to change the private password, the address manager must not be watching-only. The new passphrase keys are derived using the scrypt parameters in the options, so changing the passphrase may be used to bump the computational difficulty needed to brute force the passphrase.

func (*Manager) Close

func (m *Manager) Close()

Close cleanly shuts down the manager. It makes a best try effort to remove and zero all private key and sensitive public key material associated with the address manager from memory.

func (*Manager) ConvertToWatchingOnly

func (m *Manager) ConvertToWatchingOnly(ns walletdb.ReadWriteBucket) error

ConvertToWatchingOnly converts the current address manager to a locked watching-only address manager.

WARNING: This function removes private keys from the existing address manager which means they will no longer be available. Typically the caller will make a copy of the existing wallet database and modify the copy since otherwise it would mean permanent loss of any imported private keys and scripts.

Executing this function on a manager that is already watching-only will have no effect.

func (*Manager) Decrypt

func (m *Manager) Decrypt(keyType CryptoKeyType, in []byte) ([]byte, error)

Decrypt in using the crypto key type specified by keyType.

func (*Manager) Encrypt

func (m *Manager) Encrypt(keyType CryptoKeyType, in []byte) ([]byte, error)

Encrypt in using the crypto key type specified by keyType.

func (*Manager) FetchScopedKeyManager

func (m *Manager) FetchScopedKeyManager(scope KeyScope) (*ScopedKeyManager, error)

FetchScopedKeyManager attempts to fetch an active scoped manager according to its registered scope. If the manger is found, then a nil error is returned along with the active scoped manager. Otherwise, a nil manager and a non-nil error will be returned.

func (*Manager) ForEachAccountAddress

func (m *Manager) ForEachAccountAddress(ns walletdb.ReadBucket, account uint32,
	fn func(maddr ManagedAddress) error) error

ForEachAccountAddress calls the given function with each address of the given account stored in the manager, breaking early on error.

func (*Manager) ForEachActiveAccountAddress

func (m *Manager) ForEachActiveAccountAddress(ns walletdb.ReadBucket,
	account uint32, fn func(maddr ManagedAddress) error) error

ForEachActiveAccountAddress calls the given function with each active address of the given account stored in the manager, across all active scopes, breaking early on error.

TODO(tuxcanfly): actually return only active addresses

func (*Manager) ForEachActiveAddress

func (m *Manager) ForEachActiveAddress(ns walletdb.ReadBucket, fn func(addr util.Address) error) error

ForEachActiveAddress calls the given function with each active address stored in the manager, breaking early on error.

func (*Manager) IsLocked

func (m *Manager) IsLocked() bool

IsLocked returns whether or not the address managed is locked. When it is unlocked, the decryption key needed to decrypt private keys used for signing is in memory.

func (*Manager) Lock

func (m *Manager) Lock() error

Lock performs a best try effort to remove and zero all secret keys associated with the address manager.

This function will return an error if invoked on a watching-only address manager.

func (*Manager) MarkUsed

func (m *Manager) MarkUsed(ns walletdb.ReadWriteBucket, address util.Address) error

MarkUsed updates the used flag for the provided address.

func (*Manager) NeuterRootKey

func (m *Manager) NeuterRootKey(ns walletdb.ReadWriteBucket) error

NeuterRootKey is a special method that should be used once a caller is *certain* that no further scoped managers are to be created. This method will *delete* the encrypted master HD root private key from the database.

func (*Manager) NewScopedKeyManager

func (m *Manager) NewScopedKeyManager(ns walletdb.ReadWriteBucket, scope KeyScope,
	addrSchema ScopeAddrSchema) (*ScopedKeyManager, error)

NewScopedKeyManager creates a new scoped key manager from the root manager. A scoped key manager is a sub-manager that only has the coin type key of a particular coin type and BIP0043 purpose. This is useful as it enables callers to create an arbitrary BIP0043 like schema with a stand alone manager. Note that a new scoped manager cannot be created if: the wallet is watch only, the manager hasn't been unlocked, or the root key has been. neutered from the database.

TODO(roasbeef): addrtype of raw key means it'll look in scripts to possibly mark as gucci?

func (*Manager) ScopesForExternalAddrType

func (m *Manager) ScopesForExternalAddrType(addrType AddressType) []KeyScope

ScopesForExternalAddrType returns the set of key scopes that are able to produce the target address type as external addresses.

func (*Manager) ScopesForInternalAddrTypes

func (m *Manager) ScopesForInternalAddrTypes(addrType AddressType) []KeyScope

ScopesForInternalAddrTypes returns the set of key scopes that are able to produce the target address type as internal addresses.

func (*Manager) SetBirthday

func (m *Manager) SetBirthday(ns walletdb.ReadWriteBucket,
	birthday time.Time) error

SetBirthday sets the birthday, or earliest time a key could have been used, for the manager.

func (*Manager) SetSyncedTo

func (m *Manager) SetSyncedTo(ns walletdb.ReadWriteBucket, bs *BlockStamp) error

SetSyncedTo marks the address manager to be in sync with the recently-seen block described by the blockstamp. When the provided blockstamp is nil, the oldest blockstamp of the block the manager was created at and of all imported addresses will be used. This effectively allows the manager to be marked as unsynced back to the oldest known point any of the addresses have appeared in the block chain.

func (*Manager) SyncedTo

func (m *Manager) SyncedTo() BlockStamp

SyncedTo returns details about the block height and hash that the address manager is synced through at the very least. The intention is that callers can use this information for intelligently initiating rescans to sync back to the best chain from the last known good block.

func (*Manager) Unlock

func (m *Manager) Unlock(ns walletdb.ReadBucket, passphrase []byte) error

Unlock derives the master private key from the specified passphrase. An invalid passphrase will return an error. Otherwise, the derived secret key is stored in memory until the address manager is locked. Any failures that occur during this function will result in the address manager being locked, even if it was already unlocked prior to calling this function.

This function will return an error if invoked on a watching-only address manager.

func (*Manager) WatchOnly

func (m *Manager) WatchOnly() bool

WatchOnly returns true if the root manager is in watch only mode, and false otherwise.

type ManagerError

type ManagerError struct {
	ErrorCode   ErrorCode // Describes the kind of error
	Description string    // Human readable description of the issue
	Err         error     // Underlying error
}

func (ManagerError) Error

func (e ManagerError) Error() string

Error satisfies the error interface and prints human-readable errors.

type ObtainUserInputFunc

type ObtainUserInputFunc func() ([]byte, error)

type OpenCallbacks

type OpenCallbacks struct {

	// from the user (or any other mechanism the caller deems fit).
	ObtainSeed ObtainUserInputFunc

	// deems fit).
	ObtainPrivatePass ObtainUserInputFunc
}

type ScopeAddrSchema

type ScopeAddrSchema struct {

	// ExternalAddrType is the address type for all keys within branch 0.
	ExternalAddrType AddressType

	// (change addresses).
	InternalAddrType AddressType
}

type ScopedIndex

type ScopedIndex struct {

	// Scope is the BIP44 account' used to derive the child key.
	Scope KeyScope

	// Index is the BIP44 address_index used to derive the child key.
	Index uint32
}

type ScopedKeyManager

type ScopedKeyManager struct {
	// contains filtered or unexported fields
}

func (*ScopedKeyManager) AccountName

func (s *ScopedKeyManager) AccountName(ns walletdb.ReadBucket, account uint32) (string, error)

AccountName returns the account name for the given account number stored in the manager.

func (*ScopedKeyManager) AccountProperties

func (s *ScopedKeyManager) AccountProperties(ns walletdb.ReadBucket,
	account uint32) (*AccountProperties, error)

AccountProperties returns properties associated with the account, such as the account number, name, and the number of derived and imported keys.

func (*ScopedKeyManager) AddrAccount

func (s *ScopedKeyManager) AddrAccount(ns walletdb.ReadBucket,
	address util.Address) (uint32, error)

AddrAccount returns the account to which the given address belongs.

func (*ScopedKeyManager) AddrSchema

func (s *ScopedKeyManager) AddrSchema() ScopeAddrSchema

AddrSchema returns the set address schema for the target ScopedKeyManager.

func (*ScopedKeyManager) Address

Address returns a managed address given the passed address if it is known to the address manager. A managed address differs from the passed address in that it also potentially contains extra information needed to sign transactions such as the associated private key for pay-to-pubkey and pay-to-pubkey-hash addresses and the script associated with pay-to-script-hash addresses.

func (*ScopedKeyManager) ChainParams

func (s *ScopedKeyManager) ChainParams() *chaincfg.Params

ChainParams returns the chain parameters for this address manager.

func (*ScopedKeyManager) Close

func (s *ScopedKeyManager) Close()

Close cleanly shuts down the manager. It makes a best try effort to remove and zero all private key and sensitive public key material associated with the address manager from memory.

func (*ScopedKeyManager) DeriveFromKeyPath

func (s *ScopedKeyManager) DeriveFromKeyPath(ns walletdb.ReadBucket,
	kp DerivationPath) (ManagedAddress, error)

DeriveFromKeyPath attempts to derive a maximal child key (under the BIP0044 scheme) from a given key path. If key derivation isn't possible, then an error will be returned.

func (*ScopedKeyManager) ExtendExternalAddresses

func (s *ScopedKeyManager) ExtendExternalAddresses(ns walletdb.ReadWriteBucket,
	account uint32, lastIndex uint32) error

ExtendExternalAddresses ensures that all valid external keys through lastIndex are derived and stored in the wallet. This is used to ensure that wallet's persistent state catches up to a external child that was found during recovery.

func (*ScopedKeyManager) ExtendInternalAddresses

func (s *ScopedKeyManager) ExtendInternalAddresses(ns walletdb.ReadWriteBucket,
	account uint32, lastIndex uint32) error

ExtendInternalAddresses ensures that all valid internal keys through lastIndex are derived and stored in the wallet. This is used to ensure that wallet's persistent state catches up to an internal child that was found during recovery.

func (*ScopedKeyManager) ForEachAccount

func (s *ScopedKeyManager) ForEachAccount(ns walletdb.ReadBucket,
	fn func(account uint32) error) error

ForEachAccount calls the given function with each account stored in the manager, breaking early on error.

func (*ScopedKeyManager) ForEachAccountAddress

func (s *ScopedKeyManager) ForEachAccountAddress(ns walletdb.ReadBucket,
	account uint32, fn func(maddr ManagedAddress) error) error

ForEachAccountAddress calls the given function with each address of the given account stored in the manager, breaking early on error.

func (*ScopedKeyManager) ForEachActiveAccountAddress

func (s *ScopedKeyManager) ForEachActiveAccountAddress(ns walletdb.ReadBucket, account uint32,
	fn func(maddr ManagedAddress) error) error

ForEachActiveAccountAddress calls the given function with each active address of the given account stored in the manager, breaking early on error.

TODO(tuxcanfly): actually return only active addresses

func (*ScopedKeyManager) ForEachActiveAddress

func (s *ScopedKeyManager) ForEachActiveAddress(ns walletdb.ReadBucket,
	fn func(addr util.Address) error) error

ForEachActiveAddress calls the given function with each active address stored in the manager, breaking early on error.

func (*ScopedKeyManager) ImportPrivateKey

func (s *ScopedKeyManager) ImportPrivateKey(ns walletdb.ReadWriteBucket,
	wif *util.WIF, bs *BlockStamp) (ManagedPubKeyAddress, error)

ImportPrivateKey imports a WIF private key into the address manager. The imported address is created using either a compressed or uncompressed serialized public key, depending on the CompressPubKey bool of the WIF.

All imported addresses will be part of the account defined by the ImportedAddrAccount constant.

NOTE: When the address manager is watching-only, the private key itself will not be stored or available since it is private data. Instead, only the public key will be stored. This means it is paramount the private key is kept elsewhere as the watching-only address manager will NOT ever have access to it.

This function will return an error if the address manager is locked and not watching-only, or not for the same network as the key trying to be imported. It will also return an error if the address already exists. Any other errors returned are generally unexpected.

func (*ScopedKeyManager) ImportScript

func (s *ScopedKeyManager) ImportScript(ns walletdb.ReadWriteBucket,
	script []byte, bs *BlockStamp) (ManagedScriptAddress, error)

ImportScript imports a user-provided script into the address manager. The imported script will act as a pay-to-script-hash address.

All imported script addresses will be part of the account defined by the ImportedAddrAccount constant.

When the address manager is watching-only, the script itself will not be stored or available since it is considered private data.

This function will return an error if the address manager is locked and not watching-only, or the address already exists. Any other errors returned are generally unexpected.

func (*ScopedKeyManager) LastAccount

func (s *ScopedKeyManager) LastAccount(ns walletdb.ReadBucket) (uint32, error)

LastAccount returns the last account stored in the manager.

func (*ScopedKeyManager) LastExternalAddress

func (s *ScopedKeyManager) LastExternalAddress(ns walletdb.ReadBucket,
	account uint32) (ManagedAddress, error)

LastExternalAddress returns the most recently requested chained external address from calling NextExternalAddress for the given account. The first external address for the account will be returned if none have been previously requested.

This function will return an error if the provided account number is greater than the MaxAccountNum constant or there is no account information for the passed account. Any other errors returned are generally unexpected.

func (*ScopedKeyManager) LastInternalAddress

func (s *ScopedKeyManager) LastInternalAddress(ns walletdb.ReadBucket,
	account uint32) (ManagedAddress, error)

LastInternalAddress returns the most recently requested chained internal address from calling NextInternalAddress for the given account. The first internal address for the account will be returned if none have been previously requested.

This function will return an error if the provided account number is greater than the MaxAccountNum constant or there is no account information for the passed account. Any other errors returned are generally unexpected.

func (*ScopedKeyManager) LookupAccount

func (s *ScopedKeyManager) LookupAccount(ns walletdb.ReadBucket, name string) (uint32, error)

LookupAccount loads account number stored in the manager for the given account name

func (*ScopedKeyManager) MarkUsed

func (s *ScopedKeyManager) MarkUsed(ns walletdb.ReadWriteBucket,
	address util.Address) error

MarkUsed updates the used flag for the provided address.

func (*ScopedKeyManager) NewAccount

func (s *ScopedKeyManager) NewAccount(ns walletdb.ReadWriteBucket, name string) (uint32, error)

NewAccount creates and returns a new account stored in the manager based on the given account name. If an account with the same name already exists, ErrDuplicateAccount will be returned. Since creating a new account requires access to the cointype keys (from which extended account keys are derived), it requires the manager to be unlocked.

func (*ScopedKeyManager) NewRawAccount

func (s *ScopedKeyManager) NewRawAccount(ns walletdb.ReadWriteBucket, number uint32) error

NewRawAccount creates a new account for the scoped manager. This method differs from the NewAccount method in that this method takes the acount number *directly*, rather than taking a string name for the account, then mapping that to the next highest account number.

func (*ScopedKeyManager) NextExternalAddresses

func (s *ScopedKeyManager) NextExternalAddresses(ns walletdb.ReadWriteBucket,
	account uint32, numAddresses uint32) ([]ManagedAddress, error)

NextExternalAddresses returns the specified number of next chained addresses that are intended for external use from the address manager.

func (*ScopedKeyManager) NextInternalAddresses

func (s *ScopedKeyManager) NextInternalAddresses(ns walletdb.ReadWriteBucket,
	account uint32, numAddresses uint32) ([]ManagedAddress, error)

NextInternalAddresses returns the specified number of next chained addresses that are intended for internal use such as change from the address manager.

func (*ScopedKeyManager) RenameAccount

func (s *ScopedKeyManager) RenameAccount(ns walletdb.ReadWriteBucket,
	account uint32, name string) error

RenameAccount renames an account stored in the manager based on the given account number with the given name. If an account with the same name already exists, ErrDuplicateAccount will be returned.

func (*ScopedKeyManager) Scope

func (s *ScopedKeyManager) Scope() KeyScope

Scope returns the exact KeyScope of this scoped key manager.

type ScryptOptions

type ScryptOptions struct {
	N, R, P int
}

type SecretKeyGenerator

type SecretKeyGenerator func(

	passphrase *[]byte, config *ScryptOptions) (*snacl.SecretKey, error)

func SetSecretKeyGen

func SetSecretKeyGen(
	keyGen SecretKeyGenerator) SecretKeyGenerator

SetSecretKeyGen replaces the existing secret key generator, and returns the previous generator.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL