コード例 #1
0
ファイル: block.c プロジェクト: cjzcpsyx/Mini-Cryptocurrency
/* 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);
	}
}
コード例 #2
0
ファイル: block.c プロジェクト: dfeldman94/161proj2
/* 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 */
}
コード例 #3
0
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(&current->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(&current->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(&current->block.normal_tx, &current->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(&current->block, stdout);
			balances = balance_add(balances, &current->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, &current->block.normal_tx.dest_pubkey, 1);
				balances = balance_add(balances, &current->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;
}