def test_siganyonecanpay_none_send(self): """ SIGHASH_NONE | SIGHASH_ANYONECANPAY:signs only the txin_index input """ tx = Transaction([self.txin1_siganyonecanpay_none], [self.txout1_siganyonecanpay_none], has_segwit=True) pk = self.sk.get_public_key().to_hex() sig_signone = self.sk.sign_segwit_input( tx, 0, self.p2pkh_redeem_script, self.txin1_siganyonecanpay_none_amount, SIGHASH_NONE | SIGHASH_ANYONECANPAY) tx.witnesses = [Script([sig_signone, pk])] tx.inputs.append(self.txin2_siganyonecanpay_none) tx.outputs.append(self.txout2_siganyonecanpay_none) sig = self.sk.sign_segwit_input(tx, 1, self.p2pkh_redeem_script, self.txin2_siganyonecanpay_none_amount, SIGHASH_ALL) tx.witnesses.append(Script([sig, pk])) self.assertEqual(tx.serialize(), self.test_siganyonecanpay_none_send_result)
def test_spend_p2wpkh(self): tx = Transaction([self.txin_spend], [self.txout2], has_segwit=True) sig = self.sk.sign_segwit_input(tx, 0, self.p2pkh_redeem_script, self.txin_spend_amount) pk = self.sk.get_public_key().to_hex() tx.witnesses = [Script([sig, pk])] self.assertEqual(tx.serialize(), self.spend_p2pkh_result)
def test_spend_p2wsh(self): tx = Transaction([self.txin_spend], [self.txout2], has_segwit=True) sig1 = self.sk1.sign_segwit_input(tx, 0, self.p2wsh_redeem_script, self.txin_spend_amount) sig2 = self.sk2.sign_segwit_input(tx, 0, self.p2wsh_redeem_script, self.txin_spend_amount) pk = self.p2wsh_redeem_script.to_hex() tx.witnesses = [ Script(['OP_0', sig1, sig2, pk]) ] #print(tx.serialize()) self.assertEqual(tx.serialize(), self.spend_p2pkh_result)
def test_sigsingle_send(self): """ SIGHASH_SINGLE:signs all inputs but only txin_index output """ tx = Transaction([self.txin1_sigsingle], [self.txout1_sigsingle], has_segwit=True) pk = self.sk.get_public_key().to_hex() sig_signone = self.sk.sign_segwit_input(tx, 0, self.p2pkh_redeem_script, self.txin1_sigsingle_amount, SIGHASH_SINGLE) tx.witnesses = [Script([sig_signone, pk])] tx.outputs.append(self.txout2_sigsingle) self.assertEqual(tx.serialize(), self.test_sigsingle_send_result)
def test_p2pkh_and_p2wpkh_to_p2pkh(self): tx = Transaction([self.txin_spend_p2pkh, self.txin_spend_p2wpkh], [self.txout3], has_segwit=True) # spend_p2pkh sig1 = self.sk.sign_input(tx, 0, self.p2pkh_addr.to_script_pub_key()) pk1 = self.sk.get_public_key().to_hex() self.txin_spend_p2pkh.script_sig = Script([sig1, pk1]) tx.witnesses = [Script([])] # spend_p2wpkh sig2 = self.sk.sign_segwit_input(tx, 1, self.p2pkh_redeem_script, self.txin_spend_p2wpkh_amount) pk2 = self.sk.get_public_key().to_hex() tx.witnesses.append(Script([sig2, pk2])) self.assertEqual(tx.serialize(), self.p2pkh_and_p2wpkh_to_p2pkh_result)
def test_signone_send(self): """ SIGHASH_NONE:signs all of the inputs """ # First, only txin1 and txout1 are added to the transaction. tx = Transaction([self.txin1_signone], [self.txout1_signone], has_segwit=True) pk = self.sk.get_public_key().to_hex() sig_signone = self.sk.sign_segwit_input(tx, 0, self.p2pkh_redeem_script, self.txin1_signone_amount, SIGHASH_NONE) tx.witnesses = [Script([sig_signone, pk])] # Adding additional output signatures will not be affected tx.outputs.append(self.txout2_signone) self.assertEqual(tx.serialize(), self.test_signone_send_result)
def test_multiple_input_multiple_ouput(self): tx = Transaction([self.txin1_multiple, self.txin2_multiple, self.txin3_multiple], [self.output1_multiple, self.output2_multiple, self.output3_multiple], has_segwit=True) sig1 = self.sk1.sign_input(tx, 0, self.p2pkh_addr.to_script_pub_key()) pk1 = self.sk1.get_public_key().to_hex() self.txin1_multiple.script_sig = Script([sig1, pk1]) tx.witnesses = [ Script([]) ] sig_p2sh1 = self.sk1.sign_segwit_input(tx, 1, self.p2wsh_redeem_script, self.txin2_multiple_amount) sig_p2sh2 = self.sk2.sign_segwit_input(tx, 1, self.p2wsh_redeem_script, self.txin2_multiple_amount) pk2 = self.p2wsh_redeem_script.to_hex() tx.witnesses.append(Script(['OP_0', sig_p2sh1, sig_p2sh2, pk2])) sig3 = self.sk1.sign_segwit_input(tx, 2, self.p2pkh_addr.to_script_pub_key(), self.txin3_multiple_amount) pk3 = self.sk1.get_public_key().to_hex() tx.witnesses.append(Script([sig3, pk3])) #print(tx.serialize()) self.assertEqual(tx.serialize(), self.multiple_input_multiple_ouput_result)
def tip_or_withdrawFunc(update, ctx): # Initialise bitcoin.py setup('mainnet') query = update.callback_query chID = query.message.chat.id msgID = query.message.message_id query.answer() data = str(query.data).split(",") sender = str(query.from_user.id) if sender == data[3]: if data[4] == "t": target = data[1] if data[0] == "Y": ctx.bot.delete_message(chat_id=chID, message_id=msgID) sender_wif = PrivateKey(db.getWIF(sender)) fee = convertToSatoshis(Decimal(config.coin['minFee'])) target_address = P2wpkhAddress(getAddress(target)) sender_address = P2wpkhAddress(getAddress(sender)) sender_balance = 0 amount = convertToSatoshis(Decimal(data[2])) + fee unspent = requests.get( f"{config.apiUrl}/unspent/{sender_address.to_string()}" ).json()["result"] txin = [] for i in range(0, len(unspent)): sender_balance += unspent[i]['value'] txin.append( TxInput(unspent[i]['txid'], unspent[i]['index'])) if sender_balance >= amount: txout = [] txout.append( TxOutput((amount - fee), target_address.to_script_pub_key())) txchange = sender_balance - amount if txchange > 0: txout.append( TxOutput(txchange, sender_address.to_script_pub_key())) script_code = Script([ 'OP_DUP', 'OP_HASH160', sender_wif.get_public_key().to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG' ]) tx = Transaction(txin, txout, has_segwit=True) tx.witnesses = [] for i in range(0, len(unspent)): value = unspent[i]['value'] sig = sender_wif.sign_segwit_input( tx, i, script_code, value) tx.witnesses.append( Script([sig, sender_wif.get_public_key().to_hex()])) post_data = {'raw': tx.serialize()} txid = requests.post(f"{config.apiUrl}/broadcast", data=post_data).json()['result'] ctx.bot.send_message( chat_id=chID, text= f"Success, sent @{db.getUserName(data[1])} {data[2]} {config.coin['ticker']}." ) ctx.bot.send_message( chat_id=chID, text= f"[View Transaction](https://sugar\\.wtf/esplora/tx/{str(txid)})", parse_mode="MarkdownV2") else: ctx.bot.send_message( chat_id=chID, text="You do not have enough funds to tip that amount") elif data[0] == "N": ctx.bot.delete_message(chat_id=chID, message_id=msgID) ctx.bot.send_message( chat_id=chID, text= f"You declined sending @{db.getUserName(data[1])} {data[2]} {config.coin['ticker']}" ) elif data[4] == "w": if data[0] == "Y": ctx.bot.delete_message(chat_id=chID, message_id=msgID) sender_wif = PrivateKey(db.getWIF(sender)) fee = convertToSatoshis(Decimal(config.coin['minFee'])) sender_address = P2wpkhAddress(getAddress(sender)) sender_balance = 0 amount = convertToSatoshis(Decimal(data[2])) + fee target_address = P2wpkhAddress("sugar1q" + data[1]) unspent = requests.get( f"{config.apiUrl}/unspent/{sender_address.to_string()}" ).json()['result'] txin = [] for i in range(0, len(unspent)): sender_balance += unspent[i]['value'] txin.append( TxInput(unspent[i]['txid'], unspent[i]['index'])) if sender_balance >= amount: txout = [] txout.append( TxOutput((amount - fee), target_address.to_script_pub_key())) txchange = sender_balance - amount if txchange > 0: txout.append( TxOutput(txchange, sender_address.to_script_pub_key())) script_code = Script([ 'OP_DUP', 'OP_HASH160', sender_wif.get_public_key().to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG' ]) tx = Transaction(txin, txout, has_segwit=True) tx.witnesses = [] for i in range(0, len(unspent)): value = unspent[i]['value'] sig = sender_wif.sign_segwit_input( tx, i, script_code, value) tx.witnesses.append( Script([sig, sender_wif.get_public_key().to_hex()])) post_data = {'raw': tx.serialize()} txid = requests.post(f"{config.apiUrl}/broadcast", data=post_data).json()['result'] ctx.bot.send_message( chat_id=chID, text= f"Success, withdrew {data[2]} {config.coin['ticker']} to address {target_address.to_string()} " ) ctx.bot.send_message( chat_id=chID, text= f"[View Transaction](https://sugar\\.wtf/esplora/tx/{str(txid)})", parse_mode="MarkdownV2") else: ctx.bot.send_message( chat_id=chID, text= "You do not have enough funds to withdraw the specified amount." ) elif data[0] == "N": ctx.bot.delete_message(chat_id=chID, message_id=msgID) ctx.bot.send_message( chat_id=chID, text= f"You declined withdrawing {data[2]} {config.coin['ticker']} to address {'sugar1q' + data[1]}" )