Documentation
¶
Index ¶
- Constants
- Variables
- func CheckDoubleSpends(argTx *wire.MsgTx, txs []*wire.MsgTx) ([]*chainhash.Hash, error)
- 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 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, uint32, error)
- func (b *Blockchain) GetBlockLocatorHashes() []*chainhash.Hash
- func (b *Blockchain) GetEpoch() (*wire.BlockHeader, 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()
- 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 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) 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) GetFeePerByte(feeLevel FeeLevel) uint64
- 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, ...) error
- 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) error
- func (w *SPVWallet) Start()
- func (w *SPVWallet) SweepMultisig(utxos []Utxo, address *btc.Address, key *hd.ExtendedKey, redeemScript []byte, ...) 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) 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 = 1058400 REGTEST_CHECKPOINT_HEIGHT = 0 )
const ( PRIOIRTY FeeLevel = 0 NORMAL = 1 ECONOMIC = 2 )
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 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 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 ¶
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, uint32, error)
func (*Blockchain) GetBlockLocatorHashes ¶
func (b *Blockchain) GetBlockLocatorHashes() []*chainhash.Hash
func (*Blockchain) GetEpoch ¶
func (b *Blockchain) GetEpoch() (*wire.BlockHeader, error)
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 {
// 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 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()
}
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 the first unused index 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 *Config) (*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 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) GetFeePerByte ¶
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) error
func (*SPVWallet) ReSyncBlockchain ¶
func (*SPVWallet) Rebroadcast ¶
func (w *SPVWallet) Rebroadcast()
func (*SPVWallet) SweepMultisig ¶
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
}
This callback is passed to any registered transaction listeners when a transaction is detected for the wallet. TODO: we can maybe get rid of this and just use the btcd msgTx, but we do need the linked scriptPubkey TODO: which is not included in that object. We could possibly re-purpose the signature field.
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) 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) error
// Fetch a tx, height, and timestamp given it's hash
Get(txid chainhash.Hash) (*wire.MsgTx, int32, time.Time, error)
// Fetch all transactions from the db
GetAll() ([]Txn, error)
// Mark a transaction as dead
MarkAsDead(txid chainhash.Hash) 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.
Freeze bool
}