<p>No, by design.</p>
<p>Script evaluation gives an unconditional boolean output: valid or invalid. If script validation could depend on context, that would mean script validity would need to be re-evaluated any time that context changes, complicating reasoning about mempool transactions, the meaning of confirmations, as well just generally causing significant CPU cost to nodes that keep unconfirmed transactions around.</p>
<p>Note that neither <code>OP_CHECKLOCKTIMEVERIFY</code> or <code>OP_CHECKSEQUENCEVERIFY</code> actually let scripts depend on height/time information; they only depend on the locktime/height that's <em>in the transaction itself</em>. Validation of those locktime fields happens outside of script, which does mean that while <em>transaction</em> validity isn't entirely context-free (it can't be, because double-spending!), script validation never needs to be rerun.</p>

CC BY-SA 4.0
2024-02-27T08:50:19.547Z
What do you mean context changes? The context are the already confirmed blocks (aside from temporary forks) and the script validation would only require to take that into consideration in an immutable way
Tobias Kienzler
CC BY-SA 4.0
2024-02-27T17:55:18.077Z
Confirmed blocks can change, that is context, as it is not committed to by the transaction itself. If there was some mechanism for transactions (not scripts) to only be valid in a chain which has a block with a specified hash as ancestor, then information about that block and its ancestry could in theory be made available to the script interpreter too.
Pieter Wuille
CC BY-SA 4.0
2024-02-27T17:57:53.113Z
I'm sorry but I don't understand what you mean, how can a confirmed block change? That would modify (and thus invalidate) its hash after all, so I assume you're meaning something different than I do?
Tobias Kienzler
CC BY-SA 4.0
2024-02-27T18:00:13.270Z
No, but *which* block(s) have been confirmed can change from under a transaction. New ones can be added, old ones can be reorganized away.
Pieter Wuille
CC BY-SA 4.0
2024-02-27T18:37:03.507Z
Ah yes, that for sure, that's what I meant with temporary forks. But isn't the validity of a transaction checked in the context of the confirmed blocks so far after all? Otherwise double-spending would be possible as you stated, so I don't see a difference between that and e.g. a hypothetical `OP_LASTBLOCKHASH` pushing the parent block's hash to the the stack, the context of the confirmed blockchain must be respected either way
Tobias Kienzler
CC BY-SA 4.0
2024-02-27T19:11:51.820Z
@TobiasKienzler Yes, **transaction** validity is checked in context, but **script** is not. Its validity is a pure function of data that is committed to by the transaction itself. Transactions can get relayed long before they make it into blocks (weeks in some cases), during which time scripts would need to be re-evaluated any time the context changes.
Pieter Wuille
CC BY-SA 4.0
2024-02-27T19:23:47.947Z
Maybe I've misunderstood/misremembered something fundamental then - are you saying a P2SH is executed/validated not by the block miner but already before by the relaying nodes? The script is _evaluated_ upon block inclusion or not? Otherwise how can you be certain a node didn't sneak an invalid script into the mempool that just happens to exploit a loophole to pose as a valid transaction?
Tobias Kienzler
CC BY-SA 4.0
2024-02-28T07:03:15.893Z
@TobiasKienzler Both. Script validation is performed when the transaction is relayed across the network already (before being included in a block), and its validity is cached. When transactions are seen in blocks, the scripts are validated again (but the already validated ones can just use the cached value). If all you care about is block validity, then the context is fixed and these concerns matter less. But the network needs to be able to reason about transaction validity before being included in blocks too (how do miners know what to include? what transactions can be built on by wallets?)
Pieter Wuille
CC BY-SA 4.0
2024-02-28T10:15:19.200Z
Ah I see, thanks for your elaboration! It's a bit of a pity, context depend scripting would make for some interesting features in the direction of smart contract like features, but then again that never was the scope of Bitcoin
Tobias Kienzler
CC BY-SA 4.0
2024-02-29T08:11:23.377Z
@TobiasKienzler None of this means that context dependence is impossible - it just has to be designed such that script doesn't see it. After all, this has already happened with OP_CHECKLOCKTIMEVERIFY etc., by having an indirection through a constraint on the transaction outside of script (nLockTime for OP_CLTV, nSequence for OP_CSV). As a mentioned higher up, it would for example be possible to have a "mandatory block hash" field in transaction, making the transaction only valid in a chain descending from the specified hash, and then make properties of that block available to script.
Pieter Wuille
CC BY-SA 4.0
2024-03-01T11:00:23.843Z
Thanks! But that is purely theoretical and would require BIP first, right? The "mandatory block hash" idea could be interesting in the event of a hypothetical "fork wars" scenario, now that I think about it...
Tobias Kienzler
CC BY-SA 4.0
2024-02-26T22:20:47.100Z
2024-02-26T22:27:12.330Z
2024-02-26T22:27:12.330Z
Pieter Wuille
<p>The <a href="https://en.bitcoin.it/wiki/Script#Locktime" rel="nofollow noreferrer">locktime opcodes</a> <code>OP_CHECKLOCKTIMEVERIFY</code>and <code>OP_CHECKSEQUENCEVERIFY</code> indirectly allow for an approximate block number check, is there any way to obtain other information such as the previously mined block hash or current difficulty without having to rely on oracles?</p>

<block><script><opcodes>
Is there any way for a script to depend on blockchain info?
Tobias Kienzler
# Is there any way for a script to depend on blockchain info?

(Asked by: username_0 on 2024-02-26)

The [locktime opcodes](https://en.bitcoin.it/wiki/Script#Locktime) `OP_CHECKLOCKTIMEVERIFY`and `OP_CHECKSEQUENCEVERIFY` indirectly allow for an approximate block number check, is there any way to obtain other information such as the previously mined block hash or current difficulty without having to rely on oracles?

**Tags:** block, script, opcodes


---

## 1 answers

### Answer by username_1 on 2024-02-26. Score: 3 | Accepted answer

No, by design.

Script evaluation gives an unconditional boolean output: valid or invalid. If script validation could depend on context, that would mean script validity would need to be re-evaluated any time that context changes, complicating reasoning about mempool transactions, the meaning of confirmations, as well just generally causing significant CPU cost to nodes that keep unconfirmed transactions around.

Note that neither `OP_CHECKLOCKTIMEVERIFY` or `OP_CHECKSEQUENCEVERIFY` actually let scripts depend on height/time information; they only depend on the locktime/height that's *in the transaction itself*. Validation of those locktime fields happens outside of script, which does mean that while *transaction* validity isn't entirely context-free (it can't be, because double-spending!), script validation never needs to be rerun.

> **Comments:**
> **username_0**: What do you mean context changes? The context are the already confirmed blocks (aside from temporary forks) and the script validation would only require to take that into consideration in an immutable way  
> **username_1**: Confirmed blocks can change, that is context, as it is not committed to by the transaction itself. If there was some mechanism for transactions (not scripts) to only be valid in a chain which has a block with a specified hash as ancestor, then information about that block and its ancestry could in theory be made available to the script interpreter too.  
> **username_0**: I'm sorry but I don't understand what you mean, how can a confirmed block change? That would modify (and thus invalidate) its hash after all, so I assume you're meaning something different than I do?  
> **username_1**: No, but *which* block(s) have been confirmed can change from under a transaction. New ones can be added, old ones can be reorganized away.  
> **username_0**: Ah yes, that for sure, that's what I meant with temporary forks. But isn't the validity of a transaction checked in the context of the confirmed blocks so far after all? Otherwise double-spending would be possible as you stated, so I don't see a difference between that and e.g. a hypothetical `OP_LASTBLOCKHASH` pushing the parent block's hash to the the stack, the context of the confirmed blockchain must be respected either way  
> **username_1**: @username_0 Yes, **transaction** validity is checked in context, but **script** is not. Its validity is a pure function of data that is committed to by the transaction itself. Transactions can get relayed long before they make it into blocks (weeks in some cases), during which time scripts would need to be re-evaluated any time the context changes.  
> **username_0**: Maybe I've misunderstood/misremembered something fundamental then - are you saying a P2SH is executed/validated not by the block miner but already before by the relaying nodes? The script is _evaluated_ upon block inclusion or not? Otherwise how can you be certain a node didn't sneak an invalid script into the mempool that just happens to exploit a loophole to pose as a valid transaction?  
> **username_1**: @username_0 Both. Script validation is performed when the transaction is relayed across the network already (before being included in a block), and its validity is cached. When transactions are seen in blocks, the scripts are validated again (but the already validated ones can just use the cached value). If all you care about is block validity, then the context is fixed and these concerns matter less. But the network needs to be able to reason about transaction validity before being included in blocks too (how do miners know what to include? what transactions can be built on by wallets?)  
> **username_0**: Ah I see, thanks for your elaboration! It's a bit of a pity, context depend scripting would make for some interesting features in the direction of smart contract like features, but then again that never was the scope of Bitcoin  
> **username_1**: @username_0 None of this means that context dependence is impossible - it just has to be designed such that script doesn't see it. After all, this has already happened with OP_CHECKLOCKTIMEVERIFY etc., by having an indirection through a constraint on the transaction outside of script (nLockTime for OP_CLTV, nSequence for OP_CSV). As a mentioned higher up, it would for example be possible to have a "mandatory block hash" field in transaction, making the transaction only valid in a chain descending from the specified hash, and then make properties of that block available to script.  
> **username_0**: Thanks! But that is purely theoretical and would require BIP first, right? The "mandatory block hash" idea could be interesting in the event of a hypothetical "fork wars" scenario, now that I think about it...  

---

