Bitcoin Forum
June 22, 2024, 11:58:16 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 2 [3] 4 »  All
  Print  
Author Topic: A bitcoin blockchain parser in a few (thousand) lines of C++  (Read 16908 times)
jratcliff63367 (OP)
Member
**
Offline Offline

Activity: 82
Merit: 10


View Profile
July 07, 2013, 01:04:31 AM
 #41

Interesting, so how come on the block-explorer website it shows public-key information for all of the blocks?
piotr_n
Legendary
*
Offline Offline

Activity: 2053
Merit: 1354


aka tonikt


View Profile WWW
July 07, 2013, 01:05:42 AM
 #42

Interesting, so how come on the block-explorer website it shows public-key information for all of the blocks?
Sorry, I don't understand this question.

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
jratcliff63367 (OP)
Member
**
Offline Offline

Activity: 82
Merit: 10


View Profile
July 07, 2013, 03:00:46 PM
 #43

Wow, that was shockingly complicated.

For anyone in the future who ever has to/wants to convert a public key signature (65 byte binary embedded in most bitcoin scripts) to the ASCII representation of a bitcoin address, I have written a reference implementation that does this in a single CPP file.

I still plan to do some code cleanup on this, but it does work.

Basically, think of this as a reference implementation of what is described on this page https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses

Here is the header file with quite a bit of corresponding documentation.

https://code.google.com/p/blockchain/source/browse/trunk/BitcoinAddress.h

Here is the implementation.  I still plan to do some code cleanup on this, but the main point is that you can go from the 65 byte public-key signature to the bitcoin ASCII address with no external dependencies to any other code.  

https://code.google.com/p/blockchain/source/browse/trunk/BitcoinAddress.cpp

I hope someone else finds this useful as it took me quite a bit of work to pull the necessary code to do this from multiple sources.

As I said, I still plan to do some cleanup on this code; mostly cleaning up the 'bignum' methods which are a little sloppy right now; it does completely unnecessary memory allocations and I want to remove all of that.  The hash routines are pretty clean already and, hopefully, work well on lots of platforms.

I've only built this code with Microsoft Visual Studio.  If there are compile errors with GCC, please let me know and I will revise it accordingly.

Seriously, if you dump this one CPP/H into a project and it fails to compile, I would like to know.

Thanks,

John
piotr_n
Legendary
*
Offline Offline

Activity: 2053
Merit: 1354


aka tonikt


View Profile WWW
July 07, 2013, 03:19:58 PM
 #44

Good job.
It wasn't that hard after all, was it?

In many cases you will also want to decode the address from txout, while you do not know the public key yet.
I said before that it isn't really possible to represent each possible out script as an address, but these days most (like 99%) of the output scripts follow a standard pattern, that is:
Code:
0x76 0xa9 0x14 <20-bytes-of-addr's-RIMED> 0x88 0xAC

So from the 20 bytes you can already figure out address where the money is being sent to, yet without having its public key (that only comes later, if this output is being spent).

I once made a tool that is able to decode a raw tx data and dump the output addresses.
It needs openssl to link, but maybe you will find the code itself educational - some people prefer reading source code, over reading a wiki. Smiley
Code:
/*
gcc bctrans.c -o bctrans.exe -lcrypto -I /local/ssl/include -L /local/ssl/lib
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <strings.h>
#include <openssl/sha.h>
#include <openssl/bn.h>


static unsigned char addr_version = 0x00;
static FILE *f = NULL;

BIGNUM *bn58, dv, mo;
BN_CTX *ctx;


#define SHA256(p,l,o) { \
SHA256_CTX shactx; \
SHA256_Init(&shactx); \
SHA256_Update(&shactx, (p), (l)); \
SHA256_Final((o), &shactx); }


void readfile(unsigned char *p, int len) {
if (!f) {
int c, i;
char s[3];
while (len>0) {
for (i=0;i<2;) {
c = getchar();
if (c==EOF) {
fprintf(stderr, "File too short\n");
exit(1);
}
c = tolower(c);
if (c<='9' && c>='0' || c<='f' && c>='a')  s[i++] = (char)c;
}
s[2] = 0;
sscanf(s, "%x", &c);
*p = (unsigned char)c;
p++;
len--;
}
} else {
if (fread(p, 1, len, f)!=len) {
fprintf(stderr, "File too short\n");
fclose(f);
exit(1);
}
}
}

unsigned long long getle(unsigned char *p, int bytes) {
unsigned long long res=0;
while (bytes--) {
res|= ((unsigned long long)(p[bytes]))<<(8*bytes);
}
return res;
}

unsigned long long getvl() {
unsigned char b[8];
readfile(b, 1);
switch (*b) {
case 0xfd:
readfile(b, 2);
return getle(b, 2);
case 0xfe:
readfile(b, 4);
return getle(b, 4);
case 0xff:
readfile(b, 8);
return getle(b, 8);
}
return *b;
}


void prhash(unsigned char *p, unsigned int l) {
while (l--) printf("%02x", p[l]);
}


void hexdump(unsigned char *p, unsigned int l) {
while (l--) printf("%02x", *p++);
}


void printbtcaddr(unsigned char *p) {
static const char *chrs = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
unsigned char mod;
char out[64];
int i=0, j=0;
BIGNUM *bn = BN_bin2bn(p, 25, NULL);
while (!BN_is_zero(bn)) {
BN_div(&dv, &mo, bn, bn58, ctx);
if (BN_bn2bin(&mo, &mod)==0)  mod = 0;
out[i++] = chrs[mod];
BN_copy(bn, &dv);
}
BN_free(bn);
while ((*p)==0) {
putchar('1');
p++;
}
while (i--)  putchar(out[i]);
}


int main(int argc, char * argv[]) {
static unsigned char buf[0x10000];
unsigned long long i, sl, txcnt, v;
unsigned va, vb;
int x;
long fpos;
char *fname = NULL;

for (x=1; x<argc; x++) {
if (strcmp(argv[x], "-t")==0) {
addr_version = 0x6f; // testnet
} else {
fname = argv[x];
}
}

if (!fname) {
printf("Enter transactions hexdump data:\n");
} else {
f = fopen(fname, "rb");
if (!f) {
fprintf(stderr, "File %s not found\n", fname);
return 1;
}
}

readfile(buf, 4);
printf("Version: %llu\n", getle(buf, 4));

txcnt = getvl();
printf("TX IN cnt: %llu\n", txcnt);
for (i=0; i<txcnt; i++) {
readfile(buf, 36);
sl = getvl();

printf("%6d) : ", (int)i);
prhash(buf, 32);
printf(" Idx=%2lld  sl=%lld", getle(buf+32, 4), sl);
readfile(buf, sl);
readfile(buf, 4);

printf(" seq=%x\n", (unsigned)getle(buf, 4));
}

txcnt = getvl();
printf("TX OUT cnt: %llu\n", txcnt);

ctx = BN_CTX_new();
bn58 = BN_bin2bn("\x3a", 1, NULL);
BN_init(&dv);
BN_init(&mo);

for (i=0; i<txcnt; i++) {
readfile(buf, 8);
sl = getvl();
v = getle(buf, 8);
va = (unsigned)(v/100000000LL);
vb = (unsigned)(v%100000000LL);
printf("%6d) : %7u.%08u BTC", (int)i, va, vb, sl);
readfile(buf, sl);
if (sl!=25 || memcmp(buf, "\x76\xa9\x14", 3) || buf[23]!=0x88 || buf[24]!=0xac) {
printf("  WARNING! Unexpected SIG_SCRIPT:\n"); hexdump(buf, sl);
} else {
unsigned char dat[25];
unsigned char sha[SHA256_DIGEST_LENGTH];
unsigned char sha2[SHA256_DIGEST_LENGTH];
dat[0] = addr_version; // version
memcpy(dat+1, buf+3, 20);
SHA256(dat, 21, sha);
SHA256(sha, SHA256_DIGEST_LENGTH, sha2);
//printf("  chsum:%02x%02x%02x%02x", sha2[0], sha2[1], sha2[2], sha2[3]);
memcpy(dat+21, sha2, 4);
printf("  to address "); printbtcaddr(dat);
}
putchar('\n');
}

BN_free(bn58);
BN_CTX_free(ctx);

readfile(buf, 4);
printf("Lock Time: %llu\n", getle(buf, 4));

if (f) {
fpos = ftell(f);
fseek(f, 0, SEEK_END);
if (fpos!=ftell(f)) {
printf("WARNING!!! File too long. Only %ld bytes expected (%ld too many)\n",
fpos, ftell(f)-fpos);
} else {
printf("File size checked OK - %ld bytes\n", fpos);
}
fclose(f);
}

return 0;
}

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
jratcliff63367 (OP)
Member
**
Offline Offline

Activity: 82
Merit: 10


View Profile
July 07, 2013, 04:33:55 PM
 #45

Thanks, I prefer source too.

On further thought I have decided I'm going to retitle this post as a block-chain parser in a couple thousand lines of code; but it will still be just one CPP file when I'm done.

Actually it was kind of hard, it took me hours just to gather together the code to do SHA-256, RPMD-160, and base58cheked without dragging in massive libraries and dependencies.

I'm going to make a new Google code project called 'bitcoin-snippets' which will contain just the source to do each one of these specific operations.

Thanks,

John
etotheipi
Legendary
*
expert
Offline Offline

Activity: 1428
Merit: 1093


Core Armory Developer


View Profile WWW
July 07, 2013, 04:55:20 PM
 #46

Thanks, I prefer source too.

On further thought I have decided I'm going to retitle this post as a block-chain parser in a couple thousand lines of code; but it will still be just one CPP file when I'm done.

Actually it was kind of hard, it took me hours just to gather together the code to do SHA-256, RPMD-160, and base58cheked without dragging in massive libraries and dependencies.

I'm going to make a new Google code project called 'bitcoin-snippets' which will contain just the source to do each one of these specific operations.

Thanks,

John

Don't forget this is a crypto currency.  There is no way around having a general purpose crypto library available if you're going to do any coding in Bitcoin.  Just like you have standard headers in C++ for various data structures and algorithms, you are going to need these crypto algorithms available.   You're wasting your time reimplementing it, because it's all actually very simple, standard crypto operations (just combined in a creative way).  Once you have those standard operations available and you understand what they do, much of this will be much simpler.  Hashing is the bread and butter of Bitcoin, just get the libraries and do it.

And no one ever said bitcoin programming was easy, but you're taking the right size steps and you will get there with some patience.  What you are doing is exactly how I started two years ago and I think it's a fantastic way to learn.  You just have to appreciate that there's a lot to learn and you're going to spend a ton of time confused and digging for clarity.   That's part of the fun :-)


Founder and CEO of Armory Technologies, Inc.
Armory Bitcoin Wallet: Bringing cold storage to the average user!
Only use Armory software signed by the Armory Offline Signing Key (0x98832223)

Please donate to the Armory project by clicking here!    (or donate directly via 1QBDLYTDFHHZAABYSKGKPWKLSXZWCCJQBX -- yes, it's a real address!)
piotr_n
Legendary
*
Offline Offline

Activity: 2053
Merit: 1354


aka tonikt


View Profile WWW
July 07, 2013, 05:14:44 PM
 #47

It's true.
Depends how far you want to go, you would eventually also need ECDSA - which is much bigger piece of code than the hashing funcs and the big numbers..
So if you really care to have a small code, you will eventually prefer to link it against an external crypto lib, instead of turnign your block parser into a crypto lib.
Probably openssl is best for your purposes, since this is the most common library having everything that a blockchain parser needs.
And you can just download a built lib, for any platform/compiler you need.

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
jratcliff63367 (OP)
Member
**
Offline Offline

Activity: 82
Merit: 10


View Profile
July 07, 2013, 05:31:04 PM
 #48

Well, I'm not trying to write a full client, just something that can extract all of the transactions.

For that, as far as I can tell, I just need the two hash routines. In fact I think I'm getting pretty close to finishing this thing up.

Also, to be clear my coding website is largely educational. I'm writing this code to educate myself and releasing it open source to educate others.
Thanks,

John
Thanks, I prefer source too.

On further thought I have decided I'm going to retitle this post as a block-chain parser in a couple thousand lines of code; but it will still be just one CPP file when I'm done.

Actually it was kind of hard, it took me hours just to gather together the code to do SHA-256, RPMD-160, and base58cheked without dragging in massive libraries and dependencies.

I'm going to make a new Google code project called 'bitcoin-snippets' which will contain just the source to do each one of these specific operations.

Thanks,

John

Don't forget this is a crypto currency.  There is no way around having a general purpose crypto library available if you're going to do any coding in Bitcoin.  Just like you have standard headers in C++ for various data structures and algorithms, you are going to need these crypto algorithms available.   You're wasting your time reimplementing it, because it's all actually very simple, standard crypto operations (just combined in a creative way).  Once you have those standard operations available and you understand what they do, much of this will be much simpler.  Hashing is the bread and butter of Bitcoin, just get the libraries and do it.

And no one ever said bitcoin programming was easy, but you're taking the right size steps and you will get there with some patience.  What you are doing is exactly how I started two years ago and I think it's a fantastic way to learn.  You just have to appreciate that there's a lot to learn and you're going to spend a ton of time confused and digging for clarity.   That's part of the fun :-)


jratcliff63367 (OP)
Member
**
Offline Offline

Activity: 82
Merit: 10


View Profile
July 07, 2013, 11:26:46 PM
 #49

I did one more cleanup pass/revision before the end of today.

There is now a code snippet which does just base58 encoding.  It's based on the source code in 'cbitcoin' but I removed all memory allocation.

I also revised the BitcoinAddress snippet to go from public-key to bitcoin binary address, and from a bitcoin binary address to ASCII and from ASCII back to binary (checked).

Finally, my original snippet folds in all of this code to parse the bulk of the blockchain.  I still haven't yet assembled all of the individual transactions, I would do that the next time I find some time to spend on this effort.

All that said, I think these individual snippets, which are pretty well documented, will hopefully prove useful educational tools for future developers who won't have to go through the same trouble I went through figuring out how all of these pieces fit together.

Like a previous poster said, I prefer looking at source code as documentation than a Wiki page; so hopefully others will find this useful too.

http://codesuppository.blogspot.com/2013/07/bitcoin-code-snippets.html
etotheipi
Legendary
*
expert
Offline Offline

Activity: 1428
Merit: 1093


Core Armory Developer


View Profile WWW
July 08, 2013, 02:53:35 AM
 #50

Well, I'm not trying to write a full client, just something that can extract all of the transactions.

For that, as far as I can tell, I just need the two hash routines. In fact I think I'm getting pretty close to finishing this thing up.

Also, to be clear my coding website is largely educational. I'm writing this code to educate myself and releasing it open source to educate others.
Thanks,

John

Don't get caught up going down tangent paths.  Your issues with hashing sound much like someone who's never seen a logarithm before.  Reimplementing the log() function in C++ is not very useful nor educational, unless your goal is compiler optimizations or embedded software.  It's more important to understand the purpose and properties of the logarithm (hashing), than to distract those you are trying to educate with unnecessary details.  If I told you I didn't know what a logarithm but I needed it for my financial software, and I was working on implementing my own version of logarithm, you'd probably have the same reaction:  "go look up what a logarithm does and why it's important, and then just #include <cmath> and focus on which properties of it are needed by the financial software and why."   

Hashing is the one of the most fundamental and important atoms of cryptographic systems.  Especially Bitcoin.  And implementing it from scratch is not likely to give you any insight into how it works or how it fits into Bitcoin.   What you need to understand is that it's a function that takes any input, completely mangles it, and produces a seemingly-random X-byte output.  It must always produce the same answer for identical input, but change any bit should look equivalent to producing a random value.   It is intentionally non-invertible (i.e. SHA256 can take in any size string and always spits out 32 bytes), and each output bit should have no correlation with any input bit. 

In the context of Bitcoin transactions, it's goal is to produce a unique 32-byte identifier for a transaction, regardless of how many kB it is.  If any byte of the transaction is changed, the hash will look like a different 32-byte random number.  In the context of headers, this "randomness" to create a sort of lottery for miners.  Since we know the hash function should produce essentially-uniform randomness, we know that for a given difficulty and hashrate on the network, it should take approx 10 min on average for someone to find a lucky hash.

Similarly, if you go any further with this, you're going to need an ECDSA library in addition to hashing.  While elliptic curves are mathematically neat, you would be best to not reimplement it yourself unless you are working on speed-optimizing it.  If you think publickey->address was hard, try privatekey->publickey! (no, don't try it, just get a library and understand the properties of it).




Founder and CEO of Armory Technologies, Inc.
Armory Bitcoin Wallet: Bringing cold storage to the average user!
Only use Armory software signed by the Armory Offline Signing Key (0x98832223)

Please donate to the Armory project by clicking here!    (or donate directly via 1QBDLYTDFHHZAABYSKGKPWKLSXZWCCJQBX -- yes, it's a real address!)
jratcliff63367 (OP)
Member
**
Offline Offline

Activity: 82
Merit: 10


View Profile
July 08, 2013, 03:35:09 AM
 #51

Yeah, I know all about hashes. My issue isn't about any particular hash algorithm, my issue is having to download and build a massive library just to get access to the *one* I need.
jratcliff63367 (OP)
Member
**
Offline Offline

Activity: 82
Merit: 10


View Profile
July 08, 2013, 04:59:01 AM
Last edit: July 08, 2013, 02:44:34 PM by jratcliff63367
 #52

Let me reform the question using your analogy.

Let's say I'm working on a project and I need a log function.  Now, let's suppose that the log function (like SHA256) is not part of the C99 standard and built into the set of default libraries available in all compatible C++ compilers.

So, what if the only way to get access to a 'log' function is that I have to download some math library comprising 100,000 lines of source code with dependencies on streams, network code, a specific compiler, a complex build and configuration requirement, BOOST, the STL, exception handling, and god knows what else.

Because I needed access to 'log'.

Given the choice between dragging that into my code base or just copying only the 'log' function source code I would choose the much simpler solution.

People don't want to learn about algorithms by downloading 100,000 lines of source code libraries.

That's my position, and when I check with many of my colleagues in the computer game industry (where I come from) that tends to be our preference.

I'm a senior software engineer and I have been working on computer games and multi-platform development since 1979.

I just really prefer small code bases with minimal dependencies that are compiler and operating system agnostic.

John
ProfMac
Legendary
*
Offline Offline

Activity: 1246
Merit: 1001



View Profile
July 08, 2013, 05:28:33 AM
 #53


I'm a senior software engineer and I have been working on computer games and multi-platform development since 1979.

I just really prefer small code bases with minimal dependencies that are compiler and operating system agnostic.

John


+1

Make it as simple as possible, but not simpler.

I try to be respectful and informed.
CIYAM
Legendary
*
Offline Offline

Activity: 1890
Merit: 1078


Ian Knowles - CIYAM Lead Developer


View Profile WWW
July 08, 2013, 05:36:04 AM
 #54

I just really prefer small code bases with minimal dependencies that are compiler and operating system agnostic.

I do agree with the "minimal" approach although the STL and exceptions are *standard* C++ (if your compiler doesn't support these then it is not a C++ compiler at all but probably one of those horrible non-standard EC++ compilers from the 90's).

BTW if you want a fairly minimal SHA256 (one source and one header) then there is one in the CIYAM project here: https://github.com/ciyam/ciyam/blob/master/src/sha256.cpp and here: https://github.com/ciyam/ciyam/blob/master/src/sha256.h.

With CIYAM anyone can create 100% generated C++ web applications in literally minutes.

GPG Public Key | 1ciyam3htJit1feGa26p2wQ4aw6KFTejU
jgarzik
Legendary
*
qt
Offline Offline

Activity: 1596
Merit: 1091


View Profile
July 08, 2013, 05:53:24 AM
 #55

I'm a senior software engineer and I have been working on computer games and multi-platform development since 1979.

I just really prefer small code bases with minimal dependencies that are compiler and operating system agnostic.

There is little engineering upside to reimplementing highly complex cryptographic algorithms on your own, given the levels of engineering review and crypt-analysis of your own codebase versus an existing crypto lib.

It might be personally satisfying, but it makes little sense unless you are truly an expert crypto mathematician.




Jeff Garzik, Bloq CEO, former bitcoin core dev team; opinions are my own.
Visit bloq.com / metronome.io
Donations / tip jar: 1BrufViLKnSWtuWGkryPsKsxonV2NQ7Tcj
jratcliff63367 (OP)
Member
**
Offline Offline

Activity: 82
Merit: 10


View Profile
July 08, 2013, 12:33:38 PM
Last edit: July 08, 2013, 05:41:38 PM by jratcliff63367
 #56

Me communicate not so good.

I haven't reimplemented *any* cryptographic algorithms.  All I did was copy the two cryptographic routines I needed, and maybe slightly refactored the interface to them.

I just want the code I need and not the code I don't need and in a form which will compile without dragging in dependencies on hundreds of other source files and libraries (i.e. STL, BOOST, networking code, etc.)

To repeat, I haven't reimplemented any cryptographic algorithm, I've just tried to organize the source so I can easily build and understand it.

As I said before, if SHA256 were part of the C99 standard and built into every C/C++ compiler, that would be fine. But, it's not.

And I get that you guys have no problem building things like 'opensll' just because you need access to one or two routines; but that's not really my coding style.  By pulling out just the two routines I need into a standalone code snippet I am not 'reimplementing' anything, I'm just cleaning up an existing implementation to make it more usable and accessible and easier to understand.

After running CLOC on openSSL it reports a total of 1,589 files; 946 C files, 169 PERL scripts, 262 C/C++ header files, 76 makes files, 13 assembly files, 61 shell scripts, and a total of 234,537 lines of C code and 69,175 lines of code in header files.

In contrast, the code for *just* SHA256 and RIPMD160 the only two hash routines needed to parse the blockchain (which was my project goal) are 750 lines of code.

If you want to add a quarter million line source code project to your little utility program just so you can access 750 lines of code, go for it.  But, as I said, that's not my style.

John

P.S. For what it's worth, cryptopp doesn't seem as bad.  It's 270 source files and 'only' 56,000 lines of source.
jratcliff63367 (OP)
Member
**
Offline Offline

Activity: 82
Merit: 10


View Profile
July 08, 2013, 02:51:36 PM
 #57

Yes, I use the STL a lot, and mostly for that reason, because it's 'standard'.  However, I also try to avoid using it if I don't have to.  I won't go and write my own container class when the same container class already exists in STL but, on the other hand, if I can get away without using a container class at all, that's fine too.  I really try to keep it out of public API's if at all possible.  It just makes the code harder to follow I believe; so I typically might use it for internal implementation code but keep the public facing API as simple as possible.

The problems with the STL abound though, and they have been discussed a great deal online.  At my professional work, we have an internal standard not to use the STL.  Instead we have our own customized templates which we have highly optimized.

Our code here has to run on the following platforms:

Win32/Win64
Linux (many flavors)
Wii
Wii-U
Xbox-360
Xbox-720
PS3
PS4
Android
IOS

It's pretty crazy having to target high performance physics code on all of those platforms at the same time.

We also have a requirement that we capture every single memory allocation ever performed and never use any exception handling anywhere in the code base.

Game engines have some pretty high performance requirements, and the STL and exception handling usually don't fit this pattern.

That said, for my open source work, I always use the STL if I need a container.

John
Vinz87
Member
**
Offline Offline

Activity: 72
Merit: 10


View Profile
March 23, 2014, 07:22:29 PM
 #58

is this topic alive? i'm trying to compile your software with gcc 4.5 on OS X Mavericks, but I get these errors:

Code:
$ gcc *.cpp -o blockchain.out
BlockChain.cpp:2619:11: warning: enumeration value 'AM_LAST' not handled in switch [-Wswitch]
        switch ( m )
                 ^
1 warning generated.
main.cpp:320:116: warning: format specifies type 'int' but the argument has type 'float' [-Wformat]
  ...%d bitcoin addresses with a balance of more than %d bitcoins.\r\n", tcount, mMinBalance );
                                                      ~~                         ^~~~~~~~~~~
                                                      %f
main.cpp:334:109: warning: format specifies type 'int' but the argument has type 'float' [-Wformat]
  ...oldest bitcoin addresses with a balance of more than %d bitcoins.\r\n", tcount, mMinBalance );
                                                          ~~                         ^~~~~~~~~~~
                                                          %f
main.cpp:348:124: warning: format specifies type 'int' but the argument has type 'float' [-Wformat]
  ...older than %d days with a balance of more than %d bitcoins.\r\n", zdays, mMinBalance );
                                                    ~~                        ^~~~~~~~~~~
                                                    %f
main.cpp:418:17: warning: enumeration value 'SR_LAST' not handled in switch [-Wswitch]
                                                        switch ( mStatResolution )
                                                                 ^
main.cpp:394:12: warning: enumeration values 'CM_NONE' and 'CM_EXIT' not handled in switch [-Wswitch]
                switch ( mMode )
                         ^
5 warnings generated.
Undefined symbols for architecture x86_64:
  "std::__1::__vector_base_common<true>::__throw_length_error() const", referenced from:
      void std::__1::vector<BlockChainAddresses::StatAddress, std::__1::allocator<BlockChainAddresses::StatAddress> >::__push_back_slow_path<BlockChainAddresses::StatAddress const>(BlockChainAddresses::StatAddress const&) in BlockChainAddresses-837c2d.o
  "std::terminate()", referenced from:
      ___clang_call_terminate in BlockChain-69c2db.o
      ___clang_call_terminate in BlockChainAddresses-837c2d.o
      ___clang_call_terminate in main-b5bd23.o
  "vtable for __cxxabiv1::__class_type_info", referenced from:
      typeinfo for BlockChain in BlockChain-69c2db.o
      typeinfo for QuickSortPointers in BlockChain-69c2db.o
      typeinfo for BlockChainAddresses in BlockChainAddresses-837c2d.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for __cxxabiv1::__si_class_type_info", referenced from:
      typeinfo for BlockChainImpl in BlockChain-69c2db.o
      typeinfo for SortByAge in BlockChain-69c2db.o
      typeinfo for SortByBalance in BlockChain-69c2db.o
      typeinfo for BlockChainAddressesImpl in BlockChainAddresses-837c2d.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "operator delete[](void*)", referenced from:
      SimpleHash<FileLocation, 4194304u, 40000000u>::init() in BlockChain-69c2db.o
      BlockChainImpl::~BlockChainImpl() in BlockChain-69c2db.o
      BitcoinTransactionFactory::printOldest(unsigned int, float) in BlockChain-69c2db.o
      BitcoinTransactionFactory::printTopBalances(unsigned int, float) in BlockChain-69c2db.o
      SimpleHash<BlockHeader, 65536u, 500000u>::init() in BlockChain-69c2db.o
      BitcoinTransactionFactory::saveStatistics(bool, float) in BlockChain-69c2db.o
      BitcoinTransactionFactory::saveAddressesOverTime() in BlockChain-69c2db.o
      ...
  "operator delete(void*)", referenced from:
      createBlockChain(char const*) in BlockChain-69c2db.o
      BlockChainImpl::~BlockChainImpl() in BlockChain-69c2db.o
      createBlockChainAddresses(char const*) in BlockChainAddresses-837c2d.o
      BlockChainAddressesImpl::~BlockChainAddressesImpl() in BlockChainAddresses-837c2d.o
      std::__1::__vector_base<BlockChainAddresses::StatAddress, std::__1::allocator<BlockChainAddresses::StatAddress> >::~__vector_base() in BlockChainAddresses-837c2d.o
      std::__1::__split_buffer<BlockChainAddresses::StatAddress, std::__1::allocator<BlockChainAddresses::StatAddress>&>::~__split_buffer() in BlockChainAddresses-837c2d.o
      BlockChainAddresses::~BlockChainAddresses() in BlockChainAddresses-837c2d.o
      ...
  "operator new[](unsigned long)", referenced from:
      BlockChainImpl::buildBlockChain() in BlockChain-69c2db.o
      SimpleHash<FileLocation, 4194304u, 40000000u>::init() in BlockChain-69c2db.o
      BitcoinTransactionFactory::printOldest(unsigned int, float) in BlockChain-69c2db.o
      BitcoinTransactionFactory::printTopBalances(unsigned int, float) in BlockChain-69c2db.o
      SimpleHash<BlockHeader, 65536u, 500000u>::init() in BlockChain-69c2db.o
      BitcoinTransactionFactory::saveStatistics(bool, float) in BlockChain-69c2db.o
      BitcoinTransactionFactory::saveAddressesOverTime() in BlockChain-69c2db.o
      ...
  "operator new(unsigned long)", referenced from:
      createBlockChain(char const*) in BlockChain-69c2db.o
      createBlockChainAddresses(char const*) in BlockChainAddresses-837c2d.o
      std::__1::__split_buffer<BlockChainAddresses::StatAddress, std::__1::allocator<BlockChainAddresses::StatAddress>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<BlockChainAddresses::StatAddress>&) in BlockChainAddresses-837c2d.o
  "___cxa_begin_catch", referenced from:
      ___clang_call_terminate in BlockChain-69c2db.o
      ___clang_call_terminate in BlockChainAddresses-837c2d.o
      ___clang_call_terminate in main-b5bd23.o
  "___cxa_pure_virtual", referenced from:
      vtable for QuickSortPointers in BlockChain-69c2db.o
      vtable for BlockChain in BlockChain-69c2db.o
      vtable for BlockChainAddresses in BlockChainAddresses-837c2d.o
  "___gxx_personality_v0", referenced from:
      createBlockChain(char const*) in BlockChain-69c2db.o
      BlockChainImpl::BlockChainImpl(char const*) in BlockChain-69c2db.o
      BlockChainImpl::~BlockChainImpl() in BlockChain-69c2db.o
      SimpleHash<FileLocation, 4194304u, 40000000u>::init() in BlockChain-69c2db.o
      BlockChainImpl::~BlockChainImpl() in BlockChain-69c2db.o
      SimpleHash<BlockHeader, 65536u, 500000u>::init() in BlockChain-69c2db.o
      BitcoinTransactionFactory::gatherStatistics(unsigned int, unsigned int, bool) in BlockChain-69c2db.o
      ...
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
cassini
Member
**
Offline Offline

Activity: 112
Merit: 10



View Profile
March 24, 2014, 08:18:21 AM
 #59

is this topic alive? i'm trying to compile your software with gcc
Have you tried clang++?
See http://stackoverflow.com/questions/16660854/compiling-with-clang-with-c11-enabled-fails
If this solves some errors but not all of them, then try
http://stackoverflow.com/questions/16352833/linking-with-clang-on-os-x-generates-lots-of-symbol-not-found-errors
jgarzik
Legendary
*
qt
Offline Offline

Activity: 1596
Merit: 1091


View Profile
March 24, 2014, 02:55:52 PM
 #60

If you don't mind C (versus C++), picocoin's "blkstats" utility parses the blockchain in under 3 minutes.

https://github.com/jgarzik/picocoin/blob/master/src/blkstats.c
https://bitcointalk.org/index.php?topic=128055.0
https://github.com/jgarzik/picocoin/

Jeff Garzik, Bloq CEO, former bitcoin core dev team; opinions are my own.
Visit bloq.com / metronome.io
Donations / tip jar: 1BrufViLKnSWtuWGkryPsKsxonV2NQ7Tcj
Pages: « 1 2 [3] 4 »  All
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!