A Developer’s Guide to Starknet for Solidity Developers

A Comprehensive Guide to Starknet for Solidity Programmers

Author: Tiny Bear; Source: Denge Chain Community

Starknet is an Ethereum Layer 2 ZKRollup scaling solution. Unlike the development of Layer 2 scaling solutions compatible with EVM, Starknet has its own mode of development.

This article introduces how to develop contracts on Starknet[1] and deploy them to the Starknet test network. In order to help Solidity smart contract developers understand Starknet development more quickly, the article also includes some concept comparisons.

Recently, I have been learning Starknet development through the Basecamp[2] initiated by the Starknet Foundation, Denge Chain Community, and Openbuild’s Bootcamp[3]. This article is my study notes.

Come join our Bootcamp, there are rewards for completing assignments. In January, there will also be a Starknet hackathon. If you are interested, you can contact Xiaona (WeChat: upchainedu) to get started.

Development Language: Cairo vs Solidity

Solidity[4] is a language designed for the EVM. Its syntax is similar to Python and JavaScript. In order to verify consistency, Ethereum execution clients will re-execute all transactions that call contracts on various nodes to check if the results are the same.

Starknet uses the programming language Cairo. Cairo is a programmable language that generates proofs (without the need for users to understand ZK knowledge). The provable result is obtained from a specific program and specific input, without the need to run the program repeatedly (thus saving a lot of repeated operating expenses and achieving scaling effects).

Cairo is a general-purpose programmable language that can be widely used in other scenarios besides Starknet.

Cairo runs on CairoVM, which is similar to the Rust language and has a similar ownership model to Rust. The learning curve is a bit high. Chinese users learning Cairo can refer to the book “Cairo in Starknet” [6] translated by StarknetAstro.

Accounts

In the EVM[7], there are two types of accounts: EOA (Externally Owned Account) and contract accounts. Users usually use wallets such as MetaMask to manage external accounts.

In Starknet, it natively supports account abstraction (AA), and all accounts are smart contracts. They use contracts to verify transactions, support various signature verification methods, and support social recovery and batch transactions. The main wallets used are Braavos[8] and ArgentX[9].

Project Management Tools

Solidity projects usually use Foundry or Hardhat for development.

Cairo uses Scarb: Scarb is the project management tool of Cairo. It integrates package managers and compilers. Scarb can manage dependencies and compile Cairo projects.

Scarb installation:

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

First Cairo Contract

After installing Scarb, you can create a project. Our first Cairo contract is Ownable:

scarb new ownable

Its structure is as follows:

   src/      lib.cairo     .gitignore     Scarb.toml

Scarb.toml

Scarb.toml is the manifest file for the project, which contains the metadata for compiling the project. Copy the following content into the Scarb.toml file:

[LianGuaickage]name = "ownable"version = "0.1.0"[dependencies]starknet = ">=2.2.0"[[target.starknet-contract]]sierra = true

The first part of Scarb.toml is [LianGuaickage], which defines the project package and includes the name and version fields.

dependencies defines the library dependencies, and our contract requires the official library: starknet.

target defines the compilation target using .starknet-contract, with the intermediate language sierra.

For more key-value definitions in Scarb.toml, refer to: https://docs.swmansion.com/scarb/docs/reference/manifest.html

Cairo Contract Code

A Starknet contract is actually a Cairo module, and we replace the code in lib.cairo with the following code (see Github[10]):

#[starknet::contract]mod ownable {    use starknet::ContractAddress;    #[storage]    struct Storage {        owner: ContractAddress,    }    #[constructor]    fn constructor(ref self: ContractState,        init_owner: ContractAddress ) {            self.owner.write(init_owner);        }    #[external(v0)]    fn get_owner(self: @ContractState) -> ContractAddress {        self.owner.read()    }}

This contract code uses some macros (starting with #) to define the contract, define storage, define constructor and external functions.

Macros are a slightly more complex concept, but all we need to know is that they are used to expand the code during the compilation phase.

Compilation

Use the command:

scarb build

If the code is correct, you will see similar output:

  Compiling ownable v0.1.0 (/Users/emmett/CairoProject/ownable/Scarb.toml)   Finished release target(s) in 1 second

Compilation will generate a compiled file in target/dev/ folder: ownable.starknet_artifacts.json and ownable_ownable.contract_class.json.

Now, the contract is ready.

Next, let’s see how to deploy it on the Starknet network.

Installation of Starkli

Starkli is a command-line tool used to interact with the Starknet network (including the local network).

Starkli provides a package manager called starkliup, which allows you to fetch and install the latest release binaries. Similar to Rust, where rustup is used for installing, managing, and updating rustc.

To install starkliup:

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

Follow the installation prompts to add starkliup to the environment variable and use starkliup to install starkli with the following command:

starkliup

Wait a moment, and then starkli can be used in our terminal.

starkli --version
0.1.20 (e4d2307)

Preparing the Wallet

In order to deploy contracts on the chain, we need a wallet account to pay for gas fees. Therefore, we need to have a usable account.

You can choose Braavos[11] or ArgentX[12], both of which have browser plugin versions and operate similarly to MetaMask. Follow the instructions to create a wallet and obtain some ETH from the official faucet[13].

In Starknet, wallet accounts are smart contracts. After creating the wallet, the address we see is actually a reversible address (it doesn’t exist on the chain), and the wallet contract will be automatically deployed when the first transaction is initiated.

In Starknet, each smart wallet has two components for control: a signer and an account description.

Unlike the commonly used EOA wallets on Ethereum, EOA wallets are verified and signed by nodes and only support a private key (or mnemonic phrase, Keystore file) for managing accounts.

Smart wallets verify signatures in contracts and support multiple signature methods (signers), while the account description is used to describe the relationship between the signature and the smart wallet account.

Creating a Signer

First, create a new folder named .wallets to store the required files for the smart wallet.

mkdir .wallets

A signer can be a private key or an encrypted keystore. To avoid exposing the private key in plain text, the latter is usually chosen.

We can create a keystore from the private key exported from Braavos or ArgentX:

> starkli signer keystore from-key .wallets/keystore.json
Enter private key: Enter LianGuaissword:
Created new encrypted keystore file: /Users/emmett/CairoProject/ownable/.wallets/keystore.json
Public key: 0x075ce30939a0f44df2dbad6f24d1e82200a1ee084a387afc1bc657aba61f441b

This command prompts us to enter the private key and password. The private key can be exported from the wallet, as shown in the following image:

Afterwards, .wallets/keystore.json will be generated. When initiating a transaction with Starkli, Starkli can use the keystore to sign the transaction.

Creating an Account Description

If the account already exists on Starknet, you can use starkli account fetch to fetch the account information and create an account description file:

starkli account fetch 0x0325E8b88aedBac03c5dc9E22bF94d47E6508f9723FD085f5D7b5809afA48bC4 --output .wallets/account.json --rpc https://starknet-goerli.g.alchemy.com/v2/xxxxxxx

--output specifies the output location of the account description file.

--rpc specifies the node RPC, where we use Alchemy’s[14] node RPC here.

If the account is not deployed on the chain, you will encounter the following error:

Error: code=ContractNotFound, message="Contract not found"

You can execute a transfer transaction on the wallet, which will automatically create the wallet account.

Declare Contract (declare)

On Ethereum, you can directly deploy a Solidity contract to the network. Starknet is divided into two parts: first, publish the contract code (compiled intermediate representation), and then create an instance of the contract with the contract code.

The first part is called: declaring (declare) the contract, and the second part is called deploying the contract.

Declaring the contract requires initiating a transaction. For convenience, write the necessary account and RPC into the environment variables:

Create a file: env.sh:

export STARKNET_RPC="https://starknet-goerli.g.alchemy.com/v2/replace_with_your_key"export STARKNET_ACCOUNT=".wallets/account.json"export STARKNET_KEYSTORE=".wallets/keystore.json"

Please use your RPC key and account file in the environment variables. Apply the environment variables in the command line using source env.sh.

Use the starkli declare command to declare the contract (it will automatically use the above environment variables):

> starkli declare target/dev/ownable_ownable.contract_class.jsonEnter keystore password:Sierra compiler version not specified. Attempting to automatically decide version to use...Network detected: goerli-1. Using the default compiler version for this network: 2.1.0. Use the --compiler-version flag to choose a different version.Declaring Cairo 1 class: 0x077bd1a78e208a5e73995278e4300066fa14259f48c33123fe0de13bf8b8a24dCompiling Sierra class to CASM with compiler version 2.1.0...CASM class hash: 0x047ddccc9bd2effa6fd847b5338c59e629aab644fa847dc1ff4dfc9d37c2a318Contract declaration transaction: 0x01c1bc0f998f237d4ebdb3a4e7f0ff4973fc6b9b1a1d1c2ea9832865c439b8dfClass hash declared:0x077bd1a78e208a5e73995278e4300066fa14259f48c33123fe0de13bf8b8a24d

The ownable_ownable.contract_class.json in the command is the file generated by scarb build.

After successfully declaring the contract, a class hash will be obtained.

Deploy Contract

Deploy the contract using the command: starkli deploy class_hash [parameters], therefore:

starkli deploy 0x077bd1a78e208a5e73995278e4300066fa14259f48c33123fe0de13bf8b8a24d 0x0325E8b88aedBac03c5dc9E22bF94d47E6508f9723FD085f5D7b5809afA48bC4

If there are no errors, you will receive a similar response:

Deploying class 0x077bd1a78e208a5e73995278e4300066fa14259f48c33123fe0de13bf8b8a24d with salt 0x0633b1c1d0cbedc9f5cd924115b1dad08718d1c39fc53bc54da9d667b09a99af...The contract will be deployed at address 0x03264b6bdb740c14b776972ce2065c4b79cc6002fb0438ade0bb480c4774b272Contract deployment transaction: 0x013eaf1be2782413ded7049b48da459d9f41c3a3d68b69da7b38a2d2c3b84a8dContract deployed:0x03264b6bdb740c14b776972ce2065c4b79cc6002fb0438ade0bb480c4774b272

You can also view the contract on the StarkScan browser:

https://testnet.starkscan.co/contract/0x03264b6bdb740c14b776972ce2065c4b79cc6002fb0438ade0bb480c4774b272#overview

Calling the Contract

There are two methods for interacting with the contract: call and invoke.

call is used for read methods, and invoke is used to write data to the contract.

Now, let’s call the get_owner method of the contract:

starkli call 0x03264b6bdb740c14b776972ce2065c4b79cc6002fb0438ade0bb480c4774b272 get_owner

Response:

[    "0x0325e8b88aedbac03c5dc9e22bf94d47e6508f9723fd085f5d7b5809afa48bc4"]

You can also call the contract in the browser.

https://testnet.starkscan.co/contract/0x03264b6bdb740c14b776972ce2065c4b79cc6002fb0438ade0bb480c4774b272#read-write-contract

Summary

I believe you now have an understanding of developing contracts on Starknet. Here is a table summarizing the differences between EVM development and Starknet development:

EVM Starknet
Development Language Solidity Cairo
Development Tools Use Foundry (forge), Hardhat Use Scarb (project package management and compilation)
Interacting with the chain cast/chisel/or directly call web3.js in the console starkli
Local simulation node anvil or Hardhat Node Katana (explained later)
Accounts EOA, AA wallets Only AA wallets
Wallets Such as MetaMask Braavos, ArgentX
Deployment Method Compile and deploy the contract bytecode directly Declare the contract (code) first, then deploy an instance of the contract

We will continue to update Blocking; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Bitcoin

Ark Invest Divests Coinbase and GBTC Holdings, Acquires Bitcoin ETFs 📉🤝🚀

Ark Invest made a significant investment of $92 million in the ProShares Bitcoin Strategy ETF (BITO) and also acquire...

Blockchain

UK Government Drops the Regulatory Hammer Crypto Assets and Stablecoins Get a Dose of Rules to Prevent FTX 2.0

UK regulators pledge to implement new rules for crypto assets and stablecoins, promoting their widespread use in the ...

Market

Vanguard CEO Shuns Bitcoin ETF, Urges Long-Term Investment The Plot Thickens!

Vanguard CEO Rejects Bitcoin ETF Support, Stresses Firm's Focus on Long-Term Investing Strategy.

Bitcoin

Celsius Battles the SEC Fires During Its Bankruptcy Comeback Strategy

Fashionista, the SEC, Celsius Creditors Committee, and Fahrenheit are in talks regarding the assets owned by the Cels...

DeFi

Grove Raises $7.9 Million in Funding to Revolutionize DeFi

Grove secures $7.9 million from top investors to strengthen DeFi efforts.

Blockchain

🚀 TIA Token Hits New All-Time High: Celestia on the Rise

Since its launch in 2023, Celestia (TIA) has experienced extraordinary success, reaching an impressive value of $20 a...