It is not unique transaction ID

1 Introduction

We know that using bitcoin in 交易ID( TxID) to uniquely identify the transaction in the whole network.
In this context, the vast majority of people think TxIDit must be the whole network only.

2. Facts

The vast majority is the case.
But in fact, there have been two cases have the same TxID trading blocks in different situations, as follows:

  1. TxID:e3bf3d07d4b0375638d5f1db5255fe07ba2c4cb067cd81b84ee974b6585fb468
    1)block 91,722: 00000000000271a2dc26e7667f8419f2e15416dc6955e5a6c6cdf3f2574dd08e
    2)block 91,880: 00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721
  2. TxID: D5d27987d2a3dfc724e359870c6644b40e497bdc0589a033220fe15429d88599
    1) block 91,812: 00000000000af0aed4792b1acee3d966af36cf5def14935db8de83d6f9306f2f
    2) block 91,842: 00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec

3. Explain

Both events are and block coinbasetransactions.
In simple terms: the transaction TxIDis determined by the contents of the transaction, including input, outputand so on.
coinbaseTrading is not input, which is outputalso determined by the miners account. If the two blocks of miners using the same address, is likely to occur two coinbasecontents of the same transaction, and thus TxIDalso the same situation.
View Both events from the browser block, the block can be found in the 91,722 and 91,880 miners have to address 1GktTvnY8KGfAS72DhzGYJRyaQNvYrK9Fg, and block 91,812and 91,842miners have to address 16va6NxJrMGe5d2LP6wUzuVnzBBoKQZKom. It also validates our interpretation.

4. Processing

Deal with this issue contains two aspects:

  1. How to make the miners are not the same generation TxIDof coinbase?
  2. How to deal with the existing two incidents?

4.1. How to make the miners are not the same generation TxIDof coinbase?

Bitcoin team adopted two BIP: BIP30 and BIP34 . The former 2012 March 15 in the main network implementation, which in March 24th, 2013 a full upgrade on the main network.

4.1.1. BIP30

BIP30The core reads as follows:

Blocks are not allowed to contain a transaction whose identifier matches that of an earlier, not-fully-spent transaction in the same chain.

That translated into Chinese: the implementation of BIP30the block before and after a transaction may not contain the TxIDsame transaction, unless prior to the transaction outputhave been spent before. Otherwise, the block was determined to be invalid blocks.
BIP30Embodiment of the source code as follows:

// checkBIP0030 [validate.go]
func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block, view *UtxoViewpoint) error {
    ...
    fetchSet := make(map[wire.OutPoint]struct{})      
    for _, tx := range block.Transactions() {           
        prevOut := wire.OutPoint{Hash: *tx.Hash()}            
        for txOutIdx := range tx.MsgTx().TxOut {                  
            prevOut.Index = uint32(txOutIdx)                  
            fetchSet[prevOut] = struct{}{}            
        }      
    }      
    err := view.fetchUtxos(b.db, fetchSet)
    ...
    for outpoint := range fetchSet {            
        utxo := view.LookupEntry(outpoint)            
            if utxo != nil && !utxo.IsSpent() {                  
                str := fmt.Sprintf("tried to overwrite transaction %v "+                        
                    "at block height %d that is not fully spent",
                    outpoint.Hash, utxo.BlockHeight())                 
                return ruleError(ErrOverwriteTx, str)            
            }      
        }
        
    return nil
}

Above code implemented in fact by means output(i.e.: TxID+ index) to be checked.
Specifically, the current block all outputbe UTXOchecked. As long as there is one UTXO, and the blocks of a outputsame, indicating that UTXOthe TxIDand that output's TxID, that is also the same: the outputtransaction is located and before a transaction is TxIDthe same. Thus test results as failed, return ruleErrorerror.
But the source code to achieve seemingly ignoring a special case.

4.1.1.1. Consider the special circumstances

Since the checkBIP0030function of realization, based on output( TxID+ index) comparison, consider a case where possible: although TxIDthe same but indexdifferent.
For example: the current block a transaction TxIDof a transaction and before TxIDthe same. Currently there is only one transaction output, two transactions exist before outputbut the first outputhas been spent, and the second outputhas not been spent. Therefore, the current transaction outputtransaction and before the second outputappears: TxIDthe same but indexdifferent situations. As shown below:
Special case
In the above code implementation, this should also determines that the block is a valid block.

But this is basically not exist , because TxIDis based on calculations of the content of the transaction. If the TxIDsame, the same transaction will default content, that have the same output. So long as there is a prior transaction outputhas not been spent, and they're sure the current transaction a outputcoincidence, so as to be checked out, the corresponding block is determined to be invalid blocks.

4.1.2. BIP34

Briefly, BIP34requires the miners coinbaselocated block height is added to coinbasethe inputa scriptSig, so that the whole network can be calculated only TxID.

For this purpose, it requires three steps:

  1. Initiation Protocol: 1) to block for version definition, the definition of the old block version of the agreement is 1 block defining a new protocol version 2, and the new agreement needs to be added to the height of the block coinbasetransaction. 2) set up by miners in the new block version 1 or 2 vote. 3) At this stage, version 1 of the block will be accepted, but version 2 is defined as the height of the block that contains the block will be accepted, version 2 is defined as the height of the block and contains the block will be accepted
  2. Phase 75% (in the past when there are 1000 blocks over 750 blocks version identifier is 2): a version of the block will be accepted and the version 2 is defined as the height of the block also containing block will be accepted, but version 2 is defined as the height of blocks but did not contain the block it will not be accepted
  3. 95% of the stage (in the past when there are 1000 blocks more than 950 blocks identified as version 2): Only version 2 and is defined as the height of the block containing the block will be accepted, the other two blocks are It will not be accepted. This completes the soft fork.

Since the main network bit credits already completed BIP34soft bifurcation, the source code to retain only the last inspection, i.e.: Version 2 and is defined as coinbasethe height of the containing block. The corresponding source code is shown below:

// checkBlockContext [validate.go]
func (b *BlockChain) checkBlockContext(...) error {
    ...
    if ShouldHaveSerializedBlockHeight(header) &&      
        blockHeight >= b.chainParams.BIP0034Height {      
        coinbaseTx := block.Transactions()[0]      
        err := checkSerializedHeight(coinbaseTx, blockHeight)      
        if err != nil {            
            return err      
        }
    }
    ...
}

In addition, the need to say a few words is: BIP34to open a more elegant "soft fork" approach: three-stage soft bifurcation , back BIP66and BIP65have adopted a similar approach to achieve the soft fork.

4.2. How to deal with the existing two incidents?

For the same two cases have occurred TxIDin the incident, Bitcoin protocol to take "approved" attitude. That is considered to block both cases generated and the corresponding outputlegal.
The corresponding source code is shown below:

// checkConnectBlock [validate.go]
func (b *BlockChain) checkConnectBlock(...) error {
    ...
    if !isBIP0030Node(node) && (node.height < b.chainParams.BIP0034Height) {      
        err := b.checkBIP0030(node, block, view)      
        if err != nil {            
            return err      
        }
    }
    ...
}

Wherein isBIP0030Nodethe function code is as follows:

// checkConnectBlock [validate.go] -> isBIP0030Node
func isBIP0030Node(node *blockNode) bool {      
    if node.height == 91842 && node.hash.IsEqual(block91842Hash) {            
        return true      
    }      
    if node.height == 91880 && node.hash.IsEqual(block91880Hash) {            
        return true      
    }      
    return false
}

That is: for after a block (block 91842 and 91880) in the two incidents, omitted its BIP30examination.

In addition, by block browser Blockchair track two related addresses on 1GktTvnY8KGfAS72DhzGYJRyaQNvYrK9Fg and 16va6NxJrMGe5d2LP6wUzuVnzBBoKQZKom , we found that the two addresses after receiving the award twice mining, and did not use these incentives.

references

  1. TXID, https://learnmeabitcoin.com/guide/txid
  2. BIP-0030, https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki
  3. BIP-0034, https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki
  4. “Mastering Bitcoin 2nd”, Chapter 10, Soft Fork Signaling with Block Version, BIP-34 Signaling and Activation
Published 53 original articles · won praise 24 · views 100 000 +

Guess you like

Origin blog.csdn.net/u014633283/article/details/104759834