从 0 开始上手 Solana 智能合约
Solana CLI 基础知识
Solana CLI 是一个命令行界面工具,提供了一系列用于与 Solana Cluster 交互的命令。
我们将介绍一些最常见的命令,但你始终可以通过运行 solana --help
查看所有可能的 Solana CLI 命令列表。
Solana CLI 配置
Solana CLI 存储了一些配置设置,这些设置会影响某些命令的行为。你可以使用以下命令查看当前的配置:
solana config get
solana config get
命令将返回以下信息:
Config File
- Solana CLI 文件在计算机上的位置RPC URL
- 你使用的节点,将你连接到 localhost、Devnet 或 MainnetWebSocket URL
- 用于监听你所针对的 Cluster 事件的 WebSocket(在设置RPC URL
时计算)Keypair Path
- 运行 Solana CLI 子命令时使用的密钥对路径Commitment
- 提供网络确认(confirmation)的度量,并描述区块在某一时刻已最终确认(finalized)的程度
你可以随时使用 solana config set
命令,后跟你想要更新的设置,更改 Solana CLI 的配置。
最常见的更改将是针对的 Cluster。使用 solana config set --url
命令更改 RPC URL
。
solana config set --url localhost
solana config set --url devnet
solana config set --url mainnet-beta
类似地,你可以使用 solana config set --keypair
命令更改 Keypair Path
。然后,当运行命令时,Solana CLI 将使用指定路径上的密钥对。
solana config set --keypair ~/<FILE_PATH>
测试验证节点
通常,为了进行测试和调试,你会发现运行本地验证节点比部署到 Devnet 更有帮助。
你可以使用 solana-test-validator
命令运行本地测试验证器。此命令创建一个持续运行的进程,需要在其自己的命令行窗口中运行。
流式程序日志
通常,同时打开一个新控制台并运行 solana logs
命令,可以帮助你观察测试验证节点相关的日志。这将创建另一个持续运行的进程,会流式传输与你配置的 Cluster 相关的日志。
如果 CLI 配置指向 localhost
,则日志将始终与你创建的测试验证器相关联,但你也可以从其他 Cluster(如 Devnet 和 Mainnet Beta)中流式传输日志。当从其他 Cluster 流式传输日志时,你需要在命令中包含一个程序 ID,以限制你看到的日志仅为特定程序的日志。
密钥对
你可以使用 solana-keygen new --outfile
命令生成新的密钥对,后跟存储密钥对的文件路径。
solana-keygen new --outfile \~/\<FILE_PATH>
有时,你可能需要检查配置指向的是哪个密钥对。要查看在 solana config
中设置的当前密钥对的 publickey
,请使用 solana address
命令。
solana address
要查看在 solana config
中设置的当前密钥对的 SOL 余额,请使用 solana balance
命令。
solana balance
要在 Devnet 或 localhost 上空投 SOL,请使用 solana airdrop
命令。请注意,在 Devnet 上,每次空投限制为 5 SOL。
solana airdrop 5
在本地环境中开发和测试程序时,你可能会遇到以下原因导致的错误:
- 使用错误的密钥对
- 没有足够的 SOL 来部署程序或执行交易
- 指向错误的 Cluster
到目前为止,我们介绍的 CLI 命令应该可以帮助你迅速解决这些问题。
在本地环境中开发 Solana 程序
尽管 Solana Playground 非常有帮助,但很难超越你自己的本地开发环境的灵活性。随着你构建更复杂的程序,你可能最终会将它们与在本地环境中同样在开发中的一个或多个客户端集成。当你在本地编写、构建和部署程序时,程序和客户端之间的测试通常更简单。
创建新项目
要创建一个用于编写 Solana 程序的新 Rust 包,你可以使用 cargo new --lib
命令,后跟你想要创建的新目录的名称。
cargo new --lib <PROJECT_DIRECTORY_NAME>
此命令将创建一个新目录,其名称为你在命令末尾指定的名称。这个新目录将包含一个描述该包的 Cargo.toml
清单文件(manifest file)。
清单文件包含元数据,如名称、版本和依赖项(crates)。要编写 Solana 程序,你需要更新 Cargo.toml
文件,将 solana-program
添加为依赖项。你可能还需要添加下面显示的 [lib]
和 crate-type
行。
[package]
name = "<PROJECT_DIRECTORY_NAME>"
version = "0.1.0"
edition = "2021"
[features]
no-entrypoint = []
[dependencies] solana-program = "~1.8.14"
[lib]
crate-type = ["cdylib", "lib"]
在这一点上,你可以开始在 src
文件夹中编写程序。
构建和部署
当需要构建 Solana 程序时,可以使用 cargo build-bpf
命令。
cargo build-bpf
该命令的输出将包含部署程序的说明,看起来类似于:
To deploy this program: $ solana program deploy /Users/James/Dev/Work/solana-hello-world-local/target/deploy/solana_hello_world_local.so The program address will default to this keypair (override with --program-id): /Users/James/Dev/Work/solana-hello-world-local/target/deploy/solana_hello_world_local-keypair.json
当你准备部署程序时,使用 cargo build-bpf
输出的 solana program deploy
命令。这将把你的程序部署到你 CLI 配置中指定的 Cluster。
solana program deploy <PATH>
实验
让我们通过构建和部署我们在[Hello World 课程]中创建的 "Hello World!" 程序来进行实践。
我们将全部在本地进行,包括部署到本地测试验证节点。在开始之前,请确保你已安装了 Rust 和 Solana CLI。如果尚未设置,请参考概述中的说明。
1. 创建一个新的 Rust 项目
让我们从创建一个新的 Rust 项目开始。运行下面的 cargo new --lib
命令。随意用你自己的目录名称替换。
cargo new --lib solana-hello-world-local
记得更新 Cargo.toml
文件,将 solana-program
添加为依赖项,并确保 crate-type
行已经存在。
[package]
name = "solana-hello-world-local"
version = "0.1.0"
edition = "2021"[dependencies]
solana-program = "~1.8.14"[lib]
crate-type = ["cdylib", "lib"]
2. 编写程序
接下来,使用下面的“Hello World!”程序更新 lib.rs
。当调用程序时,该程序将简单地打印“Hello, world!”到程序日志。
use solana_program::{account_info::AccountInfo,entrypoint,entrypoint::ProgramResult,pubkey::Pubkey,msg
};entrypoint!(process_instruction);pub fn process_instruction(program_id: &Pubkey,accounts: &[AccountInfo],instruction_data: &[u8]
) -> ProgramResult{msg!("Hello, world!");Ok(())
}
- 运行本地测试验证节点
在编写好程序之后,让我们确保我们的 Solana CLI 配置指向 localhost,使用 solana config set --url 命令。
solana config set --url localhost
接下来,使用 solana config get
命令检查 Solana CLI 配置是否已更新。
solana config get
最后,在一个单独的终端窗口中运行本地测试验证器。运行 solana-test-validator
命令。只有当我们的 RPC URL
设置为 localhost 时,才需要执行此操作。
solana-test-validator
4. 构建和部署
现在我们准备好构建和部署我们的程序了。通过运行 cargo build-bpf
命令来构建程序。
cargo build-bpf
现在让我们部署程序。运行 cargo build-bpf
输出的 solana program deploy
命令。
solana program deploy <PATH>
solana program deploy
将输出程序的 Program ID
。你现在可以在[Solana Explorer]上查找已部署的程序(对于 localhost,请选择“Custom RPC URL”作为 Cluster)。
5. 查看程序日志
在调用我们的程序之前,打开一个单独的终端,并运行 solana logs
命令。这将允许我们在终端中查看程序的日志。
solana logs <PROGRAM_ID>
在测试验证节点仍在运行的情况下,尝试使用此客户端脚本调用程序。
在 index.ts
中用刚刚部署的程序的程序 ID 替换原有的程序 ID,然后运行 npm install
,接着运行 npm start
。这将返回一个 Solana Explorer URL。将该 URL 复制到浏览器中以在 Solana Explorer 上查找交易,并检查是否将“Hello, world!”打印到程序日志中。或者,你也可以在运行 solana logs
命令的终端中查看程序日志。
恭喜!你刚刚从本地开发环境中创建并部署了你的第一个 Solana 程序。
挑战
尝试创建一个新程序,将自己的消息打印到程序日志中。这次将程序部署到 Devnet,而不是 localhost。
记得使用 solana config set --url
命令将 RPC URL
更新到 Devnet。
你可以使用与实验相同的客户端脚本调用程序,只要将 connection
和 Solana Explorer URL 都更新为指向 Devnet 而不是 localhost。
let connection = new web3.Connection(web3.clusterApiUrl("devnet"));
console.log(`Transaction: https://explorer.solana.com/tx/${transactionSignature}?cluster=devnet`
);
你还可以打开一个单独的命令行窗口,并使用 solana logs | grep "<PROGRAM_ID> invoke" -A <NUMBER_OF_LINES_TO_RETURN>
。在 Devnet 上使用 solana logs
时,必须指定程序 ID。否则,solana logs
命令将从 Devnet 返回一系列恒定的日志流。例如,你可以执行以下操作来监视对 Token 程序的调用,并显示每次调用的前 5 行日志:
solana logs | grep "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke" -A 5
还可以使用像GTokenTool这样子的一键发币平台,只需简单填写相关信息就可以实现发币。
相关文章:
从 0 开始上手 Solana 智能合约
Solana CLI 基础知识 Solana CLI 是一个命令行界面工具,提供了一系列用于与 Solana Cluster 交互的命令。 我们将介绍一些最常见的命令,但你始终可以通过运行 solana --help 查看所有可能的 Solana CLI 命令列表。 Solana CLI 配置 Solana CLI 存储了…...

(六)CAN总线通讯
文章目录 CAN总线回环测试第一种基于板载CAN测试第一步确认板载是否支持第二步关闭 CAN 接口将 CAN 接口置于非活动状态第三步 配置 CAN 接口第一步 设置 CAN 接口比特率第二步 设置 CAN 启用回环模式第三步 启用 CAN 接口 第四步 测试CAN总线回环捕获 CAN 消息发送 CAN 消息 第…...

新一代智能工控系统网络安全合规解决方案
01.新一代智能工控系统概述 新一代智能工控系统是工业自动化的核心,它通过集成人工智能、工业大模型、物联网、5G等技术,实现生产过程的智能化管理和控制。这些系统具备实时监控、自动化优化、灵活调整等特点,能够提升生产效率、保证产品质量…...

Vivado中Tri_mode_ethernet_mac的时序约束、分析、调整——(一)时序约束的基本概念
1、基本概念 推荐阅读,Ally Zhou编写的《Vivado使用误区与进阶》系列文章,熟悉基本概念、tcl语句的使用。 《Vivado使用误区与进阶》电子书开放下载!! 2、Vivado中的语法例程 1)语法例程 约束的语句可以参考vivado…...

车载网络:现代汽车的数字心跳
在汽车领域,“智能汽车”一词毫不夸张。如今的汽车已不再是原始的机械工程,而是通过先进的车载网络无缝连接的精密数字生态系统。这些滚动计算机由复杂的电子控制单元(ECU)网络提供动力,ECU是负责管理从发动机性能到信息娱乐系统等一切事务的…...

python基础和redis
1. Map函数 2. filter函数 numbers generate_numbers() filtered_numbers filter(lambda x: x % 2 0, numbers) for _ in range(5):print(next(filtered_numbers)) # 输出: 0 2 4 6 83. filter map 和 reduce 4. picking and unpicking 5. python 没有函数的重载࿰…...

w~自动驾驶~合集16
我自己的原文哦~ https://blog.51cto.com/whaosoft/12765612 #SIMPL 用于自动驾驶的简单高效的多智能体运动预测基准 原标题:SIMPL: A Simple and Efficient Multi-agent Motion Prediction Baseline for Autonomous Driving 论文链接:https://ar…...
最长的指定瑕疵度的元音子串
一、题目 最长的指定瑕疵度的元音子串 定义:开头和结尾都是元音字母(aeiouAEIOU)的字符串为 元音字符串 ,其中混杂的非元音字母数量为其 瑕疵度 。比如: “a” 、 "aa"是元音字符串,其瑕疵度都为0 "aiu…...

每日算法Day15【组合、组合总和III、电话号码的字母组合】
77. 组合 算法链接: 77. 组合 - 力扣(LeetCode) 类型: 回溯 难度: 中等 回溯三步法: 1、确定参数返回值 2、确定终止条件 3、单层搜索逻辑 剪枝操作: 当path容量超过k时的数据可以不用遍历,故遍历边界条件判断: …...

C语言教程——指针进阶(2)
目录 一、函数指针数组 1.1函数指针数组写法 1.2函数指针用途 二、指向函数指针数组的指针 2.1概念 三、回调函数 3.1用法 3.2qsort排序 总结 前言 我们接着上一篇的函数指针往下学习。 一、函数指针数组 1.1函数指针数组写法 我们都知道指针数组,里面可以…...
调和级数不为整数的证明
文章目录 1. 问题引入2. 证明2.1 引理12.2 引理22.3 引理3:2.4 核心证明: 3. 参考 1. 问题引入 s ( n ) 1 1 2 1 3 ⋯ 1 n , n ∈ N ∗ , n ≥ 2 s(n) 1\frac{1}{2}\frac{1}{3}\cdots\frac{1}{n}, \quad \\n \in N^*, n \ge2 s(n)12131⋯n1,…...

基于微信小程序的在线学习系统springboot+论文源码调试讲解
第4章 系统设计 一个成功设计的系统在内容上必定是丰富的,在系统外观或系统功能上必定是对用户友好的。所以为了提升系统的价值,吸引更多的访问者访问系统,以及让来访用户可以花费更多时间停留在系统上,则表明该系统设计得比较专…...

基于 Boost.Asio 和 Boost.Beast 的异步 HTTP 服务器(学习记录)
已完成功能: 支持 GET 和 POST 请求的路由与回调处理。 解析URL请求。 单例模式 管理核心业务逻辑。 异步 I/O 技术和 定时器 控制超时。 通过回调函数注册机制,可以灵活地为不同的 URL 路由注册处理函数。 1. 项目背景 1.1 项目简介 本项目是一个基于…...

有机物谱图信息的速查技巧有哪些?
谱图信息是化学家解读分子世界的“语言”,它们在化学研究的各个领域都发挥着不可或缺的作用。它们是理解和确定分子结构的关键,对化学家来说极为重要,每一种谱学技术都提供了不同的视角来观察分子,从而揭示其独特的化学和物理特性…...
Eureka缓存机制
一、Eureka的CAP特性 Eureka是一个AP系统,它优先保证可用性(A)和分区容错性(P),而不保证强一致性(C)。这种设计使得Eureka在分布式系统中能够应对各种故障和分区情况,保…...
【LC】78. 子集
题目描述: 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1: 输入:nums [1,2,3] 输出࿱…...

协同过滤算法私人诊所系统|Java|SpringBoot|VUE|
【技术栈】 1⃣️:架构: B/S、MVC 2⃣️:系统环境:Windowsh/Mac 3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7 4⃣️:技术栈:Java、Mysql、SpringBoot、Mybatis-Plus、VUE、jquery,html 5⃣️…...
Docker部署Naocs-- 超细教程
Docker 拉取镜像 docker pull nacos/nacos-server:v2.2.0 挂载目录 如果不是root账号 前面加sudo 或者 切换root账号 su root(命令) mkdir -p /mydata/nacos/logs/ #新建logs目录 mkdir -p /mydata/nacos/conf/ #新建conf目录 启动容器…...

[java基础-集合篇]优先队列PriorityQueue结构与源码解析
优先队列PriorityQueue 优先级队列表示为平衡二进制堆: queue[n] 的两个子级是 queue[2*n1] 和 queue[2*(n1)]。 注:左子节点index2*parentIndex1,右子节点index2*parentIndex2,源码中计算parent位置时就是这样反过来计算的 优…...
12. C语言 数组与指针(深入理解)
本章目录: 前言1. 什么是数组?2. 数组的声明与初始化声明数组初始化数组 3. 访问数组元素遍历数组 4. 获取数组长度使用 sizeof 获取长度使用宏定义简化 5. 数组与指针数组名与指针的区别使用指针操作数组 6. 多维数组遍历多维数组 7. 数组作为函数参数8. 高级技巧与…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...

Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...

优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...