tx_obj = Tx(1, tx_ins, [change_output, target_output], 0, True) #signing the transaction for i in range(len(tx_ins)): z = tx_obj.sig_hash(i) der = private_key.sign(z).der() sig = der + SIGHASH_ALL.to_bytes(1, 'big') sec = public_key.sec() script_sig = Script([sig, sec]) tx_obj.tx_ins[i].script_sig = script_sig if(tx_obj.verify()): print("-------Transaction Successfully Signed-------") print("===>publishing the following transaction:") tx_serial = tx_obj.serialize().hex() print(tx_serial) #p.decoderawtransaction(tx_serial) p.sendrawtransaction(tx_serial) print("===>transaction successfully published<====") else: print("Incorrect Signature for this Transaction")
sat_in_bit = 100000000 fee = 0.0001 * sat_in_bit input_amount = tx_input.value(testnet=True) #creating the target output target_amount = int(0.005 * sat_in_bit) target_h160 = decode_base58(sender_address) target_script = p2pkh_script(target_h160) target_output = TxOut(amount=target_amount, script_pubkey=target_script) #creating the change output change_amount = int(input_amount - target_amount - fee) change_160 = decode_base58(receiver_address) change_script = p2pkh_script(change_160) change_output = TxOut(amount=change_amount, script_pubkey=change_script) #create the Tx object tx_obj = Tx(1, [tx_input], [change_output, target_output], 0, True) #signing the transaction z = tx_obj.sig_hash(0) #get sig_hash of the first input der = private_key.sign(z).der() sig = der + SIGHASH_ALL.to_bytes(1, 'big') sec = public_key.sec() script_sig = Script([sig, sec]) tx_obj.tx_ins[0].script_sig = script_sig print(tx_obj.serialize().hex()) print(sender_address) print(receiver_address)
def test_exercise_6(self): last_block_hex = '00000000000538d5c2246336644f9a4956551afb44ba47278759ec55ea912e19' secret = little_endian_to_int( hash256(b'Jimmy Song Programming Blockchain')) private_key = PrivateKey(secret=secret) addr = private_key.point.address(testnet=True) h160 = decode_base58(addr) target_address = 'mwJn1YPMq7y5F8J3LkC5Hxg9PHyZ5K4cFv' self.assertEqual(addr, target_address) target_h160 = decode_base58(target_address) target_script = p2pkh_script(target_h160) fee = 5000 node = SimpleNode('tbtc.programmingblockchain.com', testnet=True) bf = BloomFilter(30, 5, 90210) bf.add(h160) node.handshake() node.send(b'filterload', bf.filterload()) start_block = bytes.fromhex(last_block_hex) getheaders_message = GetHeadersMessage(start_block=start_block) node.send(getheaders_message.command, getheaders_message.serialize()) headers_envelope = node.wait_for_commands({HeadersMessage.command}) stream = headers_envelope.stream() headers = HeadersMessage.parse(stream) last_block = None get_data_message = GetDataMessage() for b in headers.blocks: if not b.check_pow(): raise RuntimeError('proof of work is invalid') if last_block is not None and b.prev_block != last_block: raise RuntimeError('chain broken') get_data_message.add_data(FILTERED_BLOCK_DATA_TYPE, b.hash()) last_block = b.hash() node.send(get_data_message.command, get_data_message.serialize()) prev_tx, prev_index, prev_tx_obj = None, None, None while prev_tx is None: envelope = node.wait_for_commands({b'merkleblock', b'tx'}) stream = envelope.stream() if envelope.command == b'merkleblock': mb = MerkleBlock.parse(stream) if not mb.is_valid(): raise RuntimeError('invalid merkle proof') else: prev_tx_obj = Tx.parse(stream, testnet=True) for i, tx_out in enumerate(prev_tx_obj.tx_outs): if tx_out.script_pubkey.address(testnet=True) == addr: prev_tx = prev_tx_obj.hash() prev_index = i self.assertEqual( prev_tx_obj.id(), 'e3930e1e566ca9b75d53b0eb9acb7607f547e1182d1d22bd4b661cfe18dcddf1' ) self.assertEqual(i, 0) tx_in = TxIn(prev_tx, prev_index, Script([]), 0xffffff) TxFetcher.cache[prev_tx] = prev_tx_obj tx_ins = [tx_in] total = prev_tx_obj.tx_outs[prev_index].amount tx_outs = [TxOut(total - fee, target_script)] tx_obj = Tx(1, tx_ins, tx_outs, 0, testnet=True) tx_obj.sign_input(0, private_key) self.assertEqual( tx_obj.serialize().hex(), '0100000001f1dddc18fe1c664bbd221d2d18e147f50776cb9aebb0535db7a96c561e0e93e3000000006a473044022046a49962540a89e83da0636455b6c81c11c2844b7f3cd414c02e1a13741f4d15022006eed4eeda994d2bfebb9f1a494bfa3c8bab96e7e4c82623f4a29736dfe309e70121021cdd761c7eb1c90c0af0a5963e94bf0203176b4662778d32bd6d7ab5d8628b32ffffff0001a1629ef5000000001976a914ad346f8eb57dee9a37981716e498120ae80e44f788ac00000000' )
# output_index = 1 # prev_tx_fetched = TxFetcher.fetch(tx_id=prev_tx, testnet=True) # amount = prev_tx_fetched.tx_outs[output_index].amount # Utxo(prev_tx=prev_tx, output_index=output_index, private_key = secret.to_bytes(32, 'big').hex(), amount=amount).input_utxo() # # # utxo_list = [7, 8] #retrieve utxos with ids listed in the given list f = TxFactory.retrieve_utxos(utxo_list) #get the utxos from the database tx_ins = f.create_tx_ins_array() #print(tx_ins) f.create_output_array() # print(f.output_array[0]) # print(f.output_array[1]) tx_outs = f.create_tx_outs_array() tx = Tx(1, tx_ins, tx_outs, 0, testnet=True ) #this will create the tx object--input script_sigs will be '0x00' tx.sign_all_inputs(f.utxo_array) print("Transaction:") print(tx.version) print(tx.tx_ins) print(tx_outs) print(tx.locktime) tx_serialized = tx.serialize() tx_serialized_hex = tx_serialized.hex() print(tx_serialized_hex)
tx_obj = Tx(version=1, tx_ins=tx_ins, tx_outs=tx_outs, locktime=0, testnet=True) # Step 3 hash_type = SIGHASH_ALL z = tx_obj.sig_hash(0, hash_type) pk = PrivateKey(secret=privatekey) # sign with SIGHASH_ALL sighash = SIGHASH_ALL # get the sighash z = tx_obj.sig_hash(0, sighash) # sign with priv to get der der = pk.sign(z).der() # add the sighash as a single byte bytes([sighash]) sig = der + bytes([sighash]) # get the sec from priv sec = pk.point.sec() # create a new script that has sig and sec as the new input sig tx_obj.tx_ins[0].script_sig = Script([sig, sec]) print(hexlify(tx_obj.serialize())) '''der = pk.sign(z).der() sig = der + bytes([hash_type]) sec = pk.point.sec() script_sig = bytes([len(sig)]) + sig + bytes([len(sec)]) + sec script_sig = bytes([len(script_sig)]) + script_sig tx_obj.tx_ins[0].script_sig = Script.parse(script_sig) print(hexlify(tx_obj.serialize())) '''
def save_genesis_block(): script_sig = Script( [bytes.fromhex("ffff001d"), bytes.fromhex("04"), GENESIS_THE_TIMES]) script_pubkey = Script([GENESIS_SEC_PUBKEY, 0xac]) tx_in = TxIn(prev_tx=b"\x00" * 32, prev_index=0xffffffff, script_sig=script_sig, sequence=0xffffffff) tx_out = TxOut(amount=GENESIS_BLOCK_REWARD, script_pubkey=script_pubkey) tx = Tx(version=1, tx_ins=[tx_in], tx_outs=[tx_out], locktime=0) block = Block_Full(version=1, prev_block=b"\x00" * 32, merkle_root=GENESIS_BLOCK_MERKLE_ROOT, timestamp=GENESIS_BLOCK_TIMESTAMP, bits=GENESIS_BLOCK_BITS, nonce=GENESIS_BLOCK_NONCE, txs=[tx]) tx = block.txs[0] script_sig_cmds = tx.tx_ins[0].script_sig.cmds script_pubkey_cmds = tx.tx_outs[0].script_pubkey.cmds GENESIS_SCRIPT_SIG_DB = Script_db(cmds=script_sig_cmds) GENESIS_SCRIPT_PUBKEY_DB = Script_db(cmds=script_pubkey_cmds) tx_in = tx.tx_ins[0] GENESIS_TX_IN_DB = TxIn_db(prev_tx=tx_in.prev_tx, prev_index=tx_in.prev_index, script_sig=GENESIS_SCRIPT_SIG_DB, sequence=tx_in.sequence) tx_out = tx.tx_outs[0] GENESIS_TX_OUT_DB = TxOut_db(amount=tx_out.amount, script_pubkey=GENESIS_SCRIPT_PUBKEY_DB) tx_size = len(tx.serialize()) GENESIS_TX_DB = Tx_db(segwit=False, tx_hash=tx.hash(), version=tx.version, tx_ins=[GENESIS_TX_IN_DB], tx_outs=[GENESIS_TX_OUT_DB], locktime=tx.locktime, size=tx_size) block_size = block.size() try: GENESIS_BLOCK_DB = Block_db(block_hash=GENESIS_BLOCK_HASH, block_height=0, block_reward=GENESIS_BLOCK_REWARD, version=1, prev_block=b"\x00" * 32, merkle_root=GENESIS_BLOCK_MERKLE_ROOT, timestamp=GENESIS_BLOCK_TIMESTAMP, bits=GENESIS_BLOCK_BITS, nonce=GENESIS_BLOCK_NONCE, txs=[GENESIS_TX_DB], size=block_size, mined_btc=GENESIS_BLOCK_REWARD, total_size=block_size).save() except: pass
def test_broadcast(self): from bloomfilter import BloomFilter last_block_hex = '00000000000000a03f9432ac63813c6710bfe41712ac5ef6faab093fe2917636' secret = little_endian_to_int(hash256(b'Jimmy Song')) private_key = PrivateKey(secret=secret) h160 = private_key.point.hash160() addr = private_key.point.address(testnet=True) target_address = 'mwJn1YPMq7y5F8J3LkC5Hxg9PHyZ5K4cFv' target_h160 = decode_base58(target_address) target_script = p2pkh_script(target_h160) fee = 5000 # fee in satoshis # connect to programmingblockchain.com in testnet mode node = SimpleNode('programmingblockchain.com', testnet=True) # create a bloom filter of size 30 and 5 functions. Add a tweak. bf = BloomFilter(30, 5, 90210) # add the h160 to the bloom filter bf.add(h160) # load the bloom filter with the filterload command node.send(bf.filterload()) # set start block to last_block from above start_block = bytes.fromhex(last_block_hex) # send a getheaders message with the starting block getheaders = GetHeadersMessage(start_block=start_block) node.send(getheaders) # wait for the headers message headers = node.wait_for(HeadersMessage) block_hashes = [b.hash() for b in headers.blocks] # initialize prev_tx, prev_index and prev_amount to None prev_tx, prev_index, prev_amount = None, None, None for h, tx_obj in node.get_filtered_block_txs(block_hashes): self.assertEqual(h, tx_obj.hash()) tx_obj.testnet = True # loop through the tx outs for i, tx_out in enumerate(tx_obj.tx_outs): # if our output has the same address as our address we found it if tx_out.script_pubkey.address(testnet=True) == addr: # we found our utxo. set prev_tx, prev_index, and tx prev_tx = h prev_index = i prev_amount = tx_out.amount self.assertEqual( h.hex(), 'b2cddd41d18d00910f88c31aa58c6816a190b8fc30fe7c665e1cd2ec60efdf3f' ) self.assertEqual(i, 7) break if prev_tx: break # create the TxIn tx_in = TxIn(prev_tx, prev_index) # calculate the output amount (previous amount minus the fee) output_amount = prev_amount - fee # create a new TxOut to the target script with the output amount tx_out = TxOut(output_amount, target_script) # create a new transaction with the one input and one output tx_obj = Tx(1, [tx_in], [tx_out], 0, testnet=True) # sign the only input of the transaction self.assertTrue(tx_obj.sign_input_p2pkh(0, private_key)) # serialize and hex to see what it looks like want = '01000000013fdfef60ecd21c5e667cfe30fcb890a116688ca51ac3880f91008dd141ddcdb2070000006b483045022100ff77d2559261df5490ed00d231099c4b8ea867e6ccfe8e3e6d077313ed4f1428022033a1db8d69eb0dc376f89684d1ed1be75719888090388a16f1e8eedeb8067768012103dc585d46cfca73f3a75ba1ef0c5756a21c1924587480700c6eb64e3f75d22083ffffffff019334e500000000001976a914ad346f8eb57dee9a37981716e498120ae80e44f788ac00000000' self.assertEqual(tx_obj.serialize().hex(), want) # send this signed transaction on the network node.send_tx(tx_obj)