<div dir="auto">Thanks Mats, this proposal makes sense to me (especially the idea of fork-specific addresses).  It prevents replay across forks, and makes it easy for client software, and thus potentially users, to specify which fork a tx is for.  But, like other (rougher) past proposals I&#39;ve seen, it does little to prevent users from accidentally sending on the wrong fork.<div dir="auto"><br></div><div dir="auto">Take the specific and common case of non-upgraded wallet software.  Suppose a HF happens, and becomes the network used by 90% of users.  Will old wallets still default to the old nForkId (10% legacy chain)?  If so, I&#39;d expect a lot of accidental mis-sends on that chain.</div><div dir="auto"><br></div><div dir="auto">This is just a gap in your proposal, not a flaw, but it&#39;s worth thinking about less hazard-prone ways wallets could default nForkId.  Perhaps they could listen to all forks, and default to the one whose last (recent) block had the highest difficulty?  Or just check those blocks to see if multiple forks are (nontrivially) active, and if so warn the user and force them to confirm?  Something like that.</div><div dir="auto"><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Nov 6, 2017 7:05 AM, &quot;Mats Jerratsch via bitcoin-dev&quot; &lt;<a href="mailto:bitcoin-dev@lists.linuxfoundation.org">bitcoin-dev@lists.linuxfoundation.org</a>&gt; wrote:<br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br>
<div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Presented is a generalised way of providing replay protection for future hard forks. On top of replay protection, this schema also allows for fork-distinct addresses and potentially a way to opt-out of replay protection of any fork, where deemed necessary (can be beneficial for some L2 applications).</span></div><br><div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">## Rationale</span></div><br><div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Currently when a hard fork happens, there is ad-hoc replay protection built within days with little review at best, or no replay protection at all. Often this is either resource problem, where not enough time and developers are available to sufficiently address replay protection, or the idea that not breaking compatibility is favourable. Furthermore, this is potentially a recurring problem with no generally accepted solution yet. Services that want to deal in multiple forks are expected to closely follow all projects. Since there is no standard, the solutions differ for each project, requiring custom code for every fork. By integrating replay protection into the protocol, we advocate the notion of non-hostile forks.</span></div><br><div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Users are protected against accidentally sending coins on the wrong chain through the introduction of a fork-specific incompatible address space. The coin/token type is encoded in the address itself, removing some of the importance around the question _What is Bitcoin?_. By giving someone an address, it is explicitly stated _I will only honour a payment of token X_, enforcing the idea of validating the payment under the rules chosen by the payee. </span></div><br><div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">## Iterative Forks</span></div><br><div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">In this schema, any hard fork is given an incremented id, `nForkId`. `nForkId` starts at `1`, with `0` being reserved as a wildcard. When project X decides to make an incompatible change to the protocol, it will get assigned a new unique `nForkId` for this fork. A similar approach like for BIP43 can be taken here. Potentially `nForkId` can be reused if a project has not gained any amount of traction.</span></div><br><div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">When preparing the transaction for signing or validation, `nForkId` is appended to the final template as a 4B integer (similar to [1]). Amending BIP143, this would result in</span></div><br><div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">```</span></div><div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> Double SHA256 of the serialization of:</span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><br class="m_-4918941644665611799kix-line-break"></span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">     1. nVersion of the transaction (4-byte little endian)</span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><br class="m_-4918941644665611799kix-line-break"></span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">     2. hashPrevouts (32-byte hash)</span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><br class="m_-4918941644665611799kix-line-break"></span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">     3. hashSequence (32-byte hash)</span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><br class="m_-4918941644665611799kix-line-break"></span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">     4. outpoint (32-byte hash + 4-byte little endian) </span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><br class="m_-4918941644665611799kix-line-break"></span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">     5. scriptCode of the input (serialized as scripts inside CTxOuts)</span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><br class="m_-4918941644665611799kix-line-break"></span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">     6. value of the output spent by this input (8-byte little endian)</span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><br class="m_-4918941644665611799kix-line-break"></span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">     7. nSequence of the input (4-byte little endian)</span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><br class="m_-4918941644665611799kix-line-break"></span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">     8. hashOutputs (32-byte hash)</span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><br class="m_-4918941644665611799kix-line-break"></span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">     9. nLocktime of the transaction (4-byte little endian)</span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><br class="m_-4918941644665611799kix-line-break"></span><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">    10. sighash type of the signature (4-byte little endian)</span></div><div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">    </span><span style="font-size:11pt;font-family:Arial;font-style:italic;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">11. nForkId (4-byte little endian)</span></div><div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">```</span></div><br><br><div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">For `nForkId=0` this step is ommitted. This will immediately invalidate signatures for any other branch of the blockchain than this specific fork. To distinguish between `nForkId=0` and `nForkId` hardcoded into the software, another bit has to be set in the 1B SigHashId present at the end of signatures. </span></div><br><div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">To make this approach more generic, payment addresses will contain the fork id, depending on which tokens a payee expects payments in. This would require a change on bech32 addresses, maybe to use a similar format used in lightning-rfc [2]. A wallet will parse the address, it will extract `nForkId`, and it displays which token the user is about to spend. When signing the transaction, it will use `nForkId`, such that the transaction is only valid for this specific token. This can be generalised in software to the point where replay protection *and* a new address space can be introduced for forks without breaking existing clients. </span></div><br><div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">For light clients, this can be extended by enforcing the coinbase/block header to contain the `nForkId` of the block. Then the client can distinguish between different chains and tokens it received on each. Alternatively, a new P2P message type for sending transactions could be introduced, where prevOut and `nForkId` is transmitted, such that the lite client can check for himself, which token he received. </span></div><br><div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Allowing signatures with `nForkId=1` can be achieved with a soft fork by incrementing the script version of SegWit, making this a fully backwards compatible change. </span></div><br><div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">[1]</span></div><div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><a href="https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-February/013542.html" target="_blank">https://lists.linuxfoundation.<wbr>org/pipermail/bitcoin-dev/<wbr>2017-February/013542.html</a></span></div><br><div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">[2]</span></div><div style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;font-variant-ligatures:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><a href="https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md" target="_blank">https://github.com/<wbr>lightningnetwork/lightning-<wbr>rfc/blob/master/11-payment-<wbr>encoding.md</a></span></div></div><br>______________________________<wbr>_________________<br>
bitcoin-dev mailing list<br>
<a href="mailto:bitcoin-dev@lists.linuxfoundation.org">bitcoin-dev@lists.<wbr>linuxfoundation.org</a><br>
<a href="https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev" rel="noreferrer" target="_blank">https://lists.linuxfoundation.<wbr>org/mailman/listinfo/bitcoin-<wbr>dev</a><br>
<br></blockquote></div><br></div>