bip32

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Mar 15, 2019 License: ISC Imports: 16 Imported by: 1

README

bip32

CircleCI codecov Go Report Card LICENSE

Package bip32 provides an API for bitcoin hierarchical deterministic extended keys (BIP0032).

A comprehensive suite of tests is provided to ensure proper functionality. See codecov for the coverage report.

Feature Overview

  • Full BIP0032 implementation
  • Single type for private and public extended keys
  • Convenient cryptograpically secure seed generation
  • Simple creation of master nodes
  • Support for multi-layer derivation
  • Easy serialization and deserialization for both private and public extended keys
  • Support for custom networks by registering them with chaincfg
  • Obtaining the underlying EC pubkeys, EC privkeys, and associated bitcoin address public key hashes ties in seamlessly with existing btcec and btcutil types which provide powerful tools for working with them to do things like sign transations and generate payment scripts
  • Uses the btcec package which is highly optimized for secp256k1
  • Code examples including:
    • Generating a cryptographically secure random seed and deriving a master node from it
    • Default HD wallet layout as described by BIP0032
    • Audits use case as described by BIP0032
  • Comprehensive test coverage including the BIP0032 test vectors
  • Benchmarks [WIP]

Installation and Updating

$ go get -u github.com/sammyne/bip32

Examples

Documentation

Overview

Package bip32 provides an API for bitcoin hierarchical deterministic extended keys (BIP0032).

Overview

The ability to implement hierarchical deterministic wallets depends on the ability to create and derive hierarchical deterministic extended keys.

At a high level, this package provides support for those hierarchical deterministic extended keys specified as the ExtendedKey interface, which is implemented by PrivateKey and PublicKey.Therefore, each extended key can either be a private or public extended key which itself is capable of deriving a child extended key.

Determining the Extended Key Type

Whether an extended key is a private or public extended key can be type assertion against the PrivateKey type.

Transaction Signing Keys and Payment Addresses

In order to create and sign transactions, or provide others with addresses to send funds to, the underlying key and address material must be accessible. This package provides the ECPubKey, ECPrivKey, and AddressPubKeyHash functions for this purpose.

The Master Node

As previously mentioned, the extended keys are hierarchical meaning they are used to form a tree. The root of that tree is called the master node and this package provides the NewMasterKey function to create it from a cryptographically random seed. The GenerateMasterKey function is provided as a convenient way to create a random extended private key for use where the seed would be read from the provided rand entropy reader.

Deriving Children

Once you have created a tree root (or have deserialized an extended key as discussed later), the child extended keys can be derived by using the Child function. The Child function supports deriving both normal (non-hardened) and hardened child extended keys. In order to derive a hardened extended key, use the mapping function HardenIndex(i) to get the corresponding index for generating harden child to the Child function. This provides the ability to cascade the keys into a tree and hence generate the hierarchical deterministic key chains.

Normal vs Hardened Child Extended Keys

A private extended key can be used to derive both hardened and non-hardened (normal) child private and public extended keys. A public extended key can only be used to derive non-hardened child public extended keys. As enumerated in BIP0032 "knowledge of the extended public key plus any non-hardened private key descending from it is equivalent to knowing the extended private key (and thus every private and public key descending from it). This means that extended public keys must be treated more carefully than regular public keys. It is also the reason for the existence of hardened keys, and why they are used for the account level in the tree. This way, a leak of an account-specific (or below) private key never risks compromising the master or other accounts."

Neutering a Private Extended Key

A private extended key can be converted to a new instance of the corresponding public extended key with the Neuter function. The original extended key is not modified. A public extended key is still capable of deriving non-hardened child public extended keys.

Serializing and Deserializing Extended Keys

Extended keys are serialized and deserialized with the String and ParsePrivateKey/ParsePublicKey functions. The serialized key is a Base58-encoded string which looks like the following:

public key:   xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw
private key:  xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7

Network

Extended keys are much like normal Bitcoin addresses in that they have version bytes which tie them to a specific network. The SetNet and IsForNet functions are provided to set and determinine which network an extended key is associated with.

Example (Audits)

This example demonstrates the audits use case in BIP0032.

package main

import (
	"fmt"

	"github.com/sammyne/bip32"
)

func main() {
	// The audits use case described in BIP0032 is:
	//
	// In case an auditor needs full access to the list of incoming and
	// outgoing payments, one can share all account public extended keys.
	// This will allow the auditor to see all transactions from and to the
	// wallet, in all accounts, but not a single secret key.
	//
	//   * N(m/*)
	//   corresponds to the neutered master extended key (also called
	//   the master public extended key)

	// Ordinarily this would either be read from some encrypted source
	// and be decrypted or generated as the NewMasterKey example shows, but
	// for the purposes of this example, the private extended key for the
	// master node is being hard coded here.
	master := "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jP" +
		"PqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi"

	// Start by getting an extended key instance for the master node.
	// This gives the path:
	//   m
	masterKey, err := bip32.ParsePrivateKey(master)
	if err != nil {
		fmt.Println(err)
		return
	}

	// Neuter the master key to generate a master public extended key.  This
	// gives the path:
	//   N(m/*)
	masterPubKey, err := masterKey.Neuter()
	if err != nil {
		fmt.Println(err)
		return
	}

	// Share the master public extended key with the auditor.
	fmt.Println("Audit key N(m/*):", masterPubKey)

}
Output:

Audit key N(m/*): xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8
Example (DefaultWalletLayout)

This example demonstrates the default hierarchical deterministic wallet layout as described in BIP0032.

package main

import (
	"fmt"

	"github.com/sammyne/base58"

	"github.com/sammyne/bip32"
)

func main() {
	// The default wallet layout described in BIP0032 is:
	//
	// Each account is composed of two keypair chains: an internal and an
	// external one. The external keychain is used to generate new public
	// addresses, while the internal keychain is used for all other
	// operations (change addresses, generation addresses, ..., anything
	// that doesn't need to be communicated).
	//
	//   * m/iH/0/k
	//     corresponds to the k'th keypair of the external chain of account
	//     number i of the HDW derived from master m.
	//   * m/iH/1/k
	//     corresponds to the k'th keypair of the internal chain of account
	//     number i of the HDW derived from master m.

	// Ordinarily this would either be read from some encrypted source
	// and be decrypted or generated as the NewMasterKey example shows, but
	// for the purposes of this example, the private extended key for the
	// master node is being hard coded here.
	// This is a base58-check encoded private key
	master58 := "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jP" +
		"PqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi"

	// Start by getting an extended key instance for the master node.
	// This gives the path:
	//   m
	masterKey, err := bip32.ParsePrivateKey(master58)
	if err != nil {
		fmt.Println(err)
		return
	}

	// Derive the extended key for account 0.  This gives the path:
	//   m/0H
	acct0, err := masterKey.Child(bip32.HardenIndex(0))
	if err != nil {
		fmt.Println(err)
		return
	}

	// Derive the extended key for the account 0 external chain.  This
	// gives the path:
	//   m/0H/0
	acct0Ext, err := acct0.Child(0)
	if err != nil {
		fmt.Println(err)
		return
	}

	// Derive the extended key for the account 0 internal chain.  This gives
	// the path:
	//   m/0H/1
	acct0Int, err := acct0.Child(1)
	if err != nil {
		fmt.Println(err)
		return
	}

	// At this point, acct0Ext and acct0Int are ready to derive the keys for
	// the external and internal wallet chains.

	// Derive the 10th extended key for the account 0 external chain.  This
	// gives the path:
	//   m/0H/0/10
	acct0Ext10, err := acct0Ext.Child(10)
	if err != nil {
		fmt.Println(err)
		return
	}

	// Derive the 0th extended key for the account 0 internal chain.  This
	// gives the path:
	//   m/0H/1/0
	acct0Int0, err := acct0Int.Child(0)
	if err != nil {
		fmt.Println(err)
		return
	}

	const mainNetID = 0x00
	// Get and show the address associated with the extended keys for the
	// main bitcoin	network.
	acct0ExtAddr := base58.CheckEncode(acct0Ext10.AddressPubKeyHash(), mainNetID)
	acct0IntAddr := base58.CheckEncode(acct0Int0.AddressPubKeyHash(), mainNetID)

	const format = `
Account %d %s Address %d
  - address: %s
  - depth: %d
  - hardened: %v
  - for main net: %v
`

	fmt.Printf(format, 0, "External", acct0Ext10.Index(), acct0ExtAddr,
		acct0Ext10.Depth(), acct0Ext10.Hardened(),
		acct0Ext10.IsForNet(*bip32.MainNetPrivateKey))
	fmt.Printf(format, 0, "Internal", acct0Int0.Index(), acct0IntAddr,
		acct0Int0.Depth(), acct0Int0.Hardened(),
		acct0Int0.IsForNet(*bip32.MainNetPrivateKey))

}
Output:

Account 0 External Address 10
  - address: 1HVccubUT8iKTapMJ5AnNA4sLRN27xzQ4F
  - depth: 3
  - hardened: false
  - for main net: true

Account 0 Internal Address 0
  - address: 1J5rebbkQaunJTUoNVREDbeB49DqMNFFXk
  - depth: 3
  - hardened: false
  - for main net: true

Index

Examples

Constants

View Source
const (
	// RecommendedSeedLen is the recommended length in bytes for a seed
	// to a master node.
	RecommendedSeedLen = 32 // 256 bits

	// HardenedKeyStart is the index at which a hardended key starts.  Each
	// extended key has 2^31 normal child keys and 2^31 hardned child keys.
	// Thus the range for normal child keys is [0, 2^31 - 1] and the range
	// for hardened child keys is [2^31, 2^32 - 1].
	HardenedKeyStart = 0x80000000 // 2^31

	// MinSeedBytes is the minimum number of bytes allowed for a seed to
	// a master node.
	MinSeedBytes = 16 // 128 bits

	// MaxSeedBytes is the maximum number of bytes allowed for a seed to
	// a master node.
	MaxSeedBytes = 64 // 512 bits
)
View Source
const (
	VersionLen     = 4
	DepthLen       = 1
	FingerprintLen = 4
	ChildIndexLen  = 4
	ChainCodeLen   = 32
	KeyDataLen     = 33
	// KeyLen is the length of a serialized public or private
	// extended key.  It consists of 4 bytes version, 1 byte depth, 4 bytes
	// fingerprint, 4 bytes child number, 32 bytes chain code, and 33 bytes
	// public/private key data.
	KeyLen = VersionLen + DepthLen + FingerprintLen +
		ChildIndexLen + ChainCodeLen + KeyDataLen
)

length constants about fields of key serialization

View Source
const GoldenAddOnName = "bip32_addon.golden"

GoldenAddOnName specifies the file containing the more test vectors from the btcutil/hdkeychain testing

View Source
const GoldenBase = "testdata"

GoldenBase base directory storing the golden files

View Source
const GoldenName = "bip32.golden"

GoldenName specifies the file containing the reference test vectors

View Source
const MagicLen = 4

MagicLen is the length of magic bytes for generating human-readble prefix of the base58-encoded key

Variables

View Source
var (
	// ErrBadChecksum describes an error in which the checksum encoded with
	// a serialized extended key does not match the calculated value.
	ErrBadChecksum = errors.New("bad extended key checksum")

	// ErrDeriveBeyondMaxDepth describes an error in which the caller
	// has attempted to derive a key chain longer than 255 from a root key.
	ErrDeriveBeyondMaxDepth = errors.New("cannot derive a key with more than " +

		"255 indices in its path")
	// ErrDeriveHardFromPublic describes an error in which the caller
	// attempted to derive a hardened extended key from a public key.
	ErrDeriveHardFromPublic = errors.New("cannot derive a hardened key " +
		"from a public key")

	// ErrInvalidChild describes an error in which the child at a specific
	// index is invalid due to the derived key falling outside of the valid
	// range for secp256k1 private keys. This error indicates the caller
	// should simply ignore the invalid child extended key at this index and
	// increment to the next index.
	ErrInvalidChild = errors.New("the extended key at this index is invalid")

	// ErrInvalidKeyLen describes an error in which the provided serialized
	// key isn't of the expected length.
	ErrInvalidKeyLen = errors.New("the provided serialized extended key " +
		"length is invalid")

	// ErrInvalidSeedLen describes an error in which the provided seed or
	// seed length is not in the allowed range.
	ErrInvalidSeedLen = fmt.Errorf("seed length must be between %d and %d "+
		"bits", MinSeedBytes*8, MaxSeedBytes*8)

	// ErrNoEnoughEntropy signals more entropy is needed
	ErrNoEnoughEntropy = errors.New("more entropy is needed")

	// ErrUnusableSeed describes an error in which the provided seed is not
	// usable due to the derived key falling outside of the valid range for
	// secp256k1 private keys.  This error indicates the caller must choose
	// another seed.
	ErrUnusableSeed = errors.New("unusable seed")
)
View Source
var (
	MainNetPrivateKey = &Magic{0x04, 0x88, 0xad, 0xe4} // starts with xprv
	MainNetPublicKey  = &Magic{0x04, 0x88, 0xb2, 0x1e} // starts with xpub

	TestNetPrivateKey = &Magic{0x04, 0x35, 0x83, 0x94} // starts with tprv
	TestNetPublicKey  = &Magic{0x04, 0x35, 0x87, 0xcf} // starts with tpub
)

magic bytes as version prefix for base58 encoding, and their application goes as named.

Functions

func HardenIndex

func HardenIndex(i uint32) uint32

HardenIndex maps an index in range [0,HardenedKeyStart) to its harhened corresponding one. Note: No overflow checking is implemented now.

func NewEntropyReader

func NewEntropyReader(hexStr string) io.Reader

NewEntropyReader constructs hex decoder for testing.

func ReverseCopy

func ReverseCopy(dst, src []byte)

ReverseCopy works in the opposite direction as the built-in copy()

func ToUsableScalar

func ToUsableScalar(k []byte) (*big.Int, bool)

ToUsableScalar tries to covert k to a scalar 0<s<secp256k1Curve.N as a big integer, and returns false in case of failure.

func Zero added in v1.0.1

func Zero(data []byte)

Zero clears all data items to 0

Types

type ChainGoldie

type ChainGoldie struct {
	Path               Path // child stemming from master node
	ExtendedPublicKey  string
	ExtendedPrivateKey string
}

ChainGoldie is the structure for key chains

type ChildIndex

type ChildIndex struct {
	Index    uint32
	Hardened bool
}

ChildIndex is enhanced index capable of telling whether its hardened.

type ExtendedKey

type ExtendedKey interface {
	// AddressPubKeyHash returns the public key hash (20 bytes) derived from the
	// key, which would be itself for public keys and the extended public key
	// bound to it for private keys
	AddressPubKeyHash() []byte
	// Child returns a derived child extended key at the given index.  When this
	// extended key is a private extended key, a private extended key will be
	// derived.  Otherwise, the derived extended key will be also be a public
	// extended key.
	//
	// When the index is greater to or equal than the HardenedKeyStart constant,
	// the derived extended key will be a hardened extended key.  It is only
	// possible to derive a hardended extended key from a private extended key.
	// Consequently, this function will return ErrDeriveHardFromPublic if a
	// hardened child extended key is requested from a public extended key.
	//
	// A hardened extended key is useful since, as previously mentioned, it
	// requires a parent private extended key to derive. In other words, normal
	// child extended public keys can be derived from a parent public extended
	// key (no knowledge of the parent private key) whereas hardened extended
	// keys may not be.
	//
	// NOTE: There is an extremely small chance (< 1 in 2^127) the specific child
	// index does not derive to a usable child.  The ErrInvalidChild error should
	// be returned if this should occur, and the caller is expected to ignore the
	// invalid child and simply increment to the next index.
	Child(i uint32) (ExtendedKey, error)
	// Depth returns the current derivation level with respect to the root.
	//
	// The root key has depth zero, and the field has a maximum of 255 due to
	// how depth is serialized.
	Depth() uint8
	// Hardened tells if the key of interest is hardened, whose index is greater
	// than HardenedKeyStart.
	Hardened() bool
	// Index returns the index of the key seen from its parent.
	Index() uint32
	// IsForNet checks if this key is in use for a given net specified by keyID
	IsForNet(keyID Magic) bool

	// Neuter returns a new extended public key from a extended private key. The
	// same extended key will be returned unaltered if it is already an extended
	// public key.
	//
	// As the name implies, an extended public key does not have access to the
	// private key, so it is not capable of signing transactions or deriving
	// child extended private keys.  However, it is capable of deriving further
	// child extended public keys.
	Neuter() (*PublicKey, error)
	// ParentFingerprint returns a fingerprint of the parent extended key from
	// which this one was derived.
	//
	// It's defined the be the first 32 bits of the key identifier as specified by
	// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#key-identifiers
	ParentFingerprint() uint32
	// Public converts the extended key to a btcec public key and returns it.
	Public() (*btcec.PublicKey, error)
	// SetNet associates the extended key, and any child keys yet to be derived
	// from it, with the passed network.
	SetNet(keyID Magic)
	// String returns the extended key as a human-readable base58-encoded string.
	String() string

	// Zero manually clears all fields and bytes in the
	// extended key. This can be used to explicitly clear key material from memory
	// for enhanced security against memory scraping. This function only clears
	// this particular key and not any children that have already been derived.
	Zero()
}

ExtendedKey specifies the basic api for a extended private or public key.

type Goldie

type Goldie struct {
	Seed   string
	Chains []ChainGoldie
}

Goldie is the structure of a single test vector.

type Magic

type Magic [MagicLen]byte

Magic represents the buffer to hold the magic bytes.

type Path

type Path string

Path alias string with a path decoding api

func (Path) ChildIndices

func (path Path) ChildIndices() ([]*ChildIndex, error)

ChildIndices return the child indices tree along this path

type PrivateKey

type PrivateKey struct {
	PublicKey
	Data    []byte
	Version []byte
}

PrivateKey houses all the information of an extended private key.

func GenerateMasterKey

func GenerateMasterKey(rand io.Reader, keyID Magic,
	strength ...int) (*PrivateKey, error)

GenerateMasterKey is a more convinient implemenation w.r.t to NewMasterKey. The seed needed is read from the given entropy source rand, and the seed length is optional which would be RecommendedSeedLen if omitted.

func NewMasterKey

func NewMasterKey(seed []byte, keyID Magic) (*PrivateKey, error)

NewMasterKey creates a new master node for use in creating a hierarchical deterministic key chain. The seed must be between 128 and 512 bits and should be generated by a cryptographically secure random source.

NOTE: There is an extremely small chance (< 1 in 2^127) the provided seed will derive to an unusable secret key. The ErrUnusable error will be returned if this should occur, so the caller must check for it and generate a new seed accordingly.

Example

This example demonstrates how to generate a cryptographically random seed then use it to create a new master node (extended key).

package main

import (
	"crypto/rand"
	"fmt"
	"io"

	"github.com/sammyne/bip32"
)

func main() {
	// Generate a random seed at the recommended length.
	seed := make([]byte, bip32.RecommendedSeedLen)
	if _, err := io.ReadFull(rand.Reader, seed); nil != err {
		fmt.Println(err)
		return
	}

	// Generate a new master node using the seed.
	_, err := bip32.NewMasterKey(seed, *bip32.MainNetPrivateKey)
	if err != nil {
		fmt.Println(err)
		return
	}
	// then key is the private key ready to use

}
Output:

func NewPrivateKey

func NewPrivateKey(version []byte, depth uint8, parentFP []byte, index uint32,
	chainCode, data []byte) *PrivateKey

NewPrivateKey returns a new instance of an extended private key with the given fields. No error checking is performed here as it's only intended to be a convenience method used to create a populated struct. This function should only by used by applications that need to create custom PrivateKey. All other applications should just use NewMasterKey, Child, or Neuter. **The public key part is left uninitialized yet**

func ParsePrivateKey

func ParsePrivateKey(data58 string) (*PrivateKey, error)

ParsePrivateKey a new extended private key instance out of a base58-encoded extended key. **The public key part is left uninitialized yet**

func (*PrivateKey) AddressPubKeyHash

func (priv *PrivateKey) AddressPubKeyHash() []byte

AddressPubKeyHash implements ExtendedKey

func (*PrivateKey) Child

func (priv *PrivateKey) Child(i uint32) (ExtendedKey, error)

Child implements ExtendedKey

func (*PrivateKey) IsForNet

func (priv *PrivateKey) IsForNet(keyID Magic) bool

IsForNet implements ExtendedKey

func (*PrivateKey) Neuter

func (priv *PrivateKey) Neuter() (*PublicKey, error)

Neuter implements ExtendedKey

func (*PrivateKey) Public

func (priv *PrivateKey) Public() (*btcec.PublicKey, error)

Public implements ExtendedKey

func (*PrivateKey) SetNet

func (priv *PrivateKey) SetNet(keyID Magic)

SetNet implements ExtendedKey

func (*PrivateKey) String

func (priv *PrivateKey) String() string

String implements ExtendedKey

func (*PrivateKey) ToECPrivate

func (priv *PrivateKey) ToECPrivate() *btcec.PrivateKey

ToECPrivate converts the extended key to a btcec private key and returns it. As you might imagine this is only possible if the extended key is a private extended key.

Example

this example demonstrates the conversion from the extended private key to to its corresponding secp256k1 private key

package main

import (
	"fmt"

	"github.com/sammyne/bip32"
)

func main() {
	xprv, _ := bip32.ParsePrivateKey("xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi")

	priv := xprv.ToECPrivate()

	fmt.Println("X:", priv.X)
	fmt.Println("Y:", priv.Y)
	fmt.Println("D:", priv.D)

}
Output:

X: 26070491525757212273923430130929023832023083399656255554599993618152067728834
Y: 27475340966630338619946172401610299714452031745281566289223681642426902078081
D: 105366245268346348601399826821003822098691517983742654654633135381666943167285

func (*PrivateKey) Zero added in v1.0.1

func (priv *PrivateKey) Zero()

Zero implements ExtendedKey

type PublicKey

type PublicKey struct {
	ChainCode  []byte
	ChildIndex uint32 // this is the Index-th child of its parent
	Data       []byte // the serialized data in the compressed form
	Level      uint8  // name so to avoid conflict with method Depth()
	ParentFP   []byte
	Version    []byte
}

PublicKey is the structure layout for an extended public key.

Example (WalletLayout)

this example demonstrates the derivation of child for public key

package main

import (
	"fmt"

	"github.com/sammyne/bip32"
)

func main() {
	master, _ := bip32.ParsePublicKey(
		"xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMS" +
			"gv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB")

	const format = `
----
  path: %s
  key: %s
  depth: %d
  hardened: %v,
  for main net: %v
`

	// m
	fmt.Printf(format, "m", master.String(), master.Depth(),
		master.Hardened(), master.IsForNet(*bip32.MainNetPublicKey))

	// m/0
	c0, err := master.Child(0)
	if nil != err {
		fmt.Println(err)
		return
	}
	fmt.Printf(format, "m/0", c0.String(), c0.Depth(),
		c0.Hardened(), c0.IsForNet(*bip32.MainNetPublicKey))

	// m/0/2147483647H
	c0c2147483647H, err := c0.Child(bip32.HardenIndex(2147483647))
	if nil != err {
		fmt.Printf("\n----\n%v\n", err)
		return
	}
	fmt.Printf(format, "m/0/2147483647H", c0c2147483647H.String(),
		c0c2147483647H.Depth(), c0c2147483647H.Hardened(),
		c0c2147483647H.IsForNet(*bip32.MainNetPublicKey))

}
Output:

----
  path: m
  key: xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB
  depth: 0
  hardened: false,
  for main net: true

----
  path: m/0
  key: xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH
  depth: 1
  hardened: false,
  for main net: true

----
cannot derive a hardened key from a public key

func NewPublicKey

func NewPublicKey(version []byte, depth uint8, parentFP []byte, index uint32,
	chainCode, data []byte) *PublicKey

NewPublicKey returns a new instance of an extended public key with the given fields. No error checking is performed here as it's only intended to be a convenience method used to create a populated struct. This function should only by used by applications that need to create custom PublicKey. All other applications should just use Child or Neuter.

func ParsePublicKey

func ParsePublicKey(data58 string) (*PublicKey, error)

ParsePublicKey a new extended public key instance out of a base58-encoded extended key.

func (*PublicKey) AddressPubKeyHash

func (pub *PublicKey) AddressPubKeyHash() []byte

AddressPubKeyHash implements ExtendedKey

func (*PublicKey) Child

func (pub *PublicKey) Child(i uint32) (ExtendedKey, error)

Child derive a normal(non-hardened) child for current key

func (*PublicKey) Depth

func (pub *PublicKey) Depth() uint8

Depth implements ExtendedKey

func (*PublicKey) Hardened

func (pub *PublicKey) Hardened() bool

Hardened implements ExtendedKey

func (*PublicKey) Index

func (pub *PublicKey) Index() uint32

Index implements ExtendedKey

func (*PublicKey) IsForNet

func (pub *PublicKey) IsForNet(keyID Magic) bool

IsForNet implements ExtendedKey

func (*PublicKey) Neuter

func (pub *PublicKey) Neuter() (*PublicKey, error)

Neuter implements ExtendedKey

func (*PublicKey) ParentFingerprint

func (pub *PublicKey) ParentFingerprint() uint32

ParentFingerprint implements ExtendedKey

func (*PublicKey) Public

func (pub *PublicKey) Public() (*btcec.PublicKey, error)

Public implements ExtendedKey

func (*PublicKey) SetNet

func (pub *PublicKey) SetNet(keyID Magic)

SetNet implements ExtendedKey

func (*PublicKey) String

func (pub *PublicKey) String() string

String implements ExtendedKey

func (*PublicKey) Zero added in v1.0.1

func (pub *PublicKey) Zero()

Zero implements ExtendedKey

Jump to

Keyboard shortcuts

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