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