user96608: I am trying to create a raw transaction spending a P2PKH output using rust-bitcoin, but whenever I am pushing the transaction to the testnet I receive the following error mandatory-script-verify-flag-failed (Non-canonical DER signature)
My signing code looks like this:
/// Sign a bitcoin transaction spending P2PKH outputs
/// 
/// # Arguments
/// 
/// * `tx` the transaction to be signed
/// * `script_pubkeys` list of script pubkeys of the inputs (has to be indexed in the same order as the inputs in the transaction)
/// * `skeys` list of secret keys with which to sign the inputs (has to be indexed in the same order as the inputs in the transaction)
/// * `pkeys` list of public keys for the inputs which are spent (has to be indexed in the same order as the inputs in the transaction)
/// * `curve` reference to the elliptic curve object used for signing
pub fn sign_transaction(tx : Transaction, script_pubkeys : Vec<Script>, skeys : Vec<PrivateKey>, pkeys: Vec<PublicKey>, curve : &Secp256k1<All>) -> Transaction {
    let mut signed_inp : Vec<TxIn> = Vec::new();

    for (i, unsigned_inp) in tx.input.iter().enumerate() {
        let script_pubkey = script_pubkeys.get(i).unwrap();
        let signing_key = skeys.get(i).unwrap().key;
        let pub_key = pkeys.get(i).unwrap();
        let sighash = tx.signature_hash(i, &script_pubkey, SIGHASH_ALL);
        let msg = Message::from_slice(&sighash.as_ref()).unwrap();
        let sig = curve.sign(&msg, &signing_key);
        // Standard P2PKH redeem script:
        // <sig> <pubkey>
        let redeem_script = Builder::new()
            .push_slice(&sig.serialize_der())
            .push_int(1)
            .push_key(&pub_key)
            .into_script();
        signed_inp.push(TxIn {
            previous_output : unsigned_inp.previous_output,
            script_sig: redeem_script,
            sequence : unsigned_inp.sequence,
            witness : unsigned_inp.witness.clone()
        });
        
    }
    
    Transaction {
        version : tx.version,
        lock_time : tx.lock_time,
        input : signed_inp,
        output: tx.output
    }
}

Here is an example transaction 01000000010b41a0a10f36c39b057053281d1d4d9f67410c40a093c351024f57af4e133c21010000006a46304402202d99eb85a14f483f4679b93eb1cf0f67b64d788dc4cd5ad782e75540508922ce0220752a9237e320497ba289a91edd7135dd6c53f9332dc33c71a3020bf0555607fc512103202430a99091407e6c724c5c88504e69ef6917f042a65cb990537922f823d9dfffffffff02e80300000000000017a9141831af16119be20b532668d5995bd05ac955153b872a091e00000000001976a9146b538e889cf0df7b69112b50db8faadb4e457b9288ac00000000
and in decoded form
{
   "result":{
      "txid":"b36457604e0ccd491e97c30c06a011fd906bb83d6fe81c676efb9fc60f17c5a5",
      "hash":"b36457604e0ccd491e97c30c06a011fd906bb83d6fe81c676efb9fc60f17c5a5",
      "version":1,
      "size":223,
      "vsize":223,
      "weight":892,
      "locktime":0,
      "vin":[
         {
            "txid":"213c134eaf574f0251c393a0400c41679f4d1d1d285370059bc3360fa1a0410b",
            "vout":1,
            "scriptSig":{
               "asm":"304402202d99eb85a14f483f4679b93eb1cf0f67b64d788dc4cd5ad782e75540508922ce0220752a9237e320497ba289a91edd7135dd6c53f9332dc33c71a3020bf0555607fc 1 03202430a99091407e6c724c5c88504e69ef6917f042a65cb990537922f823d9df",
               "hex":"46304402202d99eb85a14f483f4679b93eb1cf0f67b64d788dc4cd5ad782e75540508922ce0220752a9237e320497ba289a91edd7135dd6c53f9332dc33c71a3020bf0555607fc512103202430a99091407e6c724c5c88504e69ef6917f042a65cb990537922f823d9df"
            },
            "sequence":4294967295
         }
      ],
      "vout":[
         {
            "value":0.00001000,
            "n":0,
            "scriptPubKey":{
               "asm":"OP_HASH160 1831af16119be20b532668d5995bd05ac955153b OP_EQUAL",
               "hex":"a9141831af16119be20b532668d5995bd05ac955153b87",
               "reqSigs":1,
               "type":"scripthash",
               "addresses":[
                  "2MuT9izFXKft5umHqr1gviyhus6JGLCxGd6"
               ]
            }
         },
         {
            "value":0.01968426,
            "n":1,
            "scriptPubKey":{
               "asm":"OP_DUP OP_HASH160 6b538e889cf0df7b69112b50db8faadb4e457b92 OP_EQUALVERIFY OP_CHECKSIG",
               "hex":"76a9146b538e889cf0df7b69112b50db8faadb4e457b9288ac",
               "reqSigs":1,
               "type":"pubkeyhash",
               "addresses":[
                  "mqJShCuqM7FK5zPa7Z1PNJySMHTVPrK9bb"
               ]
            }
         }
      ]
   },
   "error":null,
   "id":"curltest"
}

Any help on what could be wrong is much appreciated

user112043: I believe the intention of your push_int(1) is to add SIGHASH_ALL to the transaction.
However, one of Script's many needless inflexibilities is that the sighash flag actually needs to be part of the signature itself, rather than as a separate stack element in the script.
This means that you need to take the Vec<u8> returned from Signature::serialize_der, mutate this with sig.push(1), and then add it onto the script stack. By manually editing your transaction to change the 51 (OP_1) to 01 (the 1 byte), and increasing the length in the signature opcode to consume this, I was able to make your transaction pass validation on testnet. (I didn't submit it though, to save you the annoyance of dealing with "input already spent" errors!)
I'm not thrilled with this API -- I suppose at the very least that Signature should have a a method serialize_der_with_sighashflag or something to eliminate the need for the caller to use a temporary variable and mut, but it's not super common to be manually constructing scripts like this and I guess it hasn't come up.
You might consider looking at rust-miniscript which does a lot of this stuff for you.

96608: <p>I am trying to create a raw transaction spending a P2PKH output using <a href="https://github.com/rust-bitcoin/rust-bitcoin" rel="nofollow noreferrer">rust-bitcoin</a>, but whenever I am pushing the transaction to the testnet I receive the following error <code>mandatory-script-verify-flag-failed (Non-canonical DER signature)</code>
My signing code looks like this:</p>
<pre><code>/// Sign a bitcoin transaction spending P2PKH outputs
/// 
/// # Arguments
/// 
/// * `tx` the transaction to be signed
/// * `script_pubkeys` list of script pubkeys of the inputs (has to be indexed in the same order as the inputs in the transaction)
/// * `skeys` list of secret keys with which to sign the inputs (has to be indexed in the same order as the inputs in the transaction)
/// * `pkeys` list of public keys for the inputs which are spent (has to be indexed in the same order as the inputs in the transaction)
/// * `curve` reference to the elliptic curve object used for signing
pub fn sign_transaction(tx : Transaction, script_pubkeys : Vec&lt;Script&gt;, skeys : Vec&lt;PrivateKey&gt;, pkeys: Vec&lt;PublicKey&gt;, curve : &amp;Secp256k1&lt;All&gt;) -&gt; Transaction {
    let mut signed_inp : Vec&lt;TxIn&gt; = Vec::new();

    for (i, unsigned_inp) in tx.input.iter().enumerate() {
        let script_pubkey = script_pubkeys.get(i).unwrap();
        let signing_key = skeys.get(i).unwrap().key;
        let pub_key = pkeys.get(i).unwrap();
        let sighash = tx.signature_hash(i, &amp;script_pubkey, SIGHASH_ALL);
        let msg = Message::from_slice(&amp;sighash.as_ref()).unwrap();
        let sig = curve.sign(&amp;msg, &amp;signing_key);
        // Standard P2PKH redeem script:
        // &lt;sig&gt; &lt;pubkey&gt;
        let redeem_script = Builder::new()
            .push_slice(&amp;sig.serialize_der())
            .push_int(1)
            .push_key(&amp;pub_key)
            .into_script();
        signed_inp.push(TxIn {
            previous_output : unsigned_inp.previous_output,
            script_sig: redeem_script,
            sequence : unsigned_inp.sequence,
            witness : unsigned_inp.witness.clone()
        });
        
    }
    
    Transaction {
        version : tx.version,
        lock_time : tx.lock_time,
        input : signed_inp,
        output: tx.output
    }
}
</code></pre>
<p>Here is an example transaction <code>01000000010b41a0a10f36c39b057053281d1d4d9f67410c40a093c351024f57af4e133c21010000006a46304402202d99eb85a14f483f4679b93eb1cf0f67b64d788dc4cd5ad782e75540508922ce0220752a9237e320497ba289a91edd7135dd6c53f9332dc33c71a3020bf0555607fc512103202430a99091407e6c724c5c88504e69ef6917f042a65cb990537922f823d9dfffffffff02e80300000000000017a9141831af16119be20b532668d5995bd05ac955153b872a091e00000000001976a9146b538e889cf0df7b69112b50db8faadb4e457b9288ac00000000</code></p>
<p>and in decoded form</p>
<pre><code>{
   &quot;result&quot;:{
      &quot;txid&quot;:&quot;b36457604e0ccd491e97c30c06a011fd906bb83d6fe81c676efb9fc60f17c5a5&quot;,
      &quot;hash&quot;:&quot;b36457604e0ccd491e97c30c06a011fd906bb83d6fe81c676efb9fc60f17c5a5&quot;,
      &quot;version&quot;:1,
      &quot;size&quot;:223,
      &quot;vsize&quot;:223,
      &quot;weight&quot;:892,
      &quot;locktime&quot;:0,
      &quot;vin&quot;:[
         {
            &quot;txid&quot;:&quot;213c134eaf574f0251c393a0400c41679f4d1d1d285370059bc3360fa1a0410b&quot;,
            &quot;vout&quot;:1,
            &quot;scriptSig&quot;:{
               &quot;asm&quot;:&quot;304402202d99eb85a14f483f4679b93eb1cf0f67b64d788dc4cd5ad782e75540508922ce0220752a9237e320497ba289a91edd7135dd6c53f9332dc33c71a3020bf0555607fc 1 03202430a99091407e6c724c5c88504e69ef6917f042a65cb990537922f823d9df&quot;,
               &quot;hex&quot;:&quot;46304402202d99eb85a14f483f4679b93eb1cf0f67b64d788dc4cd5ad782e75540508922ce0220752a9237e320497ba289a91edd7135dd6c53f9332dc33c71a3020bf0555607fc512103202430a99091407e6c724c5c88504e69ef6917f042a65cb990537922f823d9df&quot;
            },
            &quot;sequence&quot;:4294967295
         }
      ],
      &quot;vout&quot;:[
         {
            &quot;value&quot;:0.00001000,
            &quot;n&quot;:0,
            &quot;scriptPubKey&quot;:{
               &quot;asm&quot;:&quot;OP_HASH160 1831af16119be20b532668d5995bd05ac955153b OP_EQUAL&quot;,
               &quot;hex&quot;:&quot;a9141831af16119be20b532668d5995bd05ac955153b87&quot;,
               &quot;reqSigs&quot;:1,
               &quot;type&quot;:&quot;scripthash&quot;,
               &quot;addresses&quot;:[
                  &quot;2MuT9izFXKft5umHqr1gviyhus6JGLCxGd6&quot;
               ]
            }
         },
         {
            &quot;value&quot;:0.01968426,
            &quot;n&quot;:1,
            &quot;scriptPubKey&quot;:{
               &quot;asm&quot;:&quot;OP_DUP OP_HASH160 6b538e889cf0df7b69112b50db8faadb4e457b92 OP_EQUALVERIFY OP_CHECKSIG&quot;,
               &quot;hex&quot;:&quot;76a9146b538e889cf0df7b69112b50db8faadb4e457b9288ac&quot;,
               &quot;reqSigs&quot;:1,
               &quot;type&quot;:&quot;pubkeyhash&quot;,
               &quot;addresses&quot;:[
                  &quot;mqJShCuqM7FK5zPa7Z1PNJySMHTVPrK9bb&quot;
               ]
            }
         }
      ]
   },
   &quot;error&quot;:null,
   &quot;id&quot;:&quot;curltest&quot;
}
</code></pre>
<p>Any help on what could be wrong is much appreciated</p>
 112043: <p>I believe the intention of your <code>push_int(1)</code> is to add <code>SIGHASH_ALL</code> to the transaction.</p>
<p>However, one of Script's many needless inflexibilities is that the sighash flag actually needs to be part of the signature itself, rather than as a separate stack element in the script.</p>
<p>This means that you need to take the <code>Vec&lt;u8&gt;</code> returned from <code>Signature::serialize_der</code>, mutate this with <code>sig.push(1)</code>, and <em>then</em> add it onto the script stack. By manually editing your transaction to change the <code>51</code> (<code>OP_1</code>) to <code>01</code> (the 1 byte), and increasing the length in the signature opcode to consume this, I was able to make your transaction pass validation on testnet. (I didn't submit it though, to save you the annoyance of dealing with &quot;input already spent&quot; errors!)</p>
<p>I'm not thrilled with this API -- I suppose at the very least that <code>Signature</code> should have a a method <code>serialize_der_with_sighashflag</code> or something to eliminate the need for the caller to use a temporary variable and <code>mut</code>, but it's not super common to be manually constructing scripts like this and I guess it hasn't come up.</p>
<p>You might consider looking at <a href="https://github.com/rust-bitcoin/rust-miniscript/" rel="nofollow noreferrer">rust-miniscript</a> which does a lot of this stuff for you.</p>
