Using C code on EVM and Non-EVM Blockchains
ChainsAtlas enables developers to seamlessly run C code on both EVM and non-EVM blockchains. The examples below showcase some potential use cases.
Overview
The following documentation explains the features of C supported by the ChainsAtlas development framework.
QuickStart - Example 1: Passing Arguments to a Smart Contract
In this example, the user passes two arguments to a deployed smart contract. The function __chainsatlas_evm_sload is lowered to sload an EVM native operation that loads stored information via a key. (will be soon replaced by mload as the default argument passing mechanism)
long sum(long x, long y) {
return x + y;
}
long main() {
long x, y, z;
x = __chainsatlas_evm_sload(1);
y = __chainsatlas_evm_sload(2);
// z = __chainsatlas_evm_sload(3); if you have more arguments ...
z = sum(x, y);
return z;
}
Explanation:
The main function first fetches two stored values from keys 1 and 2 using the __chainsatlas_evm_sload function. It then calculates their sum by calling the sum function and finally returns the result.
QuickStart - Example 2: Running the 2048 Game Logic On-Chain
This example demonstrates how one can run the logic of the popular 2048 game fully on a blockchain.
long pseudo_rand(long *seed) {
*seed = 1103515245 * (*seed) + 12345;
return (long)((*seed >> 16) & 0x7FFF);
}
void addRandom(long *board, long *seed) {
long r;
do {
r = pseudo_rand(seed) % 16;
} while(board[r] != 0);
board[r] = ((pseudo_rand(seed) % 2) + 1) * 2;
}
void shiftGrid(long* grid) {
long x, y;
long line[4], count;
for (y = 0; y < 4; y++) {
count = 0;
for (x = 0; x < 4; x++) {
if (grid[x*4 + y] != 0) {
if (count > 0 && line[count-1] == grid[x*4 + y]) {
line[count-1] *= 2;
grid[x*4 + y] = 0;
} else {
line[count] = grid[x*4 + y];
count++;
}
}
}
for (x = count; x < 4; x++) {
line[x] = 0;
}
for (x = 0; x < 4; x++) {
grid[x*4 + y] = line[x];
}
}
}
long computeScore(long* grid) {
long i, score = 0;
for (i = 0; i < 16; i++)
score += grid[i];
return score;
}
long main() {
long seed = 12345;
long moves = 0b0101010101010101010101;
long i;
long grid[16];
for (i = 0; i < 16; i++) {
grid[i] = 0;
}
// skipping the first non null 2-bits allowing the distinction between moves and type promotion
moves = moves >> 2;
long len = 0;
while(moves != 0) {
moves = moves >> 2;
len++;
}
addRandom(grid, &seed);
for (i = 0; i < len; i++) {
shiftGrid(grid);
addRandom(grid, &seed);
}
long score = computeScore(grid);
return score;
}
Explanation:
This code replicates the game logic of 2048. It starts by initializing a grid with random numbers using the addRandom function. The shiftGrid function is used to combine and shift the tiles, as in the actual game. The final score is then computed using the computeScore function, taking the sum of all the grid values.
Basic Data Types
long (Recommended): While we support a rich variety of data types, long is the most stable across different chains, thus, used as the primary data type for the examples.
long number = 100;
Pointers
Utilized for array handling and direct variable modifications.
long value = 10; long *pointer = &value;
Arrays
Single-dimensional arrays:
long array[10];
Two-dimensional arrays interpreted via single-dimensional arrays:
long grid[16]; // Example of a 4x4 grid
Loop Constructs
for loops:
for(long i = 0; i < 10; i++) { // iteration logic }
while loops:
long count = 0; while(count < 10) { count++; }
Conditional Statements
if:
if(x == 10) { // logic if condition is true }
if-else:
if(x > 10) { // logic if x is greater than 10 } else { // logic if x is not greater than 10 }
Functions
User-defined functions:
void display() { // function logic }
Function Calls:
display();
Recursive Function Calls:
long factorial(long n) { if(n <= 1) return 1; return n * factorial(n-1); }
Arithmetic Operations
Basic operations:
long addition = a + b; long multiplication = a * b; long subtraction = a - b; long division = a / b;
Bitwise Operations
long shiftedValue = a >> 2; long bitwiseAnd = a & b;
Assignment Operations
long x = 10; x *= 2; // Compound assignment
Relational Operators
if(a == b) { /* logic */ } if(a > b) { /* logic */ } if(a >= b) { /* logic */ }
Pointer Operators
long value = 10; long *ptr = &value; long dereferencedValue = *ptr;
Blockchain-specific Features
__chainsatlas_evm_sstore(1, 12); long valueFromBlockchain = __chainsatlas_evm_sload(1);
Comments