合约代码和测试代码

snforge init 创建项目,自动生成一份合约代码和测试代码

合约代码位于src目录下

#[starknet::interface]
trait IHelloStarknet<TContractState> {
    fn increase_balance(ref self: TContractState, amount: felt252);
    fn get_balance(self: @TContractState) -> felt252;
}

#[starknet::contract]
mod HelloStarknet {
    #[storage]
    struct Storage {
        balance: felt252, 
    }

    #[external(v0)]
    impl HelloStarknetImpl of super::IHelloStarknet<ContractState> {
        fn increase_balance(ref self: ContractState, amount: felt252) {
            assert(amount != 0, 'Amount cannot be 0');
            self.balance.write(self.balance.read() + amount);
        }

        fn get_balance(self: @ContractState) -> felt252 {
            self.balance.read()
        }
    }
}

测试代码位于test目录下

use starknet::ContractAddress;

use snforge_std::{declare, ContractClassTrait};

use x0_contracts::IHelloStarknetSafeDispatcher;
use x0_contracts::IHelloStarknetSafeDispatcherTrait;

fn deploy_contract(name: felt252) -> ContractAddress {
    let contract = declare(name);
    contract.deploy(@ArrayTrait::new()).unwrap()
}

#[test]
fn test_increase_balance() {
    let contract_address = deploy_contract('HelloStarknet');

    let safe_dispatcher = IHelloStarknetSafeDispatcher { contract_address };

    let balance_before = safe_dispatcher.get_balance().unwrap();
    assert(balance_before == 0, 'Invalid balance');

    safe_dispatcher.increase_balance(42).unwrap();

    let balance_after = safe_dispatcher.get_balance().unwrap();
    assert(balance_after == 42, 'Invalid balance');
}

#[test]
fn test_cannot_increase_balance_with_zero_value() {
    let contract_address = deploy_contract('HelloStarknet');

    let safe_dispatcher = IHelloStarknetSafeDispatcher { contract_address };

    let balance_before = safe_dispatcher.get_balance().unwrap();
    assert(balance_before == 0, 'Invalid balance');

    match safe_dispatcher.increase_balance(0) {
        Result::Ok(_) => panic_with_felt252('Should have panicked'),
        Result::Err(panic_data) => {
            assert(*panic_data.at(0) == 'Amount cannot be 0', *panic_data.at(0));
        }
    };
}

执行测试

执行测试命令

snforge test

声明合约

部署合约之前要先declare

sncast declare -c HelloStarknet

command: declare
class_hash: 0x6e8c928290f1168df3dbb85005f7bdc674005e396d62d472e7c8b62517370f2      
transaction_hash: 0x23798767452c00cf04e744810477afe107061057a880f7151b6ba20171a18fe

部署合约

待declare交易完成执行部署合约命令,需指定上一步得到的class_hash

sncast deploy -g 0x6e8c928290f1168df3dbb85005f7bdc674005e396d62d472e7c8b62517370f2

command: deploy
contract_address: 0x38cba543f1cc1ff29a2ffd0b86febd612c9918fed490b97ca2258f588747d9e
transaction_hash: 0x3e5c1c8ec1ed7435c855b0272d36e4d82c3b39dd6899d90385c4f441d148ba2

调用合约

查询-call

指定合约和方法名,查询balance值

结果为0

sncast call -a 0x38cba543f1cc1ff29a2ffd0b86febd612c9918fed490b97ca2258f588747d9e -f get_balance  

command: call
response: [0x0]

交易-invoke

调用increase_balance 方法 参数为1

sncast invoke -a 0x38cba543f1cc1ff29a2ffd0b86febd612c9918fed490b97ca2258f588747d9e -f increase_balance -c 1

command: invoke
transaction_hash: 0x478eeb74f7c034a0344be5114dccdc9c6c7d91fe2f822e8d648a1accab5e3cb

再次执行查询方法

结果为1

sncast call -a 0x38cba543f1cc1ff29a2ffd0b86febd612c9918fed490b97ca2258f588747d9e -f get_balance

command: call
response: [0x1]