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 ) 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 ; 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: References: <5555C26F.7080706@sky-ip.org> Date: Tue, 19 May 2015 08:48:20 -0400 Message-ID: From: Stephen Morse To: Christian Decker 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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-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
<= 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">
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.
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
=

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.

But, I= don't see any reason you have to mess with the serialization this much= at all. Just do:

uint256 normalized_tx= id(CTransaction tx)
{
=C2=A0 // Coinbase= transactions are already normalized
=
=C2=A0 if (!tx.IsCoinbase())
<= div>=C2=A0 {
=C2=A0 =C2= =A0 foreach(CTxIn in : tx.vin)
=C2=A0= =C2=A0 {
=C2=A0 =C2=A0 =C2=A0 if (!ReplacePrevoutHashWithNormalizedHash(in.pr= evout))
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 throw NormalizationError("Could not lookup= prevout");
=C2=A0 =C2=A0 =C2=A0 in.scriptSig.clear();
=C2=A0 =C2=A0 }
=C2=A0 }

=C2=A0 // Serialize
=C2=A0=C2=A0CHashWriter ss(SER_GETHASH, = 0);
=C2=A0 ss << tx;
=C2=A0 return ss.GetHash();
}

An alternative c= ould be (although I like the above option better):

uint256 normalized_txid(CTransaction tx, int nHei= ght)
{
=
=C2=A0 foreach(CTxIn in : tx.vin)
=C2=A0 {
=C2=A0 =C2=A0 if (!in.prevout.IsNull() && !Re= placePrevoutHashWithNormalizedHash(in.prevout))
=C2=A0 =C2=A0 =C2=A0 throw Normalizat= ionError("Could not lookup prevout");
=C2=A0 =C2=A0 in.scriptSig.clear();
=C2=A0 }

=C2=A0= // Serialize
=C2=A0= =C2=A0CHashWriter ss(S= ER_GETHASH, 0);

if (tx.IsCoinb= ase())
ss << nHe= ight;
// or:
// ss << (tx.IsCoinbase() ? n= Height : 0);

=
=C2=A0 ss= << tx;
=C2= =A0 return ss.GetHash();
}
--001a113a0528a7e73505166eb90c--