// File: ra101[P]Generic-BlockChain-container-cpp/main.cpp
// Function: main
int main()
{
  ra::rsa_key_pair k1("127.0.0.1:80");
  ra::rsa_key_pair k2("189.0.2.47:52");

  ra::block_chain<custom_transaction, std::hash<std::string>> ra_coin(MED_DIFFICULTY, ra::verify, 50);
  // ra::block_chain<custom_transaction, std::hash<std::string>> ra_coin(MAX_DIFFICULTY, ra::verify);

  custom_transaction t1(k1.get_public_key(), k2.get_public_key(), 1000);

  /*
    Update the line below in the following manner to get the following exceptions
    comment it -> Invalid Transaction Error
    duplicate it -> Resign Exception
    replace k1 with k2 -> Mismatch
  */
  t1.sign_transaction<ra::rsa_key_pair>(k1);

  ra_coin.add_transaction(t1);

  ra_coin.mine_pending_transactions(k1.get_public_key());

  for (ra::block_chain<custom_transaction, std::hash<std::string>>::iterator abc = ra_coin.begin(); abc != ra_coin.end(); abc++)
  {
    std::cout << *abc;
  }
  std::cout << "\n\nIs Chain Valid: " << ra_coin.is_chain_valid();

  std::cout << "\n\nk2 balance : " << ra_coin.get_balance(k2.get_public_key());
  std::cout << "\nk1 balance : " << ra_coin.get_balance(k1.get_public_key());
  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1b0, %rsp            # imm = 0x1B0
movl $0x0, -0x4(%rbp)
leaq -0x39(%rbp), %rdi
movq %rdi, -0x140(%rbp)
callq 0x3450
movq -0x140(%rbp), %rdx
leaq 0x6289(%rip), %rsi      # 0xa019
leaq -0x38(%rbp), %rdi
callq 0x4590
jmp 0x3d9b
leaq -0x18(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x3770
jmp 0x3daa
leaq -0x38(%rbp), %rdi
callq 0x31a0
leaq -0x39(%rbp), %rdi
callq 0x32e0
leaq -0x81(%rbp), %rdi
movq %rdi, -0x148(%rbp)
callq 0x3450
movq -0x148(%rbp), %rdx
leaq 0x6249(%rip), %rsi      # 0xa026
leaq -0x80(%rbp), %rdi
callq 0x4590
jmp 0x3de8
leaq -0x60(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x3770
jmp 0x3df7
leaq -0x80(%rbp), %rdi
callq 0x31a0
leaq -0x81(%rbp), %rdi
callq 0x32e0
leaq 0x82d(%rip), %rdx       # 0x4640
leaq -0xe0(%rbp), %rdi
movl $0x2, %esi
movss 0x61dd(%rip), %xmm0     # 0xa004
callq 0x4690
leaq -0x18(%rbp), %rdi
callq 0x38a0
movq %rax, -0x150(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x38a0
movq -0x150(%rbp), %rsi
movq %rax, %rdx
movl $0x447a0000, -0x10c(%rbp) # imm = 0x447A0000
leaq -0x108(%rbp), %rdi
leaq -0x10c(%rbp), %rcx
callq 0x47f0
jmp 0x3e6e
movups -0x18(%rbp), %xmm0
movaps %xmm0, -0x120(%rbp)
movq -0x120(%rbp), %rsi
movq -0x118(%rbp), %rdx
leaq -0x108(%rbp), %rdi
callq 0x4870
jmp 0x3e95
leaq -0xe0(%rbp), %rdi
leaq -0x108(%rbp), %rsi
callq 0x4ac0
jmp 0x3eaa
leaq -0x18(%rbp), %rdi
callq 0x38a0
movq %rax, %rsi
leaq -0xe0(%rbp), %rdi
callq 0x4ba0
jmp 0x3ec4
leaq -0xe0(%rbp), %rdi
callq 0x4d00
movq %rax, -0x158(%rbp)
jmp 0x3ed9
movq -0x158(%rbp), %rax
movq %rax, -0x128(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0x4d60
movq %rax, -0x160(%rbp)
jmp 0x3efc
movq -0x160(%rbp), %rax
movq %rax, -0x130(%rbp)
leaq -0x128(%rbp), %rdi
leaq -0x130(%rbp), %rsi
callq 0x4d30
movb %al, -0x161(%rbp)
jmp 0x3f25
movb -0x161(%rbp), %al
testb $0x1, %al
jne 0x3f34
jmp 0x400c
leaq -0x128(%rbp), %rdi
callq 0x4ee0
movq %rax, -0x170(%rbp)
jmp 0x3f49
movq -0x170(%rbp), %rsi
movq 0xb081(%rip), %rdi      # 0xefd8
callq 0x4d90
jmp 0x3f5e
jmp 0x3f60
leaq -0x128(%rbp), %rdi
xorl %esi, %esi
callq 0x4f00
movq %rax, -0x178(%rbp)
jmp 0x3f77
movq -0x178(%rbp), %rax
movq %rax, -0x138(%rbp)
jmp 0x3ee7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x3fad
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x31a0
leaq -0x39(%rbp), %rdi
callq 0x32e0
jmp 0x411d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x3fde
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x31a0
leaq -0x81(%rbp), %rdi
callq 0x32e0
jmp 0x411d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0x50d0
jmp 0x411d
movq 0xafc5(%rip), %rdi      # 0xefd8
leaq 0x601a(%rip), %rsi      # 0xa034
callq 0x3270
movq %rax, -0x180(%rbp)
jmp 0x4028
leaq -0xe0(%rbp), %rdi
callq 0x4f30
movb %al, -0x181(%rbp)
jmp 0x403c
movq -0x180(%rbp), %rdi
movb -0x181(%rbp), %al
movzbl %al, %esi
andl $0x1, %esi
callq 0x3460
jmp 0x4056
movq 0xaf7b(%rip), %rdi      # 0xefd8
leaq 0x5fe3(%rip), %rsi      # 0xa047
callq 0x3270
movq %rax, -0x190(%rbp)
jmp 0x4072
leaq -0x60(%rbp), %rdi
callq 0x38a0
movq %rax, %rsi
leaq -0xe0(%rbp), %rdi
callq 0x5050
movss %xmm0, -0x194(%rbp)
jmp 0x4094
movss -0x194(%rbp), %xmm0
movq -0x190(%rbp), %rdi
callq 0x3200
jmp 0x40aa
movq 0xaf27(%rip), %rdi      # 0xefd8
leaq 0x5f9f(%rip), %rsi      # 0xa057
callq 0x3270
movq %rax, -0x1a0(%rbp)
jmp 0x40c6
leaq -0x18(%rbp), %rdi
callq 0x38a0
movq %rax, %rsi
leaq -0xe0(%rbp), %rdi
callq 0x5050
movss %xmm0, -0x1a4(%rbp)
jmp 0x40e8
movss -0x1a4(%rbp), %xmm0
movq -0x1a0(%rbp), %rdi
callq 0x3200
jmp 0x40fe
movl $0x0, -0x4(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0x50d0
movl -0x4(%rbp), %eax
addq $0x1b0, %rsp            # imm = 0x1B0
popq %rbp
retq
movq -0x48(%rbp), %rdi
callq 0x3430
nopw %cs:(%rax,%rax)