Emurgo / cardano-serialization-lib

This is a library, written in Rust, for serialization & deserialization of data structures used in Cardano's Haskell implementation of Alonzo along with useful utility functions.
Other
234 stars 125 forks source link

How to reference deployed scripts and datums on TransactionWitnessSet, not using TransactionBuilder? #610

Closed zxpectre closed 1 month ago

zxpectre commented 1 year ago

Our code handles all witnesses after calling TransactionBuilder.build(), among them all plutus scripts, datums and redeemers.

How can we reference deployed datums and scripts using reference inputs without adding witnesses on TransactionBuilder?

I see PlutusWitness class having the reference to deployed stuff but don't see the way to use it on TransactionWitnessSet.

Until now, adding reference inputs and redeemers is not enough aparently as node rejects due to lack of script on transaction.

lisicky commented 1 year ago

Hi @zxpectre ! Use the DatumSource and the PlutusScriptSource types. Small example by the link https://github.com/Emurgo/cardano-serialization-lib/releases/tag/11.1.0 . But in the PlutusScriptSource I recommend to use the new_ref_input_with_lang_ver, because new_ref_input can lead incorrect script_data_hash.

zxpectre commented 1 year ago

Thanks @lisicky for the quick response!

but that's exactly what make us rebuild the entire legacy workflow, I am looking to avoid adding that to any builders and your suggestion ends like this:

        //and in the and you just add plutus script input as you do it before
        let tx_inputs_builder = TxInputsBuilder::new();
        tx_inputs_builder.add_plutus_script_input(&plutus_witness, &get_script_input(), &get_amount());

If i could just use something like this, everything would be fine:

TransactionWitnessSet.set_plutus_witnesses()

We have been using cardano-serialization-lib since Q2 2021, everything works fine for us using 11.3.1, but to refactor everything for just adding referenced witnesses is problematic.

lisicky commented 1 year ago

@zxpectre You can try to use add_reference_input from the TransactionBuilder. ref inputs is not part of witnesses set, it is part of tx body.

zxpectre commented 1 year ago

I've tryied that first and had some tx validation errors from node, will review the code and retry, maybe something silly is missing. Thought has to do with a change in witnesses, so I asked here.

Thanks @lisicky for the quick response.

zxpectre commented 1 year ago

UPDATE: I've managed to solve some of the issues, internally PlutusScript instances were loosing the associated Language, causing errors on related stuff such as ScriptDataHash calculations and others. The behaviour in these cases was that PlutusScript.language_version() returns as default Plutus V1 Language, was confusing because it seems one can force V2 scripts to pass as V1 and transaction succeeds (Or the Plutus script CBORs I was using were actually V2 without knowing it).

I got reference input scripts working now using TransactionBody.set_reference_inputs() as you suggested here @lisicky

@zxpectre You can try to use add_reference_input from the TransactionBuilder. ref inputs is not part of witnesses set, it is part of tx body.

The problem I have now is with reference input datums:

Using TransactionWitnessSet.witnesses.set_plutus_data() seems to inline entire datum CBOR hex on witness set. It's not what I want to achieve but every time I use this, transaction succeeds, no matter if also providing it on TransactionBody.set_reference_inputs() .

Using only TransactionBody.set_reference_inputs() fails either if I use the datum cbor hex on ScriptDataHash calculation or not.

Any ideas?

lisicky commented 1 year ago

@zxpectre what plutus version do you use ? What error do you get from cardano node ?

zxpectre commented 1 year ago

Hey @lisicky I was able to solve this issue months ago by constructing myself the plutus witnesses, but now after changing everything internally to rely on CSL TxBuilder based on your branch I'm having issues with this old topic again.

This is a jsonned Transaction object that is trying to consume a locked UTXO at a script address. The v2 plutus script is deployed, not inlined on transaction.

{
    "body": {
        "inputs": [
            {
                "transaction_id": "26b200f3372b654bbbfd8e58bf681c26b1a2916f38024254709ca5a81ca9a08a",
                "index": 0
            }
        ],
        "outputs": [
            {
                "address": "addr_test1qzq4pdmmcldunscqc9gl2xzf50ea3tvrupsv9x43lwx5mntsa6jqq0nqen5mexc49atf0mkh6pdtd7v9fdmggs038zms4vnuge",
                "amount": {
                    "coin": "2426799",
                    "multiasset": null
                },
                "plutus_data": null,
                "script_ref": null
            }
        ],
        "fee": "173201",
        "ttl": null,
        "certs": null,
        "withdrawals": null,
        "update": null,
        "auxiliary_data_hash": "c2ac86ae4f0fe905f7dca583dad714647ccbb0c3302082222f9deb4cafaaf6e6",
        "validity_start_interval": null,
        "mint": null,
        "script_data_hash": "9d54b015ddbf28f12f9574203a399bc4528d5625561535e1b337aed327b37864",
        "collateral": [
            {
                "transaction_id": "efa2a09a9792d40fbd45d67f2e5718c7d700709f4619805b34c018b254667675",
                "index": 0
            },
            {
                "transaction_id": "d0505586a5bcc9b470125827146144b76f5d274b94992d7b149b4f8aa9955fc1",
                "index": 0
            }
        ],
        "required_signers": null,
        "network_id": "Testnet",
        "collateral_return": null,
        "total_collateral": null,
        "reference_inputs": [
            {
                "transaction_id": "7544fb6846d86a3ec346b27a76aabac2fb76213853d3e59b77cb0a1c4ed6f11a",
                "index": 0
            }
        ]
    },
    "witness_set": {
        "vkeys": [
            {
                "vkey": "ed25519_pk16ngrr068txp2r0qcnvdevvjy9af4j4pjvqh7yjpl3l43dpx7ldnse4cvdq",
                "signature": "144a843b102eff964d6312a5ee182c3be56706403ee8af4aef95d6ce4baa8b8c9a20b75b4609ff3ac50007c404c25f200913dd4e05d8cc1182de1db2f1771504"
            }
        ],
        "native_scripts": null,
        "bootstraps": null,
        "plutus_scripts": [],
        "plutus_data": {
            "elems": [
                "{\"int\":2600000}"
            ],
            "definite_encoding": false
        },
        "redeemers": [
            {
                "tag": "Spend",
                "index": "0",
                "data": "{\"constructor\":0,\"fields\":[]}",
                "ex_units": {
                    "mem": "0",
                    "steps": "0"
                }
            }
        ]
    },
    "is_valid": true,
    "auxiliary_data": {
        "metadata": {
            "73": "{\"map\":[{\"k\":{\"string\":\"bid\"},\"v\":{\"string\":\"875b9380866e9d56e7110b0ee310962c16d9d4ae103f829d62bdffd2cbe7c61d\"}},{\"k\":{\"string\":\"parent\"},\"v\":{\"string\":\"26b200f3372b654bbbfd8e58bf681c26b1a2916f38024254709ca5a81ca9a08a\"}},{\"k\":{\"string\":\"referrer\"},\"v\":{\"string\":\"http://localhost:3000\"}},{\"k\":{\"string\":\"type\"},\"v\":{\"string\":\"tx\"}},{\"k\":{\"string\":\"v\"},\"v\":{\"string\":\"1.0\"}}]}"
        },
        "native_scripts": null,
        "plutus_scripts": null,
        "prefer_alonzo_format": false
    }
}

I'm using

res.plutusScriptSourceObj=CardanoWasm().PlutusScriptSource.new_ref_input_with_lang_ver(
            CardanoWasm().ScriptHash.from_hex(script.source?.scriptHashHex||""),
            CardanoWasm().TransactionInput.new(
              CardanoWasm().TransactionHash.from_hex(script.source?.txHash||""),
              <number>script.source?.txOutIndex
            ),
            langObj
          );

res.plutusWitnessObj=CardanoWasm().PlutusWitness.new_with_ref              (res.plutusScriptSourceObj,res.plutusDatumSourceObj,res.plutusRedeemerObj);

txBuilder.add_plutus_script_input(plutusWitnessObj,txIn,multiAssetvalue);

txBuilder.calc_script_data_hash(allCostModels(useCostModelData))    

Ogmios/node was complaining something like this and other consecuential errors (this is why the tx never get's it's ex_units filled)

            {
                "missingScriptWitnesses": [
                    "52c6af0c9b744b4eecce838538a52ceb155038b3de68e2bb2fa8fc37"
                ]
            },
            {
                "extraDataMismatch": {
                    "provided": "ba653732f3bd44a11404300de31835f982e13d2eddd9f1a5daf5d5a8fb1e8dbc",
                    "inferredFromParameters": "b24e3a95a326b483b432f87f55acd2df3a848a2a49c0943a1a6e4d077f7baea9"
                }
            },

Would it be that scriptDataHash is wrong because TxBuilder is returning "plutus_scripts": [], an empty list instead of being null or empty CBOR data?

I cannot finish all this development yet, please give me some feedback, It seems this is the last blockage Im facing 🙏🙏🙏

lisicky commented 1 year ago

Hi @zxpectre ! Check ogmios doc seems you have issue with script integrity hash. And also check that you use the latest ogmios version. If you add plutus witnesses by yourself without using tx builder it also can be issue. If not, check that you are using correct language version of plutus scripts and correct cost models.

zxpectre commented 1 year ago

Hi @zxpectre ! Check ogmios doc seems you have issue with script integrity hash. And also check that you use the latest ogmios version. If you add plutus witnesses by yourself without using tx builder it also can be issue. If not, check that you are using correct language version of plutus scripts and correct cost models.

Thanks @lisicky, I was really tired. Spotted it the other day, this was wrong on my side:

So now i have the right script data hash calculations

Last questions:

zxpectre commented 1 year ago

Hi @lisicky !

lisicky commented 9 months ago

Hi @zxpectre sorry for long answer. You don't need to provide referenced datums for script hash calculation. hash_script_data() args is not sorted by CSL , you need provide them exact the same order as them will be stored into tx witness set

lisicky commented 1 month ago

Seems issue is solved, if not reopen please it