Received: from sog-mx-2.v43.ch3.sourceforge.com ([172.29.43.192] helo=mx.sourceforge.net) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from <stephencalebmorse@gmail.com>) id 1Yugwd-0002v7-UC for bitcoin-development@lists.sourceforge.net; Tue, 19 May 2015 12:48:27 +0000 Received-SPF: pass (sog-mx-2.v43.ch3.sourceforge.com: domain of gmail.com designates 209.85.160.173 as permitted sender) client-ip=209.85.160.173; envelope-from=stephencalebmorse@gmail.com; helo=mail-yk0-f173.google.com; Received: from mail-yk0-f173.google.com ([209.85.160.173]) by sog-mx-2.v43.ch3.sourceforge.com with esmtps (TLSv1:RC4-SHA:128) (Exim 4.76) id 1Yugwc-0003BR-0q for bitcoin-development@lists.sourceforge.net; Tue, 19 May 2015 12:48:27 +0000 Received: by ykeo186 with SMTP id o186so4815306yke.0 for <bitcoin-development@lists.sourceforge.net>; Tue, 19 May 2015 05:48:20 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.170.89.5 with SMTP id g5mr30103078yka.30.1432039700553; Tue, 19 May 2015 05:48:20 -0700 (PDT) Received: by 10.13.245.70 with HTTP; Tue, 19 May 2015 05:48:20 -0700 (PDT) In-Reply-To: <CALxbBHUvtoc25Eyh1KF=bmG8SbZd_UpO1QeUVLbicNqJQPHBLQ@mail.gmail.com> References: <CALxbBHUnt7ToVK9reH6W6uT4HV=7NbxGHyNWWa-OEHg+Z1+qOg@mail.gmail.com> <5555C26F.7080706@sky-ip.org> <AC0B3BAC-0934-46A3-B29A-F74238616F72@gmail.com> <CALxbBHXC=jc+7Vj-3-VT7kj-+V6ORdeJPr_G9ymOcJyFZ3hy=A@mail.gmail.com> <CAE-z3OXC-uCYQmhGJd2ZVfLrEbAZVhEz0ejkbwmcRgK3kbjSrg@mail.gmail.com> <CALxbBHUvtoc25Eyh1KF=bmG8SbZd_UpO1QeUVLbicNqJQPHBLQ@mail.gmail.com> Date: Tue, 19 May 2015 08:48:20 -0400 Message-ID: <CABHVRKSSCX8VS=T-bim_rw6VMJP-hnUi8AzLHyDM57KQi2zn+w@mail.gmail.com> From: Stephen Morse <stephencalebmorse@gmail.com> To: Christian Decker <decker.christian@gmail.com> Content-Type: multipart/alternative; boundary=001a113a0528a7e73505166eb90c X-Spam-Score: -0.6 (/) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for sender-domain 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (stephencalebmorse[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record 1.0 HTML_MESSAGE BODY: HTML included in message -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-Headers-End: 1Yugwc-0003BR-0q Cc: Bitcoin Development <bitcoin-development@lists.sourceforge.net> Subject: Re: [Bitcoin-development] [BIP] Normalized Transaction IDs X-BeenThere: bitcoin-development@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: <bitcoin-development.lists.sourceforge.net> List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/bitcoin-development>, <mailto:bitcoin-development-request@lists.sourceforge.net?subject=unsubscribe> List-Archive: <http://sourceforge.net/mailarchive/forum.php?forum_name=bitcoin-development> List-Post: <mailto:bitcoin-development@lists.sourceforge.net> List-Help: <mailto:bitcoin-development-request@lists.sourceforge.net?subject=help> List-Subscribe: <https://lists.sourceforge.net/lists/listinfo/bitcoin-development>, <mailto:bitcoin-development-request@lists.sourceforge.net?subject=subscribe> X-List-Received-Date: Tue, 19 May 2015 12:48:28 -0000 --001a113a0528a7e73505166eb90c Content-Type: text/plain; charset=UTF-8 > > 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. >> > 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 > 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't really see what that gets you, though, because the 0 is not really doing anything. But, I don't see any reason you have to mess with the serialization this much at all. Just do: uint256 normalized_txid(CTransaction tx) { // Coinbase transactions are already normalized if (!tx.IsCoinbase()) { foreach(CTxIn in : tx.vin) { if (!ReplacePrevoutHashWithNormalizedHash(in.prevout)) throw NormalizationError("Could not lookup prevout"); in.scriptSig.clear(); } } // Serialize CHashWriter ss(SER_GETHASH, 0); ss << tx; return ss.GetHash(); } An alternative could be (although I like the above option better): uint256 normalized_txid(CTransaction tx, int nHeight) { foreach(CTxIn in : tx.vin) { if (!in.prevout.IsNull() && !ReplacePrevoutHashWithNormalizedHash(in.prevout)) throw NormalizationError("Could not lookup prevout"); in.scriptSig.clear(); } // Serialize CHashWriter ss(SER_GETHASH, 0); if (tx.IsCoinbase()) ss << nHeight; // or: // ss << (tx.IsCoinbase() ? nHeight : 0); ss << tx; return ss.GetHash(); } --001a113a0528a7e73505166eb90c Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><blo= ckquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left= -width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;paddi= ng-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><span class=3D""><= blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l= eft-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;pa= dding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"g= mail_quote"><div>An option would be that the height is included in the scri= ptSig for all transactions, but for non-coinbase transctions, the height us= ed 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 ju= st add a rule that the height specified in the scriptSig in coinbase transa= ctions (and only coinbase transactions) is copied into the locktime of the = transaction before computing the normalized transaction ID and leave the lo= cktime untouched for all normal transactions</div></div></div></blockquote>= <div><br></div><div><div><span style=3D"background-color:rgba(255,255,255,0= )">No need to replace=C2=A0lock times (or any other part of the transaction= ) at all. If you have to, just serialize the height right before serializin= g the transaction (into the same buffer). And you could pre-serialize 0 ins= tead of the height for all non-coinbase transactions. I don't really se= e what that gets you, though, because the 0 is not really doing anything.</= span></div><div><span style=3D"background-color:rgba(255,255,255,0)"><br></= span></div><div><span style=3D"background-color:rgba(255,255,255,0)">But, I= don't see any reason you have to mess with the serialization this much= at all. Just do:</span></div><div><span style=3D"background-color:rgba(255= ,255,255,0)"><br></span></div><div><div><span style=3D"background-color:rgb= a(255,255,255,0)"><font face=3D"monospace, monospace">uint256 normalized_tx= id(CTransaction tx)</font></span></div><div><span style=3D"background-color= :rgba(255,255,255,0)"><font face=3D"monospace, monospace">{</font></span></= div><div><span style=3D"font-family:monospace,monospace">=C2=A0 // Coinbase= transactions are already normalized</span><span style=3D"background-color:= rgba(255,255,255,0)"><font face=3D"monospace, monospace"><br></font></span>= </div><div><span style=3D"background-color:rgba(255,255,255,0)"><font face= =3D"monospace, monospace">=C2=A0 if (!tx.IsCoinbase())</font></span></div><= div><span style=3D"background-color:rgba(255,255,255,0)"><font face=3D"mono= space, monospace">=C2=A0 {</font></span></div><div><span style=3D"backgroun= d-color:rgba(255,255,255,0)"><font face=3D"monospace, monospace">=C2=A0 =C2= =A0 foreach(CTxIn in : tx.vin)</font></span></div><div><span style=3D"backg= round-color:rgba(255,255,255,0)"><font face=3D"monospace, monospace">=C2=A0= =C2=A0 {</font></span></div><div><span style=3D"font-family:monospace,mono= space">=C2=A0 =C2=A0 =C2=A0 if (!ReplacePrevoutHashWithNormalizedHash(in.pr= evout))</span></div><div><span style=3D"font-family:monospace,monospace">= =C2=A0 =C2=A0 =C2=A0 =C2=A0 throw NormalizationError("Could not lookup= prevout");</span></div><div><span style=3D"font-family:monospace,mono= space">=C2=A0 =C2=A0 =C2=A0 in.scriptSig.clear();</span></div><div><span st= yle=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 }</span><span style= =3D"background-color:rgba(255,255,255,0)"><font face=3D"monospace, monospac= e"><br></font></span></div><div><span style=3D"font-family:monospace,monosp= ace">=C2=A0 }</span><span style=3D"background-color:rgba(255,255,255,0)"><f= ont face=3D"monospace, monospace"><br></font></span></div><div><span style= =3D"font-family:monospace,monospace"><br></span></div><div><span style=3D"f= ont-family:monospace,monospace">=C2=A0 // Serialize</span></div><div><font = face=3D"monospace, monospace">=C2=A0=C2=A0<span style=3D"color:rgb(51,51,51= );font-size:12px;line-height:16px;white-space:pre">CHashWriter </span><span= class=3D"" style=3D"color:rgb(51,51,51);font-size:12px;line-height:16px;wh= ite-space:pre">ss</span><span style=3D"color:rgb(51,51,51);font-size:12px;l= ine-height:16px;white-space:pre">(SER_GETHASH, </span><span class=3D"" styl= e=3D"color:rgb(0,134,179);font-size:12px;line-height:16px;white-space:pre">= 0</span><span style=3D"color:rgb(51,51,51);font-size:12px;line-height:16px;= white-space:pre">);</span></font></div><div><span style=3D"font-family:mono= space,monospace">=C2=A0 ss << tx;</span><br></div><div><font face=3D"= monospace, monospace">=C2=A0 return ss.GetHash();</font></div><div><span st= yle=3D"background-color:rgba(255,255,255,0)"><font face=3D"monospace, monos= pace">}</font></span></div></div></div><div><br></div><div>An alternative c= ould be (although I like the above option better):</div><div><br></div><div= ><div><div><span style=3D"background-color:rgba(255,255,255,0)"><font face= =3D"monospace, monospace">uint256 normalized_txid(CTransaction tx, int nHei= ght)</font></span></div></div><div><span style=3D"background-color:rgba(255= ,255,255,0)"><font face=3D"monospace, monospace">{</font></span></div><div>= <div><span style=3D"background-color:rgba(255,255,255,0)"><font face=3D"mon= ospace, monospace">=C2=A0 foreach(CTxIn in : tx.vin)</font></span></div><di= v><span style=3D"background-color:rgba(255,255,255,0)"><font face=3D"monosp= ace, monospace">=C2=A0 {</font></span></div><div><span style=3D"font-family= :monospace,monospace">=C2=A0 =C2=A0 if (!in.prevout.IsNull() && !Re= placePrevoutHashWithNormalizedHash(in.prevout))</span></div><div><span styl= e=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 =C2=A0 throw Normalizat= ionError("Could not lookup prevout");</span></div><div><span styl= e=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 in.scriptSig.clear();</= span></div><div><span style=3D"font-family:monospace,monospace">=C2=A0 }</s= pan></div></div><div><span style=3D"font-family:monospace,monospace"><br></= span></div><div><div><span style=3D"font-family:monospace,monospace">=C2=A0= // Serialize</span></div><div><font face=3D"monospace, monospace">=C2=A0= =C2=A0<span style=3D"color:rgb(51,51,51);font-size:12px;line-height:16px;wh= ite-space:pre">CHashWriter </span><span class=3D"" style=3D"color:rgb(51,51= ,51);font-size:12px;line-height:16px;white-space:pre">ss</span><span style= =3D"color:rgb(51,51,51);font-size:12px;line-height:16px;white-space:pre">(S= ER_GETHASH, </span><span class=3D"" style=3D"color:rgb(0,134,179);font-size= :12px;line-height:16px;white-space:pre">0</span><span style=3D"color:rgb(51= ,51,51);font-size:12px;line-height:16px;white-space:pre">);</span></font></= div></div><div><font face=3D"monospace, monospace"><span style=3D"color:rgb= (51,51,51);font-size:12px;line-height:16px;white-space:pre"><br></span></fo= nt></div><div><font face=3D"monospace, monospace"><span style=3D"color:rgb(= 51,51,51);font-size:12px;line-height:16px;white-space:pre"> if (tx.IsCoinb= ase())</span></font></div><div><font face=3D"monospace, monospace"><span st= yle=3D"color:rgb(51,51,51);font-size:12px;line-height:16px;white-space:pre"= > </span></font><span style=3D"font-size:12px;line-height:16px;white-spa= ce:pre;color:rgb(51,51,51);font-family:monospace,monospace">ss << nHe= ight;</span></div><div><span style=3D"font-size:12px;line-height:16px;white= -space:pre;color:rgb(51,51,51);font-family:monospace,monospace"> // or:</s= pan></div><div><font color=3D"#333333" face=3D"monospace, monospace"><span = style=3D"font-size:12px;line-height:16px;white-space:pre"> // </span></fon= t><span style=3D"color:rgb(51,51,51);font-family:monospace,monospace;font-s= ize:12px;line-height:16px;white-space:pre">ss << (tx.IsCoinbase() ? n= Height : 0);</span></div><div><span style=3D"color:rgb(51,51,51);font-famil= y:monospace,monospace;font-size:12px;line-height:16px;white-space:pre"><br>= </span></div><div><span style=3D"font-family:monospace,monospace">=C2=A0 ss= << tx;</span><br></div><div><font face=3D"monospace, monospace">=C2= =A0 return ss.GetHash();</font></div><div><span style=3D"background-color:r= gba(255,255,255,0)"><font face=3D"monospace, monospace">}</font></span></di= v></div></div></div></div> --001a113a0528a7e73505166eb90c--