Skip to content
This repository has been archived by the owner on Oct 9, 2019. It is now read-only.

Add opt-in transaction avoidance using well known P2SH address #127

Closed
wants to merge 5 commits into from
Closed

Add opt-in transaction avoidance using well known P2SH address #127

wants to merge 5 commits into from

Conversation

jcansdale
Copy link

@jcansdale jcansdale commented Sep 29, 2017

Based on #117 by @gavinandresen and @jgarzik.

Transactions may contain a marker output (txout) constructed as:
OP_HASH160 6e0b7d51f9f68ba28cc33a6844d41a1880c58a19 OP_EQUAL
This is a P2SH output with the vanity address:
3Bit1xA4apyzgmFNT2k8Pvnd6zb6TnwcTi.
To avoid indefinitely expanding the UTXO set, these outputs can be
spent by anyone using the intentionally concise scriptSig 03165c4d.

  1. All transactions containing this marker are considered non-standard,
    and not relayed or mined by default. They may appear in a block
    ("valid"), but the software will not do this by default. This is
    normal behavior for any valid-but-nonstandard transaction.

  2. After the BIP102 hard fork point (fSegwitSeasoned), transactions
    containing this marker are considered invalid. Blocks must not contain
    outputs to the 3Bit1xA4apyzgmFNT2k8Pvnd6zb6TnwcTi address.

jgarzik and others added 2 commits August 23, 2017 09:06
Based on a gist by @gavinandresen at https://gist.github.com/gavinandresen/2a7474a3dd5b834ed3a7d10c74ec84c5

Transactions may contain a marker, a transaction output (txout)
constructed as: OP_RETURN 'RP=!>1x'

1) All transactions containing this marker are considered non-standard,
and not relayed or mined by default. They may appear in a block
("valid"), but the software will not do this by default. This is
normal behavior for any valid-but-nonstandard transaction.

2) After the BIP102 hard fork point (fSegwitSeasoned), transactions
containing this marker are considered invalid. Blocks must not contain
transactions with a 'RP=!>1x' marker.
Transactions may contain a marker output (txout) constructed as:
`OP_HASH160 e77dfed888d33a87c2f48849f54dc55f4e63e7b4 OP_EQUAL`
This is a P2SH output with the vanity address:
`3No2xBD2uteCaTNGLpFkyoin4ctgeGMRLs`.
To avoid indefinitely expanding the UTXO set, these outputs can be
spent by anyone using the intentionally concise scriptSig `03165c4d`.

1) All transactions containing this marker are considered non-standard,
and not relayed or mined by default. They may appear in a block
("valid"), but the software will not do this by default. This is
normal behavior for any valid-but-nonstandard transaction.

2) After the BIP102 hard fork point (fSegwitSeasoned), transactions
containing this marker are considered invalid. Blocks must not contain
outputs to the `3No2xBD2uteCaTNGLpFkyoin4ctgeGMRLs` address.
@jcansdale
Copy link
Author

jcansdale commented Sep 29, 2017

Here's an example replay protected tx that outputs the minim 2730 satoshi amount for a standard transaction.

{
  "hash": "5ef96f4831c2ff41867670cf40152326eaa12116d15350a912fbde2a8319cbef",
  "ver": 1,
  "vin_sz": 0,
  "vout_sz": 1,
  "lock_time": 0,
  "size": 42,
  "in": [],
  "out": [
    {
      "value": "0.00002730",
      "scriptPubKey": "OP_HASH160 e77dfed888d33a87c2f48849f54dc55f4e63e7b4 OP_EQUAL"
    }
  ]
}

Here's an example tx that redeems one of these replay protected outputs:

{
  "hash": "9e6d108ac28e747217669ef0e4b0e5b7b4c33814595b96dc2d49d6eb5f79f979",
  "ver": 1,
  "vin_sz": 1,
  "vout_sz": 0,
  "lock_time": 0,
  "size": 56,
  "in": [
    {
      "prev_out": {
        "hash": "5ef96f4831c2ff41867670cf40152326eaa12116d15350a912fbde2a8319cbef",
        "n": 0
      },
      "scriptSig": "03165c4d"
    }
  ],
  "out": []
}

This transaction is 56 bytes and looks like:
0100000001efcb19832adefb12a95053d11621a1ea26231540cf70768641ffc231486ff95e00000000050403165c4dffffffff0000000000

In this case all output is being spent as a fee, which comes out as 2730 / 56 = 48 (satoshi / byte). It would be in the economic interest of miners to sweep up these outputs individually when fee levels are below 48 satoshi / byte. Users could consume these outputs and receive free (or better) replay protection. These outputs won't remain in the UTXO set for long. 😉

UPDATE: The proposal has been changed to use the following:

scriptAddress: 3Bit1xA4apyzgmFNT2k8Pvnd6zb6TnwcTi
scriptSig: 04148f33be
scriptPubKey: OP_HASH160 6e0b7d51f9f68ba28cc33a6844d41a1880c58a19 OP_EQUAL

@Sjors
Copy link

Sjors commented Sep 30, 2017

This might result in phishers publishing tutorials, but with a visually similar address. They would then promote those using google adwords. Google is notoriously lazy in removing those. Even legit tutorial authors might find their blog hacked. I think it's safer to build replay protection into wallets using a method that's non-trivial for a normal users to do manually.

@Sjors
Copy link

Sjors commented Sep 30, 2017

Can you clarify (1): do you mean such a transaction is non-standard for btc1 nodes?

@jcansdale
Copy link
Author

jcansdale commented Sep 30, 2017

@Sjors,

This might result in phishers publishing tutorials, but with a visually similar address.

The prefix is meant only as a partial mitigation for copy-paste errors. Building replay protection into wallets would be better, but realistically (if Bitcoin Cash is anything to go by) this is going to take a while.

Doing it this way makes it non-scary for anyone with a little bitcoin experience:

  1. Sending BTC to an address they own
  2. Sending 0.00002730 BTC to a special address

Can you clarify (1): do you mean such a transaction is non-standard for btc1 nodes?

Such a transaction would be non-standard before the fork and invalid after the fork. Perhaps it should simply be non-standard and invalid after the fork? Perhaps @jgarzik could comment.

The `3No2x` prefix only makes sense for explicitly Segwit2x supporting nodes.
There are other nodes that support larger blocks that will follow the 2x mined chain.
Change to a more neutral `3Bit1x` prefix that also makes sense for them.
@prusnak
Copy link

prusnak commented Oct 1, 2017

Opt-in replay protection is not enough as it does not prevent transaction from being included in the block. And with malicious behavior of miners we see today (triggering EDA on Bitcoin Cash by not mining, then mining blocks as fast as possible with lowered difficulty), they cannot be trusted not to include these transactions in their blocks.

@jgarzik
Copy link

jgarzik commented Oct 1, 2017

@prusnak Read the code - it prevents the transaction from being included in a block.

@JaredR26
Copy link

JaredR26 commented Oct 1, 2017

I like the concept and the approaches. I don't personally see anything wrong with providing multiple methods, even if the methods make eachother redundant, which is something I have seen suggested elsewhere. Also I like the more neutral addresses you found like 3Bit1x...

All of the approaches that invalidate a transaction on 2x need to have a sunset clause. I suggest 18-24 months out based on blockheight.

@jcansdale
Copy link
Author

jcansdale commented Oct 1, 2017

@JaredR26,

All of the ones that invalidate a transaction need to have a sunset clause. I suggest 18-24 months out based on blockheight.

I'm definitely in favor of a sunset clause. If this rule turns out still to be necessary, we can easily soft-fork it back in. That's a lot better than committing to this added complexity forever.

Since this form of replay protection doesn't require any special software and can easily be done by the user, my preference would be to have a sunset date that is easily described and meaningful.

The next halving happens on block 630000 (roughly 15 Jun 2020). This is something that would be memorable to many bitcoin users and easy to describe. We can take a view before this date arrives whether there are better options available (OP_CHECKBLOCKATHEIGHT maybe) or if this rule should be renewed.

@jcansdale
Copy link
Author

Also I like the more neutral addresses you found like 3Bit1x...

I've updated this PR to use the following:

scriptAddress: 3Bit1xA4apyzgmFNT2k8Pvnd6zb6TnwcTi
scriptSig: 04148f33be
scriptPubKey: OP_HASH160 6e0b7d51f9f68ba28cc33a6844d41a1880c58a19 OP_EQUAL

The TestNet version of this address 2N3H65h66CHVLtYsv8AN11smtKLoGFvJymb. To spend, simply use the scriptSig 04148f33be.

@jgarzik
Copy link

jgarzik commented Oct 4, 2017

Manually merged into segwit2x-dev as a3c4125

@apoelstra
Copy link

There is already user confusion about this:
https://www.reddit.com/r/Bitcoin/comments/745jlm/segwit2x_merges_in_optin_transaction_replay/dnvwiim/?context=3

It is important that users understand that spending to this address before the split doesn't do anything; and that spending to the address after the split will not protect their entire wallet unless they spend all of their coins at once.

@Sjors
Copy link

Sjors commented Oct 4, 2017

@jgarzik how does BitcoinUnlimited/BitcoinUnlimited#790 (which only uses non-standardness) to your manual merge in a3c4125 (which also makes the transaction invalid)?

Update: never mind, that was a PR for BU, not for btc1.

jcansdale referenced this pull request Oct 5, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants