As the title states, I'm trying to send a Litecoin transaction using the Blockcypher API Python SDK, and using Bitcoinlib for key management. I have extensively reviewed the documentation and source code for the tools I'm working with, and I have tried researching this specific error but still have yet to get past this roadblock.
I've gotten to a point where the transaction is built and and signatures are created, but when I try broadcasting it, the API returns this error to my console:
{'errors': [{'error': 'Error validating generated transaction:
Error running script for input 0 referencing 79d841bf41ead0e4ecbb58197c289ec9cc087e85cf1a98196e2e415b8990357a at 0:
Script was NOT verified successfully.'}],
'tx': {'block_height': -1, 'block_index': -1,
'hash': 'f2ae95498b3b209ee077ad8a32292a0461ab2d37b807a647520aee31e9c62d29',
'addresses': ['ltc1q7nyvlc6jkznpemw3g0n8f3z5z4eatfhevy07au', 'ltc1qxdvtqt9tm7rwplk8upezujtjsh6k3l85tw39ue'],
'total': 98100,
'fees': 1900,
'size': 221,
'vsize': 140,
'preference': 'low',
'relayed_by': '35.226.89.167',
'received': '2023-07-05T08:53:48.287727164Z',
'ver': 1,
'double_spend': False,
'vin_sz': 1,
'vout_sz': 2,
'confirmations': 0,
'inputs': [
{'prev_hash': '79d841bf41ead0e4ecbb58197c289ec9cc087e85cf1a98196e2e415b8990357a',
'output_index': 0,
'output_value': 100000,
'sequence': 4294967295,
'addresses': ['ltc1q7nyvlc6jkznpemw3g0n8f3z5z4eatfhevy07au'],
'script_type': 'pay-to-witness-pubkey-hash',
'age': 2502561,
'witness':
['3044022077515b45f26a56b0dfff42eb94b69d98dbf8fb896fda079ea7e99a17a768fd6f022008b3c435ee0816801e1eea22871cb935a7eaaa8df6ad472eab19b096fb62cd82'
, '034b3110d0be2b52a14c4bbccef285396c67c29586463f278a8d1efacb3c33f439']}],
'outputs': [{
'value': 10000,
'script': '00143358b02cabdf86e0fec7e0722e497285f568fcf4',
'addresses': ['ltc1qxdvtqt9tm7rwplk8upezujtjsh6k3l85tw39ue'],
'script_type': 'pay-to-witness-pubkey-hash'},
{'value': 88100,
'script': '0014f4c8cfe352b0a61cedd143e674c4541573d5a6f9',
'addresses': ['ltc1q7nyvlc6jkznpemw3g0n8f3z5z4eatfhevy07au'],
'script_type': 'pay-to-witness-pubkey-hash'}]},
'tosign': ['']}
First, I tried using the simple_spend method as shown below...
from blockcypher import simple_spend
simple_tx = simple_spend(api_key = API_KEY, from_privkey=priv_key_hex,
to_address='ltc1qxdvtqt9tm7rwplk8upezujtjsh6k3l85tw39ue', to_satoshis=10000, coin_symbol='ltc')
print('tx:', simple_tx)
... and this error was produced:
TX Error(s): Tx NOT Signed or Broadcast
Unable to find a transaction to spend for address LhYFhgm6iai5da8ADeoUjs2BnAPoPm74cm.
Not enough funds in 0 inputs to pay for 1 outputs, missing -10000.
Not enough funds after fees in 0 inputs to pay for 1 outputs, missing -11400.
Error validating generated transaction: Transaction missing input or output.
Traceback (most recent call last):
File "main.py", line 33, in <module>
simple_tx = simple_spend(api_key = API_KEY, from_privkey=priv_key_hex, to_address='ltc1qxdvtqt9tm7rwplk8upezujtjsh6k3l85tw39ue', to_satoshis=10000, coin_symbol='ltc')
File "/home/runner/sendltc/venv/lib/python3.10/site-packages/blockcypher/api.py", line 1684, in simple_spend
raise Exception('Build Unsigned TX Error')
Exception: Build Unsigned TX Error
This indicates that the private key I provided is automatically being formatted as a legacy address, where no funds for the input transaction exist because I funded the segwit derivative of the private key. I have since verified that this code will properly execute transactions when I fund the legacy derivative of the private key. But it does not work when I attempt to involve a segwit addresses as the sender or receiver.
Since I am unsure of how to ensure that the simple_spend method attempts a segwit transaction, I tried constructing it piece-by-piece.
Here's the code for that:
from bitcoinlib.keys import Key
from blockcypher import create_unsigned_tx, make_tx_signatures, broadcast_signed_transaction
API_KEY = '<api_key>'
wif = '<compressed_wif>'
priv_key_hex = Key(wif, network = 'litecoin').private_hex
pub_key_hex = Key(wif, network = 'litecoin').public_hex
sender = Key(priv_key_hex, network = 'litecoin').address(prefix='ltc', script_type='p2wpkh', encoding='bech32')
inputs = [{'address': f"{sender}"}]
outputs = [{'address': 'ltc1qxdvtqt9tm7rwplk8upezujtjsh6k3l85tw39ue', 'value': 10000}]
unsigned_tx = create_unsigned_tx(inputs=inputs, outputs=outputs, include_tosigntx=True, coin_symbol='ltc', api_key = API_KEY)
print(unsigned_tx)
privkey_list = [str(priv_key_hex)]
pubkey_list = [str(pub_key_hex)]
tx_signatures = make_tx_signatures(txs_to_sign=unsigned_tx['tosign'], privkey_list=privkey_list, pubkey_list=pubkey_list)
print('')
print(tx_signatures)
tx = broadcast_signed_transaction(unsigned_tx=unsigned_tx, signatures=tx_signatures, pubkeys=pubkey_list, coin_symbol='ltc', api_key = API_KEY)
print('')
print(tx)
So when I try to run this, the aforementioned error is returned, stating that the script could not be verified. My hunch is that it has something to do with attempting to broadcast a legacy transaction while I provided a segwit address. Upon viewing similar threads on here, it would seem that the signature is being malformed either because there is a problem with how I'm deriving my keys, or somehow I need to set a flag indicating a segwit transaction. This could lead to the root of the problem, but I could also be overlooking other issues.
Any advice, pointers, or answers would be greatly appreciated. Thank you for your time.