def sign_input(self, input_index, private_key): z = self.sig_hash(input_index) der = private_key.sign(z).der() sig = der + SIGHASH_ALL.to_bytes(1, 'big') sec = private_key.point.sec() self.tx_ins[input_index].script_sig = Script([sig, sec]) return self.verify_input(input_index)
def test_example_1(self): tx_ins = [] prev_tx = bytes.fromhex( '8be2f69037de71e3bc856a6627ed3e222a7a2d0ce81daeeb54a3aea8db274149') prev_index = 4 tx_ins.append(TxIn(prev_tx, prev_index)) tx_outs = [] h160 = decode_base58('mzx5YhAH9kNHtcN481u6WkjeHjYtVeKVh2') tx_outs.append( TxOut( amount=int(0.38 * 100000000), script_pubkey=p2pkh_script(h160), )) h160 = decode_base58('mnrVtF8DWjMu839VW3rBfgYaAfKk8983Xf') tx_outs.append( TxOut( amount=int(0.1 * 100000000), script_pubkey=p2pkh_script(h160), )) tx_obj = Tx(1, tx_ins, tx_outs, 0, testnet=True) z = tx_obj.sig_hash(0) pk = PrivateKey(secret=8675309) der = pk.sign(z).der() sig = der + SIGHASH_ALL.to_bytes(1, 'big') sec = pk.point.sec() tx_obj.tx_ins[0].script_sig = Script([sig, sec]) want = '0100000001494127dba8aea354ebae1de80c2d7a2a223eed27666a85bce371de3790f6e28b040000006b483045022100fa3032607b50e8cb05bedc9d43f986f19dedc22e61320b9765061c5cd9c66946022072d514ef637988515bfa59a660596206de68f0ed4090d0a398e70f4d81370dfb012103935581e52c354cd2f484fe8ed83af7a3097005b2f9c60bff71d35bd795f54b67ffffffff0280d54302000000001976a914d52ad7ca9b3d096a38e752c2018e6fbc40cdf26f88ac80969800000000001976a914507b27411ccf7f16f10297de6cef3f291623eddf88ac00000000' self.assertEqual(tx_obj.serialize().hex(), want)
def test_example_6(self): tx_ins = [] prev_tx = bytes.fromhex( '0d6fe5213c0b3291f208cba8bfb59b7476dffacc4e5cb66f6eb20a080843a299') prev_index = 13 tx_ins.append(TxIn(prev_tx, prev_index, Script([]), 0xffffffff)) tx_outs = [] change_amount = int(0.33 * 100000000) change_h160 = decode_base58('mzx5YhAH9kNHtcN481u6WkjeHjYtVeKVh2') change_script = p2pkh_script(change_h160) tx_outs.append(TxOut(amount=change_amount, script_pubkey=change_script)) target_amount = int(0.1 * 100000000) target_h160 = decode_base58('mnrVtF8DWjMu839VW3rBfgYaAfKk8983Xf') target_script = p2pkh_script(target_h160) tx_outs.append(TxOut(amount=target_amount, script_pubkey=target_script)) transaction = Tx(1, tx_ins, tx_outs, 0, testnet=True) z = transaction.sig_hash(0) private_key = PrivateKey(secret=8675309) der = private_key.sign(z).der() sig = der + SIGHASH_ALL.to_bytes(1, 'big') sec = private_key.point.sec() transaction.tx_ins[0].script_sig = Script([sig, sec]) want = '010000000199a24308080ab26e6fb65c4eccfadf76749bb5bfa8cb08f291320b3c21e56f0d0d0000006b4830450221008ed46aa2cf12d6d81065bfabe903670165b538f65ee9a3385e6327d80c66d3b502203124f804410527497329ec4715e18558082d489b218677bd029e7fa306a72236012103935581e52c354cd2f484fe8ed83af7a3097005b2f9c60bff71d35bd795f54b67ffffffff02408af701000000001976a914d52ad7ca9b3d096a38e752c2018e6fbc40cdf26f88ac80969800000000001976a914507b27411ccf7f16f10297de6cef3f291623eddf88ac00000000' self.assertEqual(transaction.serialize().hex(), want)
def sign_input_multisig_1by1(self, input_index, private_key,privkey_index, redeem_script,n): '''Signs the input using the private key n: n signatures that can sign transaction. private_key: must be a PrivateKey object. privkey_index: is the index of the private key according to the order of the public keys. ''' # get the signature hash (z) z = self.sig_hash(input_index, redeem_script) # get der signature of z from private key cmds = self.tx_ins[input_index].script_sig.cmds if len(cmds) == 0: #We create an array full of 0s with a lentgth of n+1. n is the number of possible private keys that can #sign the transaction. This way we can place the signatures in the right order. We get rid of the unnecesarry #0s later. print(f"cmds is empty. Creating new set of commands") cmds = [0]*(n) #we also need to append at the end the serialized redeem script: cmds.append(redeem_script.serialize()[1:]) der = private_key.sign(z).der() # append the SIGHASH_ALL to der (use SIGHASH_ALL.to_bytes(1, 'big')) sig = der + SIGHASH_ALL.to_bytes(1, 'big') #we add 1 to the index because of the OP_0 bug. cmds[privkey_index] = sig #commands.append(*redeem_script.cmds) print(f"sign_input_multisig commands: {cmds}") script_sig = Script(cmds) #script_sig = cmds # change input's script_sig to new script self.tx_ins[input_index].script_sig = script_sig # return whether sig is valid using self.verify_input #return self.verify_input(input_index) return True
def sign_input(self, input_index, private_key): # get the signature hash (z) ## ## Might need to provide logic to get sig_hash depending on whether it is segwit or not. ## The following right now is for not segwit ## ## If spending a segwit utxo then --will need to look at the form of the utxo script pubkey ## z = self.sig_hash_bip143 ## else z = self.sig_hash(input_index) # get der signature of z from private key der = private_key.sign(z).der() # append the SIGHASH_ALL to der (use SIGHASH_ALL.to_bytes(1, 'big')) sig = der + SIGHASH_ALL.to_bytes(1, 'big') # calculate the sec sec = private_key.point.sec() # initialize a new script with [sig, sec] as the cmds script = Script([sig, sec]) print("Script_Sig from within sign_input: ", script) # change input's script_sig to new script self.tx_ins[input_index].script_sig = script # return whether sig is valid using self.verify_input # verify_input will return True if the signautre is valid verify = self.verify_input(input_index) print(verify) return verify
def sign_input(self, input_index, private_key): # get the signature hash (z) z = self.sig_hash(input_index) # get der signature of z from private key der = private_key.sign(z).der() # append the SIGHASH_ALL to der (use SIGHASH_ALL.to_bytes(1, 'big')) sig = der + SIGHASH_ALL.to_bytes(1, 'big') # calculate the sec sec = private_key.point.sec() # initialize a new script with [sig, sec] as the cmds # change input's script_sig to new script self.tx_ins[input_index].script_sig = Script([sig, sec]) # return whether sig is valid using self.verify_input return self.verify_input(input_index)
def check_htlc(node, commitment_tx, secret): tx_in = TxIn(bytes.fromhex(commitment_tx.id()), 2) tx_out = TxOut(amount=commitment_tx.tx_outs[2].amount, script_pubkey=commitment_tx.tx_outs[0].script_pubkey) spendingTx = Tx(1, [tx_in], [tx_out], 0, True) z = spendingTx.sig_hash(0) signature = node.private_key.sign(z).der() + SIGHASH_ALL.to_bytes(1, 'big') combined = Script( [signature, node.public_key.sec(), str.encode(secret), b'1']) + commitment_tx.tx_outs[2].script_pubkey return combined.evaluate(z, None)
def sign_input(self, input_index, private_key): # get the signature hash (z) # get der signature of z from private key # append the SIGHASH_ALL to der (use SIGHASH_ALL.to_bytes(1, 'big')) # calculate the sec # initialize a new script with [sig, sec] as the cmds # change input's script_sig to new script # return whether sig is valid using self.verify_input #raise NotImplementedError z = self.sig_hash(input_index) der = private_key.sign(z).der() + SIGHASH_ALL.to_bytes(1, 'big') sec = private_key.point.sec() cmds = Script([der, sec]) self.tx_ins[input_index].script_sig = cmds return self.verify_input(input_index)
def sign_input(self, input_index, private_key): # added for signing p2sh script tx_in = self.tx_ins[input_index] script_lock = tx_in.get_script_lock(testnet=self.testnet) if script_lock.is_p2sh_script_pubkey(): cmd = tx_in.script_sig.cmds[ -1] # last element in script_sig of p2sh is redeem script redeem_for_parsing = encode_varint(len(cmd)) + cmd # for parsing redeem_script = script.parse(BytesIO(redeem_for_parsing)) else: redeem_script = None z = self.sig_hash(input_index, redeem_script) der = private_key.sign(z).der() sig = der + SIGHASH_ALL.to_bytes(1, 'big') sec = private_key.pubPoint.sec() script_sig = Script([sig, sec]) self.tx_ins[input_index].script_sig = script_sig return self.verify_input(input_index)
def sign_input(self, input_index, private_key, script_pubkey): # FIXME: DELETE '''Signs the input using the private key''' # get the signature hash (z) z = self.sig_hash(input_index, script_pubkey) # get der signature of z from private key der = private_key.sign(z).der() # der = Signature(*sk.sign_number(z)).der() # append the SIGHASH_ALL to der (use SIGHASH_ALL.to_bytes(1, 'big')) sig = der + SIGHASH_ALL.to_bytes(1, 'big') # calculate the sec # sec = sk.verifying_key.to_sec() sec = private_key.public_key.sec() # initialize a new script with [sig, sec] as the cmds script_sig = Script([sig, sec]) # script_sig = Script([sig]) # change input's script_sig to new script self.tx_ins[input_index].script_sig = script_sig # return whether sig is valid using self.verify_input return self.verify_input(input_index, script_pubkey)
def sign_input(self, input_index, private_key,segwit=False, p2sh = False): '''Signs the input using the private key''' # get the signature hash (z) if segwit: z = self.sig_hash_bip143(input_index, Script([0, private_key.point.hash160()]) ) else: z = self.sig_hash(input_index) # get der signature of z from private key der = private_key.sign(z).der() # append the SIGHASH_ALL to der (use SIGHASH_ALL.to_bytes(1, 'big')) sig = der + SIGHASH_ALL.to_bytes(1, 'big') # calculate the sec sec = private_key.point.sec() # initialize a new script with [sig, sec] as the cmds script_sig = Script([sig, sec]) # change input's script_sig to new script print("\nABOUT TO SIGN INPUT\n") if segwit: #The witness is a serialization of all witness data of the transaction. Each txin is associated with a witness field. #A witness field starts with a var_int to indicate the number of stack items for the txin. It is followed by stack #items, with each item starts with a var_int to indicate the length # witness: <signature> <pubkey> #wit = b'\x16' + encode_varint(len(sig)) + sig + b'\x14' + p2wpkh_script(private_key.point.hash160()).raw_serialize() #but the serialization is taking care of that #wit = [sig,p2wpkh_script(private_key.point.hash160()).raw_serialize()] wit = [sig,sec] self.tx_ins[input_index].witness = wit print(f"SIGNING INPUT Segwit: \nWitness:\n{wit} ") #AND IF IT IS A NESTED P2SH-P2WPKH: if p2sh: self.tx_ins[input_index].script_sig = Script([ Script([0, private_key.point.hash160()]).raw_serialize() ]) print(f"SIGNING INPUT: \nSCRIPT SIG:\n{self.tx_ins[input_index].script_sig} \nWIT: \n{wit}") #else: self.tx_ins[input_index].script_sig = None else: self.tx_ins[input_index].script_sig = Script() else: self.tx_ins[input_index].script_sig = script_sig self.tx_ins[input_index].witness = None print(f"SIGNING INPUT not segwit: \nSCRIPT SIG:\n{self.tx_ins[input_index].script_sig} ") # return whether sig is valid using self.verify_input return self.verify_input(input_index)
def sign_input_multisig(self, input_index, private_key_list, redeem_script): '''Signs the input using the private key''' # get the signature hash (z) z = self.sig_hash(input_index, redeem_script) # get der signature of z from private key ders = [private_key.sign(z).der() for private_key in private_key_list] # append the SIGHASH_ALL to der (use SIGHASH_ALL.to_bytes(1, 'big')) sigs = [der + SIGHASH_ALL.to_bytes(1, 'big') for der in ders ] # calculate the sec #secs = [private_key.point.sec() for private_key in private_key_list] # initialize a new script with [sig, sec] as the cmds commands = [0] for sig in sigs: commands.append(sig) commands.append(redeem_script.serialize()[1:]) #commands.append(*redeem_script.cmds) print(f"sign_input_multisig commands: {commands}") script_sig = Script(commands) #print(script_sig) # change input's script_sig to new script self.tx_ins[input_index].script_sig = script_sig # return whether sig is valid using self.verify_input return self.verify_input(input_index)
# output address that will receive the sat we have not spend change_h160 = decode_base58('mvEg6eZ3sUApodedYQrkpEPMMALsr1K1k1') change_script = p2pkh_script(change_h160) change_output = TxOut(amount=change_amount, script_pubkey=change_script) # output address that will receive our sat target_amount = int(0.00006 * 100000000) target_h160 = decode_base58('mwJn1YPMq7y5F8J3LkC5Hxg9PHyZ5K4cFv') target_script = p2pkh_script(target_h160) target_output = TxOut(amount=target_amount, script_pubkey=target_script) tx_obj = Tx(1, [tx_in], [change_output, target_output], 0, True) #print(tx_obj).hex() # now we sign the transaction z = tx_obj.sig_hash(0) private_key = PrivateKey(little_endian_to_int( hash256(b'dat_test_private_key'))) der = private_key.sign(z).der() sig = der + SIGHASH_ALL.to_bytes(1, 'big') sec = private_key.point.sec() script_sig = Script([sig, sec]) tx_obj.tx_ins[0].script_sig = script_sig print(tx_obj.serialize().hex()) # end
from helper import decode_base58, little_endian_to_int, hash256, SIGHASH_ALL from script import p2pkh_script, Script from tx import TxIn, TxOut, Tx from ecc import PrivateKey # our old private key private_key = PrivateKey(little_endian_to_int( hash256(b'dat_test_private_key'))) prev_tx1 = bytes.fromhex( '23f031f63c53f8fbaf58ff5c2df34f60099d0ddb775ecf98dbf5f27fd5c555de') prev_index1 = 0 tx_in1 = TxIn(prev_tx1, prev_index1) tx_outs = [] target_amount = int((0.00100000 * 100000000) - 192) target_h160 = decode_base58('mwJn1YPMq7y5F8J3LkC5Hxg9PHyZ5K4cFv') target_script = p2pkh_script(target_h160) target_output = TxOut(amount=target_amount, script_pubkey=target_script) tx_obj = Tx(1, [tx_in1], [target_output], 0, True) z1 = tx_obj.sig_hash(0) der1 = private_key.sign(z1).der() sig1 = der1 + SIGHASH_ALL.to_bytes(1, 'big') sec = private_key.point.sec() script_sig1 = Script([sig1, sec]) tx_obj.tx_ins[0].script_sig = script_sig1 print(tx_obj.serialize().hex())
def get_script_sig(transaction, private_key): z = transaction.sig_hash(0) signature = private_key.sign(z).der() + SIGHASH_ALL.to_bytes(1, 'big') script_sig = transaction.tx_ins[0].script_sig + Script([signature]) return script_sig