pybitcash / bitcash

BitCash: Python Bitcoin Cash Library (fork of ofek's Bit)
https://bitcash.dev
MIT License
97 stars 39 forks source link

Error while signing transaction: nft_commitment #130

Closed dinno-invis1ble closed 12 months ago

dinno-invis1ble commented 12 months ago

Hello,

I encountered an "nft_commitment" error while signing a transaction.

The issue arises from this specific line in the package: https://github.com/pybitcash/bitcash/blob/b5217302b60e9714da28977662c6933c8bb028ca/bitcash/wallet.py#L480C12-L480C12

There isn't a second parameter provided for Unspent.from_dict(). Therefore, when it attempts to access nft_commitment from an undefined object, it seems to throw an error.

This is reference to Unspent.from_dict: https://github.com/pybitcash/bitcash/blob/b5217302b60e9714da28977662c6933c8bb028ca/bitcash/network/meta.py#L76C7-L76C8

Could you clarify if this is a known issue, or perhaps I've overlooked something?

Thanks in advance!

merc1er commented 12 months ago

@yashasvi-ranawat would you have an idea?

merc1er commented 12 months ago

Also, @dinno-invis1ble would you be able to give a minimal reproducible example?

yashasvi-ranawat commented 12 months ago

That should not happen. Unspent class is slotted, so Unspent will always have "nft_commitment". When Unspent.to_dict() is used, the dictionary will have "nft_commitment" as None if its not defined. I'm not sure how you managed to feed a dictionary with undefined "nft_commitment". Perhaps in an extended use-case there's a bug which causes it!

Also, @dinno-invis1ble would you be able to give a minimal reproducible example?

would be much appreciated.

dinno-invis1ble commented 12 months ago

I am fetching UTXO from bitcore and then signing inputs using bitcash.

signed_hex = private_key.sign_transaction(tx_data)

Example of 'tx_data' variable:

{ "unspents": [ { "amount": 1982163, "script": "76a914ac850b8d9340cc1e1fd2921a15a52d8ba7fb4e1288ac", "txid": "a983b764947b4a8fa6d08ef08cd46629242a8fcf916f09703e6f17375adddefb", "txindex": 1, "confirmations": 1 } ], "outputs": [ [ "bitcoincash:qp8xlkvxxwase8dzsfvrn8x2ewyn44cx4uum45ggx3", 384986 ], [ "bitcoincash:qzkg2zudjdqvc8sl62fp59d99k96076wzgtfuyhz22", 1595425 ] ] }

dinno-invis1ble commented 12 months ago

In the code, I noticed that Unspent.from_dict expects a second argument. However, based on the references I initially mentioned, this second argument isn't provided.

yashasvi-ranawat commented 12 months ago

I am fetching UTXO from bitcore and then signing inputs using bitcash.

bitcash, since version 1.0, has different Unspent format. The Unspents also have cashtokens. You'll need to append the missing cashtoken data to your "unspents":

def unspent_core2cash(tx_data):
    unspents = tx_data["unspents"]
    for unspent in unspents:
        for i in ["category_id", "nft_capability", "nft_commitment", "token_amount"]:
            unspent[i] = unspent.get(i)
    return tx_data
tx_data = unspent_core2cash(tx_data)
signed_hex = private_key.sign_transaction(tx_data)

In the code, I noticed that Unspent.from_dict expects a second argument. However, based on the references I initially mentioned, this second argument isn't provided.

That's a class function construct, the first argument is the class itself (like "self", but @classmethods have "cls" convention). Its a python thing.

You may ask further, but close the issue if this resolves it. :)

merc1er commented 12 months ago

Thanks for addressing this! Closing.