From 10c44992885f083d41d2a8e032d692a8d62623d1 Mon Sep 17 00:00:00 2001 From: Pavitra Agarwal Date: Mon, 29 Apr 2024 00:21:34 +0530 Subject: [PATCH] testing through other librarys --- __pycache__/block.cpython-312.pyc | Bin 0 -> 1659 bytes __pycache__/op.cpython-312.pyc | Bin 0 -> 29250 bytes __pycache__/script.cpython-312.pyc | Bin 5897 -> 10625 bytes __pycache__/speck256k1.cpython-312.pyc | Bin 0 -> 16153 bytes __pycache__/tx.cpython-312.pyc | Bin 0 -> 14288 bytes __pycache__/usefulfunctions.cpython-312.pyc | Bin 5271 -> 6710 bytes block.py | 30 ++ ...4f11a555b10293879796a365f7df9d3299b88.json | 35 ++ ...b600a3a218e5716430d2d5ad9f1b3fb6d48f7.json | 53 +++ ...d59d4abba9ee0160910ac94b4bcefb294f196.json | 41 +++ ...9ebaed0c8c631d061c2e9e90957a40e99eb4c.json | 41 +++ ...234204f6caddb4228ee42b7cc7ad279a copy.json | 41 +++ ...ba799234204f6caddb4228ee42b7cc7ad279a.json | 41 +++ ...7d2091563e098c618eebf4ed205d123a3e8c4.json | 75 ++++ ...bfdedcbdfbed6b698ea177c6bb0b17f5a7ba6.json | 60 ++++ ...be6a7487977d66e18e096f8c45ba5f806bf64.json | 75 ++++ ...485852e549bf4bbd68fc49ff45994f0cb9196.json | 41 +++ ...6b21ebbc298d3ddfe272639524d36e33cb6e5.json | 41 +++ checkpool/p2wsh.json | 44 +++ main.py | 327 ++++++++++++++---- op.py | 323 +++++++++-------- output.txt | 7 + run.sh | 3 +- script.py | 161 ++++++--- usefulfunctions.py | 38 +- 25 files changed, 1219 insertions(+), 258 deletions(-) create mode 100644 __pycache__/block.cpython-312.pyc create mode 100644 __pycache__/op.cpython-312.pyc create mode 100644 __pycache__/speck256k1.cpython-312.pyc create mode 100644 __pycache__/tx.cpython-312.pyc create mode 100644 block.py create mode 100644 checkpool/00a7cd970878170da06195098c84f11a555b10293879796a365f7df9d3299b88.json create mode 100644 checkpool/0a250dfd08a8d349121a722baa0b600a3a218e5716430d2d5ad9f1b3fb6d48f7.json create mode 100644 checkpool/0a3c3139b32f021a35ac9a7bef4d59d4abba9ee0160910ac94b4bcefb294f196.json create mode 100644 checkpool/0a3fd98f8b3d89d2080489d75029ebaed0c8c631d061c2e9e90957a40e99eb4c.json create mode 100644 checkpool/0a4ce1145b6485c086f277aa185ba799234204f6caddb4228ee42b7cc7ad279a copy.json create mode 100644 checkpool/0a4ce1145b6485c086f277aa185ba799234204f6caddb4228ee42b7cc7ad279a.json create mode 100644 checkpool/0a70cacb1ac276056e57ebfb0587d2091563e098c618eebf4ed205d123a3e8c4.json create mode 100644 checkpool/0ce93f0d277ec7da2fb565e6468bfdedcbdfbed6b698ea177c6bb0b17f5a7ba6.json create mode 100644 checkpool/0e619bb379633b3a950ef89e901be6a7487977d66e18e096f8c45ba5f806bf64.json create mode 100644 checkpool/d9237779e6a79fd2891464e2f4a485852e549bf4bbd68fc49ff45994f0cb9196.json create mode 100644 checkpool/fe3d4ed0bd14414885bb8e067dc6b21ebbc298d3ddfe272639524d36e33cb6e5.json create mode 100644 checkpool/p2wsh.json create mode 100644 output.txt mode change 100644 => 100755 run.sh diff --git a/__pycache__/block.cpython-312.pyc b/__pycache__/block.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4f9cb6d4ef726947df5bd66e5691d1de6558b32c GIT binary patch literal 1659 zcmaJBO=}xh@V(uYv{odmRvgE6O;J@h_6BUVMh#6Ug# zByZYsT-~kdw&l7u)0tyhhU3LH46(8H!L@Rr65vpu46{IY2_q$Hl9Dt*%n1B}mSj`j zCnd#H07rJH7WE>x>{@xVSXR%OK`Rgg8CHBNE!rab__-wkMMq>y25R(I(o%pzO&?kj zphmHiRurhn_$>xhbVTit$F!)$yx2D5!m2r5yw2ISzK*VW7pjbJLfpJobG-@Isxsjk z)w-vwTdwdTPR%JZ;D4oKLYUB0PZ7+n@CmTau_*ikq6DHOqDe$4Kmvo#gz&PE`$E9) zb9H0ea=DQ!FtO>@>bY{wWGm$j!?u}om#wV5x0YY|EReZ**Wh0o_S*Y7-__Onj;HFn zQ>Gi#! zN&F2E@}iuHhV2SWUnaw+kT(G>VHvj7WX)7i&oKkrNPGimkNh_EZqIyVAK6cCo=jb9 zM+fTU!D2Vp$sH~BZuJ)X>7~B96taI!XZz{wQNDM(m+z;S`|7g)@HBm;=RUfBbpOfL zN&0$Uy*{#{b+m_t!}Y^LC)Zcs9&xXBu0FhT$Pe#;t-hKCcIr|)$uELCue1qf!f%sL z;nF2g_;I5EBZTAd+@@Y3T@a#w0eCWS9-4NP(K#%<;{xFa&|2Frw-CZC_HHXqR#nQ;nnGaM@x~M5$sv%gVVOJVX*@g8cf~LgK1A`g7VeR~gU#cGkj(yCtz{4^Kbm_TF SDgB+?_)A)#^DhV>U*{ipSYufL literal 0 HcmV?d00001 diff --git a/__pycache__/op.cpython-312.pyc b/__pycache__/op.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ec0659072d9369fbd838935fe38487e6f53542ae GIT binary patch literal 29250 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 literal 0 HcmV?d00001 diff --git a/__pycache__/script.cpython-312.pyc b/__pycache__/script.cpython-312.pyc index 66e3b60ed828a6b7d57d646fd265df2e3e0548c9..3e8ad0da897bd8d43ea25a6d2c48f6eebac38e6b 100644 GIT binary patch literal 10625 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 delta 1950 zcmaJ?UrbY17{8~z_qOzZ;g+@t_0m${8a0BbfW)b6pj%`j>KtZM=%3gP+j@G*QX;`E zBr9sNmh(Ut%|du8^Fb2g%d&-JPfN@eSbex_*s=#-$R0-O5|d@gcD_@=Wn(+Z{oU_; z-}%1p+~4<|b3YuK*>8JnwVF6OzWAm&dc&HtdC=KhOP~vJVcj%0YzXTq8pAxrs<1%O zq~rRzusF?y4G(nS$Z^Bwv{9+r08tThj}HUsL4$a}iCyA=HZ zHq+V0#}u#)zyU@?LB`b-OXg&I>e`i52*;8tc2kWA3&~Aw-|;@#3qwXUC~( zj*D=^D9jD(!Y0ZX8rCz$c*dB(7!!f5dP=2%QE6mUn!{Ceu_=ud3$~M^;w7t}MoU3# znbJV!MIW-06^hdGZc{;LDv2Y>WF#KOBKgh|I0marLMSmFS4)P_IK~kw7(p0KtC13l zm(W9GX0vxnH`*YJ@cC8_T_KnCNifqyF1@@dve}WIJe-_r1~t<$V02o-1?R)s#o8tGz+03KR*W8he(+OQ&XyB2=l?BxXKUHdb^feDb4YXMoH^hB#L=`F zHYimFw>FM)qf!w$G z(N|=})~Abqv}~~RXiBwiEmNzuq?_o$3;(V6O*BD`lj!aW&)q~roMIYad2lmT;}!}V z9Cg91REimCJ+T6YJrpLoL)XJ{EG5SisvJttnuSz38XJqq(CY`1>i%R}PDOBRWGpr@ zqQ(+&IT2;Hq$(>0%xcc7>13p&kHuAT)lu7o;bbX14$xN#;gX)Fzz66g1qLWNt#)6v zJkbihv>NwZSFWqfIjZ(#de`kW+1@+p`@P@WchmAeaVdpB;YQKbw&rNd zp{L&Z{Lnp5R@7>|`IECpHOckFyRQ&k8Yy}^*QCze3C*=DKRSDP{$e4r@a_xq=u%_R z+p#8fWKU?))J`7bvsVhWO9wx1*vaFc4o~ZvR)ZtOy3ti>lx{IQlrv`0x})KKXuk1Y zwCD&H(3(S;IkDMDzi89X(Iz&&>;Q5}a4z${t7wRwY*s9|hFD=X;EZoTV_*wNKplo| zSmbdJ$iO`Arce^#c%>E*BYf)$A&+)rbcVG0Co7T2ivOn|Th9Wq{j(VV_WU}~gU*pZ17rW` zxgqbIGZXAKUj)+tfJD9xdeIX3(itFEo4q8^JbpUO!Trtl0b5W6d>WQAeheVJ0bm4^ zzS5HhN|zdssMtxBDd4!$la7{p@iM4}NPEkmv?*}5J(Yvh2;QhqF_X_)f>TX&hK~Ro z2Vm(~k~1(J1UOG&v2szf9|*RC7659P+Dl=Yd&cuZL)qdLyyeas!CBtR3&+Y9y$~#$ zbiyfAHUj=;5``m`U4Z+5Vj(lF2gczK#(qS&4kY+LRB~Jb37UuH{oUAeJrN!siyXtl uR0kJF3Xa{T9wGEx$Ds?l=Tv<`R~8X!FY^dB1IP@Xi{}wKQsw|z$iDzHDc5)a diff --git a/__pycache__/speck256k1.cpython-312.pyc b/__pycache__/speck256k1.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a0f26859eeb069cfd2d1bc4166cf41ad9fd63181 GIT binary patch literal 16153 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

Lqvqbg@^L1V1* z;{}b;&inS3WM3*Y*`Kv+e= z@P$20qIp&iV~FUAB{K2e(_Xn#)H}Z#D~UVcL^DIba2BIjQ94TjcPzroUd)$_Wi8BK zXhql_6(WM(HFUuSXZnvsL0J;5OhB`js?ygY=21(@Or*eAg6`DmOS-(UhEZ#9*;njo z!K~JZNwUp4*^+aeRcI(1EyBLqF@000NjA60acqVH0pl~$=2A4(++tO`+y+$Cnm zOJ2%#6JWyj2y%#)F!gVN?Cil3ilZtPzue;+_5~He8yGz4RZPcyA+J(FMLjHQ9l#q@ z%E_?*3I;;KL=XnOlI#oHi_)1De1MknzXM$4aQTFIP8(jQIxg>qwJ=^2uSuLme9xH} zP5H95o1-1YQYp1OaUnI7t=)oBS0fqtKXt84+g9eBixN%oHAz0cK5DsdTkv-8crYGJ zzLYwYdNKL+TP@l8ZCTs)DF3kEw*jU8{3&^ zL*O;Hura#-euMj62X3rio_u+-G274@d*+jcP46}(#p@?0Pfo7QE?ghopKDkWeFma| zmUJjtk#(&}+tz%-KCD@nCvEdE*#K({KixRuF&ydiRL}21lldzR5@0f%M6L81fKtVt z1^4?xCkI4{E(awFrAglaka>W-bImYK;0jgj0AS9wAhb=_n1o%Q;R(&kX{#Wtn5nVi zMNJ(qteY`gge?!9oZ0cIVS%t_#)#Z!lw<2=v=eY(phUyNbphe+=f7M1H`{;G{yzr| zmin3-#C}r z|9Jn7XNWwt1mVciOe_AB#I@%9Y{h4$AFdRHM7L!`z@w9j!~PRNFZ6|PR&0v~WwO`J z2BmkHB~Nz{a4kOFK`e{8DhBB!+A<>rchg~k&{qBd0E;~`bN$uWs|hJ}H2P}Rz6rt^b{KhoTeJ3NCaTBy*w(Qlml4;1 zB_7`u-Fx3rpWv@=^VA_w=MpHD1XAgt(9B9(#oxclP+0#33nH9Bw8b8!e7Kn zaL!3r6vlatH{iA)g54J+DR{q9eehyB>B9eQgwJF81kNDzps=gP|j>p={v}IDimXHKvt^d z!Whixr0A4lB`<$qC@4b6usIcTzgIf#lN5`j7BD%aSY-7}$LeIZ5p2%F;H}K&oW|(# z3aFur+$XR&4`yx45ovPOjkm|!6HRYz$8RWiMyTIT| z{ccq|TlvPUb5q*3=_9*ytZmHu`UtMum>lc!Sm(D=uM$T8hyb%h%bt3VQ3Zkf_$Rjj z(EX`FaM8`_6Vv7@VbjCK%-pOK7BO@4Qv-5rTGr3wQ0zmpuWu;OHx%p*`3HisMCKCn z_|;!R2mHt3;P-ob6@!0(QJ(txZYMSS76C5-@^4toQ}uqxFqZrT*cxZA``6Z;>f`ra z(tBt^_L}?}03M$5{4cmCe$LhWoU8gLuKt(S&HVOHIe=dd@;mwZPdR{x5uOvw7x|n? zP=WmI&gju^ca0s+m=;n==SBWAa|OR*%=Q_FKcCfi^8A`H;WLi@e)^(;6Kc>1|IY{p U;Tils^_SMi_(jtk06Urg1JTC02LJ#7 literal 0 HcmV?d00001 diff --git a/__pycache__/tx.cpython-312.pyc b/__pycache__/tx.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5bfa05620bd28b9041e3b337e9b152f48396cbed GIT binary patch literal 14288 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 delta 949 zcmZWoOHUI~6z*+1(=vV82S}9=5}|cM%1fyt4=JWXgkTMX1&Nf>8SI!o$Z1PpBVG6h z$Xyr{{{RbPOx2aqoiTB3(p*h6L>FC{DDKo)&ly~4lYTwtyWhR{oB2+koxi7g-*`NV z1wXT|Bb%4q``%8rwI99h@@v7nmes&6Q$vrR#29n%Ll&z)visSUrXA(Y7J(B%wF*1v z84bM04J!*~l&#qG^neF{go~Eb+Ziy56$m4va7liy2xp~~-q@|^W&TPYlDcuBga4G@ zGe2)Q`dE!L=2Si9e9Pnzme9`om9wrhB(V!yv0C73 zN?aPmK2pE0WZ86tR8fTG<{sizun|Ew99UFIIP|<;(2EtJY#6uFdQmenMTn7P070-U zpK^CeajeJcY4--}K8aW{I_FdG!8Sk zaGihgKIok$U4q~r@$oTq)>8eUPhl&%8~`BiBVsTDrx{}c#frCNaq(S z&=3J7Z$^9kBFt3H_d+)VnSyl!x&TH9=y3Bd@WVNQX;kz26y%VjnJH%xzS= 4000000 : + break + if tx.verify() : + # print(tx.id()) + txids.append(tx.id()) + if tx.segwit : + # print(tx.wtxid()) + wxtid.append(tx.wtxid()) + else : + wxtid.append(tx.id()) + totalwu += tx.weightunit() + totalfees += tx.fee() + except Exception as e: + continue + + + + +hashes = [bytes.fromhex(h) for h in wxtid] +wxc = wxcommitment(merkle_root(hashes),bytes.fromhex(wxtidcons)).hex() +witnesscomitmentpubkeyscript = "6a24aa21a9ed"+wxc + +# so let now create the coinbase transaction +txin = [TxIn ( + prev_tx=bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000"), + prev_index=4294967295 , + script_sig=scripttype("47304402201f6e9296e322013f90f89433926509a9ff686ce91452679c82c921cf18257c95022027497b1354b4dce14b3e15d2372c69d6323ecfad9cbc0c8bb20d8d8d088fc22001210224c6633127ca04e9b678ae7d106a9828ba2aed9a402eefae69f52fbe7a065699"), + sequence=4294967295 , + witness= witnessbyte(["0000000000000000000000000000000000000000000000000000000000000000"]), + prevout=None +)] +txout = [ + TxOut( + amount=1250006517, + script_pubkey = scripttype("76a914edf10a7fac6b32e24daa5305c723f3de58db1bc888ac") + ) + , + TxOut( + amount=0, # this is the wtxid commitment value + script_pubkey = scripttype(witnesscomitmentpubkeyscript), + ) +] +ctx = Tx ( + version = 1, + tx_ins=txin, + tx_outs=txout, + locktime=0, + segwit=True ) -for txin in txex['vin'] : - vin = TxIn ( - prev_tx=bytes.fromhex(txin['txid']), - prev_index= txin['vout'], - prevout=TxOut( - script_pubkey=txin['prevout']['scriptpubkey'], - amount= txin['prevout']['value'], - ), - script_sig= None if txin['scriptsig'] == "" else txin['scriptsig'], - sequence = txin['sequence'], - witness = (txin['witness']) if tx.segwit else None , - ) - tx_ins.append(vin) -for txout in txex['vout'] : - vout = TxOut ( - script_pubkey = (txout['scriptpubkey']), - amount=txout['value'] - ) - tx_outs.append(vout) - -# it is not serliatiable because we does not implemented + + +CoinbaseTxnSerialize = ctx.serialize().hex() +# print(CoinbaseTxnSerialize) +CoinbaseTxnId = ctx.id() # this is our coinbase transaction +txids.insert(0,CoinbaseTxnId) +# print(totalfees) +# print(totalwu) +# print(txids) + + +txides = [bytes.fromhex(h) for h in txids] + +# now we can create the blockheader : + + + +block = Block ( + version= 1 , + prev_block= bytes.fromhex(base_block), + merkle_root= merkle_root(txides) , + timestamp= int(ts), + bits=bytes.fromhex('1dffff00') , + nonce= bytes.fromhex(nonce()) , #nonce()) , #nonce should be of the bytes + tx_hashes = txides +) +# print(block.serialize().hex()) #0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d7c2bac1d +# print(block.serialize().hex() == '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c') + +# print(hash256(block.serialize())[::-1].hex() == "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f") +# print(bits_to_target(bytes.fromhex('1d00ffff'))) + +# print(block.validate_merkle_root()) +# print(block.serialize().hex()) +cout = 0 +blockid = "" +while True : + block.nonce = bytes.fromhex(nonce()) + if block.hash() < bytes.fromhex(difficulty_target_hex) : + blockid = block.hash() + break + cout +=1 + # print(cout) + +block_header = hash256(block.serialize())[::-1].hex() +Coinbase_txn_serialize = ctx.serialize().hex() +Coinbase_txn_id = ctx.id() +# print(block_header) +# print(Coinbase_txn_serialize) +# for tx in txids : +# print(tx) + +script_directory = os.path.dirname(os.path.abspath(__file__)) +output_file_path = os.path.join(script_directory, "output.txt") +with open(output_file_path, "w") as output_file: + output_file.write("{}\n".format(block_header)) + output_file.write("{}\n".format(Coinbase_txn_serialize)) + for tx in txids : + output_file.write("{}\n".format(tx)) + + +#print(blockid.hex()) +# bt = bytes.fromhex("1234") +# print(len(bt)) +# print(f'correct txid - {correct}') +# print(f'error is - {error}') +# version = txex['version'] +# locktime = txex['locktime'] +# vouts = txex['vout'] +# tx_ins= [] +# tx_outs = [] +# tx = Tx( +# version=version , +# tx_ins=tx_ins , +# tx_outs= tx_outs , +# locktime=locktime , +# segwit=segwitness, +# ) +# for txin in txex['vin'] : +# vin = TxIn ( +# prev_tx=bytes.fromhex(txin['txid']), +# prev_index= txin['vout'], +# prevout=TxOut( +# script_pubkey=scripttype(txin['prevout']['scriptpubkey']), +# amount= txin['prevout']['value'], +# ), +# script_sig= None if txin['scriptsig'] == "" else scripttype(txin['scriptsig']), +# sequence = txin['sequence'], +# witness = witnessbyte(txin['witness']) if tx.segwit else None , +# ) +# tx_ins.append(vin) +# for txout in txex['vout'] : +# vout = TxOut ( +# script_pubkey = scripttype(txout['scriptpubkey']), +# amount=txout['value'] +# ) +# tx_outs.append(vout) + +# if tx.verify()==True : +# print(tx.id()) +# 1#0200000000010121adc70faebd381fd504affbd1adcdb6374134d1dea7f785557069bd570eb8ef0000000000fdffffff025bba0000000000001600146d689b16f4f33178e4241e907037c367fb1d15d890dd020000000000160014e88c315774d82dc0a417103c7200d68753686c5302 47 3044022005ce98f0b3a13b0a15ca11c8e8b3cb19fa0e03d15386e1d8cfec4b1afdbecc5c022068dd57e8287e96794b82945e99c663f2d4484cd048661bbaaeb734e8c01e055f01 21 0398c00f35640b026294b08a48054c9967a0ed79ec862af6f0e50e74af4ef8664a4cbc0c00 +# 2#0200000000010121adc70faebd381fd504affbd1adcdb6374134d1dea7f785557069bd570eb8ef0000000000fdffffff025bba0000000000001600146d689b16f4f33178e4241e907037c367fb1d15d890dd020000000000160014e88c315774d82dc0a417103c7200d68753686c5302 8e 3044022005ce98f0b3a13b0a15ca11c8e8b3cb19fa0e03d15386e1d8cfec4b1afdbecc5c022068dd57e8287e96794b82945e99c663f2d4484cd048661bbaaeb734e8c01e055f01 42 0398c00f35640b026294b08a48054c9967a0ed79ec862af6f0e50e74af4ef8664a4cbc0c00 +# 3#0200000000010121adc70faebd381fd504affbd1adcdb6374134d1dea7f785557069bd570eb8ef0000000000fdffffff025bba0000000000001600146d689b16f4f33178e4241e907037c367fb1d15d890dd020000000000160014e88c315774d82dc0a417103c7200d68753686c5302 47 3044022005ce98f0b3a13b0a15ca11c8e8b3cb19fa0e03d15386e1d8cfec4b1afdbecc5c022068dd57e8287e96794b82945e99c663f2d4484cd048661bbaaeb734e8c01e055f01 21 0398c00f35640b026294b08a48054c9967a0ed79ec862af6f0e50e74af4ef8664a4cbc0c00 +# 4#0200000000010121adc70faebd381fd504affbd1adcdb6374134d1dea7f785557069bd570eb8ef0000000000fdffffff025bba0000000000001600146d689b16f4f33178e4241e907037c367fb1d15d890dd020000000000160014e88c315774d82dc0a417103c7200d68753686c5302 47 3044022005ce98f0b3a13b0a15ca11c8e8b3cb19fa0e03d15386e1d8cfec4b1afdbecc5c022068dd57e8287e96794b82945e99c663f2d4484cd048661bbaaeb734e8c01e055f01210398c00f35640b026294b08a48054c9967a0ed79ec862af6f0e50e74af4ef8664a4cbc0c00 + +# # leairing is that pub script ins in the form of the byte then it would be good \ No newline at end of file diff --git a/op.py b/op.py index d1e26ee..9dffc1d 100644 --- a/op.py +++ b/op.py @@ -1,95 +1,139 @@ -# i am using the sample code where there is the op code mapping to reduce the workload and this is taken from the book -from usefulfunctions import encode_num , decode_num , hash160 , hash256 , hashlib +import hashlib +from speck256k1 import ( + S256Point, + Signature, +) + +from usefulfunctions import ( + hash160, + hash256, +) + +def encodenum(num): + if num == 0: + return b'' + absnum = abs(num) + negative = num < 0 + result = bytearray() + while absnum: + result.append(absnum & 0xff) + absnum >>= 8 + if result[-1] & 0x80: + if negative: + result.append(0x80) + else: + result.append(0) + elif negative: + result[-1] |= 0x80 + return bytes(result) + + +def decodenum(element): + if element == b'': + return 0 + bigendian = element[::-1] + + if bigendian[0] & 0x80: + negative = True + result = bigendian[0] & 0x7f + else: + negative = False + result = bigendian[0] + for c in bigendian[1:]: + result <<= 8 + result += c + if negative: + return -result + else: + return result -from speck256k1 import S256Point , Signature def op0(stack): - stack.append(encode_num(0)) + stack.append(encodenum(0)) return True - def op1negate(stack): - stack.append(encode_num(-1)) + stack.append(encodenum(-1)) return True def op1(stack): - stack.append(encode_num(1)) + stack.append(encodenum(1)) return True def op2(stack): - stack.append(encode_num(2)) + stack.append(encodenum(2)) return True def op3(stack): - stack.append(encode_num(3)) + stack.append(encodenum(3)) return True def op4(stack): - stack.append(encode_num(4)) + stack.append(encodenum(4)) return True def op5(stack): - stack.append(encode_num(5)) + stack.append(encodenum(5)) return True def op6(stack): - stack.append(encode_num(6)) + stack.append(encodenum(6)) return True def op7(stack): - stack.append(encode_num(7)) + stack.append(encodenum(7)) return True def op8(stack): - stack.append(encode_num(8)) + stack.append(encodenum(8)) return True def op9(stack): - stack.append(encode_num(9)) + stack.append(encodenum(9)) return True def op10(stack): - stack.append(encode_num(10)) + stack.append(encodenum(10)) return True def op11(stack): - stack.append(encode_num(11)) + stack.append(encodenum(11)) return True def op12(stack): - stack.append(encode_num(12)) + stack.append(encodenum(12)) return True def op13(stack): - stack.append(encode_num(13)) + stack.append(encodenum(13)) return True def op14(stack): - stack.append(encode_num(14)) + stack.append(encodenum(14)) return True def op15(stack): - stack.append(encode_num(15)) + stack.append(encodenum(15)) return True def op16(stack): - stack.append(encode_num(16)) + stack.append(encodenum(16)) return True @@ -100,68 +144,68 @@ def opnop(stack): def opif(stack, items): if len(stack) < 1: return False - good = [] - baad = [] - curarr = good + trueitems = [] + falseitems = [] + currentarray = trueitems found = False - num_end_if_needed = 1 + numendifsneeded = 1 while len(items) > 0: item = items.pop(0) if item in (99, 100): - num_end_if_needed += 1 - curarr.append(item) - elif num_end_if_needed == 1 and item == 103: - curarr = baad + numendifsneeded += 1 + currentarray.append(item) + elif numendifsneeded == 1 and item == 103: + currentarray = falseitems elif item == 104: - if num_end_if_needed == 1: + if numendifsneeded == 1: found = True break else: - num_end_if_needed -= 1 - curarr.append(item) + numendifsneeded -= 1 + currentarray.append(item) else: - curarr.append(item) + currentarray.append(item) if not found: return False element = stack.pop() - if decode_num(element) == 0: - items[:0] = baad + if decodenum(element) == 0: + items[:0] = falseitems else: - items[:0] = good + items[:0] = trueitems return True def opnotif(stack, items): if len(stack) < 1: return False - good = [] - baad = [] - curarr = good + trueitems = [] + falseitems = [] + currentarray = trueitems found = False - num_end_if_needed = 1 + numendifsneeded = 1 while len(items) > 0: item = items.pop(0) if item in (99, 100): - num_end_if_needed += 1 - curarr.append(item) - elif num_end_if_needed == 1 and item == 103: - curarr = baad + numendifsneeded += 1 + currentarray.append(item) + elif numendifsneeded == 1 and item == 103: + currentarray = falseitems elif item == 104: - if num_end_if_needed == 1: + if numendifsneeded == 1: found = True break else: - num_end_if_needed -= 1 - curarr.append(item) + numendifsneeded -= 1 + currentarray.append(item) else: - curarr.append(item) + currentarray.append(item) if not found: return False element = stack.pop() - if decode_num(element) == 0: - items[:0] = good + if decodenum(element) == 0: + items[:0] = trueitems else: - items[:0] = baad + items[:0] = falseitems return True @@ -169,7 +213,7 @@ def opverify(stack): if len(stack) < 1: return False element = stack.pop() - if decode_num(element) == 0: + if decodenum(element) == 0: return False return True @@ -238,13 +282,13 @@ def op2swap(stack): def opifdup(stack): if len(stack) < 1: return False - if decode_num(stack[-1]) != 0: + if decodenum(stack[-1]) != 0: stack.append(stack[-1]) return True def opdepth(stack): - stack.append(encode_num(len(stack))) + stack.append(encodenum(len(stack))) return True @@ -279,7 +323,7 @@ def opover(stack): def oppick(stack): if len(stack) < 1: return False - n = decode_num(stack.pop()) + n = decodenum(stack.pop()) if len(stack) < n + 1: return False stack.append(stack[-n - 1]) @@ -289,7 +333,7 @@ def oppick(stack): def oproll(stack): if len(stack) < 1: return False - n = decode_num(stack.pop()) + n = decodenum(stack.pop()) if len(stack) < n + 1: return False if n == 0: @@ -322,7 +366,7 @@ def optuck(stack): def opsize(stack): if len(stack) < 1: return False - stack.append(encode_num(len(stack[-1]))) + stack.append(encodenum(len(stack[-1]))) return True @@ -332,9 +376,9 @@ def opequal(stack): element1 = stack.pop() element2 = stack.pop() if element1 == element2: - stack.append(encode_num(1)) + stack.append(encodenum(1)) else: - stack.append(encode_num(0)) + stack.append(encodenum(0)) return True @@ -345,35 +389,35 @@ def opequalverify(stack): def op1add(stack): if len(stack) < 1: return False - element = decode_num(stack.pop()) - stack.append(encode_num(element + 1)) + element = decodenum(stack.pop()) + stack.append(encodenum(element + 1)) return True def op1sub(stack): if len(stack) < 1: return False - element = decode_num(stack.pop()) - stack.append(encode_num(element - 1)) + element = decodenum(stack.pop()) + stack.append(encodenum(element - 1)) return True def opnegate(stack): if len(stack) < 1: return False - element = decode_num(stack.pop()) - stack.append(encode_num(-element)) + element = decodenum(stack.pop()) + stack.append(encodenum(-element)) return True def opabs(stack): if len(stack) < 1: return False - element = decode_num(stack.pop()) + element = decodenum(stack.pop()) if element < 0: - stack.append(encode_num(-element)) + stack.append(encodenum(-element)) else: - stack.append(encode_num(element)) + stack.append(encodenum(element)) return True @@ -381,10 +425,10 @@ def opnot(stack): if len(stack) < 1: return False element = stack.pop() - if decode_num(element) == 0: - stack.append(encode_num(1)) + if decodenum(element) == 0: + stack.append(encodenum(1)) else: - stack.append(encode_num(0)) + stack.append(encodenum(0)) return True @@ -392,64 +436,64 @@ def op0notequal(stack): if len(stack) < 1: return False element = stack.pop() - if decode_num(element) == 0: - stack.append(encode_num(0)) + if decodenum(element) == 0: + stack.append(encodenum(0)) else: - stack.append(encode_num(1)) + stack.append(encodenum(1)) return True def opadd(stack): if len(stack) < 2: return False - element1 = decode_num(stack.pop()) - element2 = decode_num(stack.pop()) - stack.append(encode_num(element1 + element2)) + element1 = decodenum(stack.pop()) + element2 = decodenum(stack.pop()) + stack.append(encodenum(element1 + element2)) return True def opsub(stack): if len(stack) < 2: return False - element1 = decode_num(stack.pop()) - element2 = decode_num(stack.pop()) - stack.append(encode_num(element2 - element1)) + element1 = decodenum(stack.pop()) + element2 = decodenum(stack.pop()) + stack.append(encodenum(element2 - element1)) return True def opbooland(stack): if len(stack) < 2: return False - element1 = decode_num(stack.pop()) - element2 = decode_num(stack.pop()) + element1 = decodenum(stack.pop()) + element2 = decodenum(stack.pop()) if element1 and element2: - stack.append(encode_num(1)) + stack.append(encodenum(1)) else: - stack.append(encode_num(0)) + stack.append(encodenum(0)) return True def opboolor(stack): if len(stack) < 2: return False - element1 = decode_num(stack.pop()) - element2 = decode_num(stack.pop()) + element1 = decodenum(stack.pop()) + element2 = decodenum(stack.pop()) if element1 or element2: - stack.append(encode_num(1)) + stack.append(encodenum(1)) else: - stack.append(encode_num(0)) + stack.append(encodenum(0)) return True def opnumequal(stack): if len(stack) < 2: return False - element1 = decode_num(stack.pop()) - element2 = decode_num(stack.pop()) + element1 = decodenum(stack.pop()) + element2 = decodenum(stack.pop()) if element1 == element2: - stack.append(encode_num(1)) + stack.append(encodenum(1)) else: - stack.append(encode_num(0)) + stack.append(encodenum(0)) return True @@ -460,97 +504,97 @@ def opnumequalverify(stack): def opnumnotequal(stack): if len(stack) < 2: return False - element1 = decode_num(stack.pop()) - element2 = decode_num(stack.pop()) + element1 = decodenum(stack.pop()) + element2 = decodenum(stack.pop()) if element1 == element2: - stack.append(encode_num(0)) + stack.append(encodenum(0)) else: - stack.append(encode_num(1)) + stack.append(encodenum(1)) return True def oplessthan(stack): if len(stack) < 2: return False - element1 = decode_num(stack.pop()) - element2 = decode_num(stack.pop()) + element1 = decodenum(stack.pop()) + element2 = decodenum(stack.pop()) if element2 < element1: - stack.append(encode_num(1)) + stack.append(encodenum(1)) else: - stack.append(encode_num(0)) + stack.append(encodenum(0)) return True def opgreaterthan(stack): if len(stack) < 2: return False - element1 = decode_num(stack.pop()) - element2 = decode_num(stack.pop()) + element1 = decodenum(stack.pop()) + element2 = decodenum(stack.pop()) if element2 > element1: - stack.append(encode_num(1)) + stack.append(encodenum(1)) else: - stack.append(encode_num(0)) + stack.append(encodenum(0)) return True def oplessthanorequal(stack): if len(stack) < 2: return False - element1 = decode_num(stack.pop()) - element2 = decode_num(stack.pop()) + element1 = decodenum(stack.pop()) + element2 = decodenum(stack.pop()) if element2 <= element1: - stack.append(encode_num(1)) + stack.append(encodenum(1)) else: - stack.append(encode_num(0)) + stack.append(encodenum(0)) return True def opgreaterthanorequal(stack): if len(stack) < 2: return False - element1 = decode_num(stack.pop()) - element2 = decode_num(stack.pop()) + element1 = decodenum(stack.pop()) + element2 = decodenum(stack.pop()) if element2 >= element1: - stack.append(encode_num(1)) + stack.append(encodenum(1)) else: - stack.append(encode_num(0)) + stack.append(encodenum(0)) return True def opmin(stack): if len(stack) < 2: return False - element1 = decode_num(stack.pop()) - element2 = decode_num(stack.pop()) + element1 = decodenum(stack.pop()) + element2 = decodenum(stack.pop()) if element1 < element2: - stack.append(encode_num(element1)) + stack.append(encodenum(element1)) else: - stack.append(encode_num(element2)) + stack.append(encodenum(element2)) return True def opmax(stack): if len(stack) < 2: return False - element1 = decode_num(stack.pop()) - element2 = decode_num(stack.pop()) + element1 = decodenum(stack.pop()) + element2 = decodenum(stack.pop()) if element1 > element2: - stack.append(encode_num(element1)) + stack.append(encodenum(element1)) else: - stack.append(encode_num(element2)) + stack.append(encodenum(element2)) return True def opwithin(stack): if len(stack) < 3: return False - maximum = decode_num(stack.pop()) - minimum = decode_num(stack.pop()) - element = decode_num(stack.pop()) + maximum = decodenum(stack.pop()) + minimum = decodenum(stack.pop()) + element = decodenum(stack.pop()) if element >= minimum and element < maximum: - stack.append(encode_num(1)) + stack.append(encodenum(1)) else: - stack.append(encode_num(0)) + stack.append(encodenum(0)) return True @@ -606,9 +650,9 @@ def opchecksig(stack, z): except (ValueError, SyntaxError) as e: return False if point.verify(z, sig): - stack.append(encode_num(1)) + stack.append(encodenum(1)) else: - stack.append(encode_num(0)) + stack.append(encodenum(0)) return True @@ -619,23 +663,22 @@ def opchecksigverify(stack, z): def opcheckmultisig(stack, z): if len(stack) < 1: return False - n = decode_num(stack.pop()) + n = decodenum(stack.pop()) if len(stack) < n + 1: return False - sec_pub_keys = [] + secpubkeys = [] for _ in range(n): - sec_pub_keys.append(stack.pop()) - m = decode_num(stack.pop()) + secpubkeys.append(stack.pop()) + m = decodenum(stack.pop()) if len(stack) < m + 1: return False - der_sig = [] + dersignatures = [] for _ in range(m): - # signature is assumed to be using SIGHASHALL - der_sig.append(stack.pop()[:-1]) + dersignatures.append(stack.pop()[:-1]) stack.pop() try: - points = [S256Point.parse(sec) for sec in sec_pub_keys] - sigs = [Signature.parse(der) for der in der_sig] + points = [S256Point.parse(sec) for sec in secpubkeys] + sigs = [Signature.parse(der) for der in dersignatures] for sig in sigs: if len(points) == 0: return False @@ -643,7 +686,7 @@ def opcheckmultisig(stack, z): point = points.pop(0) if point.verify(z, sig): break - stack.append(encode_num(1)) + stack.append(encodenum(1)) except (ValueError, SyntaxError): return False return True @@ -658,7 +701,7 @@ def opchecklocktimeverify(stack, locktime, sequence): return False if len(stack) < 1: return False - element = decode_num(stack[-1]) + element = decodenum(stack[-1]) if element < 0: return False if element < 500000000 and locktime > 500000000: @@ -673,7 +716,7 @@ def opchecksequenceverify(stack, version, sequence): return False if len(stack) < 1: return False - element = decode_num(stack[-1]) + element = decodenum(stack[-1]) if element < 0: return False if element & (1 << 31) == (1 << 31): diff --git a/output.txt b/output.txt new file mode 100644 index 0000000..6a7a28a --- /dev/null +++ b/output.txt @@ -0,0 +1,7 @@ +00006da5d28edf5d7cd870443b3a382e3538a25d866d2269d8d778fb8079d3bb +010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff6a47304402201f6e9296e322013f90f89433926509a9ff686ce91452679c82c921cf18257c95022027497b1354b4dce14b3e15d2372c69d6323ecfad9cbc0c8bb20d8d8d088fc22001210224c6633127ca04e9b678ae7d106a9828ba2aed9a402eefae69f52fbe7a065699ffffffff02f595814a000000001976a914edf10a7fac6b32e24daa5305c723f3de58db1bc888ac0000000000000000266a24aa21a9ede87305b8c1fc3a4543e8f782ded05c1a464c39f9d5fe4413093c0ce1f270d5030120000000000000000000000000000000000000000000000000000000000000000000000000 +48acf3fced3d9fef33396e459b507c25c09cf70816d08f4a8c0ba5a6a97fccab +11b26c7d7881bae8dfd0378c0a6144f6a9480f68eca67c9e9c1347a5baef105f +7caf72c076992de5bb24db15004c97da0c135910eb85986ea106de9b9a750b05 +1bead20256df5fbe932c987cc8b2fbc90c74ebc945f8951a1793172b8dea40dc +fbcca1ef33984eaad190fb0f481ac0f8c9d2f0baf7718794ef596f74abef2837 diff --git a/run.sh b/run.sh old mode 100644 new mode 100755 index 721aeb2..0deaf4c --- a/run.sh +++ b/run.sh @@ -1 +1,2 @@ -# Update this file to run your own code \ No newline at end of file +# Update this file to run your own code +python3 main.py \ No newline at end of file diff --git a/script.py b/script.py index b1fba18..1fa24fb 100644 --- a/script.py +++ b/script.py @@ -1,4 +1,4 @@ -from usefulfunctions import int_to_little_endian , encode_varint , read_varint , sha256, little_endian_to_int , h160_to_p2pkh_address , h160_to_p2sh_address +from usefulfunctions import int_to_little_endian , encode_varint , read_varint , decode_base58,sha256, little_endian_to_int , h160_to_p2pkh_address , h160_to_p2sh_address from op import opequal, ophash160, opverify, OPCODEFUNCTIONS, OPCODENAMES from io import BytesIO def p2pkh_script(h160): @@ -9,6 +9,17 @@ def p2wpkh_script(h160): return Script([0x00, h160]) def p2wsh_script(h256): return Script([0x00, h256]) +def p2pkh_script(h160): + return Script([0x76, 0xa9, h160, 0x88, 0xac]) +def p2sh_script(h160): + return Script([0xa9, h160, 0x87]) +def p2wpkh_script(h160): + return Script([0x00, h160]) # <1> +def p2wsh_script(h256): + return Script([0x00, h256]) + + + class Script: @@ -18,81 +29,130 @@ def __init__(self, cmds=None): else: self.cmds = cmds + def __repr__(self): + result = [] + for cmd in self.cmds: + if type(cmd) == int: + if OPCODENAMES.get(cmd): + name = OPCODENAMES.get(cmd) + else: + name = 'OP[{}]'.format(cmd) + result.append(name) + else: + result.append(cmd.hex()) + return ' '.join(result) + + def __add__(self, other): + return Script(self.cmds + other.cmds) + + @classmethod def parse(cls, s): + # get the length of the entire field length = read_varint(s) + # initialize the cmds array cmds = [] + # initialize the number of bytes we've read to 0 count = 0 + # loopuntil we've read length bytes while count < length: + # get the current byte current = s.read(1) + # increment the bytes we've read count += 1 - currbyte = current[0] - if currbyte >= 1 and currbyte <= 75: - n = currbyte + # convert the current byte to an integer + current_byte = current[0] + # if the current byte is between 1 and 75 inclusive + if current_byte >= 1 and current_byte <= 75: + # we have an cmd set n to be the current byte + n = current_byte + # add the next n bytes as an cmd cmds.append(s.read(n)) count += n - elif currbyte == 76: - l = little_endian_to_int(s.read(1)) - cmds.append(s.read(l)) - count += l + 1 - elif currbyte == 77: - l = little_endian_to_int(s.read(2)) - cmds.append(s.read(l)) - count += l + 2 + elif current_byte == 76: + # oppushdata1 + data_length = little_endian_to_int(s.read(1)) + cmds.append(s.read(data_length)) + count += data_length + 1 + elif current_byte == 77: + # oppushdata2 + data_length = little_endian_to_int(s.read(2)) + cmds.append(s.read(data_length)) + count += data_length + 2 else: - op_code = currbyte - cmds.append(op_code) + # we have an opode. set the current byte to opcode + opcode = current_byte + # add the opcode to the list of cmds + cmds.append(opcode) if count != length: raise SyntaxError('parsing script failed') return cls(cmds) - - def serialize(self): - r = b'' + def raw_serialize(self): + result = b'' for cmd in self.cmds: if type(cmd) == int: - r += int_to_little_endian(cmd, 1) + result += int_to_little_endian(cmd, 1) else: length = len(cmd) if length < 75: - r += int_to_little_endian(length, 1) + result += int_to_little_endian(length, 1) elif length > 75 and length < 0x100: - r += int_to_little_endian(76, 1) - r += int_to_little_endian(length, 1) + result += int_to_little_endian(76, 1) + result += int_to_little_endian(length, 1) elif length >= 0x100 and length <= 520: - r += int_to_little_endian(77, 1) - r += int_to_little_endian(length, 2) + result += int_to_little_endian(77, 1) + result += int_to_little_endian(length, 2) else: - raise ValueError('cmd is not correct file script.py serialization of script ') - r += cmd - r = encode_varint(len(r)) + r - return r + raise ValueError('too long an cmd') + result += cmd + return result + + def serialize(self): + # get the raw serialization (no prepended length) + result = self.raw_serialize() + # get the length of the whole thing + total = len(result) + # encode_varint the total length of the result and prepend + return encode_varint(total) + result + def evaluate(self, z, witness): + # create a cop as we may need to add to this list if we have a + # RedeemScript cmds = self.cmds[:] stack = [] altstack = [] while len(cmds) > 0: cmd = cmds.pop(0) if type(cmd) == int: - operation = OPCODEFUNCTIONS[cmd] + # do what the opode says + opration = OPCODEFUNCTIONS[cmd] if cmd in (99, 100): - if not operation(stack, cmds): + # opif/opnotif require the cmds array + if not opration(stack, cmds): return False elif cmd in (107, 108): - if not operation(stack, altstack): + # optoaltstack/opfromaltstack require the altstack + if not opration(stack, altstack): return False elif cmd in (172, 173, 174, 175): - - if not operation(stack, z): + # these are signing oprations, they need a sig_hash + # to check against + if not opration(stack, z): return False else: - if not operation(stack): + if not opration(stack): return False else: + # add the cmd to the stack stack.append(cmd) + # p2sh rule. if the next three cmds are: + # OPHASH160 <20 byte hash> OPEQUAL this is the RedeemScript + # OPHASH160 == 0xa9 and OPEQUAL == 0x87 if len(cmds) == 3 and cmds[0] == 0xa9 \ and type(cmds[1]) == bytes and len(cmds[1]) == 20 \ and cmds[2] == 0x87: redeem_script = encode_varint(len(cmd)) + cmd + # we execute the next three opodes cmds.pop() h160 = cmds.pop() cmds.pop() @@ -101,36 +161,47 @@ def evaluate(self, z, witness): stack.append(h160) if not opequal(stack): return False + # final result should be a 1 if not opverify(stack): return False + # hashes match! now add the RedeemScript redeem_script = encode_varint(len(cmd)) + cmd stream = BytesIO(redeem_script) cmds.extend(Script.parse(stream).cmds) - if len(stack) == 2 and stack[0] == b'' and len(stack[1]) == 20: + # witness program version 0 rule. if stack cmds are: + # 0 <20 byte hash> this is p2wpkh + # tag::source3[] + if len(stack) == 2 and stack[0] == b'' and len(stack[1]) == 20: # <1> h160 = stack.pop() stack.pop() cmds.extend(witness) cmds.extend(p2pkh_script(h160).cmds) + # end::source3[] + # witness program version 0 rule. if stack cmds are: + # 0 <32 byte hash> this is p2wsh + # tag::source6[] if len(stack) == 2 and stack[0] == b'' and len(stack[1]) == 32: - s256 = stack.pop() - stack.pop() - cmds.extend(witness[:-1]) - witness_script = witness[-1] - if s256 != sha256(witness_script): + s256 = stack.pop() + stack.pop() + cmds.extend(witness[:-1]) # <3> + witness_script = witness[-1] # <4> + if s256 != sha256(witness_script): # <5> print('bad sha256 {} vs {}'.format (s256.hex(), sha256(witness_script).hex())) return False stream = BytesIO(encode_varint(len(witness_script)) + witness_script) - witness_script_cmds = Script.parse(stream).cmds + witness_script_cmds = Script.parse(stream).cmds # <6> cmds.extend(witness_script_cmds) + # end::source6[] if len(stack) == 0: return False if stack.pop() == b'': return False return True - # checking the what type of the script it is - def is_p2pkh_script_pubkey(self): + + def is_p2pkh_script_pubkey(self): + return len(self.cmds) == 5 and self.cmds[0] == 0x76 \ and self.cmds[1] == 0xa9 \ and type(self.cmds[2]) == bytes and len(self.cmds[2]) == 20 \ @@ -141,7 +212,7 @@ def is_p2sh_script_pubkey(self): and type(self.cmds[1]) == bytes and len(self.cmds[1]) == 20 \ and self.cmds[2] == 0x87 - def is_p2wpkh_script_pubkey(self): + def is_p2wpkh_script_pubkey(self): return len(self.cmds) == 2 and self.cmds[0] == 0x00 \ and type(self.cmds[1]) == bytes and len(self.cmds[1]) == 20 @@ -149,7 +220,6 @@ def is_p2wsh_script_pubkey(self): return len(self.cmds) == 2 and self.cmds[0] == 0x00 \ and type(self.cmds[1]) == bytes and len(self.cmds[1]) == 32 - def address(self, testnet=False): if self.is_p2pkh_script_pubkey(): h160 = self.cmds[2] @@ -157,4 +227,5 @@ def address(self, testnet=False): elif self.is_p2sh_script_pubkey(): h160 = self.cmds[1] return h160_to_p2sh_address(h160, testnet) - + raise ValueError('Unknown ScriptPubKey') + \ No newline at end of file diff --git a/usefulfunctions.py b/usefulfunctions.py index b61c928..032bb09 100644 --- a/usefulfunctions.py +++ b/usefulfunctions.py @@ -1,5 +1,4 @@ import hashlib - SIGHASH_ALL = 1 SIGHASH_NONE = 2 SIGHASH_SINGLE = 3 @@ -7,6 +6,18 @@ def little_endian_to_int(b): return int.from_bytes(b, 'little') +def decode_base58(s): + num = 0 + for c in s: + num *= 58 + num += BASE58_ALPHABET.index(c) + combined = num.to_bytes(25, byteorder='big') + checksum = combined[-4:] + if hash256(combined[:-4])[:4] != checksum: + raise ValueError('bad address: {} {}'.format(checksum, hash256(combined[:-4])[:4])) + return combined[1:-4] + + def read_varint(s): i = s.read(1)[0] if i == 0xfd: @@ -126,3 +137,28 @@ def h160_to_p2pkh_address(h160): def h160_to_p2sh_address(h160): prefix = b'\x05' return encode_base58_checksum(prefix + h160) + + +def merkle_parent(hash1, hash2): + + return hash256(hash1 + hash2) + + +def merkle_parent_level(hashes): + + if len(hashes) == 1: + raise RuntimeError('Cannot take a parent level with only 1 item') + if len(hashes) % 2 == 1: + hashes.append(hashes[-1]) + parent_level = [] + for i in range(0, len(hashes), 2): + parent = merkle_parent(hashes[i], hashes[i + 1]) + parent_level.append(parent) + return parent_level + + +def merkle_root(hashes): + current_level = hashes + while len(current_level) > 1: + current_level = merkle_parent_level(current_level) + return current_level[0]