Contracts for Cairo
A library for secure smart contract development written in Cairo for Starknet, a decentralized ZK Rollup.
This repo contains highly experimental code. Expect rapid iteration. Use at your own risk. |
You can track our roadmap and future milestones in our Github Project. |
Installation
The library is available as a Scarb package. Follow this guide for installing Cairo and Scarb on your machine before proceeding, and run the following command to check that the installation was successful:
$ scarb --version
scarb 2.3.0 (f306f9a91 2023-10-23)
cairo: 2.3.0 (https://crates.io/crates/cairo-lang-compiler/2.3.0)
sierra: 1.3.0
Basic usage
This is how it looks to build an account contract using the account module.
Copy the code into src/lib.cairo
.
#[starknet::contract]
mod MyAccount {
use openzeppelin::account::Account;
use openzeppelin::account::account::PublicKeyTrait;
use openzeppelin::account::interface;
use openzeppelin::introspection::interface::ISRC5;
use starknet::account::Call;
// Storage members used by this contract are defined in each imported
// module whose `unsafe_state` is used. This design will be improved
// with the addition of components in the future.
#[storage]
struct Storage {}
#[constructor]
fn constructor(ref self: ContractState, public_key: felt252) {
let mut unsafe_state = _unsafe_state();
Account::InternalImpl::initializer(ref unsafe_state, public_key);
}
#[external(v0)]
impl SRC6Impl of interface::ISRC6<ContractState> {
fn __execute__(self: @ContractState, mut calls: Array<Call>) -> Array<Span<felt252>> {
Account::SRC6Impl::__execute__(@_unsafe_state(), calls)
}
fn __validate__(self: @ContractState, mut calls: Array<Call>) -> felt252 {
Account::SRC6Impl::__validate__(@_unsafe_state(), calls)
}
fn is_valid_signature(
self: @ContractState, hash: felt252, signature: Array<felt252>
) -> felt252 {
Account::SRC6Impl::is_valid_signature(@_unsafe_state(), hash, signature)
}
}
#[external(v0)]
impl SRC5Impl of ISRC5<ContractState> {
fn supports_interface(self: @ContractState, interface_id: felt252) -> bool {
Account::SRC5Impl::supports_interface(@_unsafe_state(), interface_id)
}
}
#[external(v0)]
impl PublicKeyImpl of PublicKeyTrait<ContractState> {
fn get_public_key(self: @ContractState) -> felt252 {
Account::PublicKeyImpl::get_public_key(@_unsafe_state())
}
fn set_public_key(ref self: ContractState, new_public_key: felt252) {
let mut unsafe_state = _unsafe_state();
Account::PublicKeyImpl::set_public_key(ref unsafe_state, new_public_key);
}
}
#[external(v0)]
fn __validate_deploy__(
self: @ContractState,
class_hash: felt252,
contract_address_salt: felt252,
_public_key: felt252
) -> felt252 {
Account::__validate_deploy__(
@_unsafe_state(), class_hash, contract_address_salt, _public_key
)
}
#[inline(always)]
fn _unsafe_state() -> Account::ContractState {
Account::unsafe_new_contract_state()
}
}
You can now compile it:
scarb build