forked from etotheipi/BitcoinArmory
-
Notifications
You must be signed in to change notification settings - Fork 11
/
README
executable file
·811 lines (627 loc) · 32.7 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
################################################################################
# #
# Copyright (C) 2011-2012, Alan C. Reiner <[email protected]> #
# 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