Basic types reflect types Script operates on.
bool - a boolean value. Can be either
ifstatements expect an expression returning this type.
bit - a binary flag. Only arrays of this type can be created, see below. Array of bits is expected by
int - a 32-bit signed integer. Literals of this type can be specified in dec or hex.
int a = -1234; int b = 0xff00i; // notice `i` suffix
byte - a single byte. Literals of this type are specified in hex (with
0xprefix) or as UTF-8 strings (in doubel quotes).
byte x = 0x11; byte y = "a";
Arrays are series of values with the same type.
Overall syntax of an array type is:
[ element_type ; size ]
In case of
byte the array will mean a single byte vector on the stack in Bitcoin Virtual Machine terms.
In case of other types the array will mean a number of stack elements with element 0 on the bottom.
You can create bit array literals with
0b prefix, byte arrays with
0x prefix or double quotes
and any other arrays with comma-separated lists in brackets.
[bit;4] checkbits = 0b1011; [byte;3] a = 0x11ab33; [byte; 3] b = "abc"; [int;5] c = [1, 2, 3, 4, 5]; [[byte;2];3] d = ["ab", "cd", "ef"];
It is also possible to define a byte list if the array size is unknown at the compile time.
[byte] str = expr;
A byte array can be implicitly casted to a byte list but not the other way. It is recommended though to use explicit sizes as much as possible to leverage the static type checking of the size.
([byte] left, [byte] right) = expr @ 3; // okay ([byte;3] left, [byte] right) = expr @ 3; // better ([byte;2] left, [byte] right) = expr @ 3; // type error
With an exception of bit arrays the array elements can be accessed by an index starting from 0.
[byte] arr = "abcd" byte c = arr; byte x = arr[(i + 1) % 4];
Tuples are similar to arrays but the values can vary in types.
Overall syntax of a tuple type is:
( type1 , type2 [, …])
You can create tuple literals with a comma separated list of values in parentheses. Tuples can be deconstructed into separate variables with a deconstructing assgnment syntax:
( type1 name1 , type2 name2 [, …]) = expr ;
Elements of 2-tuples can be extracted with
([byte;4], [byte]) tuple1 = x @ 4; ([byte;4] left, [byte] right) = tuple1; [byte;4] first = fst(tuple1); [byte] second = snd(tuple1); (int, [byte], [bit;3]) tuple2 = (a, b, c);
To increase safety, Spedn introduces meaningful types that help with catching semantic errors at compile time.
These types add meaning to a raw
They must be explicitly casted from
int with a type constructor.
They cannot be casted back to
- Time - represents an absolute time.
Can be expressed as a Unix Timestamp or a Block Height and variously defined.
Time x = `2018-10-13 21:37:00`; // defined with a time literal Time y = TimeStamp(1539466620); // conversion from `int` interpreted as Unix Timestamp Time z = TimeStamp(584834); // conversion from `int` interpreted as Block Height
TimeSpan - represents a relative time period. Can be expressed as a number of blocks or 512-seconds periods.
TimeSpan x = 1d 2h 3m 4s; // Time units literal. Be awre that the number will be rounded down to full 512s periods TimeSpan y = 10b; // Blocks literal. TimeSpan z = Blocks(10); // Conversion from `int`
These types add meaning to a raw byte arrays.
They can be implicitly casted to
They must be explicitly casted from
[byte] with a type constructor.
PubKey - represents a public key.
PubKey alice = PubKey(0x11223344556677889900aabbccddeeff);
Sig - represents a tx signature (which can be checked with
Sig alice = Sig(0x11223344556677889900aabbccddeeff); verify checkSig(alice, alicePubKey);
DataSig - represents a data signature (which can be checked with
DataSig alice = DataSig(0x11223344556677889900aabbccddee); verify checkDataSig(alice, preimageHash, alicePubKey);
Ripemd160 - represents a result of RIPEMD-160 hash.
Ripemd160 h = hash160(pubKey);
Sha1 - represents a result of SHA-1 hash.
Sha1 x = sha1(secret);
Sha256 - represents a result of SHA-256 hash.
Sha256 x = hash256(secret);
Preimage - represents a raw transaction preimage. You can break it down to components with
Preimage preimage = Preimage(0xaabc45......); TxState tx = parse(preimage);
TxState - a 10-tuple containing preimage components. They can be accessed by tuple deconstruction.
- NVersion - nVersion of the transaction (4-byte little endian)
- Sha256 - hashPrevouts (32-byte hash)
- Sha256 - hashSequence (32-byte hash)
- Outpoint - outpoint (32-byte hash + 4-byte little endian)
- ScriptCode - scriptCode of the input (serialized as scripts inside CTxOuts)
- Value - value of the output spent by this input (8-byte little endian)
- NSequence - nSequence of the input (4-byte little endian)
- Sha256 - hashOutputs (32-byte hash)
- NLocktime - nLocktime of the transaction (4-byte little endian)
- Sighash - sighash type of the signature (4-byte little endian)
(NVersion v, Sha256 hp, Sha256 hs, Outpoint o, ScriptCode code, Value val, NSequence ns, Sha256 ho, NLocktime l, Sighash sh) = parse(preimage)
Alternatively you can use functions extrancing a single component.
NVersion v = nVesrion(preimage); Sha256 hp = hashPrevouts(preimage); Sha256 hs = hashSequence(preimage); Outpoint o = outpoint(preimage); ScriptCode code = scriptCode(preimage); Value val = value(preimage); NSequence s = nSequence(preimage); Sha256 ho = hashOutputs(preimage); NLocktime l = nLocktime(preimage); Sighash sh = sighash(preimage);
You can defile a type alias. The name of the new type must start with a capital letter. The types have to be defined before contracts in the code file. Syntax is:
type Name = other type ;
Once defined you can declare variables of the new type and use a type constructor for casting a raw type to an alias. It behaves the same way as constructors of of domain-specific types described in the previous sections. Actually, all of these are defined as type aliases internally.
type Message = [byte;42]; ... Message msg = Message(str);