May 17, 2025
零拷贝bytemuck与 borsh
"在上一篇博文《深入理解 Serde、Bincode 与 Borsh 的关系与区别》介绍了常用的几种解析二进制数据的方法,主要有 bincode 与 borsh, 并提到过在区块链领域里一般推荐使用 borsh 解析数据。但随着合约的开发使用borsh的地方越来越多,会经常遇到提示超出 4K Stack 大小的错误。这是因为在solana里,虚拟机 sbf 限制了一个合约最大允许使用的statck大小上限为 4k。尽管我们使用完一个大变量通过一些方法,如变量作用域、通过Box将内存移动到heap、或手动drop立即释放内存。但仍有些场景是没有采用这种办法的,这时应该如何办呢?\n如果经常看一些优秀的开源项目的话,会发现有一个 bytemuck 的crate,它是一个 zerocopy 库,可以避免内存复制带来的开销,加速解析数据速度,这里给出一个测试代码\nuse borsh::{BorshDeserialize, BorshSerialize}; use bytemuck::{Pod, Zeroable}; use solana_program::pubkey::Pubkey; use …"
April 22, 2025
深入理解 Serde、Bincode 与 Borsh 的关系与区别
"在Rust开发中,无论是构建网络服务、存储数据还是开发区块链程序,**序列化(Serialization)和反序列化(Deserialization)**都是不可或缺的操作。序列化是将内存中的数据结构(struct)转换成字节序列或者其他格式(JSON, vec),以便存储或传输;反序列化则是将字节序列还原成原来的数据结构。\nRust 生态中常用的序列化工具包括 Serde、Bincode 和 Borsh。初学者在阅读文档或实际开发中可能会发现它们名字都很熟悉,但它们的定位、使用方式和特点却不完全相同。\n本文将系统梳理三者的关系、差异和使用场景。\nSerde Serde(Serialization / Deserialization) 是 Rust官方生态最流行的序列化框架。它提供了一种 抽象接口,让你可以将 Rust 类型序列化为多种格式,而不关心底层具体实现。\n特点 通用性强:支持 JSON、YAML、TOML、Bincode 等多种格式。 灵活:可以自定义序列化逻辑。 宏支持:通过 #[derive(Serialize, Deserialize)] 自动生成序列化代码。 安全性: …"
March 28, 2025
solana中MEV监听交易的几种方法
"策略分类 在 Solana 上 MEV(最大可提取价值) 的几种策略主要有:\n套利(Arbitrage) 清算(Liquidation) 抢跑(Front-Running) 三明治攻击(Sandwich Attack) 后置插队(Back-Running) Jito MEV 竞标 套利(Arbitrage) 价格差异猎手 想象你是一个精明的商人,在不同的市场上发现同一件商品价格不同。比如,在A市场一个苹果卖1元,在B市场卖1.2元。你会怎么做?立即在A市场买入,然后在B市场卖出,赚取0.2元的差价。\n在加密世界中,这就是套利。交易员快速在不同交易所或流动性池之间捕捉加密货币价格差异,瞬间完成买卖,赚取微小但稳定的利润。\n清算(Liquidation) 充当风险管理者角色。想象银行放贷时,借款人需要提供抵押物品,如果抵押物品价值下跌到无法覆盖贷款,银行会立即收回资产。\n在加密借贷平台,当用户的抵押品价值跌破安全线,MEV机器人(清算人Liquidator) 通常可以以折扣价买入资产。这是因为在借贷平台(如 Solend、Mango Markets)中,如果用户的抵押资产价值不足以覆盖其贷 …"
March 27, 2025
SPL-Token CLI 使用入门教程
"本篇文章将对官方教程的基本上进行整理和完善,同时对一些官方未提到的一些知识点和实践进行一些介绍,方便一些刚入门solana开发的同学能够对solana开发有更完整的了解。\n本篇文章使用 spl-token 命令行进行演示操作,分别介绍 Mint Account 和 token Account 的创建、转账、关闭账户并回收租金SOL等操作。\n这里假如用户本机已经安装好solana命令行,这里使用本地集群环境,通过 solana-test-validator 命令在本地启动开发集群。\n环境准备 开启一个新终端,在本地创建一个集群 (base) ➜ ~ solana-test-validator --ledger test-ledger -r Ledger location: test-ledger Log: test-ledger/validator.log ⠠ Initializing... Waiting for fees to stabilize 1... Identity: 7U4BYYhgGtjXyujPxX7BrqwYJmLA5BGijUhEv6BACphi Genesis …"
February 25, 2025
Solana中的 Native Programs
"在Solana中有一些少量的内置原生程序,它们的程序ID格式一般为 xxx11111111111111111111111111111111。它们与第三方自定义程序不同,原生程序是 validator node 运行所必须的一部分。同时它们也是集群升级的一部分,这些升级可能包括新功能的添加、BUG修复,又或者是性能的优化提升。这些内置原生程序极少的发生变化,目前提供的所有内置原生程序可以在 https://docs.anza.xyz/runtime/programs 找到。\n其中有两个非常重要的程序很值得我们关注,因为我们在开发中,需要经常用到他们。\nSystem Program 作用:\n创建新帐户 分配帐户数据 将帐户分配给所属的程序,即指定账户与程序的对应关系 转账最小 lamports 给账户(租金),防止账户被系统回收 Program id: 11111111111111111111111111111111\nInstructions: SystemInstruction\nBPF Loader 作用: 部署所有自定义程序,并将其作为的所有自定义程序的 owner 升级和执行链条上的 …"
February 15, 2025
Solana中 PDA、ATA 与 普通Account 的区别与关系
"普通账户地址 对于账户地址的创建是由一个密钥对来生成的,但在Solana中账户地址与以太坊中的账户地址还是有一些区别的。\n以太坊账户地址 以太坊账户地址的生成过程:\n通过私钥生成公钥 对公钥进行 Keccak-256 哈希 取哈希值的最后 160 位(20 字节)作为地址 将地址以 0x 开头,并根据需要选择是否使用 EIP-55 格式 地址中通常是小写字母,但也有大写字母的变种,称为 EIP-55 格式。在 EIP-55 中,某些字符会根据哈希值的大小写进行区分,从而增加地址的错误检查能力。\nSolana 账户地址 Solana账户地址的生成过程:\n通过私钥生成公钥,一般通过调用 Keypair.generate() 生成 公钥直接映射为账户的地址,长度为 32 字节 为了使用方便,一般对其进行 Base58 编码,将公钥转换为地址字符串 代码:\nconst { Keypair } = require(\u0026#39;@solana/web3.js\u0026#39;); // 生成一个新的密钥对 const keypair = Keypair.generate(); // 获取公钥,实际上就是账户 …"
January 10, 2025
Solana中如何实现转账
"在 Solana 中转账有两种方式。\n修改结构体字段 一种是在不调用(invoking )系统程序( System Program )的情况下,将 lamports 从一个账户转移到另一个账户。它的实现是直接通过修改结构体的 lamports 字段值来实现的。\n这种方法可以实现将 lamports 从任何由您的程序拥有的账户转移到任何账户。文档\n/// Transfers lamports from one account (must be program owned) /// to another account. The recipient can by any account fn transfer_service_fee_lamports( from_account: \u0026amp;AccountInfo, to_account: \u0026amp;AccountInfo, amount_of_lamports: u64, ) -\u0026gt; ProgramResult { // Does the from account have enough lamports to transfer? …"
December 22, 2024
Solana中账户类型 Account、AccountInfo与 SystemAccount 的区别
"在Solana中 Account 的角色很重要,它就像Linux中一切皆文件的概念一样,无处不在。了解它也是开发Solana的基础,本节主要介绍我们最经常使用的 Account 、AccountInfo 和 SystemAccount 这三种账户类型的区别与使用场景。\n当然除此之外还有一些账户类型也很重要,如 UncheckedAccount、Signer、TokenAccount、Mint、CpiAccount、Loader、Program、AssociatedToken 等,我们这里就不再一一讲解,有兴趣的话可以参考官方相关文档。\n由于多数情况下都是使用anchor框架开发Solana合约,因此本文主要是根据 anchor-lang 文档里介绍账户来讲解\n账户类型 以下我们分别对这三种账户类型做一些简单的介绍。\nAccountInfo 在 Solana 中 AccountInfo 是最基础的账户类型。\n其它几种账户类型都是对它的封装,它的定义\n#[repr(C)] pub struct AccountInfo\u0026lt;\u0026#39;a\u0026gt; { pub key: \u0026amp;\u0026#39;a …"
December 6, 2024
什么是Layer2网络
"我们平时提到的比特币、以太坊、Solana,它们都属于Layer 1网络,而Layer 2(L2) 网络是指基于Layer1网络之上构建的一层网络,它很类似于Layer 1 网络,也是一个独立的区块链。但它的主要目的并不是为了代替 Layer 1 ,而是为了通过扩展 Layer 1 层网络从而解决一些在 Layer 1 网络中存在的一些问题,它同时继承了 Layer 1 网络的安全性和去中心化性。\n以太坊存在的问题 这里以以太坊为例,在 L1 网络上随着交易量越来越大,交易频率也越来越频繁,导致Gas(网络交易费)越来越高,一笔交易可能在网络繁忙的时候高达十几美元,导致一些交易可能需要花费好久才可以真正成交到区块网络。\n这两个问题大大提高了用户使用门槛,那有没有好的解决办法呢?\n解决方案 区块链的三个核心特性是 去中心化、安全性和可扩展性,一般简单的区块链架构只能实现其中两个特性(这一点很类似于分布式中的CAP理论)。想要一个安全且去中心化的区块链的话,只能牺牲可扩展性,而这也正是第二层网络发挥作用的地方。\n以太坊生态系统坚定认为,第 2 层扩展是解决可扩展性三难问题的唯一途径,同时保 …"
December 4, 2024
Solana中如何解析指令
"开发过Solodity的同学都知道在合约开发中,不同指令对应的不同前端Endpoint(API接口),这种开发模式特别的清晰且易维护。那在开发Solana合约时没有有对应的方法呢?\nSolana开发方式 开发 Solana 合约,一般分 Native 和 Anchor 框架开发。\nNative 主要是开发者通过SDK 手动实现所有业务逻辑。 这种模式一般对开发者要求比较高,除了需要了解相关概念外,最重要的还需要知道对应的SDK实现,如PDA账户的创建。\nAnchor框架 推荐使用,只需要一些宏即可以实现一些逻辑,不需要用户关心底层实现。这种开发方式对于指令的处理基本与Solidity中一致,开发者只要搞明白了基本用法就可以了。\n下面主要讲一下在 Native 这种方式下,如何实现指令或附加数据的解析。\n如果你对 指令这个概念不太理解的话,可以将其视为路由。其类于似在mvc开发中控制器路由,如 /user/info、 /user/base、/user/changepwd 之类。\n示例介绍 我们先看一个在 https://beta.solpg.io 网站上创建的一个 Native …"