Provable smart contracts use cryptographic techniques to verify that computations done outside the blockchain are correct. This means that instead of doing all the work on-chain, which can be slow and expensive, the heavy lifting is done off-chain, and only a proof of the result is stored on the blockchain.
Key Benefits
- Scalability: By handling computations off-chain, provable smart contracts reduce the load on the blockchain, allowing for more transactions to be processed at lower costs.
- Security: Cryptographic proofs ensure that only valid computations are accepted, enhancing the security of smart contracts.
- Privacy: Techniques like Zero-Knowledge Proofs (ZKPs) can validate transactions without revealing any sensitive information.
StarkNet and Cairo
StarkNet is a Layer-2 network on Ethereum that uses STARK (Scalable Transparent Argument of Knowledge) proofs to provide scalability and security. It allows developers to build dApps that can handle many transactions per second while benefiting from Ethereum’s security.
StarkNet Architecture

State Changes and STARK Proofs in StarkNet
When a smart contract is executed on StarkNet, it involves state changes. These state changes are the updates made to the contract’s storage as a result of executing its functions. To ensure the correctness of these state changes, StarkNet generates and verifies STARK proofs.
Here’s a step-by-step explanation of how this process works:
1. Smart Contract Execution
When a user interacts with a smart contract on StarkNet, for instance, by calling a function like increase_counter, the following steps occur:
- Function Call: The function is invoked with specific inputs. For example, calling
increase_counter(10)to increase the counter by 10. - Computation: The StarkNet virtual machine (VM) executes the function, performing the necessary computations to update the contract’s state. This involves reading the current state, applying the changes, and writing the new state back to storage.
2. Trace Generation
During the execution of the smart contract, StarkNet generates a trace. The trace is a detailed log of every computational step taken during the execution, including the initial state, the operations performed, and the resulting state. This trace is crucial for generating the proof.
3. STARK Proof Generation
Using the trace generated in the previous step, StarkNet produces a STARK proof. This proof is a cryptographic certificate that attests to the correctness of the computation and the resulting state changes. Here’s how it works:
- Data Representation: The trace is converted into a format suitable for cryptographic operations.
- Proof Computation: Using the STARK protocol, the proof is computed. This involves complex mathematical operations that produce a concise representation of the trace’s correctness.
4. Proof Submission and Verification
The generated STARK proof, along with the new state changes, is submitted to the Ethereum mainnet for verification. This is where the efficiency of STARKs shines:
- On-Chain Verification: Instead of re-executing the entire computation, the Ethereum smart contract (StarkNet Verifier) only needs to verify the STARK proof. This verification process is much faster and requires significantly less computational power than re-execution.
- State Commitment: Once the proof is verified, the new state changes are accepted and committed to the StarkNet state.
Example Workflow
Let’s consider our counter contract to illustrate this process:
- Initial State: Assume the counter value is 0.
- Function Call: A user calls
increase_counter(10). - Computation: The StarkNet VM computes the new counter value, which is 10.
- Trace Generation: A trace is generated that logs the initial counter value (0), the increment operation, and the resulting counter value (10).
- Proof Generation: Using the trace, a STARK proof is generated that certifies the computation (0 + 10 = 10) was performed correctly.
- Proof Submission: The STARK proof, along with the new counter value (10), is submitted to the Ethereum mainnet.
- Verification: The Ethereum smart contract verifies the STARK proof.
- State Commitment: Upon successful verification, the new counter value (10) is committed to StarkNet’s state.
What is the Cairo Language?
Cairo (Computer Algebra for RISC Operations) is a programming language specifically designed for writing provable programs. It is the native language for developing smart contracts on StarkNet, leveraging zero-knowledge proofs to ensure computational integrity.
Key Features of Cairo:
- Proof Generation: Cairo allows for the creation of succinct proofs that attest to the correctness of a computation.
- Efficiency: Designed for high-performance computations, Cairo can handle complex algorithms efficiently.
- Interoperability: Cairo smart contracts can interact seamlessly with Ethereum and other blockchain platforms.
In this article, we will explore the steps to build, deploy, and interact with a smart contract on StarkNet.
Prerequisites
Before we start, make sure you have the following installed:
- Rust (>= 1.51.0)
cargo(Rust's package manager)- Node.js (>= 12.x)
- npm (Node Package Manager)
starknet-devnet(StarkNet local testnet)starknetCLIscarb(Cairo’s package manager for Rust)
You can install the necessary tools using the following commands:
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install Node.js and npm (if not already installed)
sudo apt-get install nodejs
sudo apt-get install npm
# Install StarkNet CLI
pip install starknet-devnet
# Install Scarb (Cairo's package manager for Rust)
curl -L https://github.com/software-mansion/scarb/releases/download/latest/scarb-x86_64-unknown-linux-gnu.tar.gz | tar xz
sudo mv scarb /usr/local/bin
Setting Up StarkNet Devnet
Start StarkNet Devnet with the following command:
starknet-devnet
This command will start a local instance of StarkNet Devnet on http://localhost:5000.
Creating the Rust Cairo Project
Create a new Rust project and add the necessary dependencies for Cairo. Run the following commands:
cargo new starknet_counter
cd starknet_counter
Add the following dependencies to your Cargo.toml file:
[dependencies]
cairo = "0.1"
starknet = { git = "https://github.com/starkware-libs/cairo.git" }
Writing the Smart Contract
Create a file named src/main.rs and add the following code for a simple counter contract:
use cairo::contract;
use cairo::types::felt::Felt252;
use cairo::starknet::storage::Storage;
use cairo::starknet::types::Address;
#[contract]
mod counter {
use super::*;
#[storage]
struct Storage {
counter: Felt252,
}
#[constructor]
fn new() -> Storage {
Storage {
counter: Felt252::from(0),
}
}
#[external]
fn increase_counter(storage: &mut Storage, amount: Felt252) {
storage.counter += amount;
}
#[view]
fn get_counter(storage: &Storage) -> Felt252 {
storage.counter
}
}
This contract defines a simple counter with two functions:
increase_counter(amount: Felt252): Increases the counter by a specified amount.get_counter() -> Felt252: Retrieves the current value of the counter.
Compiling the Contract
Compile the contract using the Scarb tool:
scarb build
This will generate the necessary compiled files in the target directory.
Deploying the Contract
Deploy the compiled contract to StarkNet Devnet using the StarkNet CLI:
starknet deploy --contract target/release/starknet_counter.sierra.json --abi target/release/starknet_counter.abi.json --network localhost


