Smart Contract Deployment to StarkNet

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
Smart Contract Deployment to StarkNet
Medium
from 4 hours to 2 business days
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1215
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1043
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

Deploying Smart Contracts in StarkNet

StarkNet is a ZK Rollup from StarkWare running on top of Ethereum. Unlike zkSync Era with its EVM compatibility, StarkNet uses its own Cairo language and CASM virtual machine. You cannot directly port a Solidity contract to StarkNet — you need to rewrite it from scratch or use the Warp transpiler (which only works with a limited subset of Solidity). This must be factored into effort estimation.

Cairo: StarkNet's Contract Language

Cairo 1.x vs Cairo 0.x

Historically, Cairo was written in a procedural style with explicit hint management, which was non-trivial. Starting with Cairo 1.0 (2023), the syntax has been redesigned to be Rust-like, with contracts now written as #[starknet::contract] modules:

#[starknet::contract]
mod Counter {
    use starknet::ContractAddress;

    #[storage]
    struct Storage {
        count: u128,
        owner: ContractAddress,
    }

    #[event]
    #[derive(Drop, starknet::Event)]
    enum Event {
        Incremented: Incremented,
    }

    #[derive(Drop, starknet::Event)]
    struct Incremented {
        new_count: u128,
    }

    #[constructor]
    fn constructor(ref self: ContractState, owner: ContractAddress) {
        self.owner.write(owner);
        self.count.write(0);
    }

    #[abi(embed_v0)]
    fn increment(ref self: ContractState) {
        let current = self.count.read();
        self.count.write(current + 1);
        self.emit(Incremented { new_count: current + 1 });
    }
}

The compiler is scarb (a package manager and build tool for Cairo, similar to Cargo). Contracts compile to Sierra (Safe Intermediate Representation), then to CASM for execution.

Key Differences from Solidity

  • Storage — Cairo storage works differently. There are no dynamic arrays in storage directly: use Vec<T> through StorageVec or mappings through Map<K, V>. Structures are automatically decomposed into separate storage slots.
  • Felt252 — the basic data type, a 252-bit field. Familiar uint256 is implemented as a struct of two felt252. U256 arithmetic is more expensive in gas than working with felt252.
  • Account Abstraction is Native — StarkNet has no EOA in the Ethereum sense. Each account is a contract implementing the IAccount interface. This means multicall, session keys, social recovery — all are "out of the box" at the account level.

Deployment Infrastructure

Scarb and Project Initialization

# Install Scarb
curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh | sh

# New project
scarb new my_contract
cd my_contract

# Scarb.toml
[package]
name = "my_contract"
version = "0.1.0"

[dependencies]
starknet = ">=2.6.0"

[[target.starknet-contract]]
sierra = true
casm = true
# Compilation
scarb build
# Result: target/dev/my_contract_Counter.contract_class.json (Sierra)
#         target/dev/my_contract_Counter.compiled_contract_class.json (CASM)

Deployment via starkli

starkli is the primary CLI tool for interacting with StarkNet:

# Install
curl https://get.starkli.sh | sh

# Setup keystore
starkli signer keystore new ~/.starkli-wallets/deployer/keystore.json

# Declare contract class — unique to StarkNet
# First the class is registered on the network, then an instance is deployed
starkli declare \
  target/dev/my_contract_Counter.contract_class.json \
  --account ~/.starkli-wallets/deployer/account.json \
  --keystore ~/.starkli-wallets/deployer/keystore.json \
  --rpc https://starknet-mainnet.public.blastapi.io

# Deploy instance with constructor arguments
starkli deploy \
  CLASS_HASH \
  OWNER_ADDRESS \
  --account ~/.starkli-wallets/deployer/account.json \
  --keystore ~/.starkli-wallets/deployer/keystore.json \
  --rpc https://starknet-mainnet.public.blastapi.io

The two-step declare/deploy model is a StarkNet architectural feature. A single class_hash can have thousands of instances — this saves space on the network.

Deployment via starknet-rs / starknet.js

For programmatic deployment via TypeScript:

import { RpcProvider, Account, Contract, json, stark } from 'starknet'
import fs from 'fs'

const provider = new RpcProvider({
  nodeUrl: 'https://starknet-mainnet.public.blastapi.io',
})

const account = new Account(
  provider,
  ACCOUNT_ADDRESS,
  PRIVATE_KEY,
  '1' // Cairo version
)

// Declare
const compiledSierra = json.parse(
  fs.readFileSync('./target/dev/my_contract_Counter.contract_class.json').toString('ascii')
)
const compiledCasm = json.parse(
  fs.readFileSync('./target/dev/my_contract_Counter.compiled_contract_class.json').toString('ascii')
)

const declareResponse = await account.declare({
  contract: compiledSierra,
  casm: compiledCasm,
})
await provider.waitForTransaction(declareResponse.transaction_hash)

// Deploy
const deployResponse = await account.deployContract({
  classHash: declareResponse.class_hash,
  constructorCalldata: [OWNER_ADDRESS],
})
await provider.waitForTransaction(deployResponse.transaction_hash)

Verification and Voyager

StarkNet explorer — Voyager (voyager.online) and Starkscan. Verification via Voyager accepts Cairo sources and Scarb.toml. API for programmatic verification:

curl -X POST https://api.voyager.online/beta/contract/verify \
  -H "Content-Type: application/json" \
  -d '{
    "contractAddress": "0x...",
    "files": { "src/lib.cairo": "..." },
    "scarbVersion": "2.6.0"
  }'

Effort Estimation

Scenario Timeline
Simple contract (counter, storage) from scratch 4–8 h
ERC-20 / ERC-721 migration from Solidity 1 d (OpenZeppelin Cairo already implements standards)
Custom DeFi logic (rewrite from Solidity) 1–2 d + tests

If a contract is already written in Solidity and there's no fundamental need for StarkNet-specific features (native AA, ZK-proofs for custom logic) — I recommend first considering zkSync Era with its EVM compatibility. The move to Cairo is justified when you need capabilities that Cairo provides natively.