Data types
The CIDL defines three forms of data types. A developer can cover all available use cases through these.
Data types in the CIDL are all specified in lowercase, except for custom-defined types.
Native Types: These are primitive data types like u32
, bool
, string
, etc. It is important to note that what is
a primitive type in the context of the CIDL may not be a primitive type in the generated version.
Extended Types: Built-in extended types implemented by Código like sol:pubkey
, sol:merkle_tree
, and others.
These data types can be specific to a programming language, blockchain, or a particular form of handling them.
Types: These are the custom types defined by a developer. In this document, we will cover everything related to native and extended data types. For custom-defined types read more here
Definition
Native
The following table is a comprehensive list of the supported native types by the CIDL.
Data Type | Length | Attributes |
---|---|---|
u8 | 8-bit unsigned integer | |
u16 | 16-bit unsigned integer | |
u32 | 32-bit unsigned integer | |
u64 | 64-bit unsigned integer | |
u128 | 128-bit unsigned integer | |
i8 | 8-bit signed integer | |
i16 | 16-bit signed integer | |
i32 | 32-bit signed integer | |
i64 | 64-bit signed integer | |
i128 | 128-bit signed integer | |
f32 | 32-bit signed float | |
f64 | 64-bit signed float | |
bool | 1 bit | |
string | Depends on the targeted blockchain | cap |
Extended
The following table is a comprehensive list of the supported extended types by the CIDL.
Data Types | Length | Attributes | Comments |
---|---|---|---|
array | Depends on the targeted blockchain | cap | |
sol:pubkey | 32 bytes | Type specific to the Solana blockchain. Transpiles to Pubkey data type. | |
sol:account<T?, seeds.K?> | It depends | sol:writable sol:init sol:init_if_needed sol:close sol:close_uncheck sol:space sol:owner sol:address sol:rent-payer sol:rent-receiver sol:uncheck_account | Type specific to the Solana blockchain. T is the name of a custom-defined type, it can be omitted with underscored _ . K is the name of a seed definition. T and K can reference imported CIDLs in the form of ref.type_name , where ref is the value set in the imports |
sol:merkle_tree | It depends | sol:init sol:init_if_needed sol:authority sol:canopy cap | Type specific to the Solana blockchain. Transpiles to AccountInfo data type with the owner set to the account compression program. |
array<string>
is in WIP
Attributes
In the below examples, certain keywords are omitted so the attribute can stand out
Multiple attributes can be combined to achieve the desired behavior. Learning how to combine them is the complex part of the CIDL.
Attributes that require a value i.e. cap
, sol:owner
, etc. are set with the assignment operator =
a.k.a. equal
sign.
Attributes that are prefixed with sol:
are only applicable to the Solana blockchain.
cap
The cap=\d+
(capacity) attribute defines the maximum length/size of a type. The capacity attribute is required
for string
, array
, and sol:merkle_tree
when creating the account, read more about
sol:merkle_tree
here.
types:
Example:
fields:
- name: product_name
type: string
attributes: [ cap=36 ]
- name: rating
type: array<u8>
attributes: [ cap=5 ]
methods:
- name: initialize_merkle_tree
inputs:
- name: merkle_tree
type: sol:merkle_tree
attributes: [ cap=100000000 ]
sol:writable
The sol:writable
attribute sets the is_writable
property of an account to true
. If omitted, the account will
be read-only, you can read more about read-only here. This attribute
is only applicable to sol:account<T?, K?>
types.
methods:
- name: transfer_funds_from_wallet
inputs:
- name: wallet
type: sol:account
attributes: [ sol:writable ]
sol:init
The sol:init
attribute generates the code to do a CPI call to the create_account method of the Solana SystemProgram.
Methods that have input with this attribute can only be called once per account, otherwise, it will throw a Solana
runtime error because it will try to create an account that's already created. This attribute
is only applicable to sol:account<T?, K?>
and sol:merkle_tree
types.
methods:
- name: create_wallet
inputs:
- name: wallet
type: sol:account
attributes: [ sol:init ]
sol:init_if_needed
The sol:init_if_needed
attribute behaves how sol:init
does, with the difference that before trying to create the
account it will check if the account is already created. Thus, avoiding the Solana runtime error.
This can sound convenient, but take special care because this can open the possibility of Reinitialization attacks. A reinitialization attack is when the data of your account is reset to the initial/default state.
methods:
- name: create_wallet
inputs:
- name: wallet
type: sol:account
attributes: [ sol:init_if_needed ]
sol:close
The sol:close
attribute generates the code to close an account. An account is closed when the account's data is
zeroed out, all the lamports are withdrawn, and the Solana runtime garbage collects the account. This attribute is only
applicable to sol:account<T?, K?>
and sol:merkle_tree
types.
methods:
- name: close_wallet
inputs:
- name: wallet
type: sol:account
attributes: [ sol:close ]
sol:close_uncheck
The sol:close_uncheck
attribute behaves how sol:close
does, with the difference that if the account is a Non-PDA
account it WILL NOT set the account as a signer. To understand this behavior, first, we need to understand that in
Solana, accounts can only be modified by their owner, Solana doesn't enforce that a Non-PDA account requires to be a signer when closing it.
Take special care when using this attribute, otherwise, you will be open to a vulnerability where an attacker can pass any account owned by your program and close it.
Non-PDA accounts are those accounts where K is not defined. sol:account<T?, K?>
.
This attribute is only applicable to Non-PDA accounts.
methods:
- name: close_wallet
inputs:
- name: wallet
type: sol:account
attributes: [ sol:close_uncheck ]