MetacoSA / NBitcoin

Comprehensive Bitcoin library for the .NET framework.
MIT License
1.88k stars 848 forks source link

Transaction Built with Negative Miner Fee #243

Closed kyluke closed 7 years ago

kyluke commented 7 years ago

Hi Nicolas.

I've come across a problem which causes the library to create transactions with negative mining fees. I believe it is due to incorrectly discarding input transactions provided in a List<Coin> object.

The problem is as follows.

I add in input transactions to a List<Coin> object in a loop:

var tmpCoin = new Coin(uint256.Parse(history[i].transactionID), (uint)history[i].N, new Money(Convert.ToInt32(history[i].value), MoneyUnit.Satoshi), simpleSecret.ScriptPubKey);
coinList.Add(tmpCoin);

// Add the private key
txBuilder.AddKeys(simpleSecret.PrivateKey);

For this example, I use the following transaction ID's:

Using Transactions: 721c7256299bcada148aa2e96dfae2839b1f5e3e1c01959ad0901eb0e773eabc
Using Transactions: 4b43ee07d120de5b0b10c793dbb2fa7e1e1534a9c2825d13ee8747ea4556f754
Using Transactions: afbb9ce8516cee36b0c7d9b1b0c5d5afb987b07de6e29d21d854c8a418bf4853

Then I add a number of outputs to the transaction:

var fee = ((coinList.Count * 180 + 3 * 34 + 10) * 140);
txNew = txBuilder
    .AddCoins(coinList)
    .Send(address1, new Money((decimal)0.003, MoneyUnit.BTC))
    .Send(address2, new Money((decimal)0.00008, MoneyUnit.BTC))
    .SetChange(changeAddress)
    .SendFees(fee)
    .BuildTransaction(true);

Which results in:

01000000015348bf18a4c854d8219de2e67db087b9afd5c5b0b1d9c7b036ee6c51e89cbbaf000000006b48304502210080e74f51421b89b796c081c599b8a99bfe99702eccbdf321019b65f6a09ee20302200bd2a00c6b0492ed51a21c3ac0c206288fbd8ac42d313a469ca34a7a74082e72012102d121755b9325528c6d59340c2c7f18a1531aa03694580417b7090f053a4555eaffffffff0360540500000000001976a91467b41b28c4190c2206efbf7bf60eb9389e4a689488ace0930400000000001976a914c497d5d8ae1940b80cf616f541ab715a4272f12c88ac401f0000000000001976a914e203908360d5239dccf12179ea9af126fd6e727588ac00000000

Result:

{
  "txid": "c9a63b889b55e383d499d4920ca694c93aabce4954fb570f4eb0958f009b351d",
  "hash": "c9a63b889b55e383d499d4920ca694c93aabce4954fb570f4eb0958f009b351d",
  "size": 260,
  "vsize": 260,
  "version": 1,
  "locktime": 0,
  "vin": [
    {
      "txid": "afbb9ce8516cee36b0c7d9b1b0c5d5afb987b07de6e29d21d854c8a418bf4853",
      "vout": 0,
      "scriptSig": {
        "asm": "304502210080e74f51421b89b796c081c599b8a99bfe99702eccbdf321019b65f6a09ee20302200bd2a00c6b0492ed51a21c3ac0c206288fbd8ac42d313a469ca34a7a74082e72[ALL] 02d121755b9325528c6d59340c2c7f18a1531aa03694580417b7090f053a4555ea",
        "hex": "48304502210080e74f51421b89b796c081c599b8a99bfe99702eccbdf321019b65f6a09ee20302200bd2a00c6b0492ed51a21c3ac0c206288fbd8ac42d313a469ca34a7a74082e72012102d121755b9325528c6d59340c2c7f18a1531aa03694580417b7090f053a4555ea"
      },
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 0.0034928,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 67b41b28c4190c2206efbf7bf60eb9389e4a6894 OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a91467b41b28c4190c2206efbf7bf60eb9389e4a689488ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "mpyHeoXySSFTgvVbKqzRFyNXeG7XCLPeEn"
        ]
      }
    },
    {
      "value": 0.003,
      "n": 1,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 c497d5d8ae1940b80cf616f541ab715a4272f12c OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a914c497d5d8ae1940b80cf616f541ab715a4272f12c88ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "mySSdMf9PEXZ1iu6GXzeCtkgxUo3BaQAyZ"
        ]
      }
    },
    {
      "value": 0.00008,
      "n": 2,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 e203908360d5239dccf12179ea9af126fd6e7275 OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a914e203908360d5239dccf12179ea9af126fd6e727588ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "n281H5EbJUqtHiGbwyqCrFVYWCMonQoTYS"
        ]
      }
    }
  ]
}

Additional info
Sum of inputs: 0.00051320
Sum of outputs: 0.00657280
Fee: -0.00605960

As you can see, the library is for some reason discarding the other 2 input transactions, required to make this transaction. Is there something I am perhaps doing incorrectly?

Thanks Nicolas.

NicolasDorier commented 7 years ago

Are you sure you added the coins related to all the inputs and not just the one you sign ? And that their value is correct ?

kyluke commented 7 years ago

Hi @NicolasDorier.

After further investigation, the problem occured due to malleated transaction IDs. We have a system in place which dealt with those, but a few slipped through. This is been fixed.

As a point of interest, how is the NBitcoin library determining which transaction ID's it can use and which it cannot? Does it fail to sign the input or is there another indicator being used that a given transaction ID is not usable?

Thanks Nicolas.

NicolasDorier commented 7 years ago

the TransactionBuilder does not care about whether or not you can use the Transaction ID. It only cares if you have the Coin so it can build the transaction. You need to gather the coins to spend yourself. Either with a block explorer or with BitcoinCore listunspent.