热门话题
#
Bonk 生态迷因币展现强韧势头
#
有消息称 Pump.fun 计划 40 亿估值发币,引发市场猜测
#
Solana 新代币发射平台 Boop.Fun 风头正劲
上周 @redacted_noah 在 @anchorlang 上发了一篇关于 Zero Copy™️ 的 rant,称其是每个 @solana 开发者的完美 alpha。
我原以为 zero copy 只用于非常大的账户。
我意识到我有时使用它的原因完全不明。
我决定深入研究,让我带你一起了解 👇

@SuperteamFRANCE @SuperteamJapan 首先,我们为什么要讨论零拷贝数据解析?
Anchor 的默认数据解析器称为 Borsh。
在调用 Anchor 指令时,Borsh 将把您的账户数据复制到 Borsh 结构中(到一个称为 "堆" 的内存槽,稍后会详细介绍)
当您在指令中包含一个账户时,您使用的格式看起来像这样。

使用零拷贝时,您的代码将如下所示。

那么那里到底发生了什么?
一开始并不明显!
首先,我们需要理解 Solana 如何使用其 Rust 应用数据:堆、栈和 "零拷贝" 空间。
1. 栈:
这是我们存储本地和简单数据类型的地方。
每个栈有 4KiB 的空间,每个函数调用都有自己的 4KiB 分配。
当你超过最大栈大小时,会出现类似于 "在地址 XXXXX 的栈帧 X 中发生访问违规,大小为 X。" 的错误。
在 Anchor 中,解决此错误的第一个方法是使用 `Box` 将数据从栈移动到 "堆" 👇

2. Solana中的堆:
程序默认在BPF虚拟机中运行,堆大小为32KB。这是一次性分配,用于一次完整的调用。
在这里,您将存储更多动态数据类型(Vec,String)
使用Borsh反序列化账户时,数据会复制到堆中,快速占用空间。
3. 零拷贝:
如果你必须绕过堆和栈,因为你的数据预算超出了(大量的CPI,带有大账户),你将使用零拷贝。
零拷贝使你能够在不先分配或复制数据的情况下直接处理数据,跳过反序列化。
何时使用零拷贝是有意义的?
1. 大数据
2. 处理大量CPI
让我们继续:
1. 大数据
假设你想跟踪一份钱包列表,以便能够进行完全的链上检查(如果你需要这样做,可以研究梅克尔树😅,这不是正确的方法)
就像在抽奖中,在进行最终抽奖并选择获胜者之前,存储每个参与者的地址。
这将很容易超过32kb的内存。一个参与者 = 32字节,因此如果你计划成功并为1000个参与者分配空间,这已经占用了整个堆大小(32,000字节)
在这种情况下,你可以使用零拷贝来绕过限制,并能够处理更大的账户,而不会触及堆或栈的限制。
如何修复?
简单!只需在任何地方使用 Zero Copy。
就像这样简单 👇(将 #[account("zero_copy")] 宏属性添加到 RootEscrow 账户)
但是 Zero Copy 也带来了另一个挑战,这正是 Anchor 最初选择 Borsh 的原因:字节对齐。

字节对齐是一种每个 Solana 开发者都应该理解的低级技术,无论是否使用零拷贝。
它要求通过 bytemuck 确保结构体是零拷贝安全的(字节对齐如果处理不当可能会导致恐慌)。
我会很快发布另一个关于这个*令人兴奋*主题的帖子 🔥
与此同时,查看一下 @legendsdotfun,这是我自九月中旬以来一直在开发的产品,并参与了 @colosseum Cypherpunk 黑客马拉松
注册你的产品,给有前景的新团队投票
让每个 Solana 传奇都闪耀 🤝
非常感谢这些大神们:
- @redacted_noah
- @blockiosaurus
- @0xIchigo
感谢你们校对这个实时发现的主题!
5.71K
热门
排行
收藏

