2 个版本
| 0.1.1 | 2024 年 3 月 20 日 | 
|---|---|
| 0.1.0 | 2024 年 2 月 15 日 | 
| 0.0.1 |  | 
#10 in #axiom
165KB
 4K  SLoC
axiom-sdk
用法
查看 ./examples/account_age.rs 以获取示例 Axiom 计算电路。要运行 account_age 电路
cargo run --example account_age -- --input data/account_age_input.json -k 12 -p <PROVIDER_URI> <CMD>
其中 PROVIDER_URI 是一个 JSON-RPC URL,而 CMD 是 mock,prove,keygen 或 run。
lib.rs:
axiom-sdk
安装
要将我们的 Rust 电路 SDK 安装到 Cargo 项目中,请运行
cargo add axiom-sdk
概述
要使用 Rust SDK 实现 Axiom 电路,您需要
- 指定一个由本地 Rust 类型以及 ethers-rs类型(例如u64,Address,H256等)组成的输入结构。结构名必须以Input结尾(例如MyCircuitInput)。
- 在您的输入结构上实现 AxiomComputeFn特性
输入规范
您的输入结构可以包含原生Rust类型(例如 u64,[usize; N] 等)和 ethers-rs 类型(例如 Address,H256 等),并且其名称必须以 Input 结尾(例如 MyCircuitInput)。如果它们实现了 RawInput 特性,则可以使用额外的类型(请参阅这里)。结构必须用 #[AxiomComputeInput] 属性注释,以便实现足够的电路特性。此属性还会生成一个新的结构,将 Input 替换为 CircuitInput(例如 AccountAgeInput -> AccountAgeCircuitInput),它具有指定结构体的所有字段,但使用 halo2-lib 类型在您的电路内部(如 AssignedValue<Fr>)。
以下是一个示例
#[AxiomComputeInput]
pub struct AccountAgeInput {
    pub addr: Address,
    pub claimed_block_number: u64,
}
计算函数规范
您必须在您的输入结构上实现 AxiomComputeFn。只有一个特例函数必须实现
fn compute(
    api: &mut AxiomAPI,
    assigned_inputs: AccountAgeCircuitInput<AssignedValue<Fr>>,
) -> Vec<AxiomResult>
其中应将 AccountAgeCircuitInput 替换为您派生的电路输入结构。
AxiomAPI 结构为您提供访问子查询调用函数的权限,以及一个 RlcCircuitBuilder 来指定您的电路。然后,您的计算函数应返回任何您希望传递到链上的值,在 Vec<AxiomResult> 中(AxiomResult 是一个枚举,可以是 HiLo<AssignedValue<Fr>> 或 AssignedValue<Fr>,在这种情况下,它将为您转换为高-低)。
以下是一个示例
impl AxiomComputeFn for AccountAgeInput {
    fn compute(
        api: &mut AxiomAPI,
        assigned_inputs: AccountAgeCircuitInput<AssignedValue<Fr>>,
    ) -> Vec<AxiomResult> {
        let gate = GateChip::new();
        let zero = api.ctx().load_zero();
        let one = api.ctx().load_constant(Fr::one());
        let prev_block = gate.sub(api.ctx(), assigned_inputs.claimed_block_number, one);
        let account_prev_block = api.get_account(prev_block, assigned_inputs.addr);
        let prev_nonce = account_prev_block.call(AccountField::Nonce);
        let prev_nonce = api.from_hi_lo(prev_nonce);
        api.ctx().constrain_equal(&prev_nonce, &zero);
        let account = api.get_account(assigned_inputs.claimed_block_number, assigned_inputs.addr);
        let curr_nonce = account.call(AccountField::Nonce);
        let curr_nonce = api.from_hi_lo(curr_nonce);
        api.range.check_less_than(api.ctx(), zero, curr_nonce, 40);
        vec![
            assigned_inputs.addr.into(),
            assigned_inputs.claimed_block_number.into(),
        ]
    }
}
运行电路
要运行您的电路,创建一个 main 函数,并使用您的输入结构作为泛型参数调用 run_cli 函数
fn main() {
    env_logger::init();
    run_cli::<AccountAgeInput>();
}
main 函数将运行一个 CLI,允许您运行模拟证明、密钥生成和电路证明。CLI具有以下命令
Commands:
    mock    Run the mock prover
    keygen  Generate new proving & verifying keys
    prove   Generate a new proof
    run     Generate an Axiom compute query
    help    Print this message or the help of the given subcommand(s)
Options:
    -k, --degree <DEGREE>        To determine the size of your circuit (12..25)
    -p, --provider <PROVIDER>    JSON RPC provider URI
    -i, --input <INPUT_PATH>     JSON inputs to feed into your circuit
    -d, --data-path <DATA_PATH>  For saving build artifacts (optional)
    -c, --config <CONFIG>        For custom advanced usage only (optional)
    -h, --help                   Print help
    -V, --version                Print version
例如
cargo run --example account_age -- --input data/account_age_input.json -k 12 -p <PROVIDER_URI> <CMD>
其中 PROVIDER_URI 是一个 JSON-RPC URI,而 CMD 是 mock、prove、keygen 或 run。
依赖关系
~36–52MB
~1M SLoC