带构造函数的Cairo合约无法编译,请求技术协助
Cairo合约编译失败的修复方案
问题分析与修复步骤
你的合约存在语法规范和账户合约必填逻辑的问题,以下是具体修复点:
1. 修正use语句的空格错误
Cairo中use语句的模块与成员之间不能有空格,所有类似use serde:: Serde;的写法都要去掉中间空格,比如:
use starknet:: ContractAddress;→use starknet::ContractAddress;use ecdsa :: check_ecdsa_signature;→use ecdsa::check_ecdsa_signature;
2. 修正存储变量的访问方式
构造函数中访问存储字段必须通过storage实例,不能直接用字段名作为模块调用:
- 错误写法:
fam_code::write(_fam_key); - 修正写法:
storage.fam_code.write(_fam_key);
3. 补充账户合约必需的入口函数
标记#[account_contract]的合约必须实现__validate__和__execute__函数,这是StarkNet账户合约的强制要求,分别负责交易验证和执行逻辑。
修复后的完整合约代码
use serde::Serde; use starknet::ContractAddress; use array::ArrayTrait; use option::OptionTrait; #[derive(Drop, Serde)] struct Call{ to: ContractAddress, selector: felt252, calldata: Array<felt252>, } #[account_contract] mod Account{ use starknet::get_caller_address; use starknet::get_tx_info; use starknet::call_contract_syscall; use starknet::VALIDATED; use array::ArrayTrait; use array::SpanTrait; use box::BoxTrait; use ecdsa::check_ecdsa_signature; use option::OptionTrait; use super::Call; use starknet::ContractAddress; use zeroable::Zeroable; use serde::ArraySerde; struct Storage { fam_code: felt252, } #[constructor] fn constructor(_fam_key: felt252){ storage.fam_code.write(_fam_key); } // 账户合约必填:交易验证函数 #[external(v0)] fn __validate__(self: @ContractState) -> felt252 { // 实际场景需替换为ECDSA签名验证逻辑,示例直接返回验证通过标识 VALIDATED } // 账户合约必填:交易执行函数 #[external(v0)] fn __execute__(self: @ContractState, calls: Array<Call>, nonce: felt252) -> Array<felt252> { let mut results = ArrayTrait::new(); for call in calls { let result = call_contract_syscall( call.to, call.selector, call.calldata.span() ).unwrap(); results.append(result); } results } }
编译验证
修复后执行scarb build命令即可完成编译。注意:示例中的__validate__仅做演示,生产环境需要补充完整的签名验证逻辑,确保只有账户所有者能发起合法交易。
内容的提问来源于stack exchange,提问作者CCDev
相关产品推荐
相关产品推荐

