I am still a beginner in python and suddenly, I gave myself a project as a guideline and allowing me to improve. I opted for the creation of a wallet package, in order to be able to integrate it into another project, but I am stuck with the ecdsa library to generate the signature of a transaction. here is the error I get:
Traceback (most recent call last): File "Programs\Python\Python311\Lib\site-packages\ecdsa\keys.py", line 170, in from_public_point self.pubkey = ecdsa.Public_key( ^^^^^^^^^^^^^^^^^ File "Programs\Python\Python311\Lib\site-packages\ecdsa\ecdsa.py", line 155, in init raise InvalidPointError("Point does not lay on the curve") ecdsa.ecdsa.InvalidPointError: Point does not lay on the curve
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File "xxx-wallet\index.py", line 33, in print("valid tx: ", validate_transaction(_tx, a_unspent_tx_outs)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:neon-wallet\neon_wallet\transaction\transactions.py", line 56, in validate_transaction [ File "C:neon-wallet\neon_wallet\transaction\transactions.py", line 57, in validate_tx_in(txIn, transaction, a_unspent_tx_outs) File "C:neon-wallet\neon_wallet\transaction\transactions.py", line 110, in validate_tx_in key = ecdsa.VerifyingKey.from_string( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:Programs\Python\Python311\Lib\site-packages\ecdsa\keys.py", line 281, in from_string return cls.from_public_point(point, curve, hashfunc, validate_point) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C: Programs\Python\Python311\Lib\site-packages\ecdsa\keys.py", line 174, in from_public_point raise MalformedPointError("Point does not lay on the curve") ecdsa.errors.MalformedPointError: Point does not lay on the curve
I tried to create one that validates each transaction, for this I need to validate the list of incoming transactions, but this function generates a problem with the ECDSA python library
# Define a function that commits a transaction based on unspent
# transaction outputs
def validate_transaction(
transaction: Transaction, a_unspent_tx_outs: List[UnspentTxOut]
) -> bool:
"validate transaction"
# Check if transaction structure is valid
if not is_valid_transaction_structure(transaction):
return False
# Check if transaction id matches
# to the hash of the transaction contents
if get_transaction_id(transaction) != transaction.id:
print("invalid tx id: " + transaction.id)
return False
# Check if all transaction inputs are valid
has_valid_tx_ins = all(
[
validate_tx_in(txIn, transaction, a_unspent_tx_outs)
for txIn in transaction.tx_ins
]
)
if not has_valid_tx_ins:
print("some of the txIns are invalid in tx: " + transaction.id)
return False
# Calculate sum of amounts of transaction inputs
t_tx = [get_tx_in_amount(txIn, a_unspent_tx_outs) for txIn in transaction.tx_ins]
total_tx_in_values = sum(t_tx)
# Calculate sum of transaction output amounts
total_tx_out_values = sum([txOut.amount for txOut in transaction.tx_outs])
# Check if sums are equal
if total_tx_out_values != total_tx_in_values:
_id = transaction.id
print(f"totalTxOutValues !== totalTxInValues in tx: {_id}")
return False
return True
# Define a function that validates a transaction input against
# unspent transaction outputs
def validate_tx_in(
tx_in: TxIn,
transaction: Transaction,
a_unspent_tx_outs: List[UnspentTxOut],
) -> bool:
"""validate transaction in"""
# Find the unspent transaction output that
# matches transaction input
referenced_uTx_out = next(
(
uTxO
for uTxO in a_unspent_tx_outs
if (uTxO.tx_out_id == tx_in.tx_out_id)
and (uTxO.tx_out_index == tx_in.tx_out_index)
),
None,
)
if referenced_uTx_out is None:
print("referenced txOut not found: " + str(tx_in))
return False
# Extract address from unspent transaction output
address = referenced_uTx_out.address
print('ref address', address)
# Create an ECDSA public key from the address
key = ecdsa.VerifyingKey.from_string(
bytes.fromhex(address),
curve=ecdsa.SECP256k1,
)
# Check the signature of the transaction entry with the
# public key and transaction id
valid_signature = key.verify(
bytes.fromhex(tx_in.signature), bytes.fromhex(transaction.id)
)
if not valid_signature:
tx_s = tx_in.signature
tx_id = transaction.id
ref = referenced_uTx_out.address
print(f"invalid txIn signature: {tx_s} txId: {tx_id} address: {ref}")
return False
return True
"""test index"""
from neon_wallet.transaction.transaction import Transaction
from neon_wallet.transaction.transactions import (
get_transaction_id,
validate_transaction,
)
from neon_wallet.transaction.tx_in import TxIn
from neon_wallet.transaction.tx_out import TxOut
from tests.transaction.helpers_tests import utxo1, utxo2, utxo3
_tx = Transaction(
[
TxIn("tx1", 0, "serges007"),
TxIn("tx0", 1, "serges007"),
],
[
TxOut(
"04b0bd634234abbbcc1ba1e986e884185c61cf43da82f5963a8c70171b1b200c006a8421997ac617d91d406e5fa52bbf4d16e2a069e6b9b668a3935dabaecbc403",
50.0,
),
TxOut(
"04b0bd634234abbbdd1ba1e986e884185c61cf43da82f5963a8c70171b1b200c006a8421997ac617d91d406e5fa52bbf4d16e2a069e6b9b668a3935dabaecbc402",
100.0,
),
],
)
a_unspent_tx_outs = [utxo1, utxo2, utxo3]
# Appeler la fonction à tester avec cet objet
TX_ID = get_transaction_id(_tx)
# Vérifier que le résultat est conforme à l'attendu
# print("id :", TX_ID)
print("valid tx: ", validate_transaction(_tx, a_unspent_tx_outs))