diff --git a/Block.py b/Block.py index e272092f..ddcdd57b 100644 --- a/Block.py +++ b/Block.py @@ -2,6 +2,9 @@ from unittest import TestCase import Transacttions from Helper import * +import time + + GENESIS_BLOCK = bytes.fromhex('0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c') TESTNET_GENESIS_BLOCK = bytes.fromhex('0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff001d1aa4ae18') @@ -32,8 +35,8 @@ def serialize_blockheader(self): result = int_to_little_endian(self.version, 4) # prev_block - 32 bytes, little endian result += self.prev_block[::-1] - # merkle_root - 32 bytes, little endian - result += self.merkle_root[::-1] + # merkle_root - 32 bytes, little endian -> require it in natural order in grader + result += self.merkle_root # timestamp - 4 bytes, little endian result += int_to_little_endian(self.timestamp, 4) # bits - 4 bytes @@ -88,25 +91,18 @@ def get_mined_tx_data(cls, tx_files): @classmethod def create_block(cls, tx_files): # we assume that the tx_files are in sorted in fee_rate - version = 803823616 - timestamp = 1714064564 + timestamp = int(time.time()) prev_block= "000000000000000000030ed9d2b8643c4c1d8519f34fbecaf150136e20ee183f" prev_block_in_bytes= bytes.fromhex(prev_block) #------------------------------------------------------------------------------------------ - # create a list of tx_hashes of all tx which are to be mined in our block - tx_hashes_list= [] - - for tx in tx_files: - tx_hash = Transacttions.Tx.get_tx_hash(tx) - tx_hashes_list.append(tx_hash) + #--------------------------------------------------------------------------------------------- - merkle_root_hash= merkle_root(tx_hashes_list) bits= "1f00ffff" bits_in_bytes=bytes.fromhex(bits) target ="0000ffff00000000000000000000000000000000000000000000000000000000" @@ -116,31 +112,51 @@ def create_block(cls, tx_files): # get the data related to tx mined in our block (tx_count,tx_included,fees_collected,weight_stored)=Block.get_mined_tx_data(tx_files) - # print("fee_included:{}",format(fees_collected)) - # print("weight stored: {}".format(weight_stored)) + + #------------------------------------------------------------------------------------------- + + # create coinbase tx and get serliased form + + + + # get the serliased coinbase transaction + serliased_coinbase_tx= Transacttions.Tx.get_serliased_coinbase_tx(fees_collected,tx_files) + + #______________________________________________________________________________________________ + + + # create a list of tx_hashes of all tx which are to be mined in our block + + # First element in it -> coinbase tx_hash + tx_hashes_list= [hash256(bytes.fromhex(serliased_coinbase_tx))] + + for tx in tx_files: + tx_hash = Transacttions.Tx.get_tx_hash(tx) + tx_hashes_list.append(tx_hash) + + #___________________________________________________________________________________________ + + # we need to have coinbase tx_hash to get correct merkle root + merkle_root_hash= merkle_root(tx_hashes_list) + + # create an instance of a block block= Block(version,prev_block_in_bytes,merkle_root_hash,timestamp,bits_in_bytes,nonce,tx_hashes_list) # get the serliased block header serliased_block_header= block.serialize_blockheader() - - #------------------------------------------------------------------------------------------- - # get valid block header/ pow - - valid_block= block.get_valid_nonce(target) - #______________________________________BLOCK_HEADER_________________________________________ - - # get the serliased coinbase transaction - serliased_coinbase_tx= Transacttions.Tx.get_serliased_coinbase_tx(fees_collected,tx_files) - #______________________________________________________________________________________________ + #______________________________________BLOCK_HEADER_________________________________________ # Now print all the txids which are included in our block # get the txids from tx_hashes_list + # As per Readme -> first tx will be coinbase tx_id + # wit_hashes.append(hash256(Tx.serialize(tx))) + # coinbase_txid_in_bytes= (hash256(bytes.fromhex(serliased_coinbase_tx)))[::-1] tx_ids_list= [] for tx_hashes in tx_hashes_list: tx_ids_list.append((tx_hashes[::-1]).hex()) @@ -151,10 +167,32 @@ def create_block(cls, tx_files): # now print the required block details in the output.txt # print the serliased block header - print(valid_block.serialize_blockheader()) + serliased= valid_block.serialize_blockheader() + print(serliased) + + + + + + + + # print("merkle root : \n {}".format(valid_block.merkle_root.hex())) + # print(serliased) + # serliased_in_bytes= bytes.fromhex(serliased) + + + # desired_slice = serliased_in_bytes[36:68].hex() + # print(desired_slice) + # print(desired_slice == valid_block.merkle_root.hex()) # print("{} {} {} {} {} {} ".format(valid_block.version,(valid_block.prev_block).hex(),(valid_block.merkle_root).hex(),valid_block.timestamp,(valid_block.bits).hex(),valid_block.nonce)) # print("block hash: {}".format(valid_block.hash())) + + + + + + # serliased coinbase transaction print(serliased_coinbase_tx) @@ -205,4 +243,5 @@ def get_valid_nonce(self,target): # block_header= "0060e92f3f18ee206e1350f1cabe4ff319851d4c3c64b8d2d90e030000000000000000005f73d58ab5be2407065a26a290750250c1ebebc46a280e6f2b1c5032b3397c2ab48c2a66ffff001f00000000" # target ="0000ffff00000000000000000000000000000000000000000000000000000000" -# print(Block.check_pow(block_header,target)) \ No newline at end of file +# print(Block.check_pow(block_header,target)) + diff --git a/Transacttions.py b/Transacttions.py index 4fda91d9..cac1e3e9 100644 --- a/Transacttions.py +++ b/Transacttions.py @@ -443,7 +443,7 @@ def get_serliased_coinbase_tx(cls,fees_collected,tx_files): witness_commitment = Tx.get_witness_commitment(tx_files) amount_2 = 0 script_pubkey_2 = "6a24aa21a9ed" + witness_commitment - + witness_reserved_value = "0000000000000000000000000000000000000000000000000000000000000000" @@ -494,7 +494,13 @@ def get_serliased_coinbase_tx(cls,fees_collected,tx_files): @classmethod def get_witness_commitment(cls, tx_files): - wit_hashes = [] + + # Note -> for calculating witness_root -> we also require witness_txid of coinbase tx -> which is set to all zeroes + # As witness_commitment will be inside the tx -> so this value is used in order to prvent circular reference + + # wit_hashes will contain hashes in bytes + coinbase_wtxid= "0000000000000000000000000000000000000000000000000000000000000000" + wit_hashes = [bytes.fromhex(coinbase_wtxid)] for tx in tx_files: wit_hashes.append(hash256(Tx.serialize(tx))) @@ -637,6 +643,4 @@ def categorize_sequence(sequence): return result - - - \ No newline at end of file + diff --git a/__pycache__/Block.cpython-311.pyc b/__pycache__/Block.cpython-311.pyc index 78a06c7a..a04350f6 100644 Binary files a/__pycache__/Block.cpython-311.pyc and b/__pycache__/Block.cpython-311.pyc differ diff --git a/__pycache__/Transacttions.cpython-311.pyc b/__pycache__/Transacttions.cpython-311.pyc index 569a0c71..d5c7a58a 100644 Binary files a/__pycache__/Transacttions.cpython-311.pyc and b/__pycache__/Transacttions.cpython-311.pyc differ diff --git a/output.txt b/output.txt index a0a398bf..39ec36ca 100644 --- a/output.txt +++ b/output.txt @@ -1,5 +1,6 @@ -0060e92f3f18ee206e1350f1cabe4ff319851d4c3c64b8d2d90e03000000000000000000d40eb0df1c5945f0059bfb300ab3d2f2064ad229f15aaac08d9f7c6896d0a395b48c2a66ffff001f627f0100 -010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff11030cd3bf0c004f4345414e2e58595a002effffffff02e412bf13000000001976a9142c30a6aaac6d96687291475d7d52f4b469f665a688ac0000000000000000266a24aa21a9ed07528e9068d79f4fa737ce2b8cdea09f1b9c3c7a588948ff29e9d29d9a9cb2ef0120000000000000000000000000000000000000000000000000000000000000000000000000 +0060e92f3f18ee206e1350f1cabe4ff319851d4c3c64b8d2d90e03000000000000000000664d84331a42280c640a257b7e2223c2774445a448668a242a075add51187f5719232d66ffff001f87110000 +010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff11030cd3bf0c004f4345414e2e58595a002effffffff02e412bf13000000001976a9142c30a6aaac6d96687291475d7d52f4b469f665a688ac0000000000000000266a24aa21a9ed68d3d720d695be2c9d1e2f33c3d9d1042bdec1ce26b563afdc471db6a02a12520120000000000000000000000000000000000000000000000000000000000000000000000000 +96cb0dce25d42069df3ad24623a1d0c303e32b30412821f25cb7f6619d2e66c5 dcd522b3588c7adb0418454539e1a929fff936f211e5a20383fdcbc3ad8751b9 423c61f1ec58b9400a373e1052c26debdd5d55eb0057900c3dcf41f54762486c 141655b0e4239480afbdc12874e642ffeb94da72536ee4b8bace750820b26a06 @@ -4606,3 +4607,4 @@ a7df823f41af9f4b16d14076776680f0a0b4992672e5dd48b55751ceb91687e1 172224957b79af8a907b2a50b69a55d4b3dc77ed44ab7ac91506e45579a5d0d7 2164dcfb6fb3fac50f08cb48e33d1aecaef232e0706e7986ded1ef3bb12bfadf 2fd700bef22948f7754792ee9418c582444135a685e3b9f7d721c633035228ef +2fd700bef22948f7754792ee9418c582444135a685e3b9f7d721c633035228ef diff --git a/trial.js b/trial.js new file mode 100644 index 00000000..d2583043 --- /dev/null +++ b/trial.js @@ -0,0 +1,20 @@ +const WITNESS_RESERVED_VALUE = Buffer.from( + '0000000000000000000000000000000000000000000000000000000000000000', + 'hex', +) + +// print(WITNESS_RESERVED_VALUE) +console.log(typeof WITNESS_RESERVED_VALUE) +console.log(WITNESS_RESERVED_VALUE.toString('hex')); + + +const str = WITNESS_RESERVED_VALUE.toString('hex'); +let count = 0; + +for (let i = 0; i < str.length; i++) { + if (str[i] === '0') { + count++; + } +} + +console.log("Number of zeros:", count); \ No newline at end of file