buzzkillb

signtx.py

Jul 18th, 2020
874
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import struct
  2. import base58
  3. import hashlib
  4. import ecdsa
  5. import codecs
  6. import binascii
  7.  
  8. #youtube vidceo https://www.youtube.com/watch?v=156XBrW22Bw
  9. #github example https://github.com/zeltsi/Mybitcoin/blob/master/tx%20as%20seen%20on%20youtube.py
  10.  
  11. Bob_addr = "1NWzVg38ggPoVGAG2VWt6ktdWMaV6S1pJK"
  12.  
  13. #bob_hashed_pubkey = base58.b58decode_check(Bob_addr)[1:].encode("hex")
  14.  
  15. Bob_private_key = "CF933A6C602069F1CBC85990DF087714D7E86DF0D0E48398B7D8953E1F03534A"
  16.  
  17. prv_txid = "84d813beb51c3a12cb5d0bb18c6c15062453d476de24cb2f943ca6e20115d85c"
  18.  
  19. #Charlie_adr = "17X4s8JdSdLxFyraNUDBzgmnSNeZpjm42g"
  20. #charlie_hashed_pubkey = base58.b58decode_check(Charlie_adr)[1:].encode("hex")
  21.  
  22. def doubleSha256(hex):
  23.    bin = binascii.unhexlify(hex)
  24.    hash = hashlib.sha256(bin).digest()
  25.    hash2 = hashlib.sha256(hash).digest()
  26.    print("Input Hex: "+str(hex,"ascii"))
  27.    print("SHA256:\n   "+str(binascii.hexlify(hash),"ascii"))
  28.    print("Double-SHA256:\n   "+str(binascii.hexlify(hash2),"ascii"))
  29.  
  30. class raw_tx:
  31.     version         = struct.pack("<L", 1)
  32.     tx_in_count     = struct.pack("<B", 1)
  33.     tx_in           = {} #TEMP
  34.     tx_out_count    = struct.pack("<B", 1)
  35.     tx_out1         = {} #TEMP
  36.     lock_time       = struct.pack("<L", 0)
  37.  
  38. #Input of the TX
  39. rtx = raw_tx()
  40. #txid hash 32 bytes long and flip bytes to big endian
  41. #rtx.tx_in["txouthash"]         = flip_byte_order(prv_txid).decode("hex")
  42. rtx.tx_in["txouthash"] = codecs.encode(codecs.decode(prv_txid, 'hex')[::-1], 'hex').decode()
  43. print(rtx.tx_in["txouthash"])
  44. #single output to address (vout) index 4 bytes, index 0 for example
  45. rtx.tx_in["tx_in_index"] = struct.pack("<L", 0)
  46. #get scriptpubkey of address OP76 OPa9 14 hashedpublickey OP88 OPac
  47. #hashed public key is 20bytes long represented by 14 in hex
  48. #from scripthash.py and put into HEX don't flip endian for this one
  49. #p2pkh script validation, this might not be right just yet, is this correct or needs to be in some other format?
  50. rtx.tx_in["script"]         = "dca35c23679120087ccf656014ecea1f1f89eb34ba0489288480edc024acbf1f"
  51. print(rtx.tx_in["script"])
  52. rtx.tx_in["scrip_bytes"]    = struct.pack("<B", len(rtx.tx_in["script"]))
  53. print(rtx.tx_in["scrip_bytes"])
  54. #4 bytes
  55. hex_string = "0xffffffff"[2:]
  56. bytes_object = bytes.fromhex(hex_string)
  57. print(bytes_object)
  58.  
  59. rtx.tx_in["sequence"] = bytes.fromhex('ffffffff').decode('utf-16-be')
  60. print(rtx.tx_in["sequence"])
  61.  
  62. ##########################################
  63. #Output of the TX
  64. # amount of coins to send, example 0.00100000, in denariis, BE CAREFUL ON THIS AMOUNT!!!
  65. #8 byte integer
  66. rtx.tx_out1["value"]        = struct.pack("<Q", 100000)
  67. rtx.tx_out1["pk_script"]    = "dca35c23679120087ccf656014ecea1f1f89eb34ba0489288480edc024acbf1f"
  68. rtx.tx_out1["pk_script_bytes"] = struct.pack("<B", len(rtx.tx_out1["pk_script"]))
  69. print(rtx.tx_out1["pk_script_bytes"])
  70.  
  71. raw_tx_string = (
  72.  
  73.     rtx.version
  74.     + rtx.tx_in_count
  75.     + rtx.tx_in["txouthash"]
  76.     + rtx.tx_in["tx_out_index"]
  77.     + rtx.tx_in["scrip_bytes"]
  78.     + rtx.tx_in["script"]
  79.     + rtx.tx_in["sequence"]
  80.     + rtx.tx_out_count
  81.     + rtx.tx_out1["value"]
  82.     + rtx.tx_out1["pk_script_bytes"]
  83.     + rtx.tx_out1["pk_script"]
  84.     + rtx.lock_time
  85.     + struct.pack("<L", 1)
  86.  
  87.     )
  88.  
  89. #hash the transaction 2x sha256 (not sure if this works or what the output should be in)
  90. hashed_tx_to_sign = doubleSha256(raw_tx_string)
  91.  
  92. #create signing key (sk is from youtube example that won't work)
  93. #sk = ecdsa.SigningKey.from_string(Bob_private_key.decode("hex"), curve = ecdsa.SECP256k1)
  94.  
  95. #example i have no clue anymore (https://stackoverflow.com/questions/56013591/python-ecdsa-same-public-keygenerated-with-ecdsa-verifyingkey-does-not-verify)
  96. sk = ecdsa.SigningKey.generate(curve=ecdsa.NIST256p, hashfunc = hashlib.sha256)
  97. pk = sk.get_verifying_key()
  98. publicKeyVerifyObject = ecdsa.VerifyingKey.from_string(bytes.fromhex(binascii.hexlify(pk.to_string()).decode('utf-8')), curve=ecdsa.NIST256p, hashfunc = hashlib.sha256)
  99.  
  100.  
  101. #continue from youtube example, copied and pasted
  102. public_key = ('\04' + pk.to_string()).encode("hex")
  103.  
  104.  
  105. #Sign Transaction
  106. signature = sk.sign_digest(hashed_tx_to_sign, sigencode = ecdsa.util.sigencode_der_canonize)
  107.  
  108. sigscript = (
  109.  
  110.     signature
  111.     + "\01"
  112.     + struct.pack("<B", len(public_key.decode("hex")))
  113.     + public_key.decode("hex")
  114.  
  115.     )
  116.  
  117. real_tx = (
  118.     rtx.version
  119.     + rtx.tx_in_count
  120.     + rtx.tx_in["txouthash"]
  121.     + rtx.tx_in["tx_out_index"]
  122.     + struct.pack("<B", len(sigscript) + 1)
  123.     + struct.pack("<B", len(signature) + 1)
  124.     + sigscript
  125.     + rtx.tx_in["sequence"]
  126.     + rtx.tx_out_count
  127.     + rtx.tx_out1["value"]
  128.     + rtx.tx_out1["pk_script_bytes"]
  129.     + rtx.tx_out1["pk_script"]
  130.     + rtx.tx_out2["value"]
  131.     + rtx.tx_out2["pk_script_bytes"]
  132.     + rtx.tx_out2["pk_script"]
  133.     + rtx.lock_time
  134.  
  135.     )
  136.  
  137. print real_tx.encode("hex")
  138.  
  139.  
  140.  
  141. ########################
  142. #test junk
  143. test = bytes.fromhex('4a4b4c').decode('utf-8')
  144. print(test)
RAW Paste Data