<div dir="ltr"><div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div>Sorry, I was careless with the use of `&gt;=` there. You are correct, forks form a tree. For this proposal, every leaf must be assigned a unique `nForkId`. The relationship between `nForkId` is irrelevant (e.g. which number is bigger), as long as they are unique. Transactions are only valid IFF `nForkId` matches exactly the `nForkId` of the software validating it. As described above, the transaction doesn&#39;t even contain `nForkId`, and the node surely is not starting to guess which one it could be. </div></div></blockquote></div></div><div><br></div><div>OK, but then it seems to me you have a dilemma for, eg, your LN commitment tx.  You either give it the specific nForkId of the fork it&#39;s created on - making it invalid on <i>all</i> other forks (eg, any future &quot;non-contentious upgrade&quot; HF that replaces that fork).  Or you give it nForkId 0 - which has the &quot;BCH tx valid on Segwit2x (&amp; vice versa)&quot; flaw.</div><div><br></div><div>It may make sense to revise your proposal to incorporate Luke&#39;s <a href="https://github.com/bitcoin/bips/blob/master/bip-0115.mediawiki">OP_CHECKBLOCKATHEIGHT</a>, and make the fork ID a (block height, hash) pair rather than just a number.  But I still think the idea of fork-specific addresses is a keeper!</div><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Nov 14, 2017 at 8:49 AM, Mats Jerratsch <span dir="ltr">&lt;<a href="mailto:mats@blockchain.com" target="_blank">mats@blockchain.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><span class="gmail-"><br><blockquote type="cite"><div><div dir="auto"><div dir="auto">But I like the &#39;old&#39; idea of putting the hash of a block that MUST be on the chain that this txn can eventually be added to. If the hash is not a valid block on the chain, the txn can&#39;t be added.<br></div><div dir="auto"><br></div><div dir="auto">It means you can choose exactly which forks you want to allow your txn on, pre-fork for both, post-fork for only one, and gets round the issue of who gets to decide the nForkid value.. since you don&#39;t need one. Also, all the old outputs work fine, and LN not an issue.</div><div dir="auto"><br></div><div dir="auto">I&#39;m missing why this scheme would be better ?<br></div></div></div></blockquote><div><br></div></span><div>I do agree that solutions like `SIGHASH_BLOCKCOMMIT` are superior in the sense that they are very difficult to circumvent. However, a fork could also follow the original chain in SPV mode and allow transactions protected with these mechanism. Since it&#39;s fundamentally impossible to disallow transactions in future projects, the goal shouldn&#39;t be to make this overly complicated. </div><div><br></div><div>Furthermore, this schema is not just adding replay protection. It makes transacting safer overall (due to a dedicated address format per fork) and allows light clients to differentiate between multiple forks. In the past three months, at least $600k has been lost by users sending BCH to a BTC address [1].</div><span class="gmail-"><div><br></div><blockquote type="cite"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Thanks for the clarification.  How would a tx specify a constraint like &quot;nForkId&gt;=1&quot;?  I was thinking of it just as a number set on the tx.</div></blockquote></div></div></blockquote><div><br></div></span><div>Whether the transaction is replay protected or not is specified by setting a bit in the `SigHashId`. If this bit is set, then the signature *preimage* MUST have `nForkId` appended. `nForkId` is not part of the final transaction, someone who wants to verify the transaction must know which `nForkId` it was created with. </div><div><br></div><div>If the bit isn&#39;t set, it means `nForkId=0`, which allows other forks to validate the signature.</div><span class="gmail-"><div><br></div><blockquote type="cite"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Also note that since forks form a partial order, but IDs (numbers) form a total order, &quot;&gt;=&quot; will miss some cases.  Eg, suppose BCH had forked with nForkId 2, and then you set up a LN funding tx on BCH with nForkId&gt;=2, and then Segwit2x forked (from BTC!) with nForkId 3.  The BCH funding tx would be valid on Segwit2x.  This is more of a fundamental problem than a bug - to avoid it you&#39;d have to get into stuff like making each fork reference its parent-fork&#39;s first block or something, someone has written about this...<br></div></div></blockquote></div></div></blockquote><div><br></div></span><div>Sorry, I was careless with the use of `&gt;=` there. You are correct, forks form a tree. For this proposal, every leaf must be assigned a unique `nForkId`. The relationship between `nForkId` is irrelevant (e.g. which number is bigger), as long as they are unique. Transactions are only valid IFF `nForkId` matches exactly the `nForkId` of the software validating it. As described above, the transaction doesn&#39;t even contain `nForkId`, and the node surely is not starting to guess which one it could be. </div></div><br><div>[1]</div><div><a href="https://twitter.com/khannib/status/930223617744437253" target="_blank">https://twitter.com/khannib/<wbr>status/930223617744437253</a></div></div></blockquote></div><br></div></div>