You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中如何使用Borsh反序列化长度为1000000的自定义数组?

问题解答

首先可以确定:Borsh支持对该类型的大数组进行序列化/反序列化,你遇到的报错是Borsh默认实现限制和存储设计不合理共同导致的,具体原因和解决方法如下:

报错根因

Borsh 0.10版本之前仅为长度≤32的数组默认实现了BorshSerialize、BorshDeserialize trait,你使用的长度为1000000的数组超出了默认实现范围,因此会抛出trait未实现的错误。
额外需要注意的是:(Pubkey, u8)单个元素大小为33字节,100万元素总大小为33MB,远超出Solana单账户最大10MB的存储上限,即便解决了序列化问题也无法部署上链。

可选解决方案

  • 方案1:手动实现大数组的Borsh trait(仅适合本地测试)
    如果你仅需要本地测试该结构,可以通过newtype包裹大数组后手动实现序列化/反序列化逻辑,示例代码如下:

    use borsh::{BorshSerialize, BorshDeserialize};
    use anchor_lang::prelude::*;
    
    // 单个像素结构,派生Borsh trait
    #[derive(Clone, Copy, BorshSerialize, BorshDeserialize, Default)]
    pub struct Pixel(pub Pubkey, pub u8);
    
    // 大数组newtype包裹
    #[derive(Clone, Copy, Default)]
    pub struct PixelArray(pub [Pixel; 1_000 * 1_000]);
    
    // 手动实现序列化
    impl BorshSerialize for PixelArray {
        fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
            for pixel in self.0.iter() {
                pixel.serialize(writer)?;
            }
            Ok(())
        }
    }
    
    // 手动实现反序列化
    impl BorshDeserialize for PixelArray {
        fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
            let mut arr = [Pixel::default(); 1_000 * 1_000];
            for pixel in arr.iter_mut() {
                *pixel = Pixel::deserialize_reader(reader)?;
            }
            Ok(Self(arr))
        }
    }
    

    之后账户结构体中直接使用pixels: PixelArray即可通过编译。

  • 方案2:拆分存储到动态Vec+多账户(生产环境推荐)
    放弃单账户存储全量像素的设计,按坐标区块拆分像素存储到多个独立账户,每个账户内使用Borsh原生支持的Vec<(Pubkey, u8)>存储像素集合,单账户存储像素数量控制在30万以内即可满足10MB的大小限制。
    对应账户字段定义如下:

    #[account]
    pub struct PixelChunk {
        // 区块坐标,用于定位
        pub chunk_x: u16,
        pub chunk_y: u16,
        // 该区块内的像素集合,Borsh原生支持序列化
        pub pixels: Vec<(Pubkey, u8)>,
    }
    

    初始化账户时需要提前计算空间:8 + 2 + 2 + 4 + 33 * 单区块像素数量。

  • 方案3:单像素对应PDA存储(存储成本最优)
    如果你的业务场景中需要频繁读写单个像素,可以直接为每个像素派生独立PDA,PDA种子使用像素的x、y坐标即可,单个像素账户仅需要存储33字节数据,不需要维护数组结构,完全避免了大数组序列化的问题,读写成本也更低。

内容的提问来源于stack exchange,提问作者Foobar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 22:15:04