Solana 编程语言
主要的 Solana 编程语言是 Rust,但也支持 C, C++,甚至是 Python。
Solana 编程语言使用 Rust、C 和 C++ 的方式非常相似。我们将在后面的章节中讨论 Python。
Rust 是一种编译型语言。如果你在电脑上编译 Rust,它最终会变成 LLVM-IR(低级虚拟机中间表示),然后 LLVM 会将其转换为能在你机器(x86、arm64 等)上运行的字节码。
在 Solana 中,流程是这样的:1) 将 Rust 编译为 LLVM-IR,然后编译为 BPF(Berkeley Packet Filter),并将字节码存储在区块链上。2) 验证者将 BPF JIT 编译(即时编译)为与其硬件兼容的指令集,通常是 x86,但 arm64 也可能是另一个常见目标。
你可能会问,Packet Filter(数据包过滤器)?为什么 Solana 编程语言会和互联网数据包扯上关系?
这实际上是 Solana 在设计上的一个明智之举。
用户空间与内核空间
Linux 具有内核空间(kernel space)和用户空间(user space)的概念。如果你想执行诸如打开文件或启动另一个进程等操作,你的可执行文件需要请求操作系统代为执行。假设你写了一个 Python 脚本来打开一个文件并打印所有偶数行。实际加载文件字节码的过程发生在内核空间,但一旦字节码交给了脚本,解释为 ASCII 码并判断行号是奇数还是偶数的过程则发生在用户空间。
这种抽象的存在有几个原因,其中最明显的一个就是安全性。并非每个用户或可执行文件都应该能够打开或执行任意文件。操作系统决定了哪些“API”是被允许的。(顺便说一下,在操作系统的术语中,用于打开文件的“API”在技术上被称为“系统调用”)。
同样,也不应允许程序和可执行文件任意访问传入的互联网数据包。在默认情况下,它们必须进行系统调用,向操作系统请求查看数据包的权限,而这些数据包只能从内核空间进行访问。
这里必须强调一个重要概念:在用户空间和内核空间之间来回切换通常是很慢的。
如果你正在过滤传入的互联网数据包,那么这将在用户空间和内核空间之间产生大量的来回跳转。想象一下,将每一个传入的数据包从内核空间复制到用户空间,那将会产生大量的系统开销。
这就是 BPF 被发明的原因。你可以在内核空间内部运行可执行文件,从而避免这种跳转。
但如果你对拥有内核特权有所了解,你就会知道这是极其危险的!如果存在 bug,拥有对内核(操作系统)的控制权可能会导致计算机崩溃。更糟糕的是,如果恶意代码被执行,其破坏将是不可估量的。
当然,BPF 的设计者也想到了这一点。在 BPF 代码执行之前,它会被验证以确保其运行时间固定(即必须能终止),并且只能访问指定的内存区域,同时遵循其他相应的限制。
顺便说一句,自发明以来,BPF 的用途已经扩展到了过滤数据包之外,但它的名字却保留了下来。
为什么 Solana 语言使用 BPF
通过利用使 BPF 程序变得安全而进行的现有研究,Solana 可以在智能合约运行最快的地方——内核中运行它们!仔细想想,这是非常了不起的。你可以在操作系统最敏感(但也最高效)的部分(操作系统内核)运行由任何人编写的不受信任的智能合约。Solana 得以利用该领域数十年的研究和投资来获得可观的性能提升。
BPF 不是机器指令;它仍然是自己的一套字节码。然而,它可以被 JIT 编译为各种 CPU 架构。
回到 Rust、C 和 C++
这三种编程语言早就受到 LLVM 的支持。这是 Solana 可以利用数十年投资的另一个领域(是的,用“数十年”来谈论一项技术可能有些奇怪,但 LLVM 问世于 2003 年)。
你可以使用 C 或 C++ 作为 Solana 编程语言,但你在工具方面获得的辅助支持要少得多。通常建议你使用 Rust,哪怕你是 C 或 C++ 专家。如果你已经精通 C++,那么学习 Rust 会很容易。
编写 Solana 程序需要掌握多少 Rust?
不需要太多,但仍然需要进行一些学习。Rust 不是一门你可以“靠谷歌搜索一路摸索”的语言。例如,假设你有 Java 或 Scala 的背景,现在要用 Ruby 编程。在这种情况下,你可以很容易地在谷歌上搜索等效的编程模式(你的代码看起来可能不够地道,但它是可读且能起作用的)。如果(当你)从 Stack Overflow 上复制粘贴代码时,你仍然会对代码的作用有很好的直觉。
然而,如果你对 Rust 也这样做,你将会遇到一些令人沮丧的障碍。Rust 具有很难查找的语法(比如尝试在搜索引擎中查找“#”),并且它拥有其他编程语言中找不到的概念。
Rust 是一门庞大的语言。不过,你只需要掌握它的一个子集。我们的 Solana 开发课程将 Rust 与 Solana 结合起来教学,因此你只需专注于你所需要的 Rust 部分。
Solana 如何使用 Python
将 Rust、C 或 C++ 编译为 BPF 是非常直接的。但对于 Python,情况就大不相同了;很明显,Python 是一门解释型语言,而不是一门可以通过 LLVM 编译的语言。
简单来说,Python 被转译(transpile)为 Rust,然后一切就像上面描述的那样运行。
如果你想了解具体的工作流程,seahorse-lang 的 github 上有直观的文档说明。
Solana 程序通常不使用原生 Rust 编写;大多数开发者会使用 Anchor Framework。因此,尽管 Seahorse 进行的是相当典型的转译,但它也利用了框架设计上预期的相似性。
Seahorse Framework 密切模仿了 Anchor Framework 的模式,因此 Python 代码可以被转化为与在 Anchor Framework 中编写方式高度一致的 Rust 代码。
请注意,该项目目前处于测试阶段(beta)。
Solana 使用 Solidity 吗?
是的,用 Solidity 编写 Solana 应用程序是可能的,但带有一些实验性质。solang solidity compiler 的构建就是为了支持将 Solidity 编译成 BPF。
Solana 客户端编程语言
与运行在节点上的程序(智能合约)不同,支持区块链运行的节点程序,即 Solana 客户端本身是用 Rust 编写的。目前,Jump Crypto 正在重新实现一个名为 firedancer 的 Solana 客户端,它完全用 C 语言编写。
补充:Rust 正在将 BPF 迁移到 SBF。
自 2022 年 10 月起,Solana 开始从 BPF 迁移到 SBF(Solana binary format)。截至撰写本文时,关于这一更改的文档还非常少,但这不会影响大多数开发者。如果你的构建工具配置为编译为 BPF,你将收到一个弃用警告,但一切仍会正常运行。只需更改你的构建标志(build flags)即可。
从 RareSkills 了解更多
想掌握以太坊开发吗?请查看我们的 Solidity Bootcamp
参考资源
https://www.kernel.org/doc/html/latest/bpf/instruction-set.html
https://docs.rs/solana_rbpf/latest/solana_rbpf/ebpf/index.html
https://www.youtube.com/watch?v=5jQvuPWpzcE
https://ebpf.io/what-is-ebpf/
https://www.youtube.com/watch?v=Q8eY67hDvkc
原载于 2022 年 12 月 1 日