Global Variables
Global time lock variables
Bitcoin Cash has support for different kinds of time locks, which can be used to specify time-based conditions inside Bitcoin Cash contracts. These time locks can be separated by three main attributes: location, targeting and metric. The location can be the transaction level or the contract level, but contract level locks also require you to use a corresponding transaction level lock. The targeting can be relative (e.g. at least 4 hours have passed) or absolute (e.g. the block number is at least 600,000). The metric can be blocks or seconds.
It can be difficult to fully grasp the intricacies of time locks, so if you're starting out it is recommended to start off with the simplest version: absolute block-based time locks. If you do want to dive into the more advanced uses of time locks, James Prestwich wrote the best article explaining time locks in Bitcoin that also fully applies to Bitcoin Cash.
tx.time
tx.time
is used to create absolute time locks. The value of tx.time
can either represent the block number of the spending transaction or its timestamp. When comparing it with values below 500,000,000
, it is treated as a blocknumber, while higher values are treated as a timestamp.
tx.time
corresponds to the nLocktime
field of the current transaction using the OP_CHECKLOCKTIMEVERIFY
opcode. Because of this tx.time
can only be used in the following way:
require(tx.time >= <expression>);
Because of the way time locks work, a corresponding time lock needs to be added to the transaction. The CashScript SDK automatically sets this transaction level time lock to the most recent block number, as this is the most common use case. If you need to use a different block number or timestamp, this should be passed into the CashScript SDK using the withTime()
function. If the default matches your use case, no additional actions are required.
tx.age
tx.age
is used to create relative time locks. The value of tx.age
can either represent a number of blocks, or a number of chunks, which are 512 seconds. The corresponding transaction level time lock determines which of the two options is used.
tx.age
corresponds to the nSequence
field of the current UTXO using the OP_CHECKSEQUENCEVERIFY
opcode. Because of this tx.age
can only be used in the following way:
require(tx.age >= <expression>);
Because of the way time locks work, a corresponding time lock needs to be added to the transaction. This can be done in the CashScript SDK using the withAge()
function. However, the value passed into this function will always be treated as a number of blocks, so it is currently not supported to use tx.age
as a number of second chunks.
Globally available units
An integer literal can take a suffix of either monetary or temporary units to add semantic value to these integers and to simplify arithmetic. When these units are used, the underlying integer is automatically multiplied by the value of the unit.
BCH Units
The units sats
, finney
, bits
and bitcoin
can be used to denominate Bitcoin Cash amounts.
Example
require(1 sats == 1);
require(1 finney == 10);
require(1 bit == 100);
require(1 bitcoin == 1e8);
Time Units
The units seconds
, minutes
, hours
, days
and weeks
can be used to denote time.
Be careful when using these units in precise calendar calculations though, because not every year equals 365 days and not even every minute has 60 seconds because of leap seconds.
Example
require(1 seconds == 1);
require(1 minutes == 60 seconds);
require(1 hours == 60 minutes);
require(1 days == 24 hours);
require(1 weeks == 7 days);