Description
Now that there are multiple versions of Clarity, with different keywords and different interpretations of existing keywords, we need to determine the rules for how (at-block)
, contract-call?
and smart contract deployment should work. I suggest the following:
-
The Clarity version used in a transaction is immutable over the transaction's lifetime. Moreover, the Clarity version used is determined early -- i.e. at or before the instantiation of the transaction's
GlobalContext
. -
A
ContractCall
transaction runs with the Clarity version of the contract it calls, not the current epoch. Similarly, aSmartContract
transaction runs with the Clarity version it indicates in its pragma ([Chainstate]SmartContract
tx wire format to indicate which Clarity version to use #2719), not the current epoch (the current epoch is only used to infer the Clarity version if theSmartContract
payload indicates to do so). If the contract is deployed with Clarity1 rules, then all top-level contract calls into it use Clarity1. If a contract is deployed with Clarity1 rules, and it calls other contracts as part of its code-body evaluation, then these contract-calls follow Clarity1 rules as well. Same goes for the use of Clarity2. -
The closure in
(at-block)
runs with the Clarity version of the caller, not the target block. So, if a Clarity2 contract calls(at-block)
, its code body runs with Clarity2 rules even if the block was mined before Clarity2 was allowed. Similarly, if a Clarity1 contract calls(at-block)
, its code body runs with Clarity1 rules even if the block was mined when Clarity2 was allowed. If the closure fails for any reason -- even viaCheckErrors
resulting from the Clarity version's rules rendering the closure's code invalid -- the error is always (re-)interpreted as a runtime error ([clarity] All check errors must be handled as runtime errors #3107) so the transaction can still be mined. -
The closure in
(at-block)
can only call other contracts that have been successfully instantiated. This precludes calling a contract that uses Clarity2 keywords but was deployed in epoch 2.05 or earlier via(at-block)
-- the call should fail even if the contract could have worked in Clarity2, because the contract itself should not have passed the analysis check when its transaction was mined.