Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: jl2012 on October 03, 2012, 04:45:45 AM



Title: Transaction script with block height as condition
Post by: jl2012 on October 03, 2012, 04:45:45 AM
I wonder if a transaction script like this would be allowed: If block height < x, use condition A; if block height >= x, use condition B

This could be very useful as trust-free, zero-confirmation exchange wallet

Assuming the exchange owns private key E, the user owns private key U, and x is the block height of near future (e.g. current block height + 10000), a transaction script would look like this: If block height < x, 2-by-2 multisig with E and U is required; if block height >= x, U is required. A script hash is derived

The user will comfortably send any amount of coins to this script hash. If private key E was compromised, no fund could be stolen. Even if the exchange operator disappeared (like Torwallet), the user could get the coins back after block x.

If the user wants to sell the coins before block x, he will sign a multisig transaction to send the coins to the address of key E (or any other addresses exclusively owned by the exchange). Since it is bound by the multisig requirement before block x, the user is not possible to double spend. Therefore, the BTC is readily available for trading with zero-confirmation.

To avoid the risk of double spend or Finney Attack, the multisig transaction should be signed by the user well before block x is generated, e.g. x - 10. After that, the exchange will not accept it by zero-confirmation. However, it will still accept it after 6 confirmations.

This also works for online wallet providers, stock market, marketplace, or Bitcoinica-type services. It won't totally eliminate the risk, but people could then deposit a large amount of BTC to these services and spend instantly at any time.

EDIT: For a bitcoin buyer, the exchange will send the freshly bought coins to the his script hash. Therefore, the buyer is also protected, while he could also sell the coins instantly.


Title: Re: Transaction script with block height as condition
Post by: kjj on October 04, 2012, 04:47:54 PM
As far as transactions are concerned, there are no blocks, there is no chain, there is no height.  This is not an accident or an oversight.  Please search next time.


Title: Re: Transaction script with block height as condition
Post by: jl2012 on October 04, 2012, 05:25:06 PM
As far as transactions are concerned, there are no blocks, there is no chain, there is no height.  This is not an accident or an oversight.  Please search next time.

I think you totally misunderstand my proposal.

Let me explain this way: A user does not fully trust the exchange but he wants to sell his BTC through the exchange. He wants to transfer the BTC to the exchange at the last minute before he sells. However, the exchange requires 6 confirmations to prevent double-spending.

One way to do this is to have a 2-by-2 multisig account, which the exchange owns one of the keys (E), and the user owns the other key (U). The user will send his BTC to this multisig account. When the user wants to sell the BTC later, he sign a transaction by U to send the BTC in the multisig account to an account owned by the exchange exclusively. The exchange will complete the transaction by signing it with E. Since the user is not possible to double-spend, the exchange can accept it with zero confirmation and the user can sell his BTC immediately.

However, if the exchange is completely disappeared, the BTC in the multi-sig accounts will be lost forever. Therefore, we need some "emergency exit mechanism". When the multisig account is setting up, an additional condition is added: (e.g.) "After 1 Jan 2013, the coins in this account can be spent by signature of key U only". That means in the worst case, if the exchange fails tomorrow, the user can get his coins back after 1 Jan 2013.

Of course, in bitcoin world, time is measured by block height, not days. So the condition becomes "after block height > 220000, the coins in this account can be spent by signature of key U only". If the user tries to spend the coins today (block height = 201800) without involving the exchange, the transaction is considered invalid.

And the following notice explains why we need this system:

Quote
GLBSE is offline

For those worried about their bitcoin, please calm yourselves there has been no hack and your coins are safe and all accounted for.

I apologize for the lack of notice and the downtime, but there isn't much choice. We will update our users on Saturday.


Title: Re: Transaction script with block height as condition
Post by: Pieter Wuille on October 04, 2012, 05:43:37 PM
Transactions actually do have a rarely-used feature called nLocktime. It can be used to specify the block height or UNIX timestamp after which the transaction is allowed to become stored in the block chain.


Title: Re: Transaction script with block height as condition
Post by: kjj on October 04, 2012, 06:18:44 PM
I think you totally misunderstand my proposal.

No, I got it, I understand what you are saying.  You want a script that knows what time it is (or some proxy for time), and can be valid or not valid based on that time.  It is a bad idea, and there are a whole bunch of threads that explain how and why it is a bad idea.  Don't take it personally, it is a very popular idea, but still a bad one.  :)

And the following notice explains why we need this system:

Quote
GLBSE is offline

Your scheme probably won't help here.  If the recipient was hit by a bus, you might have a way to recall the transaction.  But if the recipient is planning to steal your money, they'll redeem the transaction first, making this pointless.

As Pieter points out, there are tools (nLockTime and P2SH) that will eventually be used to accomplish basically the same end goals, and they don't involve adding the idea of time to the script system.


Title: Re: Transaction script with block height as condition
Post by: Gavin Andresen on October 04, 2012, 07:02:44 PM
However, if the exchange is completely disappeared, the BTC in the multi-sig accounts will be lost forever. Therefore, we need some "emergency exit mechanism". When the multisig account is setting up, an additional condition is added: (e.g.) "After 1 Jan 2013, the coins in this account can be spent by signature of key U only".

If you held a pre-signed transaction that sends the funds back to you with a lockTime of 1 Jan 2013 that would work.

Lets see... thinking out loud...

Start by asking the exchange for a brand-new public key to use for their half of the 2-of-2 transaction. Call the send-coins-into-2-of-2 transaction "F" (for Fund).

You create and sign that transaction, but don't broadcast it yet.

Use it's transaction id to create a second, one-input-two-signature, lockTime=1/1/2013 transaction that refunds the coins to you.  Call that "R" (for Refund).

Send R to the exchange and ask them to sign it using that brand-new public key they gave you. The exchange checks the lockTime and then returns R and the signature to you. You check the signature, and if it is good, broadcast F (and keep the half-signed R someplace safe).

If 1/1/2013 rolls around and you want your coins back, you sign your half of R and broadcast it.



I'd have to think a little harder than I want to right now about whether or not signing R knowing only txid==HASH(F) opens up the exchange to attacks. I can't think of any, but the exchange providing a signature when it doesn't know the details of exactly what it is signing makes me nervous.

You could send the unsigned R and the signed-but-not-broadcast F to the exchange and trust that the exchange will not broadcast F unless they agree to sign R.


I think holding on to pre-signed-but-not-broadcast-yet transactions is a technique "we" don't think about enough.


Title: Re: Transaction script with block height as condition
Post by: ByteCoin on October 05, 2012, 02:29:55 AM
If you held a pre-signed transaction that sends the funds back to you with a lockTime of 1 Jan 2013 that would work.
I've been out of the loop for a while.. Does lockTime work correctly nowadays? If not, when is it scheduled to be implemented?

I'd have to think a little harder than I want to right now about whether or not signing R knowing only txid==HASH(F) opens up the exchange to attacks. I can't think of any, but the exchange providing a signature when it doesn't know the details of exactly what it is signing makes me nervous.

Well, the worst case scenario (under plausible assumptions) for the exchange signing something arbitrary with some key is to lose control of (or unwittingly commit to) everything associated with that key, so it's important that the key has not been used for anything else.

Now of course if my proposal about transaction id hashes not including signatures were adopted, then the funding transaction could be sent in its unsigned form to the exchange and the exchange could verify that the refund spent the funding transaction because of course the transaction id wouldn't change on signing.

ByteCoin


Title: Re: Transaction script with block height as condition
Post by: jl2012 on October 05, 2012, 02:53:51 AM
However, if the exchange is completely disappeared, the BTC in the multi-sig accounts will be lost forever. Therefore, we need some "emergency exit mechanism". When the multisig account is setting up, an additional condition is added: (e.g.) "After 1 Jan 2013, the coins in this account can be spent by signature of key U only".

If you held a pre-signed transaction that sends the funds back to you with a lockTime of 1 Jan 2013 that would work.

Lets see... thinking out loud...

Start by asking the exchange for a brand-new public key to use for their half of the 2-of-2 transaction. Call the send-coins-into-2-of-2 transaction "F" (for Fund).

You create and sign that transaction, but don't broadcast it yet.

Use it's transaction id to create a second, one-input-two-signature, lockTime=1/1/2013 transaction that refunds the coins to you.  Call that "R" (for Refund).

Send R to the exchange and ask them to sign it using that brand-new public key they gave you. The exchange checks the lockTime and then returns R and the signature to you. You check the signature, and if it is good, broadcast F (and keep the half-signed R someplace safe).

If 1/1/2013 rolls around and you want your coins back, you sign your half of R and broadcast it.



I'd have to think a little harder than I want to right now about whether or not signing R knowing only txid==HASH(F) opens up the exchange to attacks. I can't think of any, but the exchange providing a signature when it doesn't know the details of exactly what it is signing makes me nervous.

You could send the unsigned R and the signed-but-not-broadcast F to the exchange and trust that the exchange will not broadcast F unless they agree to sign R.


I think holding on to pre-signed-but-not-broadcast-yet transactions is a technique "we" don't think about enough.


I read the previous discussion at https://bitcointalk.org/index.php?topic=6439.0 and https://bitcointalk.org/index.php?topic=1786

Satoshi rejected the idea of OP_BLOCKNUMBER because of this:

Quote
If the script language is not stateless, if it has access to any outside information that changes or varies between nodes, attackers can use it to fork the chain.  The only exception is if it is always false before a certain time and permanently true after, which is implemented with nLockTime.

Yes, he is correct. So it is possible to incorporate the idea of nLockTime into script? For example:

1. The coin can be spent by 2-by-2 multisig with key E and key U at ANY TIME
2. If block height >= x, the coin can be spent by key U. The 2-by-2 multisig, however, is still a vaild way to spend the coin.

Therefore, the first condition is permanently true, regardless of block height. The second condition is always false before block height = x, and permanently true after.

It is better than using nLockTime because the user can deposit to the script hash at any time, without the need of sending nLockTime transaction back-and-forth and storing them. It also avoids the problem of asking the exchange to sign an unknown transaction


Title: Re: Transaction script with block height as condition
Post by: Pieter Wuille on October 06, 2012, 12:12:46 AM
If you held a pre-signed transaction that sends the funds back to you with a lockTime of 1 Jan 2013 that would work.
I've been out of the loop for a while.. Does lockTime work correctly nowadays? If not, when is it scheduled to be implemented?

nLocktime has ever worked since it was introduced.

What doesn't exist yet is transaction replacement (which is necessary for many, but not all, of nLocktime's applications). Thankfully, implementing transaction replacement doesn't need any protocol change or fork or miner support.


Title: Re: Transaction script with block height as condition
Post by: gmaxwell on October 06, 2012, 02:09:10 AM
Yes, he is correct. So it is possible to incorporate the idea of nLockTime into script? For example:

1. The coin can be spent by 2-by-2 multisig with key E and key U at ANY TIME
2. If block height >= x, the coin can be spent by key U. The 2-by-2 multisig, however, is still a vaild way to spend the coin.
Validating that use of height is actually stateless in script would be horrific and more or less intractable. If script were designed so that there was a table of redemption options which had their own lock time then it could have been done... but alas.

It's no big deal in any case:

You are selling me your car. We decide to use a 2-of-2 escrow.  But I'm afraid you'll hold up the funds if the deal falls through.

I compute the payment into the escrow and sign it. But I do not announce it yet.  I also compute a transaction spending the escrow transaction and paying it all back to me with the locktime set some months from now.  I sign that transaction.  I give it to you (along with the txout its spending but not the whole payment). You can look at it and confirm that it is indeed unlocked until whenever, so sign it and give it back.  Then I announce the payment into the escrow. You don't need height in scripts to get refund timeouts. QED.


Title: Re: Transaction script with block height as condition
Post by: flipperfish on October 15, 2012, 05:24:29 PM
Is there actively being worked on enabling replacement of transactions?

A great application for nLockTime would be a dead-man-switch for encrypted wallets. The main problem I see with encrypted wallets for the average user is, that if the password is lost, the coins are lost, too. I have been thinking for a long time about a solution, where to store the password (besides my brain), so that in case I suffer from amnesia, I still have access to my coins. But the best solution I can imagine, is to store a signed transaction with nLockTime set to some time in the future, which sends the coins in the encrypted wallet to some other address. The private key to this new address could be given to someone/stored somewhere you trust in the case you suffer from amnesia, but do not trust for day-to-day usage. As long as you remember the password to the wallet, the nLockTime-Transaction can be refresehed, so it never gets locked. In case you forget the password, the coins become availiable after the nLockTime-Transaction locks.

I believe this idea is not new, but it would be nice to have it implemented soon, because it helps to make bitcoin more reliable and thus more trusted by average people.


Title: Re: Transaction script with block height as condition
Post by: Gavin Andresen on October 15, 2012, 06:30:19 PM
... But the best solution I can imagine, is to store a signed transaction with nLockTime set to some time in the future, which sends the coins in the encrypted wallet to some other address....

You don't need the whole network to support transaction replacement to do that; just write some code that holds a time-locked transaction, has a way of replacing it with another time-locked transaction, and have it automatically broadcast the transaction onto the network if not replaced before the time-lock expires.

It would be more convenient to have the whole network support transaction replacement, but I don't think it is reasonable for the whole network to remember everybody's dead-man-switch transactions. And even if they did, you'd run the risk that a miner eager to get an extra transaction fee would ignore a newer version of the transaction and mine the old transaction.


Title: Re: Transaction script with block height as condition
Post by: flipperfish on October 15, 2012, 08:53:37 PM
You don't need the whole network to support transaction replacement to do that; just write some code that holds a time-locked transaction, has a way of replacing it with another time-locked transaction, and have it automatically broadcast the transaction onto the network if not replaced before the time-lock expires.

I had in mind to not broadcast the time-locked tx until it's needed. But what happens, if it gets broadcasted somehow before I can replace it? Does it get included into a block? Does it hang around in the network as some zombie-tx, which can not yet be included in a block, but is valid and can't be thrown away?

As far as I know the only way to replace such a transaction is by spending the same outputs without nLockTime set. But then the client would not relay the transaction because replacement is not enabled and it would be considered as double-spend, right?


Title: Re: Transaction script with block height as condition
Post by: Mike Hearn on October 15, 2012, 10:02:40 PM
I don't think 2-of-2 escrow buys you anything, which is why I haven't discussed it in any of my posts/talks/wiki pages.

If I want to screw the seller, then I'll just broadcast the refund transaction after driving away and it'll enter the memory pool, preventing any other transactions from spending the 2-of-2 output. I get the money back (after a few months).

If the seller wants to screw me, after creating the 2-of-2 transaction and we agree on the sale by both signing for the multisig output, he broadcasts the tx giving himself the money and then refuses to give me the car keys. He drives away and I lose the money.

In no case are we better off than just using a regular payment.

2-of-3 with a mediator doesn't have these problems, nor does a smart property construction in which the transaction making the payment also transfers control of the car atomically.

The "dead mans switch" idea doesn't work either. If the key the recovery transaction to is also encrypted then it doesn't help if you forget the password. If it's not encrypted then if somebody gains access to your wallet, they can broadcast the recovery transaction and make your wallet unspendable, then broadcast a spend of the recovery transactions output. The thief would have to wait a few months to claim the money but they'd get it eventually. Not to mention that the recovery transaction would have to be rebuilt every time the wallet contents changed!

Anyone thinking about nLockTime should remember this - a transaction that is time locked enters the memory pool and stays there until the lock time is reached. Once broadcast the inputs that transaction spends are used and double spends won't be accepted.


Title: Re: Transaction script with block height as condition
Post by: flipperfish on October 17, 2012, 01:13:09 PM
a transaction that is time locked enters the memory pool and stays there until the lock time is reached. Once broadcast the inputs that transaction spends are used and double spends won't be accepted.

This could be changed by implementing transaction replacement (correct me if I'm wrong) and would make time-locked transactions (and both mentioned use cases) useful. That's why I'm asking, if there is actively being worked on this.


Title: Re: Transaction script with block height as condition
Post by: Mike Hearn on October 21, 2012, 06:39:13 PM
Replacement transactions need to have the same inputs as the transaction they are replacing, so no, it makes no difference.


Title: Re: Transaction script with block height as condition
Post by: flipperfish on October 22, 2012, 09:40:14 AM
Replacement transactions need to have the same inputs as the transaction they are replacing, so no, it makes no difference.
Of course I want to replace a transaction with the same inputs. How else would it be possible to invalidate the time-locked transaction? I thought "transaction replacement" enables the replacement (or better "update") of pending transactions in the memory pool. Or is this another unlucky naming of things, which actually do something else?


Title: Re: Transaction script with block height as condition
Post by: Mike Hearn on October 22, 2012, 12:33:52 PM
Transaction replacement lets you replace transactions in the memory pool, yes. However that transaction must have the same inputs as the previous transaction. Perhaps I misunderstood what you're saying. Even with transaction replacement enabled, once broadcast some version of the transaction is in the memory pool at all times and all the inputs are marked as spent. You can't change which inputs are spent by replacing it.


Title: Re: Transaction script with block height as condition
Post by: flipperfish on October 22, 2012, 01:52:15 PM
Thank you for taking your time to explain these issues to me. But unfortunateley I still can't follow you're explanaitions.

Let's leave the more advanced scenarios aside for the moment and concentrate just on replacing a single broadcasted, but time-locked transaction. With transaction replacement enabled, it seems possible to do just that, as long as the same inputs are used within the replacing transaction.

So assume this order of actions:

Pre-Conditions:
- Transaction replacement is enabled.

Invariants:
- Input A is not used in any other not explicitly listed transaction.

1.) Create and broadcast a time-locked (until t_lock) transaction with input A and Output 1
2a.) Before t_lock create and broadcast a non-time-locked transaction with input A and Output 2 (different from Output 1)
2b.) After t_lock create and broadcast a non-time-locked transaction with input A and Output 3 (different form Output 1 and 2)

What happens in 2a.) and 2b.)?

My guess:
2a.) The transaction from 1.) is replaced in the memory pool. As the time-constraint is now removed it can be included in a block. The transaction becomes valid, outputs of input A become available at Output 2.
2b.) The transaction from 1.) is included in a block because the time-constraint is met. The transaction from 2b.) will be considered invalid because the inputs have been already spent. The outputs of input A are availible at Output 1.


What happens if there is no transaction replacement (= current implementation?)?

My guess:
2a. and 2b.) The transaction from 1.) is in the memory pool and can't be replaced. It stays there until the time-constraint is met. The outputs of input A finally become availiable at Output 1.


Title: Re: Transaction script with block height as condition
Post by: Maged on October 25, 2012, 03:51:51 AM
I don't think 2-of-2 escrow buys you anything, which is why I haven't discussed it in any of my posts/talks/wiki pages.
It buys instant confirmation for the receiver if the 2-of-2 escrow with refund was staged before it was needed, since the receiver would have to know of any double-spends simply because they would have had to sign them. This is perfect for staging Bitcoins on an exchange so that you don't have to wait 6 confirmations before you can make a trade, but without the risk of them being stolen in a hack or lost due to the site going down.

The "dead mans switch" idea doesn't work either. If the key the recovery transaction to is also encrypted then it doesn't help if you forget the password. If it's not encrypted then if somebody gains access to your wallet, they can broadcast the recovery transaction and make your wallet unspendable, then broadcast a spend of the recovery transactions output. The thief would have to wait a few months to claim the money but they'd get it eventually. Not to mention that the recovery transaction would have to be rebuilt every time the wallet contents changed!

Anyone thinking about nLockTime should remember this - a transaction that is time locked enters the memory pool and stays there until the lock time is reached. Once broadcast the inputs that transaction spends are used and double spends won't be accepted.
"Once broadcast the inputs that transaction spends are used and double spends won't be accepted" ... into the memory pool. Unless I'm totally wrong, that means that all you need to do is manage to get your replacement transaction into a block before the time locked transaction can be entered into a block (which if you did it right, should be several months). For an entity like MtGox, even without transaction replacement being generally enabled on the network, this would be no problem.


Title: Re: Transaction script with block height as condition
Post by: Mike Hearn on October 25, 2012, 11:35:36 AM
It buys instant confirmation for the receiver if the 2-of-2 escrow with refund was staged before it was needed, since the receiver would have to know of any double-spends simply because they would have had to sign them. This is perfect for staging Bitcoins on an exchange so that you don't have to wait 6 confirmations before you can make a trade, but without the risk of them being stolen in a hack or lost due to the site going down.

How does it make a difference? I have a payment from me to {me,mtgox} and a signed payment back from {me,mtgox} to me, then when I decide to send that money to MtGox so I can trade with it, they still have to wait the 6 confirmations to be sure I don't double-spend with the refund tx.

If I don't have a signed refund TX then if the site goes offline, I can't get my money back either.

"Once broadcast the inputs that transaction spends are used and double spends won't be accepted" ... into the memory pool. Unless I'm totally wrong, that means that all you need to do is manage to get your replacement transaction into a block before the time locked transaction can be entered into a block (which if you did it right, should be several months). For an entity like MtGox, even without transaction replacement being generally enabled on the network, this would be no problem.

You're right, you could try and do a Finney attack against your own transaction. However this is a bizarre hack that tries to recreate transaction replacement. It'd be better to just re-enable that feature, and then the whole scheme makes sense (my point was specifically about the suggestion of doing it before tx replacement is re-activated). We need replacement for other things anyway. The recovery transaction can have sequence numbers of zero. Because only somebody who can decrypt the wallet can create a replacement for it, as long as you notice the recovery transaction was broadcast by a thief it is safe to have it lying around. It's a neat idea.

I think in future it would make sense to change miners so they discourage blocks that include double spends against their memory pool. Finney attacks aren't helpful today to the network and discouraging blocks that contain them would help many people. It has to be thought about carefully to avoid opening up new attacks though.

flipperfish, your understanding is correct.


Title: Re: Transaction script with block height as condition
Post by: jl2012 on October 26, 2012, 07:30:50 AM
It buys instant confirmation for the receiver if the 2-of-2 escrow with refund was staged before it was needed, since the receiver would have to know of any double-spends simply because they would have had to sign them. This is perfect for staging Bitcoins on an exchange so that you don't have to wait 6 confirmations before you can make a trade, but without the risk of them being stolen in a hack or lost due to the site going down.

How does it make a difference? I have a payment from me to {me,mtgox} and a signed payment back from {me,mtgox} to me, then when I decide to send that money to MtGox so I can trade with it, they still have to wait the 6 confirmations to be sure I don't double-spend with the refund tx.

If I don't have a signed refund TX then if the site goes offline, I can't get my money back either.



Use the nlocktime flag so the refund TX won't be valid before certain time in the future


Title: Re: Transaction script with block height as condition
Post by: Mike Hearn on October 26, 2012, 02:10:43 PM
So you're saying I should put my money into a state where if I want to send it to MtGox, that's fast, but if I want to use it for something else, I have to wait. I don't see why this is better than "if I want to use my money for something else, I can do so immediately, and if I want to trade, I have to wait". Given that in a healthy system most users will be using Bitcoin to buy goods/services rather than trying to exploit currency fluctuations ...


Title: Re: Transaction script with block height as condition
Post by: Maged on October 27, 2012, 02:41:21 AM
It buys instant confirmation for the receiver if the 2-of-2 escrow with refund was staged before it was needed, since the receiver would have to know of any double-spends simply because they would have had to sign them. This is perfect for staging Bitcoins on an exchange so that you don't have to wait 6 confirmations before you can make a trade, but without the risk of them being stolen in a hack or lost due to the site going down.

How does it make a difference? I have a payment from me to {me,mtgox} and a signed payment back from {me,mtgox} to me, then when I decide to send that money to MtGox so I can trade with it, they still have to wait the 6 confirmations to be sure I don't double-spend with the refund tx.
As jl2012 mentioned, that isn't the case at all. As long as the locktime is sufficiently in the future, there is little concern that the refund transaction will get into a block before the spending transaction does. This is completely different than the risks associated with accepting regular zero-confirmation transactions. And in the end, all that it comes down to is risk.

If I don't have a signed refund TX then if the site goes offline, I can't get my money back either.
Even without a refund transaction, this is still better than the current situation since the bitcoins would be provably in "cold storage" (in a sense, not literally, since both keys could be online) and unspendable by hackers. This is compared to us just having to trust that a cold storage exists.

You're right, you could try and do a Finney attack against your own transaction. However this is a bizarre hack that tries to recreate transaction replacement. It'd be better to just re-enable that feature, and then the whole scheme makes sense (my point was specifically about the suggestion of doing it before tx replacement is re-activated). We need replacement for other things anyway. The recovery transaction can have sequence numbers of zero. Because only somebody who can decrypt the wallet can create a replacement for it, as long as you notice the recovery transaction was broadcast by a thief it is safe to have it lying around. It's a neat idea.
Oh, yes, it is totally a hack. But, it would also be totally compatible with transaction replacement if it is re-enabled.

I think in future it would make sense to change miners so they discourage blocks that include double spends against their memory pool. Finney attacks aren't helpful today to the network and discouraging blocks that contain them would help many people. It has to be thought about carefully to avoid opening up new attacks though.
Agreed. However, in addition to making sure not to open up new attacks, we also have to be careful and not prevent future legitimate reasons for doing a Finney attack.

So you're saying I should put my money into a state where if I want to send it to MtGox, that's fast, but if I want to use it for something else, I have to wait.
Not at all. At least, no more than you have to wait for a normal transaction. Remember, we're assuming that we still trust our example of MtGox in general, just not 100% of the time (which is what we must currently accept if we want to stage funds there). So, you release the funds to MtGox and immediately withdraw through their interface. If the withdrawal exceed their hot wallet, there will have to be a transaction dependent on the release transaction, true, making things slower. However, if MtGox is willing to hold some of their own funds in a hot wallet for their customer's convenience, it'd be no different than sending a transaction from MtGox now.

Using the release transaction as a dependency for withdrawal like this would certainly decrease the risks, though. In fact, a withdrawal could even be sent directly from the staged transaction, making the withdrawal transaction just a regular bitcoin transaction (with all the risks that entails) that MtGox signed off on to acknowledge that the funds are no longer staged.

I don't see why this is better than "if I want to use my money for something else, I can do so immediately, and if I want to trade, I have to wait". Given that in a healthy system most users will be using Bitcoin to buy goods/services rather than trying to exploit currency fluctuations ...
The only downside to this over storing bitcoins in your own wallet is that you have to trust that when you want to spend the bitcoins that whoever you have them staged with will let you. If they don't let you, you'll just have to wait until the refund transaction matures.

The upside, however, is that it can also be a green address that was used to sign off on the release of the bitcoins, with all the benefits that entails.


Title: Re: Transaction script with block height as condition
Post by: jl2012 on October 27, 2012, 03:27:02 PM
So you're saying I should put my money into a state where if I want to send it to MtGox, that's fast, but if I want to use it for something else, I have to wait. I don't see why this is better than "if I want to use my money for something else, I can do so immediately, and if I want to trade, I have to wait". Given that in a healthy system most users will be using Bitcoin to buy goods/services rather than trying to exploit currency fluctuations ...

You can still use it for something else. As long as MtGox is working properly, they will send the coins in the 2-by-2 address to any address based on your instruction. The nlocktime transaction sending back to you is only an "emergency exit": if MtGox is suddenly closed, you will still get your coins back some time in the future. In 99.9% cases, you don't actually need to use this nlocktime tx.


Title: Re: Transaction script with block height as condition
Post by: jl2012 on October 27, 2012, 07:48:37 PM
It seems that my question was not answered. At least I would like to know why it does not work.

I have modified my proposed scheme. A script could be constructed like this:

1. At any time, the coin can be spent by satisfying condition A (e.g. signatures from X and Y)
2. If block height >= n, the coin can be spent by satisfying condition A OR condition B (e.g. signature from Z)

Therefore, the condition A permanently valid. The condition B is always invalid before block height = n, and permanently true after. It is equivalent to an nLockTime tx, signed by condition A, and send to an output for condition B.

It is better than using nLockTime because the user can deposit to the script hash at any time, without the need of sending nLockTime transaction back-and-forth and storing them.


Title: Re: Transaction script with block height as condition
Post by: Maged on November 02, 2012, 09:42:31 PM
If you held a pre-signed transaction that sends the funds back to you with a lockTime of 1 Jan 2013 that would work.

Lets see... thinking out loud...

Start by asking the exchange for a brand-new public key to use for their half of the 2-of-2 transaction. Call the send-coins-into-2-of-2 transaction "F" (for Fund).

You create and sign that transaction, but don't broadcast it yet.

Use it's transaction id to create a second, one-input-two-signature, lockTime=1/1/2013 transaction that refunds the coins to you.  Call that "R" (for Refund).

Send R to the exchange and ask them to sign it using that brand-new public key they gave you. The exchange checks the lockTime and then returns R and the signature to you. You check the signature, and if it is good, broadcast F (and keep the half-signed R someplace safe).

If 1/1/2013 rolls around and you want your coins back, you sign your half of R and broadcast it.



I'd have to think a little harder than I want to right now about whether or not signing R knowing only txid==HASH(F) opens up the exchange to attacks. I can't think of any, but the exchange providing a signature when it doesn't know the details of exactly what it is signing makes me nervous.
That should be safe if and only if a unique key is used to sign, and you can be absolutely certain that it has not nor will not be used for anything else until the exchange receives the signed transaction F. That means that the key can't be from a pre-generated list that may have been backed up, because that backup might eventually need to be used and the key could unknowingly be used for something else. It'd be a hard attack to pull off, but the potential for an attack is certainly there. So, the exchange would need to generate the key for signing transaction R on-the-fly and mark it specifically for this purpose. Thus, there's no risk that the key might be used for something else once it is backed up. If F is never sent then, the worst-case scenario is that a brand-new key will have only ever signed one transaction and never received anything. Since the key would have to be newly-generated, the worst-case scenario is that the exchange loses that key but you still have a signed transaction to get your money back later, anyway.

I think holding on to pre-signed-but-not-broadcast-yet transactions is a technique "we" don't think about enough.
That being said, I also have a more general-case solution that will allow this technique to work in all cases...
You could send the unsigned R and the signed-but-not-broadcast F to the exchange and trust that the exchange will not broadcast F unless they agree to sign R.
Generally that may be safe, but there's a chance that your money might fall into the void. So, the problem here is that F needs to be invalid when we send it to the exchange, but needs to be able to be made valid without changing anything in the transaction, meaning that we can't withhold signatures. So, let's just not withhold anything in this transaction at all. The very problem we're seeing here is actually it's own solution: the exchange doesn't want to sign something when it only knows the hash of an input transaction, but not the input transaction itself. It's the same for miners: they need the input transactions, not just the hashes, to enter a transaction into the blockchain.

So, the user just needs to not tell anyone about "Fi", an input to "F", until they get back "R". If "F" is broadcast and "R" is never signed, it's okay, because "F" was just an orphan and will never hit the blockchain unless the user broadcasts "Fi".


Title: Re: Transaction script with block height as condition
Post by: mmeijeri on February 17, 2014, 03:02:03 PM
I've been reading some threads on allowing checks of block height in scripts, and I still don't understand what's so dramatically bad about it. It's clear enough that a previously valid transaction can become invalid after a reorganisation, but that is solved in most cases if you wait for enough confirmations. The exception appears to be that after a lengthy segmentation you would get much more collateral damage than usual.

There was some suggestion that it might also allow people to deliberately create reorganisations, but I don't understand how that would work. Also, some developers seem to have changed their minds a bit. So, what's current thinking about a block height opcode and what exactly are the scenarios people are worried about?


Title: Re: Transaction script with block height as condition
Post by: jl2012 on February 17, 2014, 04:09:19 PM
I've been reading some threads on allowing checks of block height in scripts, and I still don't understand what's so dramatically bad about it. It's clear enough that a previously valid transaction can become invalid after a reorganisation, but that is solved in most cases if you wait for enough confirmations. The exception appears to be that after a lengthy segmentation you would get much more collateral damage than usual.

There was some suggestion that it might also allow people to deliberately create reorganisations, but I don't understand how that would work. Also, some developers seem to have changed their minds a bit. So, what's current thinking about a block height opcode and what exactly are the scenarios people are worried about?

With the random malleability attack, the refund transaction in micro-payment channel is no longer reliable, as the txid is not fixed until confirmed. Pushing block height and block timestamp in the script will be very useful.

By the way, malleability will also make any previously valid transaction becoming invalid in case of reorg.