// File: jeffchan[P]blockchain-parser/BlockChain.cpp
// Function: BitcoinTransactionFactory::saveAddressesOverTime()
void saveAddressesOverTime(void)
	{
		FILE *fph = fopen("BlockChainAddresses.bin", "wb");
		if ( fph )
		{
			const char *header = "BLOCK_CHAIN_ADDRESSES";
			fwrite(header,strlen(header)+1,1,fph);
			uint32_t version = 1;
			fwrite(&version, sizeof(version), 1, fph );

			// first..we need to count how many addresses are being used for this report.
			uint32_t *addressIndex = new uint32_t[mAddresses.size()];	// convert from master address list to used by statistics address list table
			uint32_t *inverseAddress = new uint32_t[mAddresses.size()]; // convert from remapped list back to master address.

			memset(addressIndex,0,sizeof(uint32_t)*mAddresses.size());
			memset(inverseAddress,0,sizeof(uint32_t)*mAddresses.size());

			uint32_t fcount = 0; // number of unique addresses found

			for (uint32_t i=0; i<mStatCount; i++)
			{
				StatRow &row = mStatistics[i];
				for (uint32_t i=0; i<row.mAddressCount; i++)
				{
					StatAddress &sa = row.mAddresses[i];
					assert( sa.mAddress	 );
					uint32_t a = sa.mAddress-1;
					assert( a < mAddresses.size() );
					if ( addressIndex[a] == 0 ) // if this is the first time we have encountered this address, then we add it to the forward and inverse lookup tables.
					{
						addressIndex[a] = fcount+1;
						inverseAddress[fcount] = a;
						fcount++;
					}
				}
			}
			// ok..now ready to write out the address headers.
			fwrite(&fcount,sizeof(fcount),1,fph);	// save how many unique addresses were found.
			// now write out the 20 byte public key address for each.
			for (uint32_t i=0; i<fcount; i++)
			{
				uint32_t a = inverseAddress[i]; // get the original address.
				BitcoinAddress *ba = mAddresses.getKey(a);
				fwrite(ba,20,1,fph);// write out the bitcoin address 160 bit public key (20 bytes long)
			}

			fwrite(&mStatCount, sizeof(mStatCount), 1, fph );

			for (uint32_t i=0; i<mStatCount; i++)
			{
				StatRow &row = mStatistics[i];
				fwrite(&row.mTime,sizeof(row.mTime),1, fph); // write out the time that this row was recorded...
				if ( i == 0 ) 
				{
					fwrite(&row.mAddressCount,sizeof(row.mAddressCount),1,fph);
				}
				else
				{
					fwrite(&row.mNewAddressCount,sizeof(row.mNewAddressCount),1,fph);
				}
				fwrite(&row.mChangeAddressCount,sizeof(row.mChangeAddressCount),1,fph);
				fwrite(&row.mDeleteAddressCount,sizeof(row.mDeleteAddressCount),1,fph);
			}

			for (uint32_t i=0; i<mStatCount; i++)
			{
				StatRow &row = mStatistics[i];
				if ( i == 0 )
				{
					for (uint32_t i=0; i<row.mAddressCount; i++)
					{
						StatAddress sa = row.mAddresses[i];
						sa.mAddress = addressIndex[sa.mAddress-1]; // convert to the new sequentially ordered hash
						fwrite(&sa,sizeof(sa),1,fph); // write it out...
					}
				}
				else
				{
					for (uint32_t i=0; i<row.mNewAddressCount; i++)
					{
						StatAddress sa = row.mNewAddresses[i];
						sa.mAddress = addressIndex[sa.mAddress-1]; // convert to the new sequentially ordered hash
						fwrite(&sa,sizeof(sa),1,fph); // write it out...
					}
					for (uint32_t i=0; i<row.mChangeAddressCount; i++)
					{
						StatAddress sa = row.mChangedAddresses[i];
						sa.mAddress = addressIndex[sa.mAddress-1]; // convert to the new sequentially ordered hash
						fwrite(&sa,sizeof(sa),1,fph); // write it out...
					}
					for (uint32_t i=0; i<row.mDeleteAddressCount; i++)
					{
						uint32_t da = row.mDeletedAddresses[i];
						uint32_t a = addressIndex[da-1];
						fwrite(&a,sizeof(uint32_t),1,fph);
					}
				}
			}
			delete []addressIndex;
			delete []inverseAddress;
			fclose(fph);
		}
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xf0(%rbp)
leaq 0x10dc9(%rip), %rdi     # 0x321ba
leaq 0x107b5(%rip), %rsi     # 0x31bad
callq 0x2190
movq %rax, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x21adf
leaq 0x10dbf(%rip), %rax     # 0x321d2
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x108(%rbp)
movq -0x18(%rbp), %rdi
callq 0x2090
movq -0x108(%rbp), %rdi
movq %rax, %rsi
addq $0x1, %rsi
movq -0x10(%rbp), %rcx
movl $0x1, %edx
callq 0x2270
movl $0x1, -0x1c(%rbp)
movq -0x10(%rbp), %rcx
leaq -0x1c(%rbp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x2270
movq -0xf0(%rbp), %rdi
callq 0x1d960
movl %eax, %eax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x2040
movq -0xf0(%rbp), %rdi
movq %rax, -0x28(%rbp)
callq 0x1d960
movl %eax, %eax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x2040
movq -0xf0(%rbp), %rdi
movq %rax, -0x30(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x100(%rbp)
callq 0x1d960
movq -0x100(%rbp), %rdi
movl %eax, %eax
movl %eax, %edx
shlq $0x2, %rdx
xorl %esi, %esi
callq 0x20b0
movq -0xf0(%rbp), %rdi
movq -0x30(%rbp), %rax
movq %rax, -0xf8(%rbp)
callq 0x1d960
movq -0xf8(%rbp), %rdi
movl %eax, %eax
movl %eax, %edx
shlq $0x2, %rdx
xorl %esi, %esi
callq 0x20b0
movl $0x0, -0x34(%rbp)
movl $0x0, -0x38(%rbp)
movq -0xf0(%rbp), %rcx
movl -0x38(%rbp), %eax
cmpl 0x2000050(%rcx), %eax
jae 0x21665
movq -0xf0(%rbp), %rax
addq $0x2000058, %rax        # imm = 0x2000058
movl -0x38(%rbp), %ecx
imulq $0x190, %rcx, %rcx      # imm = 0x190
addq %rcx, %rax
movq %rax, -0x40(%rbp)
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
movq -0x40(%rbp), %rcx
cmpl 0x150(%rcx), %eax
jae 0x21655
movq -0x40(%rbp), %rax
movq 0x158(%rax), %rax
movl -0x44(%rbp), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
cmpl $0x0, (%rax)
je 0x215a5
jmp 0x215c4
leaq 0x10c3c(%rip), %rdi     # 0x321e8
leaq 0xf69d(%rip), %rsi      # 0x30c50
movl $0xf61, %edx            # imm = 0xF61
leaq 0x10c35(%rip), %rcx     # 0x321f4
callq 0x20c0
movq -0xf0(%rbp), %rdi
movq -0x50(%rbp), %rax
movl (%rax), %eax
subl $0x1, %eax
movl %eax, -0x54(%rbp)
movl -0x54(%rbp), %eax
movl %eax, -0x10c(%rbp)
callq 0x1d960
movl %eax, %ecx
movl -0x10c(%rbp), %eax
cmpl %ecx, %eax
jae 0x215f3
jmp 0x21612
leaq 0x10c32(%rip), %rdi     # 0x3222c
leaq 0xf64f(%rip), %rsi      # 0x30c50
movl $0xf63, %edx            # imm = 0xF63
leaq 0x10be7(%rip), %rcx     # 0x321f4
callq 0x20c0
movq -0x28(%rbp), %rax
movl -0x54(%rbp), %ecx
cmpl $0x0, (%rax,%rcx,4)
jne 0x21645
movl -0x34(%rbp), %edx
addl $0x1, %edx
movq -0x28(%rbp), %rax
movl -0x54(%rbp), %ecx
movl %edx, (%rax,%rcx,4)
movl -0x54(%rbp), %edx
movq -0x30(%rbp), %rax
movl -0x34(%rbp), %ecx
movl %edx, (%rax,%rcx,4)
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x21647
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x2156e
jmp 0x21657
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x21533
movq -0x10(%rbp), %rcx
leaq -0x34(%rbp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x2270
movl $0x0, -0x58(%rbp)
movl -0x58(%rbp), %eax
cmpl -0x34(%rbp), %eax
jae 0x216cd
movq -0xf0(%rbp), %rdi
movq -0x30(%rbp), %rax
movl -0x58(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0x5c(%rbp)
movl -0x5c(%rbp), %esi
callq 0x1d360
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rdi
movq -0x10(%rbp), %rcx
movl $0x14, %esi
movl $0x1, %edx
callq 0x2270
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x21683
movq -0xf0(%rbp), %rdi
addq $0x2000050, %rdi        # imm = 0x2000050
movq -0x10(%rbp), %rcx
movl $0x4, %esi
movl $0x1, %edx
callq 0x2270
movl $0x0, -0x6c(%rbp)
movq -0xf0(%rbp), %rcx
movl -0x6c(%rbp), %eax
cmpl 0x2000050(%rcx), %eax
jae 0x217d2
movq -0xf0(%rbp), %rax
addq $0x2000058, %rax        # imm = 0x2000058
movl -0x6c(%rbp), %ecx
imulq $0x190, %rcx, %rcx      # imm = 0x190
addq %rcx, %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rdi
addq $0xc, %rdi
movq -0x10(%rbp), %rcx
movl $0x4, %esi
movl $0x1, %edx
callq 0x2270
cmpl $0x0, -0x6c(%rbp)
jne 0x2176a
movq -0x78(%rbp), %rdi
addq $0x150, %rdi            # imm = 0x150
movq -0x10(%rbp), %rcx
movl $0x4, %esi
movl $0x1, %edx
callq 0x2270
jmp 0x21788
movq -0x78(%rbp), %rdi
addq $0x160, %rdi            # imm = 0x160
movq -0x10(%rbp), %rcx
movl $0x4, %esi
movl $0x1, %edx
callq 0x2270
movq -0x78(%rbp), %rdi
addq $0x168, %rdi            # imm = 0x168
movq -0x10(%rbp), %rcx
movl $0x4, %esi
movl $0x1, %edx
callq 0x2270
movq -0x78(%rbp), %rdi
addq $0x164, %rdi            # imm = 0x164
movq -0x10(%rbp), %rcx
movl $0x4, %esi
movl $0x1, %edx
callq 0x2270
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0x216f5
movl $0x0, -0x7c(%rbp)
movq -0xf0(%rbp), %rcx
movl -0x7c(%rbp), %eax
cmpl 0x2000050(%rcx), %eax
jae 0x21a9c
movq -0xf0(%rbp), %rax
addq $0x2000058, %rax        # imm = 0x2000058
movl -0x7c(%rbp), %ecx
imulq $0x190, %rcx, %rcx      # imm = 0x190
addq %rcx, %rax
movq %rax, -0x88(%rbp)
cmpl $0x0, -0x7c(%rbp)
jne 0x218c3
movl $0x0, -0x8c(%rbp)
movl -0x8c(%rbp), %eax
movq -0x88(%rbp), %rcx
cmpl 0x150(%rcx), %eax
jae 0x218be
movq -0x88(%rbp), %rax
movq 0x158(%rax), %rax
movl -0x8c(%rbp), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rcx
movq %rcx, -0xa4(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x9c(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x94(%rbp)
movq -0x28(%rbp), %rax
movl -0xa4(%rbp), %ecx
subl $0x1, %ecx
movl %ecx, %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0xa4(%rbp)
movq -0x10(%rbp), %rcx
leaq -0xa4(%rbp), %rdi
movl $0x18, %esi
movl $0x1, %edx
callq 0x2270
movl -0x8c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8c(%rbp)
jmp 0x21824
jmp 0x21a8c
movl $0x0, -0xa8(%rbp)
movl -0xa8(%rbp), %eax
movq -0x88(%rbp), %rcx
cmpl 0x160(%rcx), %eax
jae 0x21967
movq -0x88(%rbp), %rax
movq 0x178(%rax), %rax
movl -0xa8(%rbp), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rcx
movq %rcx, -0xc0(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0xb8(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0xb0(%rbp)
movq -0x28(%rbp), %rax
movl -0xc0(%rbp), %ecx
subl $0x1, %ecx
movl %ecx, %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0xc0(%rbp)
movq -0x10(%rbp), %rcx
leaq -0xc0(%rbp), %rdi
movl $0x18, %esi
movl $0x1, %edx
callq 0x2270
movl -0xa8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa8(%rbp)
jmp 0x218cd
movl $0x0, -0xc4(%rbp)
movl -0xc4(%rbp), %eax
movq -0x88(%rbp), %rcx
cmpl 0x168(%rcx), %eax
jae 0x21a0b
movq -0x88(%rbp), %rax
movq 0x180(%rax), %rax
movl -0xc4(%rbp), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rcx
movq %rcx, -0xdc(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0xd4(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0xcc(%rbp)
movq -0x28(%rbp), %rax
movl -0xdc(%rbp), %ecx
subl $0x1, %ecx
movl %ecx, %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0xdc(%rbp)
movq -0x10(%rbp), %rcx
leaq -0xdc(%rbp), %rdi
movl $0x18, %esi
movl $0x1, %edx
callq 0x2270
movl -0xc4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc4(%rbp)
jmp 0x21971
movl $0x0, -0xe0(%rbp)
movl -0xe0(%rbp), %eax
movq -0x88(%rbp), %rcx
cmpl 0x164(%rcx), %eax
jae 0x21a8a
movq -0x88(%rbp), %rax
movq 0x188(%rax), %rax
movl -0xe0(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0xe4(%rbp)
movq -0x28(%rbp), %rax
movl -0xe4(%rbp), %ecx
subl $0x1, %ecx
movl %ecx, %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0xe8(%rbp)
movq -0x10(%rbp), %rcx
leaq -0xe8(%rbp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x2270
movl -0xe0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xe0(%rbp)
jmp 0x21a15
jmp 0x21a8c
jmp 0x21a8e
movl -0x7c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x7c(%rbp)
jmp 0x217d9
movq -0x28(%rbp), %rax
movq %rax, -0x118(%rbp)
cmpq $0x0, %rax
je 0x21ab9
movq -0x118(%rbp), %rdi
callq 0x21d0
movq -0x30(%rbp), %rax
movq %rax, -0x120(%rbp)
cmpq $0x0, %rax
je 0x21ad6
movq -0x120(%rbp), %rdi
callq 0x21d0
movq -0x10(%rbp), %rdi
callq 0x2140
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
nopl (%rax,%rax)