ElementsProject / rust-elements

Rust support for Elements transaction/block deserialization
Creative Commons Zero v1.0 Universal
52 stars 33 forks source link

Witness construction help #187

Closed i5hi closed 11 months ago

i5hi commented 11 months ago

Currently when constructing a Witness, we have to construct it as a Vec<Vec> in elements

FWIU bitcoin::blockdata::witness::Witness struct abstracts aspects of the BIP141 spec, which one would have to do manually with the elements crate.

I have been running into issues while attempting to solve the same script in Elements, as I have in Bitcoin.

In bitcoin, the working witness construction is as follows:

        let mut witness = Witness::new();
        witness.push_bitcoin_signature(&signature.serialize_der(), hash_type);
        witness.push(preimage.bytes.unwrap());
        witness.push(self.swap_script.to_script().unwrap().as_bytes());

In elements, I am attempting the following:

        let mut script_witness: Vec<Vec<u8>> = vec![vec![]];
        script_witness.push(sig);
        script_witness.push(preimage.bytes.unwrap().to_vec());
        script_witness.push(self.swap_script.to_script().as_bytes().to_vec());

This fails with Signature must be zero for failed CHECK(MULTI)SIG operation

This could be an error with how I have contructed the Transaction; although I think I have got that right. Even if I have not, is the above Witness construction correct?

i5hi commented 11 months ago

If adding Witness to the library would be as straightforward as copying and adapting existing code from rust-bitcoin, I would love to attempt it.

i5hi commented 11 months ago

Updated the initialization since its adding an empty array at the start.

let mut script_witness: Vec<Vec<u8>> = vec![sig];
// script_witness.push(sig);
script_witness.push(preimage.bytes.unwrap().to_vec());
script_witness.push(self.swap_script.to_script().as_bytes().to_vec());

Still get the same error.

i5hi commented 11 months ago

Yes, the error was in my construction of the SigHash Message. I was using the output value instead of the previous_output value.

I got it to work by constructing a Witness and then using to_vec()