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
231 stars 125 forks source link

How to sign a FixedTransaction without deserializing the body? #604

Closed barfights closed 1 year ago

barfights commented 1 year ago

Hi! First of all thank you for CSL. :)

I'm having an issue that most likely stems from https://github.com/Emurgo/cardano-serialization-lib/issues/550 and https://github.com/Emurgo/cardano-serialization-lib/issues/429#issuecomment-1117524724 .

The situation is as follows:

So the frontend is getting the CBOR of the transaction. I'm creating a FixedTransaction from it, but then I still need to extract the hash from the body to create a witness.

    const transaction = CSL.FixedTransaction.from_hex(cbor)
    const { paymentKey } = getKeysFromMnemonic(mnemonic, passphrase)
    const txHash = CSL.hash_transaction(transaction.body())
    const vkeyWitness = CSL.make_vkey_witness(txHash, paymentKey)

   // ... add witness to the set and so on.

Problem is that it the body hash I'm getting here is still different than the one that I can see on the backend. This results in an InvalidWitnessError for the wallet signature.

This is my private testnet environment, so I can just pass the backend tx hash for signing and everything works fine. But CIP30 states that I'm supposed to pass the whole transaction as an argument to signTx so in that case the problem will be the same.

Is there something I'm missing regarding the usage of FixedTransaction? How can I avoid the serialization issue while trying to sign?

I also tried doing it the other way around, I took the body of the TX from the backend, created a new TX, signed it with the wallet, and tried to add the other necessary signatures on the backend afterwards. This completely broke the TX with a list of errors: MissingScriptWitnessesError, InvalidWitnessesError, ValueNotConservedError, BadInputsError.

lisicky commented 1 year ago

Hi @barfights ! Use raw_body from FixedTransaction it return the original tx body bytes. Use a raw_body to get a valid tx hash by TransactionHash.from_bytes(blake2b(32).update(raw_body).digest('binary')); , after you put it as argument for make_vkey_witness