Пример #1
0
// Open loads an already-created wallet from the passed database and namespaces.
func Open(pubPass []byte, params *chaincfg.Params, db walletdb.DB, waddrmgrNS, wtxmgrNS walletdb.Namespace, cbs *waddrmgr.OpenCallbacks) (*Wallet, error) {
	addrMgr, err := waddrmgr.Open(waddrmgrNS, pubPass, params, cbs)
	if err != nil {
		return nil, err
	}
	txMgr, err := wtxmgr.Open(wtxmgrNS)
	if err != nil {
		if !wtxmgr.IsNoExists(err) {
			return nil, err
		}
		log.Info("No recorded transaction history -- needs full rescan")
		err = addrMgr.SetSyncedTo(nil)
		if err != nil {
			return nil, err
		}
		txMgr, err = wtxmgr.Create(wtxmgrNS)
		if err != nil {
			return nil, err
		}
	}

	log.Infof("Opened wallet") // TODO: log balance? last sync height?
	w := &Wallet{
		db:                  db,
		Manager:             addrMgr,
		TxStore:             txMgr,
		lockedOutpoints:     map[wire.OutPoint]struct{}{},
		FeeIncrement:        defaultFeeIncrement,
		rescanAddJob:        make(chan *RescanJob),
		rescanBatch:         make(chan *rescanBatch),
		rescanNotifications: make(chan interface{}),
		rescanProgress:      make(chan *RescanProgressMsg),
		rescanFinished:      make(chan *RescanFinishedMsg),
		createTxRequests:    make(chan createTxRequest),
		unlockRequests:      make(chan unlockRequest),
		lockRequests:        make(chan struct{}),
		holdUnlockRequests:  make(chan chan HeldUnlock),
		lockState:           make(chan bool),
		changePassphrase:    make(chan changePassphraseRequest),
		chainParams:         params,
		quit:                make(chan struct{}),
	}
	return w, nil
}
Пример #2
0
func exampleCreateTxStore() (*wtxmgr.Store, func(), error) {
	dir, err := ioutil.TempDir("", "pool_test_txstore")
	if err != nil {
		return nil, nil, err
	}
	db, err := walletdb.Create("bdb", filepath.Join(dir, "txstore.db"))
	if err != nil {
		return nil, nil, err
	}
	wtxmgrNamespace, err := db.Namespace([]byte("testtxstore"))
	if err != nil {
		return nil, nil, err
	}
	s, err := wtxmgr.Create(wtxmgrNamespace)
	if err != nil {
		return nil, nil, err
	}
	return s, func() { os.RemoveAll(dir) }, nil
}
Пример #3
0
func TstCreateTxStore(t *testing.T) (store *wtxmgr.Store, tearDown func()) {
	dir, err := ioutil.TempDir("", "pool_test_txstore")
	if err != nil {
		t.Fatalf("Failed to create txstore dir: %v", err)
	}
	db, err := walletdb.Create("bdb", filepath.Join(dir, "txstore.db"))
	if err != nil {
		t.Fatalf("Failed to create walletdb: %v", err)
	}
	wtxmgrNamespace, err := db.Namespace([]byte("testtxstore"))
	if err != nil {
		t.Fatalf("Failed to create walletdb namespace: %v", err)
	}
	s, err := wtxmgr.Create(wtxmgrNamespace)
	if err != nil {
		t.Fatalf("Failed to create txstore: %v", err)
	}
	return s, func() { os.RemoveAll(dir) }
}
Пример #4
0
// CreateNewWallet creates a new wallet using the provided public and private
// passphrases.  The seed is optional.  If non-nil, addresses are derived from
// this seed.  If nil, a secure random seed is generated.
func (l *Loader) CreateNewWallet(pubPassphrase, privPassphrase, seed []byte) (*Wallet, error) {
	defer l.mu.Unlock()
	l.mu.Lock()

	if l.wallet != nil {
		return nil, ErrLoaded
	}

	dbPath := filepath.Join(l.dbDirPath, walletDbName)
	exists, err := fileExists(dbPath)
	if err != nil {
		return nil, err
	}
	if exists {
		return nil, ErrExists
	}

	// Create the wallet database backed by bolt db.
	err = os.MkdirAll(l.dbDirPath, 0700)
	if err != nil {
		return nil, err
	}
	db, err := walletdb.Create("bdb", dbPath)
	if err != nil {
		return nil, err
	}

	// Create the address manager.
	if seed != nil {
		if len(seed) < hdkeychain.MinSeedBytes ||
			len(seed) > hdkeychain.MaxSeedBytes {

			return nil, hdkeychain.ErrInvalidSeedLen
		}
	}
	addrMgrNamespace, err := db.Namespace(waddrmgrNamespaceKey)
	if err != nil {
		return nil, err
	}
	_, err = waddrmgr.Create(addrMgrNamespace, seed, pubPassphrase,
		privPassphrase, l.chainParams, nil)
	if err != nil {
		return nil, err
	}

	// Create empty transaction manager.
	txMgrNamespace, err := db.Namespace(wtxmgrNamespaceKey)
	if err != nil {
		return nil, err
	}
	_, err = wtxmgr.Create(txMgrNamespace)
	if err != nil {
		return nil, err
	}

	// Open the newly-created wallet.
	w, err := Open(pubPassphrase, l.chainParams, db, addrMgrNamespace, txMgrNamespace, nil)
	if err != nil {
		return nil, err
	}

	l.onLoaded(w, db)
	return w, nil
}
Пример #5
0
func Example_basicUsage() {
	// Open the database.
	db, dbTeardown, err := testDB()
	defer dbTeardown()
	if err != nil {
		fmt.Println(err)
		return
	}

	// Create or open a db namespace for the transaction store.
	ns, err := db.Namespace([]byte("txstore"))
	if err != nil {
		fmt.Println(err)
		return
	}

	// Create (or open) the transaction store in the provided namespace.
	s, err := wtxmgr.Create(ns)
	if err != nil {
		fmt.Println(err)
		return
	}

	// Insert an unmined transaction that outputs 10 BTC to a wallet address
	// at output 0.
	err = s.InsertTx(exampleTxRecordA, nil)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = s.AddCredit(exampleTxRecordA, nil, 0, false)
	if err != nil {
		fmt.Println(err)
		return
	}

	// Insert a second transaction which spends the output, and creates two
	// outputs.  Mark the second one (5 BTC) as wallet change.
	err = s.InsertTx(exampleTxRecordB, nil)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = s.AddCredit(exampleTxRecordB, nil, 1, true)
	if err != nil {
		fmt.Println(err)
		return
	}

	// Mine each transaction in a block at height 100.
	err = s.InsertTx(exampleTxRecordA, &exampleBlock100)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = s.InsertTx(exampleTxRecordB, &exampleBlock100)
	if err != nil {
		fmt.Println(err)
		return
	}

	// Print the one confirmation balance.
	bal, err := s.Balance(1, 100)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(bal)

	// Fetch unspent outputs.
	utxos, err := s.UnspentOutputs()
	if err != nil {
		fmt.Println(err)
	}
	expectedOutPoint := wire.OutPoint{Hash: exampleTxRecordB.Hash, Index: 1}
	for _, utxo := range utxos {
		fmt.Println(utxo.OutPoint == expectedOutPoint)
	}

	// Output:
	// 5 BTC
	// true
}