From a8ffaa2bb50a48c066cef0cfb9663cbec38c0ce3 Mon Sep 17 00:00:00 2001 From: Divyansh Gupta Date: Sat, 27 Apr 2024 21:05:23 +0530 Subject: [PATCH] fix: made some changes to pass grader * Print Coinbase tx after the serliased coinbase tx * Include coinbase tx in tx_hash_list & tx_id_list -> thus include it in merkle_root & witness_commitment --- Block.py | 89 ++++++++++++++++------ Transacttions.py | 14 ++-- __pycache__/Block.cpython-311.pyc | Bin 6848 -> 7051 bytes __pycache__/Transacttions.cpython-311.pyc | Bin 21462 -> 21556 bytes output.txt | 6 +- trial.js | 20 +++++ 6 files changed, 97 insertions(+), 32 deletions(-) create mode 100644 trial.js 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 78a06c7aec6ae0bb4b023f3a531561adb3378d83..a04350f62d6ff0d34d15f708975ca72c4c985c12 100644 GIT binary patch delta 1432 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 diff --git a/__pycache__/Transacttions.cpython-311.pyc b/__pycache__/Transacttions.cpython-311.pyc index 569a0c71893c6c7d7ac475b51a6d5289711a3b4d..d5c7a58a490651ee4eac96389a24f8fe4f4bba67 100644 GIT binary patch delta 516 zcmcb%oN>zvM!w~|yj%=GP|2&Crslhm?~EN+1S12(bcPhhTBgbCJe4P(G3FOYXRKwe zVRT`LwW(#PVP3#AxzSi;@+oni$pU`Llk<4_C-3Lwn;c*-%*Z=AUsgs4sF$sT9b_y7 z)Ubj~n#3nCd6}^wTP=GH`vUgK6U~(-|Fh@eDhdKBDhdV?lervJ6{>&?O^za6kl+d+ zaf>fGKQk{Wu{brpyrd#CWwNJ(9xDe>LSb^XgQ3DQAgh7l10REAG-C(fT`}qDxs!4i z_+1n;z9MFPLDXdPR)!~~>5iq21d zAD}D+lFMXZaA3&%Uk^0J6v!>Q03t3<)(K2v%-Y-^$jHcc86TBaIC7lv4yTIL$21(O?% zMR*xXm_ceGVDbWO<;hjD{F5gL@J-&&%g4sZ&|_P|Ir*Tmlt?X03S%uRvg#U^$$1jW zle?YxC;ze+W@f8ln=Ig9FxksNRVoN*UQsZJr~(q2>_xgD_6i^|x!*x=@@6i<$>$wZ zIQxMD4Ga%N#WxE(hB7fSZO(K~XJp*B`J&4oMlpU?jSmb!;v+Kyn_x@y2PTk!%I3#z z(Tt2oC);~?Fv@T4@X%po)Y`n&6R6v4GPln$sr?{}4uFV*AVL5{h=PbilQ;THaJhh( zAVPLCudg%{qu*pr{|W&#O(3O;j6Rz$`zJGs?*J;!frSwhLlF~@A5wH~vTvX=L(L1tc<+!dI_n6mk8AR{B&C6LI)$zOsz7;j9r4URN$;$YPKz<{0n2p0c>EbBM< HSa2QytPyuV 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