<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>An option would be that the height is included in the scriptSig for all transactions, but for non-coinbase transctions, the height used is zero.<br></div></div></div></div></blockquote></span><div>No need to add an extra field to the transaction just to include the height. We can just add a rule that the height specified in the scriptSig in coinbase transactions (and only coinbase transactions) is copied into the locktime of the transaction before computing the normalized transaction ID and leave the locktime untouched for all normal transactions</div></div></div></blockquote><div><br></div><div><div><span style="background-color:rgba(255,255,255,0)">No need to replace lock times (or any other part of the transaction) at all. If you have to, just serialize the height right before serializing the transaction (into the same buffer). And you could pre-serialize 0 instead of the height for all non-coinbase transactions. I don&#39;t really see what that gets you, though, because the 0 is not really doing anything.</span></div><div><span style="background-color:rgba(255,255,255,0)"><br></span></div><div><span style="background-color:rgba(255,255,255,0)">But, I don&#39;t see any reason you have to mess with the serialization this much at all. Just do:</span></div><div><span style="background-color:rgba(255,255,255,0)"><br></span></div><div><div><span style="background-color:rgba(255,255,255,0)"><font face="monospace, monospace">uint256 normalized_txid(CTransaction tx)</font></span></div><div><span style="background-color:rgba(255,255,255,0)"><font face="monospace, monospace">{</font></span></div><div><span style="font-family:monospace,monospace">  // Coinbase transactions are already normalized</span><span style="background-color:rgba(255,255,255,0)"><font face="monospace, monospace"><br></font></span></div><div><span style="background-color:rgba(255,255,255,0)"><font face="monospace, monospace">  if (!tx.IsCoinbase())</font></span></div><div><span style="background-color:rgba(255,255,255,0)"><font face="monospace, monospace">  {</font></span></div><div><span style="background-color:rgba(255,255,255,0)"><font face="monospace, monospace">    foreach(CTxIn in : tx.vin)</font></span></div><div><span style="background-color:rgba(255,255,255,0)"><font face="monospace, monospace">    {</font></span></div><div><span style="font-family:monospace,monospace">      if (!ReplacePrevoutHashWithNormalizedHash(in.prevout))</span></div><div><span style="font-family:monospace,monospace">        throw NormalizationError(&quot;Could not lookup prevout&quot;);</span></div><div><span style="font-family:monospace,monospace">      in.scriptSig.clear();</span></div><div><span style="font-family:monospace,monospace">    }</span><span style="background-color:rgba(255,255,255,0)"><font face="monospace, monospace"><br></font></span></div><div><span style="font-family:monospace,monospace">  }</span><span style="background-color:rgba(255,255,255,0)"><font face="monospace, monospace"><br></font></span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">  // Serialize</span></div><div><font face="monospace, monospace">  <span style="color:rgb(51,51,51);font-size:12px;line-height:16px;white-space:pre">CHashWriter </span><span class="" style="color:rgb(51,51,51);font-size:12px;line-height:16px;white-space:pre">ss</span><span style="color:rgb(51,51,51);font-size:12px;line-height:16px;white-space:pre">(SER_GETHASH, </span><span class="" style="color:rgb(0,134,179);font-size:12px;line-height:16px;white-space:pre">0</span><span style="color:rgb(51,51,51);font-size:12px;line-height:16px;white-space:pre">);</span></font></div><div><span style="font-family:monospace,monospace">  ss &lt;&lt; tx;</span><br></div><div><font face="monospace, monospace">  return ss.GetHash();</font></div><div><span style="background-color:rgba(255,255,255,0)"><font face="monospace, monospace">}</font></span></div></div></div><div><br></div><div>An alternative could be (although I like the above option better):</div><div><br></div><div><div><div><span style="background-color:rgba(255,255,255,0)"><font face="monospace, monospace">uint256 normalized_txid(CTransaction tx, int nHeight)</font></span></div></div><div><span style="background-color:rgba(255,255,255,0)"><font face="monospace, monospace">{</font></span></div><div><div><span style="background-color:rgba(255,255,255,0)"><font face="monospace, monospace">  foreach(CTxIn in : tx.vin)</font></span></div><div><span style="background-color:rgba(255,255,255,0)"><font face="monospace, monospace">  {</font></span></div><div><span style="font-family:monospace,monospace">    if (!in.prevout.IsNull() &amp;&amp; !ReplacePrevoutHashWithNormalizedHash(in.prevout))</span></div><div><span style="font-family:monospace,monospace">      throw NormalizationError(&quot;Could not lookup prevout&quot;);</span></div><div><span style="font-family:monospace,monospace">    in.scriptSig.clear();</span></div><div><span style="font-family:monospace,monospace">  }</span></div></div><div><span style="font-family:monospace,monospace"><br></span></div><div><div><span style="font-family:monospace,monospace">  // Serialize</span></div><div><font face="monospace, monospace">  <span style="color:rgb(51,51,51);font-size:12px;line-height:16px;white-space:pre">CHashWriter </span><span class="" style="color:rgb(51,51,51);font-size:12px;line-height:16px;white-space:pre">ss</span><span style="color:rgb(51,51,51);font-size:12px;line-height:16px;white-space:pre">(SER_GETHASH, </span><span class="" style="color:rgb(0,134,179);font-size:12px;line-height:16px;white-space:pre">0</span><span style="color:rgb(51,51,51);font-size:12px;line-height:16px;white-space:pre">);</span></font></div></div><div><font face="monospace, monospace"><span style="color:rgb(51,51,51);font-size:12px;line-height:16px;white-space:pre"><br></span></font></div><div><font face="monospace, monospace"><span style="color:rgb(51,51,51);font-size:12px;line-height:16px;white-space:pre">  if (tx.IsCoinbase())</span></font></div><div><font face="monospace, monospace"><span style="color:rgb(51,51,51);font-size:12px;line-height:16px;white-space:pre">    </span></font><span style="font-size:12px;line-height:16px;white-space:pre;color:rgb(51,51,51);font-family:monospace,monospace">ss &lt;&lt; nHeight;</span></div><div><span style="font-size:12px;line-height:16px;white-space:pre;color:rgb(51,51,51);font-family:monospace,monospace">  // or:</span></div><div><font color="#333333" face="monospace, monospace"><span style="font-size:12px;line-height:16px;white-space:pre">  // </span></font><span style="color:rgb(51,51,51);font-family:monospace,monospace;font-size:12px;line-height:16px;white-space:pre">ss &lt;&lt; (tx.IsCoinbase() ? nHeight : 0);</span></div><div><span style="color:rgb(51,51,51);font-family:monospace,monospace;font-size:12px;line-height:16px;white-space:pre"><br></span></div><div><span style="font-family:monospace,monospace">  ss &lt;&lt; tx;</span><br></div><div><font face="monospace, monospace">  return ss.GetHash();</font></div><div><span style="background-color:rgba(255,255,255,0)"><font face="monospace, monospace">}</font></span></div></div></div></div></div>