一. 序言
什么是Scaffold-stark?
一个让你可以快速启动基于Starknet的去中心化应用的框架
PS:对于Starknet 初学者友好
1. 利用Scaffold-Stark开发Counter智能合约
- public 和 Private 函数
- 构造函数
- 事件
- Storage
- view和External函数
2. 利用Scaffold-Stark开发CrowdFund智能合约
- 合约之间的交互
- Mapping
- 常用函数
二. 开发环境的准备
scffold-stark-2 脚手架github地址 https://github.com/Scaffold-Stark/scaffold-stark-2
创建starknet 目录
mkdir starknet & cd starknet
拉取脚手架
git clone https://github.com/Scaffold-Stark/scaffold-stark-2.git
脚手架拉取完成
使用vscode等开发IDE打开项目
我这里使用windsurf
windsurf .
项目目录如下
.
└── scaffold-stark-2
├── CONTRIBUTING.md
├── package.json
├── packages
│ ├── nextjs
│ └── snfoundry
├── README.md
└── yarn.lock
-
安装docker desktop https://www.docker.com/
-
在vscode 中安装插件 dev container https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers
-
使用vscode 打开scaffold-stark-2项目, 打开命令面板(Cmd+Shift+P / Ctrl+Shift+P),输入Dev Container 或者 reopen in Container,如下图

可以看terminal 已经进入了docker环境
在本地使用 docker ps

这样我们就准备好了本地的开发环境
开发
在terminal中运行 yarn install
yarn install
完成

运行在本地的环境,下面是yarn chain 语法
To run a fork :
yarn chain --fork-network <URL> [--fork-block <BLOCK_NUMBER>]
yarn chain
可以看到环境给我们生成了账户

上面在docker中起到了一个本地starknet的环境,如果你想连接其他环境可以是配置文件 packages/nextjs/scaffold.config.ts
从新开启一个terminal,运行 yarn start
yarn start

可以看到通过 http://localhost:3000 可以访问项目网站

这时我们是没有看到项目中的合约

这时可以运行yarn deploy部署本地的合约到docker 的starknet上
yarn deploy

问题
yarn deploy 的时候报错
yarn deploy
Compiling contracts v0.2.0 (/workspaces/scaffold-stark-2/packages/snfoundry/contracts/Scarb.toml)
error: Plugin diagnostic: `starknet::interface` functions must have a `self` parameter.
--> /workspaces/scaffold-stark-2/packages/snfoundry/contracts/src/Counter.cairo:5:5
fn increment();
^^^^^^^^^^^^^^
warn: Plugin diagnostic: Failed to generate ABI: Entrypoints must have a self first param.
--> /workspaces/scaffold-stark-2/packages/snfoundry/contracts/src/Counter.cairo:9:1
#[starknet::contract]
^^^^^^^^^^^^^^^^^^^^^
error[E0004]: Not all trait items are implemented. Missing: 'increment'.
--> /workspaces/scaffold-stark-2/packages/snfoundry/contracts/src/Counter.cairo:21:10
impl Counter of ICounter<ContractState> {
^^^^^^^
error[E0002]: Method `read` not found on type `core::starknet::storage::storage_base::StorageBase::<core::integer::u256>`. Consider importing one of the following traits: `starknet::storage::StoragePointerReadAccess`.
--> /workspaces/scaffold-stark-2/packages/snfoundry/contracts/src/Counter.cairo:23:26
self.counter.read()
^^^^
源代码如下:
#[starknet::interface]
trait ICounter<TContractState> {
// view function
fn get_count(self: @TContractState) -> u256;
fn increment();
}
#[starknet::contract]
mod Counter {
use super::ICounter;
#[storage]
struct Storage {
counter: u256,
}
// public functions
// increment and get_count
#[abi(embed_v0)]
impl Counter of ICounter<ContractState> {
fn get_count(self: @ContractState) -> u256 {
self.counter.read()
}
// fn increment(ref self: ContractState) {
// let current = self.counter.read();
// self.counter.write(current + 1_u256);
// }
}
}
- #[starknet::interface] 里的函数必须有 self 参数
[error: Plugin diagnostic:
starknet::interfacefunctions must have aselfparameter]
- impl 里必须实现所有接口方法 [ error E0004: Not all trait items are implemented. Missing: 'increment'.]
- read 和 ==write== 方法报错
[errorE0002: Method
readnot found on type ]
修改后代码:
#[starknet::interface]
trait ICounter<TContractState> {
// view function
fn get_count(self: @TContractState) -> u256;
fn increment(ref self: TContractState);
}
#[starknet::contract]
mod Counter {
use super::ICounter;
use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};
#[storage]
struct Storage {
counter: u256,
}
#[abi(embed_v0)]
impl Counter of ICounter<ContractState> {
fn get_count(self: @ContractState) -> u256 {
self.counter.read()
}
fn increment(ref self: ContractState) {
let current = self.counter.read();
self.counter.write(current + 1_u256);
}
}
}
总结代码的问题: 1. fn increment(); → 必须带 self。 2. impl 里少了 increment 的实现。 3. 忘记 use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; 导入。
继续运行yarn deploy命令,还是有报错

报错关键信息:
Killed
Error during deployment: Error: Command failed: cd contracts && scarb build ...
status: 137
在 Linux / Devcontainer 环境里,status: 137 几乎都是 内存不足 (OOM) 被系统 kill 掉。
也就是说,不是 Cairo 合约本身写错了,而是 scarb build 过程中编译器占用的内存太大,被容器或宿主机 kill 掉了。
那我们就查看容器内存配置
docker inspect 5b9e82ddb94e --format='{{.HostConfig.Memory}}'

如果输出是 0,表示没有限制(容器能用宿主机所有可用内存)。所以应该问题不是内存问题
在contracts目录下单独构建
scarb build -vv

完成了构建。 再尝试清理缓存
scarb clean
再次运行 yarn deploy
yarn deploy
部署成功了
启动前端
yarn start
访问本地 http://localhost:3000,查看页面我们的合约已经部署上链了
