/* Mine a block. Increment the nonce until the block's hash output satisfies * TARGET_HASH. */ void block_mine(struct block *b) { hash_output h; block_hash(b, h); while (hash_output_is_below_target(h) != 1) { b->nonce++; block_hash(b, h); } }
/* Mine a block. Increment the nonce until the block's hash output satisfies * TARGET_HASH. */ void block_mine(struct block *b) { hash_output h; int i = 0; do { i ++; b->nonce = b->nonce + 1; block_hash(b, h); } while(!(hash_output_is_below_target(h))); /* TODO */ }
int main(int argc, char *argv[]) { int i; struct block* blocks = malloc(argc * sizeof(struct block)); /* Read input block files. */ for (i = 1; i < argc; i++) { char *filename; struct block b; int rc; filename = argv[i]; rc = block_read_filename(&b, filename); if (rc != 1) { fprintf(stderr, "could not read %s\n", filename); exit(1); } /* TODO */ /* Feel free to add/modify/delete any code you need to. */ blocks[i] = b; } qsort(&blocks[0], argc, sizeof(struct block), compare); // sort block list w.r.t height /* Organize into a tree, check validity, and output balances. */ /* TODO */ // /* Make a linked list of sorted blocks*/ struct blockchain_node *root; struct blockchain_node *current; struct blockchain_node *lastNode; root = malloc(sizeof (struct blockchain_node)); lastNode = malloc(sizeof(struct blockchain_node)); int x=0; hash_output currentHash; /*Find root*/ while (x < argc) { struct block b = blocks[x]; block_hash(&b, currentHash); if (blocks[x].height == 0) { if (byte32_cmp(GENESIS_BLOCK_HASH, currentHash) == 0) { root->next = 0; root->block = blocks[x]; root->height = 0; root->parent = 0; root->is_valid = 1; current = root; x = argc; break; } else { root->is_valid = 0; x++; } } else { x++; } } /*Build linked list*/ for (i = 1; i < argc; i ++) { if (blocks[i].height != 0) { current->next = malloc(sizeof(struct blockchain_node)); current->next->is_valid = 1; current->next->block = blocks[i]; current->next->height = blocks[i].height; current->next->prev = current; current->next->parent = 0; current->next->next = 0; findPrevTx(&blocks[i], blocks, current->next, argc); current = current->next; } } lastNode = current; /*Build tree*/ current = root; while (current != 0) { struct blockchain_node *currentChild = current->next; hash_output currHash; block_hash(¤t->block, currHash); while (currentChild != 0 && (currentChild->height == current->height + 1 || currentChild->height == current->height)) { if (byte32_cmp(currHash, currentChild->block.prev_block_hash) == 0) { currentChild->parent = current; } if (currentChild->next != 0) { currentChild = currentChild->next; } else { break; } } current = current->next; } /*Check validity*/ current = lastNode; struct transaction *prev_transaction; prev_transaction = malloc(sizeof (struct transaction)); while (current && current != 0) { hash_output currentBlockHash; block_hash(¤t->block, currentBlockHash); if (hash_output_is_below_target(currentBlockHash) == 0) { current->is_valid = 0; } else if (!current->parent) { if (current->height != 0) { current->is_valid = 0; } } else if ( (current->block.reward_tx.height != current->height) || (current->block.normal_tx.height != current->height) ) { current->is_valid = 0; } else if ( byte32_is_zero(current->block.reward_tx.prev_transaction_hash) == 0 || byte32_is_zero(current->block.reward_tx.src_signature.r) == 0 || byte32_is_zero(current->block.reward_tx.src_signature.s) == 0 ) { current->is_valid = 0; } else if (byte32_is_zero(current->block.normal_tx.prev_transaction_hash) == 0 ) { if (checkAncestorTx(current) == 0) { current->is_valid = 0; } else if (transaction_verify(¤t->block.normal_tx, ¤t->prev_transaction) != 1) { current->is_valid = 0; } else if (checkAncestorPrevTx(current) == 1) { current->is_valid = 0; } } current = current->prev; } /*Find main chain*/ current = lastNode; while (current && current != 0) { if (hasValidPath(current) == 1) { markMainChain(current); break; } current = current->prev; } /*Add up balances*/ current = root; struct balance *balances = NULL; while (current && current != 0) { if (current->is_main == 1) { // reward_tx increment. //block_print(¤t->block, stdout); balances = balance_add(balances, ¤t->block.reward_tx.dest_pubkey, 1); // normal_tx increment and decrement. if (!byte32_is_zero(current->block.normal_tx.prev_transaction_hash)) { balances = balance_add(balances, ¤t->block.normal_tx.dest_pubkey, 1); balances = balance_add(balances, ¤t->prev_transaction.dest_pubkey, -1); } } current = current->next; } struct balance *p, *next; /* Print out the list of balances. */ for (p = balances; p != NULL; p = next) { next = p->next; printf("%s %d\n", byte32_to_hex(p->pubkey.x), p->balance); free(p); } /*Find leaf node (of the main chain)*/ current = lastNode; struct blockchain_node *block5_node; struct blockchain_node *leafNode; while (current && current != 0) { if ((current->is_main)) { leafNode =current; break; } else { current = current->prev; } } current = lastNode; while (current && current != 0) { if ((current->is_main) && (current->height == 5)){ block5_node =current; break; }else{ current = current->prev; } } struct block newblock; struct block headblock; struct block block5; headblock = leafNode->block; block5 = block5_node->block; block_init(&newblock, &headblock); const EC_KEY *mykey = key_read_filename("mykey.priv"); if (mykey == NULL) { printf("%s\n", "FAIL"); } EC_KEY *block5_key = key_read_filename("block5_key.priv"); // BLOCK 5 // mine a new block that transfers the reward of block 5 to mykey.priv. build off of myblock1.blk block_init(&newblock, &headblock); transaction_set_dest_privkey(&newblock.reward_tx, mykey); /* The last transaction was in the previous block. */ transaction_set_prev_transaction(&newblock.normal_tx, &block5.reward_tx); transaction_set_dest_privkey(&newblock.normal_tx, mykey); int check = transaction_sign(&newblock.normal_tx, block5_key); if (check == 0) { printf("%s\n", "transaction sign failed"); } /* Mine the new block and save to a file. */ block_mine(&newblock); block_write_filename(&newblock, "myblock2.blk"); // block_print(&headblock,stdout); // printf("%s\n", "NEWBLOCK"); // block_print(&newblock, stdout); // transaction_set_dest_privkey(&newblock.reward_tx, mykey); // transaction_set_prev_transaction(&newblock.normal_tx, &block4.normal_tx); // // /* Send it to us and sign it with the guessed private key */ // transaction_set_dest_privkey(&newblock.normal_tx, mykey); // int check = transaction_sign(&newblock.normal_tx, weakkey); // if (check == 0) { // printf("%s\n", "transaction sign failed"); // } // // /* Mine the new block and save to a file. */ // //block_mine(&newblock); // //block_write_filename(&newblock, "myblock1.blk"); return 0; }