将任意长度数据传递给 Anchor (Solana) 指令调用的最佳方法是什么?

What's the best way to pass arbitrary length data to an Anchor (Solana) instruction call?

我想在 Solana 帐户中存储任意长度的结构化数据集合...类似于 [{foo: "bar"}, {foo: "quux"}] 在 JS 中的内容,理想情况下是在对象中任意嵌套。我正在考虑将它存储在 Rust 结构中的 Vec<T> 中(这是正确的方法吗?)但目前还不清楚如何使用 Anchor RPC 通过网络发送它,即如何对其进行 borsh 编码。

更具体地说,例如我有 this instruction 但我不知道如何使用 Anchor 的 program.rpc.createWorkSpec.

将数据发送给它

有什么指点吗?

好吧,这和我开始时的预期差不多,所以我一定是在我尝试过的中间过程中做错了什么。

您可以看到 https://github.com/workbenchapp/worknet/blob/c51113b09b64201cc25a22dfb845a295f6ee5072/programs/worknet/src/lib.rs#L12 接受 Vec<Container> 作为其参数之一 ...

#[derive(Default, Copy, Clone, AnchorSerialize, AnchorDeserialize)]
pub struct PortMapping {
    pub inner_port: u16,
    pub outer_port: u16,
    pub port_type: PortType,
}

#[derive(Clone, AnchorSerialize, AnchorDeserialize)]
pub struct Container {
    pub image: String,
    pub args: Vec<String>,
    pub port_mappings: Vec<PortMapping>,
}

#[account]
#[derive(Default)]
pub struct WorkSpec {
    containers: Vec<Container>,
}

可以传递嵌套的 object/array 映射(rust_snake 转换为 jsCamelCase

const specContainers = [
    {
        image: "alpine",
        args: ["echo", "hi"],
        portMappings: [],
    },
];
await program.rpc.createWorkSpec(specContainers, {
    accounts: {
        spec: spec.publicKey,
        authority: provider.wallet.publicKey,
        systemProgram: SystemProgram.programId,
    },
    signers: [spec],
});