#smart-contracts #smart #contracts #solana #contract

poc-framework

一个用于以痛苦和直观的方式创建Solana智能合约PoC的框架

7个版本

0.2.0 2022年7月13日
0.1.6 2022年4月20日
0.1.5 2022年3月2日
0.1.4 2022年1月1日
0.1.0 2021年8月30日

#69 in #smart

34 monthly downloads

MIT/Apache

445KB
1K SLoC

包含(ELF库,165KB) src/programs/spl_token-3.1.0.so、(ELF库,130KB) spl_associated-token-account-1.0.1.so、(ELF库,75KB) src/programs/spl_memo-3.0.0.so、(ELF库,18KB) src/programs/spl_memo-1.0.0.so

Solana PoC Framework

免责声明:强烈反对以非法方式使用此框架。大多数Solana项目提供的漏洞赏金都相当丰厚。此外,您也不想自己的膝盖被打破。

使用方法

要开始,只需将以下行添加到您的dependencies部分中的Cargo.toml

[dependencies]
poc-framework = "0.2.0"

此crate已重新导出您可能需要的所有Solana依赖项。

此框架的用途

此框架是为安全研究人员制作的,旨在简化Solana智能合约或甚至Solana核心中漏洞的Proof-of-Concept的快速便捷开发。通用的Environment接口允许在本地开发漏洞,然后在Testnet或Devnet上进行测试。

功能概述

实用工具

此框架提供许多实用函数,这些函数在我们的Neodyme审核的智能合约PoC中多次证明非常有用。

在PoC中,您首先想做的事情是设置日志记录。如果您使用本地环境,这将特别有用,因为这是唯一找出交易为何无法执行(例如,如果签名者缺失)的方法。

setup_logging(LogLevel::DEBUG);

之后,您需要定义将使用哪些密钥。在打印交易时,密钥应该易于识别。这通过 keypair(n: u8) 函数来实现。该框架包含 256 个预先生成的密钥,以 Kxxx 开头,其中 xxx 是参数 n 的三位数字表示。请注意,base58 字符集中不包含 0,因此我们使用了 o

let authority = keypair(0);   // KoooVyhdpoRPA6gpn7xr3cmjqAvtpHcjcBX6JBKu1nf
let target    = keypair(1);   // Koo1BQTQYawwKVBg71J2sru7W51EJgfbyyHsTFCssRW
let mint      = keypair(2);   // Koo2SZ393psmp7ags3hMz59ciV3XWLj1GkPousNgTH1
let victim    = keypair(137); // K137jwH7CncXBTadHbLDsHNWUhuLDN4ddegJL2hmn6u

如果您不介意识别密钥对,还有一个 random_keypair 函数。

对于调试目的,以整洁的方式打印交易结果也非常有价值。为此,框架提供了 PrintableTransaction 特性,它既实现了 ConfirmedTransaction,也实现了 EncodedConfirmedTransaction。此特性提供了 print 函数,可以方便地链接到任何 env.execute_transaction 调用的末尾

env.execute_as_transaction(&[...], &[...]).print();

环境

该框架的核心是 Environment 特性。这封装了在某个链状态上执行交易的能力,以及拥有一个 payer(付款人)来支付所有费用和租金的便利性。

目前有两种不同的实现:在集群上执行所有交易的 RemoteEnvironment,以及在任意链状态上本地执行所有交易的 LocalEnvironment

Environment 特性还提供了许多发送交易的快捷方式,例如与 spl-token 账户交互,甚至创建具有任意内容的账户(但显然拥有固定的所有者)。

远程环境

要构建远程环境,您需要一个 RpcClient。可以使用 devnet_client()/testnet_client()/localhost_client() 来方便地构建。我们不鼓励在主网上使用此框架。还实现了空投,包括 new_with_airdropairdrop 函数。

let payer = read_keypair_file("big-fat-wallet.json").unwrap();
let client = devnet_client();
let mut env = RemoteEnvironment::new(client, payer);

本地环境

构建本地环境通常需要一些努力,因为首先需要克隆相关的链状态。框架提供了许多不同的方法来完成这项工作。从从文件部署合约到插入任意账户,甚至从集群中克隆账户和整个可升级程序

let mut env = LocalEnvironment::builder()
    .add_account_with_lamports(authority, system_program::ID, sol_to_lamports(10.0))
    .add_token_mint(mint, Some(authority), 0, 1, None)
    .add_associated_token_account(authority, mint, 1337)
    .clone_upgradable_program_from_cluster(client, my_program::ID)
    .build();

然而,请注意,使用此构建器可以创建不合法的链状态(例如,属于程序且程序本身永远不会写入其状态的账户),导致仅能在本地复制的漏洞。尽可能多地使用环境中的交易来防止这些陷阱。

依赖项

~79MB
~1.5M SLoC