Documentation ¶
Index ¶
- Constants
- Variables
- func EstimateSerializeSize(inputCount int, txOuts []*wire.TxOut, addChangeOutput bool) int
- func MakeMerkleParent(left *chainhash.Hash, right *chainhash.Hash) *chainhash.Hash
- func NewCoin(txid []byte, index uint32, value btc.Amount, numConfs int64, ...) coinset.Coin
- func SumOutputSerializeSizes(outputs []*wire.TxOut) (serializeSize int)
- func TorLookupIP(host string) ([]net.IP, error)
- type Blockchain
- func (b *Blockchain) ChainState() ChainState
- func (b *Blockchain) CheckHeader(header wire.BlockHeader, prevHeader StoredHeader) bool
- func (b *Blockchain) Close()
- func (b *Blockchain) CommitHeader(header wire.BlockHeader) (bool, *StoredHeader, uint32, error)
- func (b *Blockchain) GetBlockLocatorHashes() []*chainhash.Hash
- func (b *Blockchain) GetEpoch() (*wire.BlockHeader, error)
- func (b *Blockchain) GetLastGoodHeader(bestHeader, prevBestHeader StoredHeader) (*StoredHeader, error)
- func (b *Blockchain) GetNPrevBlockHashes(n int) []*chainhash.Hash
- func (b *Blockchain) SetChainState(state ChainState)
- type ChainState
- type Coin
- type Config
- type Datastore
- type FeeLevel
- type Fees
- type HeaderDB
- func (h *HeaderDB) Close()
- func (h *HeaderDB) GetBestHeader() (sh StoredHeader, err error)
- func (h *HeaderDB) GetPreviousHeader(header wire.BlockHeader) (sh StoredHeader, err error)
- func (h *HeaderDB) Height() (uint32, error)
- func (h *HeaderDB) Print(w io.Writer)
- func (h *HeaderDB) Prune() error
- func (h *HeaderDB) Put(sh StoredHeader, newBestHeader bool) error
- type Headers
- type KeyPath
- type KeyPurpose
- type Keys
- type PeerManager
- type PeerManagerConfig
- type SPVWallet
- func (w *SPVWallet) AddTransactionListener(callback func(TransactionCallback))
- func (w *SPVWallet) AddWatchedScript(script []byte) error
- func (w *SPVWallet) Balance() (confirmed, unconfirmed int64)
- func (s *SPVWallet) Broadcast(tx *wire.MsgTx) error
- func (w *SPVWallet) BumpFee(txid chainhash.Hash) (*chainhash.Hash, error)
- func (w *SPVWallet) ChainTip() uint32
- func (w *SPVWallet) Close()
- func (w *SPVWallet) CreateMultisigSignature(ins []TransactionInput, outs []TransactionOutput, key *hd.ExtendedKey, ...) ([]Signature, error)
- func (w *SPVWallet) CurrencyCode() string
- func (w *SPVWallet) CurrentAddress(purpose KeyPurpose) btc.Address
- func (w *SPVWallet) EstimateFee(ins []TransactionInput, outs []TransactionOutput, feePerByte uint64) uint64
- func (w *SPVWallet) GenerateMultisigScript(keys []hd.ExtendedKey, threshold int) (addr btc.Address, redeemScript []byte, err error)
- func (w *SPVWallet) GetConfirmations(txid chainhash.Hash) (uint32, error)
- func (w *SPVWallet) GetFeePerByte(feeLevel FeeLevel) uint64
- func (w *SPVWallet) GetTransaction(txid chainhash.Hash) (Txn, error)
- func (w *SPVWallet) HasKey(addr btc.Address) bool
- func (w *SPVWallet) MasterPrivateKey() *hd.ExtendedKey
- func (w *SPVWallet) MasterPublicKey() *hd.ExtendedKey
- func (w *SPVWallet) Multisign(ins []TransactionInput, outs []TransactionOutput, sigs1 []Signature, ...) ([]byte, error)
- func (w *SPVWallet) NewAddress(purpose KeyPurpose) btc.Address
- func (w *SPVWallet) Params() *chaincfg.Params
- func (w *SPVWallet) ReSyncBlockchain(fromHeight int32)
- func (w *SPVWallet) Rebroadcast()
- func (w *SPVWallet) Spend(amount int64, addr btc.Address, feeLevel FeeLevel) (*chainhash.Hash, error)
- func (w *SPVWallet) Start()
- func (w *SPVWallet) SweepAddress(utxos []Utxo, address *btc.Address, key *hd.ExtendedKey, redeemScript *[]byte, ...) (*chainhash.Hash, error)
- func (w *SPVWallet) Transactions() ([]Txn, error)
- type Signature
- type StoredHeader
- type Stxo
- type Stxos
- type TransactionCallback
- type TransactionInput
- type TransactionOutput
- type TransactionRecord
- type TxStore
- func (ts *TxStore) CheckDoubleSpends(argTx *wire.MsgTx) ([]*chainhash.Hash, error)
- func (ts *TxStore) GetCurrentKey(purpose KeyPurpose) (*hd.ExtendedKey, error)
- func (ts *TxStore) GetFreshKey(purpose KeyPurpose) *hd.ExtendedKey
- func (ts *TxStore) GetKeyForScript(scriptPubKey []byte) (*hd.ExtendedKey, error)
- func (ts *TxStore) GetKeys() []*hd.ExtendedKey
- func (ts *TxStore) GetPendingInv() (*wire.MsgInv, error)
- func (ts *TxStore) GimmeFilter() (*bloom.Filter, error)
- func (ts *TxStore) Ingest(tx *wire.MsgTx, height int32) (uint32, error)
- func (ts *TxStore) PopulateAdrs() error
- type Txn
- type Txns
- type Utxo
- type Utxos
- type WatchedScripts
Constants ¶
const ( SYNCING = 0 WAITING = 1 REORG = 2 )
const ( MAINNET_CHECKPOINT_HEIGHT = 443520 TESTNET3_CHECKPOINT_HEIGHT = 1114848 REGTEST_CHECKPOINT_HEIGHT = 0 )
const ( PRIOIRTY FeeLevel = 0 NORMAL = 1 ECONOMIC = 2 FEE_BUMP = 3 )
const ( // RedeemP2PKHSigScriptSize is the worst case (largest) serialize size // of a transaction input script that redeems a compressed P2PKH output. // It is calculated as: // // - OP_DATA_73 // - 72 bytes DER signature + 1 byte sighash // - OP_DATA_33 // - 33 bytes serialized compressed pubkey RedeemP2PKHSigScriptSize = 1 + 73 + 1 + 33 // P2PKHPkScriptSize is the size of a transaction output script that // pays to a compressed pubkey hash. It is calculated as: // // - OP_DUP // - OP_HASH160 // - OP_DATA_20 // - 20 bytes pubkey hash // - OP_EQUALVERIFY // - OP_CHECKSIG P2PKHPkScriptSize = 1 + 1 + 1 + 20 + 1 + 1 // RedeemP2PKHInputSize is the worst case (largest) serialize size of a // transaction input redeeming a compressed P2PKH output. It is // calculated as: // // - 32 bytes previous tx // - 4 bytes output index // - 1 byte compact int encoding value 107 // - 107 bytes signature script // - 4 bytes sequence RedeemP2PKHInputSize = 32 + 4 + 1 + RedeemP2PKHSigScriptSize + 4 // P2PKHOutputSize is the serialize size of a transaction output with a // P2PKH output script. It is calculated as: // // - 8 bytes output value // - 1 byte compact int encoding value 25 // - 25 bytes P2PKH output script P2PKHOutputSize = 8 + 1 + P2PKHPkScriptSize )
Worst case script and input/output size estimates.
const FlagPrefix = 0x00
const LOOKAHEADWINDOW = 100
const MAX_HEADERS = 2000
const WALLET_VERSION = "0.1.0"
Variables ¶
var ( BKTHeaders = []byte("Headers") BKTChainTip = []byte("ChainTip") KEYChainTip = []byte("ChainTip") )
var ( // ErrTorInvalidAddressResponse indicates an invalid address was // returned by the Tor DNS resolver. ErrTorInvalidAddressResponse = errors.New("invalid address response") // ErrTorInvalidProxyResponse indicates the Tor proxy returned a // response in an unexpected format. ErrTorInvalidProxyResponse = errors.New("invalid proxy response") // ErrTorUnrecognizedAuthMethod indicates the authentication method // provided is not recognized. ErrTorUnrecognizedAuthMethod = errors.New("invalid proxy authentication method") )
var (
MAX_UNCONFIRMED_TIME time.Duration = time.Hour * 24 * 7
)
Functions ¶
func EstimateSerializeSize ¶
EstimateSerializeSize returns a worst case serialize size estimate for a signed transaction that spends inputCount number of compressed P2PKH outputs and contains each transaction output from txOuts. The estimated size is incremented for an additional P2PKH change output if addChangeOutput is true.
func MakeMerkleParent ¶
func SumOutputSerializeSizes ¶
SumOutputSerializeSizes sums up the serialized size of the supplied outputs.
Types ¶
type Blockchain ¶
type Blockchain struct {
// contains filtered or unexported fields
}
Wrapper around Headers implementation that handles all blockchain operations
func NewBlockchain ¶
func NewBlockchain(filePath string, params *chaincfg.Params) (*Blockchain, error)
func (*Blockchain) ChainState ¶
func (b *Blockchain) ChainState() ChainState
func (*Blockchain) CheckHeader ¶
func (b *Blockchain) CheckHeader(header wire.BlockHeader, prevHeader StoredHeader) bool
func (*Blockchain) Close ¶
func (b *Blockchain) Close()
func (*Blockchain) CommitHeader ¶
func (b *Blockchain) CommitHeader(header wire.BlockHeader) (bool, *StoredHeader, uint32, error)
func (*Blockchain) GetBlockLocatorHashes ¶
func (b *Blockchain) GetBlockLocatorHashes() []*chainhash.Hash
func (*Blockchain) GetEpoch ¶
func (b *Blockchain) GetEpoch() (*wire.BlockHeader, error)
func (*Blockchain) GetLastGoodHeader ¶
func (b *Blockchain) GetLastGoodHeader(bestHeader, prevBestHeader StoredHeader) (*StoredHeader, error)
Returns last header before reorg point
func (*Blockchain) GetNPrevBlockHashes ¶
func (b *Blockchain) GetNPrevBlockHashes(n int) []*chainhash.Hash
func (*Blockchain) SetChainState ¶
func (b *Blockchain) SetChainState(state ChainState)
type ChainState ¶
type ChainState int
type Coin ¶
type Config ¶
type Config struct { // Network parameters. Set mainnet, testnet, or regtest using this. Params *chaincfg.Params // Bip39 mnemonic string. If empty a new mnemonic will be created. Mnemonic string // The user-agent that shall be visible to peers UserAgent string // Location of the data directory RepoPath string // An implementation of the Datastore interface DB Datastore // If you wish to connect to a single trusted peer set this. Otherwise leave nil. TrustedPeer net.Addr // A Tor proxy can be set here causing the wallet will use Tor Proxy proxy.Dialer // The default fee-per-byte for each level LowFee uint64 MediumFee uint64 HighFee uint64 // The highest allowable fee-per-byte MaxFee uint64 // External API to query to look up fees. If this field is nil then the default fees will be used. // If the API is unreachable then the default fees will likewise be used. If the API returns a fee // greater than MaxFee then the MaxFee will be used in place. The API response must be formatted as // { "fastestFee": 40, "halfHourFee": 20, "hourFee": 10 } FeeAPI url.URL // A logger. You can write the logs to file or stdout or however else you want. Logger logging.Backend }
func NewDefaultConfig ¶
func NewDefaultConfig() *Config
type Datastore ¶
type Datastore interface { Utxos() Utxos Stxos() Stxos Txns() Txns Keys() Keys WatchedScripts() WatchedScripts }
type FeeLevel ¶
type FeeLevel int
Selecting the correct fee for a transaction can be difficult for end users. We try to simplify this by create three generic fee levels (the exact data for which can either be hardcoded or fetched via API).
type HeaderDB ¶
type HeaderDB struct {
// contains filtered or unexported fields
}
HeaderDB implements Headers using bolt DB
func NewHeaderDB ¶
func (*HeaderDB) GetBestHeader ¶
func (h *HeaderDB) GetBestHeader() (sh StoredHeader, err error)
func (*HeaderDB) GetPreviousHeader ¶
func (h *HeaderDB) GetPreviousHeader(header wire.BlockHeader) (sh StoredHeader, err error)
type Headers ¶
type Headers interface { // Put a block header to the database // Total work and height are required to be calculated prior to insertion // If this is the new best header, the chain tip should also be updated Put(header StoredHeader, newBestHeader bool) error // Delete all headers after the MAX_HEADERS most recent Prune() error // Returns all information about the previous header GetPreviousHeader(header wire.BlockHeader) (StoredHeader, error) // Retreive the best header from the database GetBestHeader() (StoredHeader, error) // Get the height of chain Height() (uint32, error) // Cleanly close the db Close() // Print all headers Print(io.Writer) }
Database interface for storing block headers
type KeyPath ¶
type KeyPath struct { Purpose KeyPurpose Index int }
type KeyPurpose ¶
type KeyPurpose int
The end leaves on the HD wallet have only two possible values. External keys are those given to other people for the purpose of receiving transactions. These may include keys used for refund addresses. Internal keys are used only by the wallet, primarily for change addresses but could also be used for shuffling around UTXOs.
const ( EXTERNAL KeyPurpose = 0 INTERNAL = 1 )
type Keys ¶
type Keys interface { // Put a bip32 key to the database Put(scriptPubKey []byte, keyPath KeyPath) error // Import a loose private key not part of the keychain ImportKey(scriptPubKey []byte, key *btcec.PrivateKey) error // Mark the script as used MarkKeyAsUsed(scriptPubKey []byte) error // Fetch the last index for the given key purpose // The bool should state whether the key has been used or not GetLastKeyIndex(purpose KeyPurpose) (int, bool, error) // Returns the first unused path for the given purpose GetPathForScript(scriptPubKey []byte) (KeyPath, error) // Returns an imported private key given a script GetKeyForScript(scriptPubKey []byte) (*btcec.PrivateKey, error) // Get a list of unused key indexes for the given purpose GetUnused(purpose KeyPurpose) ([]int, error) // Fetch all key paths GetAll() ([]KeyPath, error) // Get the number of unused keys following the last used key // for each key purpose. GetLookaheadWindows() map[KeyPurpose]int }
Keys provides a database interface for the wallet to save key material, track used keys, and manage the look ahead window.
type PeerManager ¶
type PeerManager struct {
// contains filtered or unexported fields
}
func NewPeerManager ¶
func NewPeerManager(config *PeerManagerConfig) (*PeerManager, error)
func (*PeerManager) CheckForMoreBlocks ¶
func (pm *PeerManager) CheckForMoreBlocks(height uint32) (moar bool)
Iterates over our peers and sees if any are reporting a height greater than our height. If so switch them to the download peer and start the chain download again.
func (*PeerManager) ConnectedPeers ¶
func (pm *PeerManager) ConnectedPeers() []*peer.Peer
func (*PeerManager) DownloadPeer ¶
func (pm *PeerManager) DownloadPeer() *peer.Peer
func (*PeerManager) Start ¶
func (pm *PeerManager) Start()
func (*PeerManager) Stop ¶
func (pm *PeerManager) Stop()
type PeerManagerConfig ¶
type PeerManagerConfig struct { // The network parameters to use Params *chaincfg.Params // The target number of outbound peers. Defaults to 10. TargetOutbound uint32 // Duration of time to retry a connection. Defaults to 5 seconds. RetryDuration time.Duration // UserAgentName specifies the user agent name to advertise. It is // highly recommended to specify this value. UserAgentName string // UserAgentVersion specifies the user agent version to advertise. It // is highly recommended to specify this value and that it follows the // form "major.minor.revision" e.g. "2.6.41". UserAgentVersion string // The directory to store cached peers AddressCacheDir string // If this field is not nil the PeerManager will only connect to this address TrustedPeer net.Addr // Function to get bloom filter to give to peers GetFilter func() (*bloom.Filter, error) // Function to beging chain download StartChainDownload func(*peer.Peer) // Functon returns info about the last block in the chain GetNewestBlock func() (hash *chainhash.Hash, height int32, err error) // Listeners to handle messages from peers. If nil, no messages will be handled. Listeners *peer.MessageListeners // An optional proxy dialer. Will use net.Dial if nil. Proxy proxy.Dialer }
type SPVWallet ¶
type SPVWallet struct { PeerManager *PeerManager // contains filtered or unexported fields }
func NewSPVWallet ¶
func (*SPVWallet) AddTransactionListener ¶
func (w *SPVWallet) AddTransactionListener(callback func(TransactionCallback))
func (*SPVWallet) AddWatchedScript ¶
func (*SPVWallet) CreateMultisigSignature ¶
func (w *SPVWallet) CreateMultisigSignature(ins []TransactionInput, outs []TransactionOutput, key *hd.ExtendedKey, redeemScript []byte, feePerByte uint64) ([]Signature, error)
func (*SPVWallet) CurrencyCode ¶
func (*SPVWallet) CurrentAddress ¶
func (w *SPVWallet) CurrentAddress(purpose KeyPurpose) btc.Address
func (*SPVWallet) EstimateFee ¶
func (w *SPVWallet) EstimateFee(ins []TransactionInput, outs []TransactionOutput, feePerByte uint64) uint64
func (*SPVWallet) GenerateMultisigScript ¶
func (*SPVWallet) GetConfirmations ¶
func (*SPVWallet) GetFeePerByte ¶
func (*SPVWallet) GetTransaction ¶
func (*SPVWallet) MasterPrivateKey ¶
func (w *SPVWallet) MasterPrivateKey() *hd.ExtendedKey
func (*SPVWallet) MasterPublicKey ¶
func (w *SPVWallet) MasterPublicKey() *hd.ExtendedKey
func (*SPVWallet) Multisign ¶
func (w *SPVWallet) Multisign(ins []TransactionInput, outs []TransactionOutput, sigs1 []Signature, sigs2 []Signature, redeemScript []byte, feePerByte uint64, broadcast bool) ([]byte, error)
func (*SPVWallet) NewAddress ¶
func (w *SPVWallet) NewAddress(purpose KeyPurpose) btc.Address
func (*SPVWallet) ReSyncBlockchain ¶
func (*SPVWallet) Rebroadcast ¶
func (w *SPVWallet) Rebroadcast()
func (*SPVWallet) SweepAddress ¶
func (*SPVWallet) Transactions ¶
type Signature ¶
This object contains a single signature for a multisig transaction. InputIndex specifies the index for which this signature applies.
type StoredHeader ¶
type StoredHeader struct {
// contains filtered or unexported fields
}
type TransactionCallback ¶
type TransactionCallback struct { Txid []byte Outputs []TransactionOutput Inputs []TransactionInput Height int32 Timestamp time.Time Value int64 WatchOnly bool }
This callback is passed to any registered transaction listeners when a transaction is detected for the wallet.
type TransactionInput ¶
type TransactionOutput ¶
type TransactionRecord ¶
type TransactionRecord struct { Txid string Index uint32 Value int64 ScriptPubKey string Spent bool }
OpenBazaar uses p2sh addresses for escrow. This object can be used to store a record of a transaction going into or out of such an address. Incoming transactions should have a positive value and be market as spent when the UXTO is spent. Outgoing transactions should have a negative value. The spent field isn't relevant for outgoing transactions.
type TxStore ¶
type TxStore struct { Adrs []btcutil.Address Param *chaincfg.Params Datastore // contains filtered or unexported fields }
func NewTxStore ¶
func (*TxStore) CheckDoubleSpends ¶
GetDoubleSpends takes a transaction and compares it with all transactions in the db. It returns a slice of all txids in the db which are double spent by the received tx.
func (*TxStore) GetCurrentKey ¶
func (ts *TxStore) GetCurrentKey(purpose KeyPurpose) (*hd.ExtendedKey, error)
func (*TxStore) GetFreshKey ¶
func (ts *TxStore) GetFreshKey(purpose KeyPurpose) *hd.ExtendedKey
func (*TxStore) GetKeyForScript ¶
func (ts *TxStore) GetKeyForScript(scriptPubKey []byte) (*hd.ExtendedKey, error)
func (*TxStore) GetKeys ¶
func (ts *TxStore) GetKeys() []*hd.ExtendedKey
func (*TxStore) GetPendingInv ¶
GetPendingInv returns an inv message containing all txs known to the db which are at height 0 (not known to be confirmed). This can be useful on startup or to rebroadcast unconfirmed txs.
func (*TxStore) GimmeFilter ¶
... or I'm gonna fade away
func (*TxStore) Ingest ¶
Ingest puts a tx into the DB atomically. This can result in a gain, a loss, or no result. Gain or loss in satoshis is returned.
func (*TxStore) PopulateAdrs ¶
PopulateAdrs just puts a bunch of adrs in ram; it doesn't touch the DB
type Txns ¶
type Txns interface { // Put a new transaction to the database Put(txn *wire.MsgTx, value, height int, timestamp time.Time, watchOnly bool) error // Fetch a raw tx and it's metadata given a hash Get(txid chainhash.Hash) (*wire.MsgTx, Txn, error) // Fetch all transactions from the db GetAll(includeWatchOnly bool) ([]Txn, error) // Update the height of a transaction UpdateHeight(txid chainhash.Hash, height int) error // Delete a transactions from the db Delete(txid *chainhash.Hash) error }
type Utxo ¶
type Utxo struct { // Previous txid and output index Op wire.OutPoint // Block height where this tx was confirmed, 0 for unconfirmed AtHeight int32 // The higher the better Value int64 // Output script ScriptPubkey []byte // If true this utxo will not be selected for spending. The primary // purpose is track multisig UTXOs which must have separate handling // to spend. WatchOnly bool }