#switchboard #verifiable #function #sgx #chain #container #verification

sb_functions_sdk

这个crate是编写Switchboard可验证函数的实用SDK

9个版本

0.1.8 2023年9月1日
0.1.7 2023年6月14日

#18#switchboard

Download history 6/week @ 2024-03-30

118 每月下载量

MIT 许可证

27KB
576

Switchboard Functions SDK

crates.io

此SDK是离链编写可验证函数的顶级实用SDK。

Switchboard函数提供作为区块链原语的安全区域(TEE)。

使用Switchboard函数,您可以使用Switchboard的预言机网络验证任何由Switchboard签名的代码是否在SGX内部运行。

一次性操作

Switchboard允许您按cron或按需计划运行任何代码。

Solana函数示例

const DEMO_PID: Pubkey = pubkey!("8kjszBCEgkzAsU6QySHSZvr9yFaboau2RnarCQFFvasS");

#[derive(Clone, AnchorSerialize, AnchorDeserialize, Debug, Default)]
pub struct PingParams {
    pub prices: Vec<BorshDecimal>,
    pub volumes: Vec<BorshDecimal>,
    pub twaps: Vec<BorshDecimal>,
}
impl Discriminator for PingParams {
    const DISCRIMINATOR: [u8; 8] = [0; 8];
    fn discriminator() -> [u8; 8] {
        ix_discriminator("ping")
    }
}
impl InstructionData for PingParams {}

#[allow(non_snake_case)]
#[derive(Deserialize, Clone, Debug)]
struct Ticker {
    symbol: String,
    weightedAvgPrice: String,
    lastPrice: String,
    volume: String,
}

#[tokio::main(worker_threads = 12)]
async fn main() {
    let symbols = ["BTCUSDC", "ETHUSDC", "SOLUSDT"];

    let symbols = symbols.map(|x| format!("\"{}\"", x)).join(",");
    let tickers = reqwest::get(format!(
        "https://api.binance.com/api/v3/ticker?symbols=[{}]&windowSize=1h",
        symbols
    ))
    .await
    .unwrap()
    .json::<Vec<Ticker>>()
    .await
    .unwrap();
    println!("{:#?}", tickers);

    let enclave_signer = generate_signer();
    let (fn_key, fn_quote) = fn_accounts();
    let ix = Instruction {
        program_id: DEMO_PID,
        accounts: vec![
            AccountMeta::new_readonly(fn_key, false),
            AccountMeta::new_readonly(fn_quote, false),
            AccountMeta::new_readonly(enclave_signer.pubkey(), true),
        ],
        data: PingParams {
            prices: tickers
                .iter()
                .map(|x| BorshDecimal::from(&x.lastPrice))
                .collect(),
            volumes: tickers
                .iter()
                .map(|x| BorshDecimal::from(&x.volume))
                .collect(),
            twaps: tickers
                .iter()
                .map(|x| BorshDecimal::from(&x.weightedAvgPrice))
                .collect(),
        }
        .data(),
    };
    FunctionResult::generate_verifiable_solana_tx(enclave_signer, vec![ix])
        .await
        .unwrap()
        .emit();
}

Solana链上验证

为了接收结果并验证SGX报价是否通过,请在此链上使用此crate:https://crates.io/crates/solana_attestation_sdk

查看此类函数的示例输出:请参阅 https://explorer.solana.com/tx/FnJ13SxdKmMadsnUg884msNnM76QuJkV8gxj9CEikBYbcJzgS3x1KLBiZzrav3tntJezhfYyn2KqrA7AoLRpf9k?cluster=devnet

示例函数

要查看示例函数容器,请参阅:https://github.com/switchboard-xyz/sbv3-function-example

将您的函数添加到cron计划

要定期运行您的函数,请使用我们的typescript sdk将其附加到验证队列

import {
  SwitchboardProgram,
  FunctionAccount,
  AttestationQueueAccount,
} from "@switchboard-xyz/solana.js";

// ...
const functionKeypair = anchor.web3.Keypair.generate();
const [functionAccount] = await FunctionAccount.create(switchboard, {
  name: "FUNCTION_NAME",
  metadata: "FUNCTION_METADATA",
  schedule: "30 * * * * *", // every 30 seconds
  container: "switchboardlabs/function-example",
  version: "v1",
  mrEnclave: new Uint8Array(0), // Leave blank to auto-populate after first run
  attestationQueue: new AttestationQueueAccount(
    switchboard,
    <QUEUE_PUBKEY>
  ),
  keypair: functionKeypair,
});
console.log(`Function: ${functionAccount.publicKey.toString()}`);

依赖项

~76MB
~1.5M SLoC