FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Unable to decode serialized TxOut · Issue #262 · ElementsProject/rust-elements · GitHub

Repository navigation

Unable to decode serialized TxOut #262

Description

There is an issue in serialization of TxOut, we're unable to decode it after serialization.
The problem lyes in the simplicityhl::elements::encode::serialize.
For unblinding it misses Rangeproof inside. For some reason it isn't serialized inside.
TxOut contains TxOutSecrets inside

pub struct TxOut {
, but TxOutWitness has its own serialization
impl_consensus_encoding!(TxOutWitness, surjection_proof, rangeproof);
while TxOut just truncates it
impl Encodable for TxOut {
.

Here is a quick code snippet to test it:

use std::time::Duration;
        use simplicityhl::elements::{ Transaction, TxOut,};
        use simplicityhl::elements::bitcoin::secp256k1;
        use simplicityhl::elements::encode;
        
        pub const PUBLIC_SECRET_BLINDER_KEY: [u8; 32] = [1; 32];
        let secret_key = SecretKey::from_slice(&PUBLIC_SECRET_BLINDER_KEY).unwrap();

        
        let tx_id = "8e12b0c994293d15b7f43abaeb6c119ce3612ff00246b7ae9079dca90a35031f";
        let url = format!("https://blockstream.info/liquidtestnet/api/tx/{}/hex", tx_id);
        let client = reqwest::blocking::Client::builder()
            .timeout(Duration::from_secs(10))
            .build()
            .unwrap();
        let tx_hex = client
            .get(&url)
            .send()
            .unwrap()
            .error_for_status()
            .unwrap()
            .text()
            .unwrap();
        
        let transaction: Transaction = encode::deserialize(&hex::decode(&tx_hex).unwrap()).unwrap();
        let tx_out_from_reqwest = transaction.output[0].clone();
        assert!(tx_out_from_reqwest.unblind(secp256k1::SECP256K1, secret_key).is_ok());
        
        let tx_out_from_request_serialized = encode::serialize(&tx_out_from_reqwest);
        let tx_out_from_request_deserialized: TxOut = encode::deserialize(&tx_out_from_request_serialized).unwrap();
        
        assert!(tx_out_from_request_deserialized.unblind(secp256k1::SECP256K1, secret_key).is_ok());

Activity

  1. apoelstra commented on Jan 1, 2026

    Member

    Can you post a reproduction that only uses rust-elements?

  2. apoelstra commented on Jan 1, 2026

    Member

    Oh, I see, the issue is that if you directly encode/decode a TxOut it does not include the TxOutWitness. You have to encode/decode this separately, beacuse it appears in a separate part of the transaction.

    This is an unfortunate footgun but it sorta falls out of the existing encoding trait. When we move to bitcoin-consensus-encoding I'll try to make the API for this better. Probably we want a separate TxOutWithoutWitness type which isn't really usable until the users finds a witness somewhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL