Bitcoin

Separated Witnesses – Sign Segwit transactions using Bitcoin boxes

I’m trying to use a Bitcoin box to programmatically create a transaction in Rust that consumes output associated with a P2WPKH address. Here is the relevant code snippet:

fn sign_transaction<SignFun>(
    own_public_key: &(u8),
    own_address: &Address,
    own_utxos: &(Utxo),
    mut transaction: Transaction,
    key_name: String,
    derivation_path: Vec<Vec<u8>>,
    signer: SignFun,
) -> Transaction
where
    SignFun: Fn(String, Vec<Vec<u8>>, Vec<u8>) -> Vec<u8>,


    let txclone = transaction.clone();
    let mut hash_cache = sighash::SighashCache::new(&txclone);
    for (index, input) in transaction.input.iter_mut().enumerate() 
        let value = get_value(input, own_utxos);    // Look up the value by finding the corresponding UTXO
        let sighash = hash_cache
            .segwit_signature_hash(index, &own_address.script_pubkey(), value, SIG_HASH_TYPE)
            .expect("Creating the segwit signature hash failed.");

        let signature = signer(key_name.clone(), derivation_path.clone(), sighash.to_vec()).await;

        // Convert signature to DER.
        let der_signature = sec1_to_der(signature);

        let mut sig_with_hashtype = der_signature;
        sig_with_hashtype.push(SIG_HASH_TYPE.to_u32() as u8);
        let witness_bytes = vec!(sig_with_hashtype, own_public_key.to_vec());
        input.witness = Witness::from_vec(witness_bytes);
    

    transaction

When sending a signed transaction to my local Bitcoin node registration test The following error occurs in mode:

error code: -26
error message:
non-mandatory-script-verify-flag (Signature must be zero for failed CHECK(MULTI)SIG operation)

I recorded the following information:

  • Public key: 0377f5de845ac601f24e7cbf2e4abcc9e1040cd4ae971ecaa00837b1c74684e15b
  • Address: bcrt1qh3zle7xs34azdyycg8cpf9wx5nxjpcqyqv4eyc
  • Input spent as value: 625000000
  • Transaction to sign: 0100000001ceac446d9350730c2a886220bed7ae154ca3f717897819091d5e72dcd0f0895e0000000000ffffffff0200e1f505000000001600148be949ae15ee4b 5da9af0ce2bf8d3f3c43c582da26 dc4a1f00000000160014bc45fcf8d08d7a26909841f01495c6a4cd20e00400000000
  • Sigh: d7e5696f18363b58c84b8d57014d291c9f7ebbac562d219f7e7014b9a5685bbf
  • SEC1 signature: c10c09b210914e49f295c07c9f96352e085df9d2c4272292239445d6f89483bc64c9903bf998d217c80375c36b60b212a824b63435e30205b2 ed5a6a
  • DER signature: 3045022100c10c09b210914e49f295c07c9f96352e085df9d2c4272292239445d6f89483bc02206 4c9903bebaba4bbf998d217c80375c36b60b212a82 4 b63435e30205b2ed5a6a
  • DER signature using Sighash type: 3045022100c10c09b210914e49f295c07c9f96352e085df9d2c4272292239445d6f89483bc02206 4c9903bebaba4bbf998d217c80375c36b60b 21 2a824b63435e30205b2ed5a6a01
  • Signed transaction: 01000000000101ceac446d9350730c2a886220bed7ae154ca3f717897819091d5e72dcd0f0895e0 000000000ffffffff0200e1f505000000001600148be949ae1 5ee4b5da9af0ce2bf8d3f3c43c582 da26dc4a1f00000000160014bc45fcf8d08d7a26909841f01495c6a4cd20e00402483045022100c 10c09b210914e49f295c 0 7c9f96352e085df9d2c4272292239445d6f89483bc022064c9903bebab a4bbf998d217c80375c36b60b212a824b63435e30205b2ed5a6a01210377f5de845ac 601f2 4e7cb f2e4abcc9e1040cd4ae971ecaa00837b1c74684e15b00000000

A similar code snippet for a legacy (P2PKH) transaction using the same ECDSA signer works perfectly, so we assume the signer is okay.

Any help in finding out where the problem is would be greatly appreciated!

Related Articles

Back to top button