/BitcoinArmory

Python-Based Bitcoin Software

Primary LanguageC++OtherNOASSERTION

################################################################################
#                                                                              #
#  Copyright (C) 2011-2012, Alan C. Reiner    <alan.reiner@gmail.com>          #
#  Distributed under the GNU Affero General Public License (AGPL v3)           #
#  See LICENSE or http://www.gnu.org/licenses/agpl.html                        #
#                                                                              #
################################################################################

********************************************************************************
*
* Project:    Armory
* Author:     Alan Reiner
* Orig Date:  02 Feb, 2011
* Descr:      Armory is a full-featured Bitcoin client, offering a dozen 
*             innovative features not found in any other client software!
*             Manage multiple wallets (deterministic and watching-only), 
*             print paper backups that work forever, import or sweep private 
*             keys, and keep your savings in a computer that never touches 
*             the internet, while still being able to manage incoming payments, 
*             and create outgoing payments with the help of a USB key.
* 
*             Multi-signature transactions are accommodated under-the-hood 
*             about 80%, and will be completed and integrated into the UI soon.
*
*             ***As of version 0.7-alpha, Armory NO LONGER requires holding the
*             blockchain in RAM, and systems with even 1GB of RAM should be able
*             to use Armory.  The drawback is that full rescans will take approx
*             30-120 seconds depending on the system, and currently one is done
*             on every load.
*             
*             ***Armory has no independent networking components built in.
*             Instead, it relies on on the Satoshi client to securely connect 
*             to peers, validate blockchain data, and broadcast transactions
*             for us.  Although it was initially planned to cut the umbilical
*             cord to the Satoshi client and implement independent networking,
*             that could be a multi-month task, and instead I may resort to 
*             cannabilizing the Satoshi code, or a related project, to integrate 
*             and existing, secure, robust, networking system into Armory with
*             out risks of major bugs and blockchain forks.
*           
*
********************************************************************************
*
* Please take a moment to donate 1.0 BTC!   1ArmoryXcfq7TnCSuZa9fQjRYwJ4bkRKfv 
*
********************************************************************************

********************************************************************************
*  STATUS:   Last Updated - 28 Mar, 2012
*            Legend:   
*                      _    not implemented
*                      .    implemented but not tested
*                      +    implemented and partially tested
*                      X    implemented and tested
*  
*                                        
*  Library Functional Status (armoryengine.py)
*
*     ---------------------------------------------------------------
*      (01)  Ser/Unser Block Objects              X
*      (02)  Hash160/Hash256                      X
*      (03)  Difficulty calcs                     X
*      (04)  Address Generation                   X
*      (05)  Address Verify/Manip                 X
*     ---------------------------------------------------------------
*      (06)  BlkHeaders read/scan/org             X
*      (07)  BlkHeaders reorgs                    X
*      (08)  Blockchain read/scan/org             X
*      (09)  Blockchain reorgs                    X
*      (10)  Blockchain verify integrity          X
*     ---------------------------------------------------------------
*      (11)  NonStd Tx Detection                  +
*      (12)  Arbitrary script parsing             X
*      (13)  OP_CHECKSIG/CHECKMULTISIG            X
*      (14*) Arbitrary script eval                X
*      (15)  ECDSA Sign/Verify                    X
*     ---------------------------------------------------------------
*      (16)  Address/Wallet tracking              X
*      (17)  Scan blkchain for Tx                 X
*      (18)  Scan blkchain for NonStd             X
*      (19)  Reorg w/ double-spend                X
*      (20)  Add new blockdata real-time          X
*     ---------------------------------------------------------------
*      (21)  SecureBinaryData                     X
*      (22)  Crypto++ ECDSA Hooked                X
*      (23)  Crypto++ AES Hooked                  X
*      (24)  Crypto++ RandNumGen Hooked           X
*      (25)  Key-derivation (time&mem bound)      X
*     ---------------------------------------------------------------
*      (26)  Address Encrypt (AES)                X
*      (27)  Address Encrypt (Change Passwd)      X
*      (28)  Deterministic Addr Gen (ECDSAPriv)   X
*      (29)  Deterministic Addr Gen (ECDSAPub)    X
*      (30)  Deterministic Addr Gen (Random)     
*     ---------------------------------------------------------------
*      (31)  PyWallet/Addr File I/O               X
*      (32)  SelectCoins for tx                   X
*      (33)  Tx fee calculations                  X
*      (34)  Tx construct given inputs            X
*      (35)  Distribution Proposals (std)         X
*      (36*) Distribution Proposals (multi-sig)   .
*     ---------------------------------------------------------------
*
*
*  GUI/Client Functionality Status (ArmoryQt.py + supporting python files):
*     ---------------------------------------------------------------
*      (01)  Multiple wallets                     X
*      (02)  Deterministic Wallets                X
*      (03)  Watching-only wallets                X
*      (04)  Printing Paper Backups               X
*      (05)  Restore paper backup (typed)         X
*     ---------------------------------------------------------------
*      (06)  Restore paper backup (scann QR)     
*      (07)  Import/Sweep Hex Priv Keys           X
*      (08)  Import/Sweep Base58 Priv Keys        X
*      (09)  Import/Sweep Mini-Priv Key Format    X
*      (10)  Zero-confirmation transactions       X
*     ---------------------------------------------------------------
*      (11)  Spend change outputs immediately     X
*      (12)  User modes (Std/Adv/Dev)             X
*      (13)  SelectCoins customization            X  (impl but no GUI options, yet)
*      (14)  Guaranateed Tx Fee calculation       X  (impl but tx will not be accepted)
*      (15)  Full Wallet encryption with KDF      X
*     ---------------------------------------------------------------
*      (16)  Change encryption passphrase         X
*      (17)  Change key-derivation time/mem 
*      (18)  COMPLETE OFFLINE WALLET MANAGEMENT   X
*      (19)  Individual Key/Address backup        X
*      (20)  Convert Satoshi wallets to Armory    X
*     ---------------------------------------------------------------
*      (21)  Address books                         
*      (22)  System-tray notifications           
*      (23)  Multi-signature Tx handling          .
*
*
*
********************************************************************************


Building Armory from Source:   
   http://bitcoinarmory.com/index.php/building-armory-from-source


********************************************************************************

   Information on dependencies (mainly for developers)
   (much of this information may be out-of-date: use at your own risk!)

********************************************************************************

Armory contains over 20,000 lines of code, between the C++ and python
libraries.  This can be very confusing for someone unfamiliar with the 
code (you).  Below I have attempted to illustrate the CONOPS (concept of 
operations) that the library was designed for, so you know how to use it 
in your own development activities.  There is a TON of sample code in
the following three files:

   [**SWIG**]   unittest.py    (this has almost everything!)

   [ C++    ]   cppForSwig/BlockUtilsTest.cpp
   [ Python ]   armoryengine.py

But of course, sample code alone does not make great documentation.  I will
attempt to provide reference info for everything else you need to know, here.
For a list of library features, see the STATUS table in the README.  Note
that all features with an X in either column are accessible in SWIG.

 
################################################################################
***Dependencies (from README) ***
 
   - Crypto++  
            Linux:   Install package "libcrypto++-dev"
            Windows: Download from "http://www.cryptopp.com/#download"
            (MSVS: Copy cryptopp source dir into same location as .sln)

   - SWIG
            Linux:   Install package "swig"
            Windows: "http://www.swig.org/download.html"
            (MSVS: Copy swigwin-2.x directory next to cryptopp as "swigwin")

   - Python 2.6/2.7
            Linux:   Should be preinstalled...
            Windows: "http://www.python.org/getit/"

   - Python Twisted -- asynchronous networking
            Linux:   Install package 'python-twisted'
            Windows: "http://twistedmatrix.com/trac/wiki/Downloads"

   - PyQt 4 (for Python 2.X)
            Linux:   Install  "libqtcore4", "libqt4-dev" and "python-qt4"
            Windows: "http://www.riverbankcomputing.co.uk/software/pyqt/download"
                     Also will need the QtSDK

   - qt4reactor.py -- combined eventloop for PyQt and Twisted
            All OS:   https://launchpad.net/qt4reactor
            Windows Only:  qt4reactor relies on pywin32 (for win32event module)
                        http://sourceforge.net/projects/pywin32/files/pywin32/Build216/

   - pywin32
   - py2exe
            (OPTIONAL - if you want to make a standalone executable in Windows)
            Windows: http://www.py2exe.org/



*** Compiling ***

   Linux:   From the cppForSwig directory "make" to make the C++ code alone, 
            "make swig" to create and compile the SWIG wrappers


            sudo apt-get install git-core build-essential libcrypto++-dev swig libqtcore4 libqt4-dev python-qt4 python-dev python-twisted
            git clone git://github.com/etotheipi/BitcoinArmory.git
            cd BitcoinArmory
            git checkout qtdev
            cd cppForSwig
            make swig
            cd ..
            python ArmoryQt.py


            NOTE:  If you get a "undefined reference in QtCore.so", it's likely
                   due to another library installed that hijacked the system
                   Qt installation.  In my case, it was a CUDA installation
                   which provided its own, older version of QtCore which was 
                   causing this issue.
   
   Windows: MSVS 2010 vcxproj included but not maintained.  Only compiles C++.
            MSVS 2005 vcproj included.  Setup to compile everything,
            and even runs swig and py2exe as pre- and post-build events.            

            In windows you're going to have to do a bit more work than just
            installing the programs below.  Specifically, you need to add
            a few libraries I couldn't distributed through git (for various
            reasons), and also make sure the MSVS has the right includes
            for your python version/location.

            Most importantly, check that the following settings match your
            python installation (currently configured for Python 2.6 in 
            the MSVS 2005 project):
            
               C/C++  --> General --> Additional Include Directories:
               Linker --> General --> Additional Library Directories:
               Linker --> Input   --> Additional Library Directories:



   SWIG Notes:
            Running SWIG takes in all the source code and the CppBlockUtils.i
            and creates a C++ source file called CppBlockUtils_wrap.cxx, as 
            well as CppBlockUtils.py.
            The result of compiling this source file in linux:
               _CppBlockUtils.so
            In windows, compiling will generally produce
               _CppBlockUtils.dll  --> MUST BE RENAMED --> _CppBlockUtils.pyd
               
            The previously-created CppBlockUtils.py expects to find this 
            shared-object or pyd in the same directory.


   PyQt4 Notes:
            Getting PyQt4 setup in Linux is trivial: "apt-get" install as above

            Getting PyQt4 setup in Windows was a pain.  I'm still not positive
            I could repeat the process and succeed.  It does involve:
               -- Getting and installing QtSDK
               -- Getting mingw matching you QtSDK version
               -- Unzip mingw somewhere and referencing it when install QtSDK
               -- Download PyQt4 matching your python version
               -- Manipulate your PATH (environment variables) to make sure
                  it has PyQt4 directory (C:\Python2X\Lib\site-packages\PyQt4)
    

   
################################################################################
#
# NOTE:  05 Dec, 2011
#        This documentation is accurate, but only represents a fraction of the
#        available functionality in the libraries.  I will update this as soon
#        as I get the first client release out of the way.  For now, you can
#        can see most of the C++ methods below (accessed via Python), and then
#        do an "import armoryengine; help(armoryengine)" to see a MASSIVE
#        list of the available classes and methods.  Seriously... it's huge.
#
################################################################################
*** Documentation ***

   This documentation is broken into three sections:

      - SWIG
      - C++
      - Python

   Most of what you need to know is actually in the C++ section, since every 
   C++ function call is mapped directly into python calls through SWIG.  These
   C++ functions are at the heart of everything you do that touches the block-
   chain.  

   If you are impatient, just jump to the "C++ Code Overview" and you will
   see 80% of what you need in the methods lists there.

   Python will be needed for anything involving Base-58 address strings,
   or ECDSA operations.  Signing and verification works, though, it's not part
   of any demo, besides unittest.py which verifies a tx from the blockchain
   
   I will eventually be adding sample projects that exhaustively demonstrate 
   each feature of the library in the combined SWIG interface.  



################################################################################
*** SWIG Code Overview ***

   There is no explicit library file for combining python and C++ methods.  You
   import both CppBlockUtils and pybtcengine in python, and off you go. 

   The one important thing to know is that the modules are spread out in the 
   project directory, and thus you need to add some directories to your path.
   The best solution is to append the paths you need at the top of your python
   file.  You need to make sure that the directories containing
      pybtcengine.py
      CppBlockUtils.py
      _CppBlockUtils.so (linux) _CppBlockUtils.pyd (windows)

   are all on your path.

   For instance, if you are running the example blockexplorer in the pyqt dir,
   you will need the following lines at the top of your script to point python
   to search the other directories for the modules:

      import sys
      sys.path.append('..')
      sys.path.append('../cppForSwig')
      from pybtcengine import *
      from CppBlockUtils import *


   Most of the CONOPS for using the combined library is actually knowing how
   to use the C++ code.  Most calls you make will be on SWIGified objects
   pulled in through the .dll(.pyd)/.so.  In this case, the best documentation 
   really is the example code.  Look at cppForSwig/testswig.py; this file
   has examples of nearly every function.  You can use this as a reference
   for what functions require C++ calls, and which ones are from pybtcengine.py.
   In general, if it came from the BlockDataManager:

      bdm = BlockDataManager_FullRam.GetInstance()
      bdm.getTxByHash(...)
      ...

   Then the resulting objects will be C++/SWIG objects.  The list of useful
   methods in the C++ documentation, below, will identify all the available
   methods. 

   **** One other important note:  
   SWIG does *not* work with any overloaded methods involving 
   BinaryData objects:  this is because I created a SWIG typemap to 
   simplify passing binary data between python and C++, but it led to a few 
   important methods getting disabled.  Instead of 
         BtcWallet::addAddress(...)
   use:
         BtcWallet::addAddress_1_(...)
         BtcWallet::addAddress_3_(...)
         BtcWallet::addAddress_5_(...)
   The number at the end specifies how many arguments the method takes.
   The original method has 4 optional arguments, but SWIG didn't know
   what to do with it.

   The same thing needed to be done with 
         BlockDataRef::unserialize()
   replaced with:
         BlockDataRef::unserialize_1_()

   This might be necessary for a few other methods, but I haven't run into
   any of them yet.
   

   
   


################################################################################
*** C++ Code Overview ***

What's there:   
      - Blockchain reading from file, scanning
      - Checking blk0001.dat file integrity
      - Organizing and finding the longest chain
      - Efficient access to ALL data in the blockchain
      - Standard and Non-standard script detection
      - Binary wallet tracking, with address ledgers

What's NOT there:
      - BigNum library:  cannot do any Base58/address manipulations.  
      - ECDSA library:   cannot do any signing/verification operations
                         (however, crypto++ is linked, could be easy to add)                         
      - Address storage: addresses that have not 
                         information on a given address, you must do a full
                         scan of the blockchain, which takes about 5s.  If
                         you need to do this quicker, you can revive some
                         old code I had which took about 30s
      - Constructing transaction packets:  this could be easy to add, since
        the library does make it easy to find all TxOuts for a given wallet


The basics:  The goal of the C++ code is to provide an optimized layer for 
             accessing the blockchain.  It reads the specified blk0001.dat 
             file (where the blockchain is stored in raw, binary form)
             and maintains a series of maps and pointers to this data with
             minimal copy operations.  IT IS VERY FAST. 

             The C++ code has no BigNum or ECDSA code in it, which means
             it cannot sign/verify anything, or calculate address strings.


*************************
Class BinaryData:
   This class is a simple wrapper for {vector<uint8_t>, uint32_t size}.
   It has a ton of convenience methods for searching, slicing and hashing
   these objects.  All data that isn't human-readable strings will be
   passed around with BinaryData objects  (typedef'd to "HashString")

*************************
Class BinaryDataRef:
   This class is REFERENCE class for what would otherwise be used by 
   BinaryData.  It holds a {uint8_t*, uint32_t size}.  Since many of our 
   objects are persistent (see rule 1), it's safe to pass around 
   references to them.  This class has easy conversions to and from 
   BinaryData, and has most of the same methods.
            
*************************
Class BtcUtils:
   This is a helper class that contains methods and constants that might be 
   shared between multiple classes.  THIS IS A STATIC-METHOD-ONLY class. 
   Therefore all methods and members must be scoped with BtcUtils::

   Useful Methods:
      BtcUtils::GenesisHash_;
      BtcUtils::EmptyHash_;
      BtcUtils::MagicBytes_;

      BtcUtils::readVarInt()
      BtcUtils::readVarIntLength()
      BtcUtils::getHash256() 
      BtcUtils::getHash160()
      BtcUtils::calculateMerkleRoot()
      BtcUtils::calculateMerkleTree()

      BtcUtils::TxInCalcLength()
      BtcUtils::TxOutCalcLength()
      BtcUtils::TxCalcLength()

      BtcUtils::getTxInScriptType()
      BtcUtils::getTxOutScriptType()
      BtcUtils::getTxOutRecipientAddr()
      BtcUtils::convertDiffBitsToDouble()

      BtcUtils::getOpCodeName()
      BtcUtils::convertScriptToOpStrings()


*************************
Classes in BlockObjRef:
   These are the core of the library; all these objects have a serialize() 
   and unserialize() method which uses the specified formats in:

      https://en.bitcoin.it/wiki/Protocol_specification

   These objects do not hold any serialized information, only a BinaryDataRef
   to where it is serialized in RAM by the BlockDataManager.  All data that
   is not officially part of its serialized state is stored as extra members

   Useful methods:

     BlockHeaderRef
         BlockHeaderRef::getVersion()
         BlockHeaderRef::getPrevHash()
         BlockHeaderRef::getMerkleRoot()
         BlockHeaderRef::getDifficulty()
         BlockHeaderRef::getTimestamp()
         BlockHeaderRef::getNonce()
         BlockHeaderRef::pprint()  
      
         BlockHeaderRef::serialize()
         BlockHeaderRef::unserialize()

         BlockHeaderRef::getThisHash()
         BlockHeaderRef::getDifficultySum()
         BlockHeaderRef::getBlockSize()     // in bytes
         BlockHeaderRef::getTxRefPtrList()  // access to all Tx's in this block
         BlockHeaderRef::getTxHashList()    // access to all Tx's in this block

         BlockHeaderRef::verifyMerkleRoot()
         BlockHeaderRef::verifyIntegrity()  // checks merkleroot and hash zeros

         
     OutPointRef
         OutPointRef::getTxHash()
         OutPointRef::getTxOutIndex()

         OutPointRef::serialize()
         OutPointRef::unserialize()
   
     TxInRef
         TxInRef::getOutPoint()
         TxInRef::getScript()
         TxInRef::getSequence()
         TxInRef::isCoinbase()
         TxInRef::pprint()

         TxInRef::serialize()
         TxInRef::unserialize()
         TxInRef::getSize()         // number of serialized bytes
         TxInRef::getScriptSize()   // number of serialized bytes

         TxInRef::getScriptType()
         TxInRef::isScriptStandard()
         TxInRef::isScriptCoinbase()
         TxInRef::isScriptSpendCB()
         TxInRef::isScriptUnknown()
         TxInRef::getSenderAddrIfAvailable()  // Coinbase TxIns don't have this

         TxInRef::getCopy()         // Creates TxIn; not used much/ever
         TxInRef::getParentTxPtr()  // Coinbase TxIns don't have this
         
     TxOutRef
         TxOutRef::getValue()
         TxOutRef::getScript()
         TxOutRef::pprint()

         TxOutRef::serialize()
         TxOutRef::unserialize()
         TxOutRef::getSize()         // number of serialized bytes
         TxOutRef::getScriptSize()   // number of serialized bytes

         TxOutRef::isScriptStandard()
         TxOutRef::isScriptCoinbase()
         TxOutRef::isScriptUnknown()

         TxOutRef::getRecipientAddr()
         TxOutRef::getParentTxPtr()
         TxOutRef::getCopy()       // Creates TxOut; not used much/ever
        
   
     TxRef
         TxRef::getVersion()
         TxRef::getNumTxIn()
         TxRef::getNumTxOut()
         TxRef::getTxInRef(index)
         TxRef::getTxOutRef(index)
         TxRef::getLockTime()
         TxRef::pprint()
      
         TxRef::serialize()
         TxRef::unserialize()
         TxRef::getSize()           // number of serialized bytes

         TxRef::getThisHash()

         TxRef::getHeaderPtr()
         TxRef::setHeaderPtr()
         TxRef::getBlockTimestamp()
         TxRef::getBlockHeight()


   
*************************
Classes in BlockObj:
   These are not used much, except for OutPoint which is used as the key
   for some of the maps.  Generally these objects are used if you need to
   make a copy of a *Ref object, but this isn't common.  Also, because of
   their lack of use, they may not have all methods you would expect them 
   to have.  
   
   (NOTE:  you cannot create a BlockObjRef from a BlockObj, because the
           BlockObj does not store a serialization of itself, which is 
           what is needed to create a *Ref object.  You can only go the
           other way.                                                   )


*************************
Class TxIORefPair:
   All Bitcoin transfers are simply converting older TxOuts to newer TxOuts
   by signing a TxIn to prove that you own them.  As such, each TxOut has
   exactly one or zero TxIns.  If it has a TxIn, it is spent and can be
   forgotten.  If not, it is unspent, and availble for use.

   Given the above, maintaining a wallet is much simpler if these objects
   are paired intelligently.  Finding a TxOut during a blockchain scan
   will create an unspent TxIORefPair in your wallet (and a pointer to the
   Tx in which it is found).  When you find a TxIn, it must reference a 
   TxOut that you have already seen, and so we retreive the TxIORefPair
   and update it.  It has now been spent.

   One major benefit of this technique is that it becomes painfully obvious
   which of your TxOuts are available to be spent, and if you are creating
   a lightweight client, you can purge all TxIORefPairs that have both
   objects to save space.

   Useful methods:
      
      TxIORefPair::hasTxOut()
      TxIORefPair::hasTxIn()
      TxIORefPair::hasValue()

      TxIORefPair::getValue()
      TxIORefPair::getTxOutRef()
      TxIORefPair::getTxInRef()
      TxIORefPair::getTxRefOfOutput()
      TxIORefPair::getTxRefOfInput()

      TxIORefPair::setTxInRef()
      TxIORefPair::setTxOutRef()

      TxIORefPair::isUnspent()
      TxIORefPair::isSpent()
   
      TxIORefPair::isStandardTxOutScript()


*************************
Class LedgerEntry:
   This is a reduced form of a transaction.  IT HAS DUAL-UTILITY:  it can
   represent a ledger entry for a single address, or for an entire wallet.
   This is an important distinction since an address is maintained via a 
   list of TxIns and TxOuts, but a wallet only cares about the sum of TxIns
   and TxOuts in the transaction.

   When we use the BtcWallet::scanTx() method, the list of ledger entries
   for both wallet and child addresses will be updated.  They can also be
   sorted by timestamp, or made invalid
      
   Useful methods:
      LedgerEntry::getAddrStr20()
      LedgerEntry::getValue()
      LedgerEntry::getBlockNum()
      LedgerEntry::getTxHash()
      LedgerEntry::getIndex()   // index of Tx for wallet, TxIn/TxOut for addr
       

*************************
Class BtcAddress:
   Holds as much information as we know about a given address.  Will also
   hold an updated balance/ledger everytime it's parent BtcWallet is updated
   Since there are multiple ways to represent each field, we label each 
   member with the number of bytes

   NOTE:  The C++ address objects no longer have fields for public and 
          private keys.  All that data will be handled by Python/SWIG
   
   Useful Methods:
      BtcAddress::get/setAddrStr20()
      BtcAddress::get/setFirstBlockNum()
      BtcAddress::get/setFirstTimestamp()
      BtcAddress::get/setLastBlockNum()
      BtcAddress::get/setLastTimestamp()
      
      BtcAddress::getBalance()
      BtcAddress::cleanLedger()       // remove invalid entries, sort by time

      BtcAddress::addTxIO()           // add a ref/ptr to this address's list
      BtcAddress::addLedgerEntry()    
      BtcAddress::getTxIOList()       // Get all relevant TxIORefPair objects
      BtcAddress::getTxLedger()       // get a vector of ledger entries

*************************
Class BtcWallet:
   This basically just holds a bunch of BtcAddresses, and will aggregate 
   information relevant to all addresses in it.

   Useful methods:

      BtcWallet::addAddress()
      BtcWallet::addAddress_X_()     // needed to play nicely with SWIG
      BtcWallet::hasAddr()

      BtcWallet::scanTx()
      BtcWallet::scanNonStdTx()

      BtcWallet::getBalance()
      BtcWallet::getNumAddr()
      BtcWallet::getAddrByIndex()
      BtcWallet::getAddrByHash160()

      BtcWallet::getTxLedger()
      BtcWallet::cleanLedger()

      BtcWallet::getTxIOMap()         // all relevant TxIORefPairs
      BtcWallet::getNonStdTxIO()      // in this list if TxOut has nonstd script

      BtcWallet::getUnspentOutPoints()    // all relevant TxIORefPairs
      BtcWallet::getNonStdUnspentOutPoints() // all relevant TxIORefPairs

      BtcWallet::lockTxOut()        // may want to lock when attempting tx
      BtcWallet::unlockTxOut()        

*************************
Class BlockDataManager (BDM):
   This is your one-stop-shopping location for anything related to the
   blockchain.  It is a SINGLETON meaning only one of them can ever
   be created, and it is accessed via:

      BlockDataManager bdm = BlockDataManager::GetInstance()

   Useful methods in BlockDataManager:

      BlockDataManager::readBlkFile_FromScratch           (filename)
      BlockDataManager::organizeChain                     (void)
      BlockDataManager::getHeaderByHash                   (BinaryData)
      BlockDataManager::getHeaderByHeight                 (uint32_t)
      BlockDataManager::getTxByHash                       (BinaryData)
      BlockDataManager::scanBlockchainForTx_FromScratch   (BtcWallet)
      BlockDataManager::scanBlockchainForTx_FromScratch   (vector<BtcWallet>)
      BlockDataManager::findAllNonStdTx                   (void)
   



*** Using the C++ code ***

***RULE 1:  DON'T COPY PERSISTENT OBJECTS

   The following object types are stored EXACTLY once by BlockDataManager:

      -BlockHeaderRef
      -TxRef

   The following object types are stored EXACTLY once by BtcWallet/BtcAddress:

      -TxIORefPair

   All operations involving one of these object types should use pointers 
   to the single instance of them.  This is not as hard as it sounds, because
   all methods that using these objects as inputs/outputs only use pointers.

   While the point of the *Ref classes was to not have to worry about copy
   operations, THEY CONTAIN POST-CONSTRUCTION MEMBERS that may be large
   and slow/complicated to re-compute.  For instance:  TxRef contains a pointer
   to a BlockHeaderRef.  However, this pointer can change (upon reorg) and
   thus, if we had multiple copies of the TxRef, we'd have to make sure they
   all get updated.  



***RULE 2:  ONLY COPY OutPointRef, TxInRef, TxOutRef OBJECTS

   Unlike BlockHeadeRef and TxRef, these three classes contain no members 
   that are created post-construction.  They are also very fast to recompute
   given a pointer to where they are serialized.

   Therefore, we rarely use ptrs/refs to these objects, and instead create 
   new ones on the fly whenever we need them.  Use 

         uint32_t  TxRef::getNumTxIn  (void);
         uint32_t  TxRef::getNumTxOut (void);

         TxInRef   TxRef::getTxInRef  (index i);
         TxOutRef  TxRef::getTxOutRef (index i);

   
***RULE 3:  TxIns ARE COMPLICATED 
            (I know this isn't "rule", but it is important)

   We'd like to think that TxIns contain all the information we need about
   where and how much money is coming from in a Tx.  However, this is not 
   actually the case.  Standard TxIn serializations do not hold the values
   and MAY NOT EVEN HOLD THE SENDER ADDRESS.  To get this information, you
   have to follow its OutPoint and get it's TxOut, you need the help of 
   the BlockDataManager to find it.  Three convenience methods have been
   created for this purpose:

      TxOutRef   BlockDataManager::getPrevTxOut    (TxInRef & txin);
      BinaryData BlockDataManager::getSenderAddr20 (TxInRef & txin); 
      int64_t    BlockDataManager::getSentValue    (TxInRef & txin);


***RULE 4:  ALWAYS RESCAN YOUR WALLET(S) AFTER BLOCKCHAIN UPDATES 
          (OR PASS NEW TX DATA DIRECTLY TO YOUR WALLET, IN ADDITION TO BDM)

   You create a BtcWallet object and then add your addresses to it.  However,
   the BlockDataManager has no persistent knowledge of your wallet. You must
   update your wallet balances/ledgers with a call to:

      BlockDataManager::scanBlockchainForTx_FromScratch(MyBtcWallets)

   Or you can plug the new Tx information directly into the wallet:

      BtcWallet::scanTx( TxRef, txIndex, blockNumber, blockTimestamp)

   The extra information is to make sure that you wallet can update all of its
   pointers correctly, and store first-seen information (to improve searching)
   
   

################################################################################
*** Python Code Overview ***

   Coming soon!  

   Until then, there are examples of every python capability distributed
   throughout random scripts.  Here's the most useful example code:

      unittest.py  (mostly lower-level stuff, like Base58-ops, endianness, etc)
      extras/mysteryHex.py
      extras/createTestChain.py  (includes block creation, signing) 
      
   Less-useful example code:
      extras/extractKeysFromWallet.py  
      extras/findaddr.py