Types¶
SolScript provides a rich type system optimized for Solana development.
Integer Types¶
Unsigned Integers¶
| Type | Size | Range |
|---|---|---|
uint8 | 8 bits | 0 to 255 |
uint16 | 16 bits | 0 to 65,535 |
uint32 | 32 bits | 0 to 4,294,967,295 |
uint64 | 64 bits | 0 to 18,446,744,073,709,551,615 |
uint128 | 128 bits | Very large numbers |
uint256 | 256 bits | Maximum precision |
Signed Integers¶
| Type | Size | Range |
|---|---|---|
int8 | 8 bits | -128 to 127 |
int16 | 16 bits | -32,768 to 32,767 |
int32 | 32 bits | -2,147,483,648 to 2,147,483,647 |
int64 | 64 bits | Large signed numbers |
int128 | 128 bits | Very large signed numbers |
int256 | 256 bits | Maximum precision signed |
Integer Operations¶
uint256 a = 10;
uint256 b = 3;
uint256 sum = a + b; // 13
uint256 diff = a - b; // 7
uint256 prod = a * b; // 30
uint256 quot = a / b; // 3 (integer division)
uint256 rem = a % b; // 1 (remainder)
// Comparisons
bool eq = a == b; // false
bool ne = a != b; // true
bool lt = a < b; // false
bool le = a <= b; // false
bool gt = a > b; // true
bool ge = a >= b; // true
// Bitwise
uint256 and = a & b; // Bitwise AND
uint256 or = a | b; // Bitwise OR
uint256 xor = a ^ b; // Bitwise XOR
uint256 shl = a << 2; // Left shift
uint256 shr = a >> 2; // Right shift
Boolean¶
bool active = true;
bool inactive = false;
// Logical operations
bool and = active && inactive; // false
bool or = active || inactive; // true
bool not = !active; // false
Address¶
The address type represents a Solana public key (32 bytes):
address owner = msg.sender;
address zero = address(0); // Zero address
// Comparison
bool isOwner = owner == msg.sender;
// Address literals (hex)
address treasury = 0x1234567890abcdef...;
String¶
Strings are UTF-8 encoded text:
string name = "SolScript";
string message = "Hello, World!";
// String concatenation (in memory)
string greeting = string.concat("Hello, ", name);
Bytes¶
Fixed-Size Bytes¶
Dynamic Bytes¶
bytes data; // Dynamic byte array
// Operations
data.push(0x01); // Append byte
uint256 len = data.length;
bytes1 first = data[0];
Arrays¶
Fixed-Size Arrays¶
uint256[5] fixed; // Array of 5 uint256
fixed[0] = 1;
fixed[4] = 5;
uint256 len = fixed.length; // 5
Dynamic Arrays¶
uint256[] dynamic;
// Operations
dynamic.push(1); // Append element
dynamic.push(2);
uint256 len = dynamic.length; // 2
uint256 last = dynamic.pop(); // Remove and return last
Array Literals¶
Mappings¶
Key-value storage (implemented as PDAs on Solana):
mapping(address => uint256) public balances;
mapping(address => mapping(address => uint256)) public allowances;
mapping(uint256 => User) public users;
// Usage
balances[msg.sender] = 100;
uint256 balance = balances[msg.sender];
allowances[owner][spender] = amount;
Mapping Behavior
- Keys are not enumerable
- All values default to zero/false/empty
- Cannot get the size of a mapping
Structs¶
Custom data structures:
struct User {
address wallet;
uint256 balance;
bool active;
string name;
}
// Declaration
User public admin;
User[] public users;
mapping(address => User) public userByAddress;
// Initialization
User memory newUser = User({
wallet: msg.sender,
balance: 0,
active: true,
name: "Alice"
});
// Or positional
User memory user2 = User(msg.sender, 0, true, "Bob");
// Access
admin.balance = 100;
string memory name = admin.name;
Enums¶
Named constants:
enum Status {
Pending, // 0
Active, // 1
Completed, // 2
Cancelled // 3
}
Status public status = Status.Pending;
function activate() public {
status = Status.Active;
}
function isActive() public view returns (bool) {
return status == Status.Active;
}
Tuples¶
Multiple return values:
function getValues() public pure returns (uint256, bool, string memory) {
return (42, true, "hello");
}
// Destructuring
(uint256 num, bool flag, string memory text) = getValues();
// Partial destructuring
(uint256 num, , ) = getValues(); // Ignore some values
Type Conversions¶
Implicit Conversions¶
Smaller types can convert to larger types:
Explicit Conversions¶
uint256 large = 1000;
uint8 small = uint8(large); // Explicit cast (may overflow!)
int256 signed = -100;
uint256 unsigned = uint256(signed); // Be careful with negative values!
Address Conversions¶
Storage Locations¶
Storage¶
Permanent on-chain storage:
Memory¶
Temporary during function execution:
function process(uint256[] memory data) public pure {
uint256[] memory temp = new uint256[](10);
// temp exists only during this call
}
Calldata¶
Read-only function parameters:
function process(uint256[] calldata data) external pure {
// data is read-only, more gas efficient
}
Type Aliases¶
Create readable type names:
type TokenId is uint256;
type Amount is uint128;
function transfer(TokenId id, Amount amount) public {
// ...
}
Next Steps¶
- Functions - Function definitions and patterns
- State Variables - Managing on-chain state
- Control Flow - Control flow statements