Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
v1xingyue authored Aug 15, 2023
2 parents 6028e98 + 5aa68cc commit ad76bad
Show file tree
Hide file tree
Showing 48 changed files with 235 additions and 607 deletions.
40 changes: 1 addition & 39 deletions docs/Solana-Co-Learn/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ sidebar_class_name: green

## Module4: Solana Module4

- [本地环境设置和PDA
](./module4/local-env-setup-and-pdas/README.md)
- [PDA介绍](./module4/pdas/README.md)

- [跨程序调用](./module4/cross-program-invocations/README.md)

Expand All @@ -72,40 +71,3 @@ sidebar_class_name: green
- [Randomness](./module6/randomness/README.md)

- [Finishing touches](./module6/finishing-touches/README.md)

## Modules: Solana Modules

### Beyond the Basics

- Solana程序中的环境变量
- Solana Pay
- 版本化的事务和查找表
- Rust过程宏

### Solana程序安全

- 如何处理程序安全模块
- 签名人授权
- Owner check
- 账户数据匹配
- 重新初始化攻击
- 重复的可变账户
- Type cosplay
- Arbitrary CPIs
- 碰撞种子规范化
- 关闭账户和恢复攻击
- PDA sharing

### 其他

- 使用Solidity 编写Solana合约
- Solidity 与PDAs
- Solidity 与 CPIs
- token2020 token如何发行
- Compression NFT 如何发行
- 如何在Solana中使用The Graph
- Oracles Pyth sdk的使用
- TipLink 如何使用
- 如何在quicknode申请RPC endpoint
- 如何在helius申请RPC endpoint
- etc ...
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ sidebar_class_name: green
# 客户端开发

- 📹使用Gage在Solana上读取和写入数据
- [从 Solana 🤓 区块链读取数据
](./read-data-from-the-solana-network/README.md)
- [从 Solana 🤓 区块链读取数据](./read-data-from-the-solana-network/README.md)
- [✍将数据写入区块链](./write-data-to-the-blockchain/README.md)
- [📝 构建一个互动脚本](./build-an-interaction-script/README.md)
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ sidebar_class_name: green

# 📝 构建一个互动脚本

准备好戳一下Solana网络了吗?我们将编写一个脚本,生成一个密钥对,用`devnet` SOL资金进行充值,并与Solana网络上的现有程序进行交互。
准备好和Solana网络交互了吗?

这个程序是一个简单的“`ping`”计数器:我们击中它,它记录我们对它的`ping`,并增加一个计数器。我们以后会介绍Rust和我们自己的程序,现在我们将使用JS/TS。
我们将编写一个脚本,生成一个密钥对,用`devnet` SOL资金进行充值,并与Solana网络上的现有程序进行交互。

这个程序是一个简单的“`ping`”计数器:我们点击它,它记录我们对它的`ping`,并增加一个计数器。我们以后会介绍Rust和我们自己的程序,现在我们将使用JS/TS。

## 🚧 在本地设置 Solana 客户端

让我们改变一下方式 - 我们将离开`React/Next.js`,在这里使用纯TypeScript构建一个本地客户端。这比搭建前端并构建大量的用户界面要快得多。你可以在一个单独的TS文件中工作,并异步运行它与网络进行交互。


在您的Solana工作区中创建一个新文件夹,并使用这个方便的命令来设置本地客户端:

```bash
Expand Down Expand Up @@ -43,6 +44,7 @@ import dotenv from 'dotenv';
dotenv.config();

async function main() {

}

main()
Expand Down Expand Up @@ -112,7 +114,7 @@ Finished successfully

保持测试帐户独立非常重要,这就是为什么这个脚本特别酷的原因 - 它消除了创建和管理测试钱包的麻烦。

现在,如果我们也能自动获取 devnet SOL 就好了。哦等等,我们可以!
现在,如果我们也能自动获取` devnet SOL` 就好了。哦等等,我们可以!

快来看看这个超酷的空投功能-

Expand Down Expand Up @@ -254,7 +256,7 @@ async function pingProgram(connection: Web3.Connection, payer: Web3.Keypair) {

既然我们已经一起学习了如何将交易发送到网络,现在轮到你独立尝试了。

按照上一步骤的类似流程,从头开始创建一个脚本,使您能够在Devnet上将SOL从一个账户转移到另一个账户。确保打印出交易签名,以便您可以在Solana Explorer上查看。
按照上一步骤的类似流程,从头开始创建一个脚本,使您能够在`Devnet`上将SOL从一个账户转移到另一个账户。确保打印出交易签名,以便您可以在Solana Explorer上查看。

想想到目前为止你学到了什么 -

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
sidebar_position: 13
sidebar_label: 从Solana 🤓区块链中读取数据
sidebar_label: 从Solana 🤓 区块链中读取数据
sidebar_class_name: green
---

Expand Down Expand Up @@ -36,7 +36,7 @@ Solana 上有三种类型的账户
| `owner` | 这个账户的所有者程序 |
| `executable` | 这个账户成是否可以处理指令 |
| `data` | 这个账户存储的数据的字节码 |
| `rent_epoch` | 下一个需要付租金的epoch(代) |
| `rent_epoch` | 下一个需要付租金的`epoch`(代) |

我们现在只关注我们需要了解的事情,所以如果有些东西不太明白,就继续前进吧 - 我们会边进行下去边填补空白。

Expand Down Expand Up @@ -212,4 +212,4 @@ const addressSubmittedHandler = (address: string) => {

在你自己努力尝试之前,不要看答案!这个很简单!

完成后,请[查看](https://github.com/RustyCab/solana-intro-frontend/tree/challenge-solution)此处的挑战解决分支的参考资料。
完成后,请[查看](https://github.com/CreatorsDAO/solana-intro-frontend/tree/challenge-solution)此处的挑战解决分支的参考资料。
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,4 @@ async function callProgram(
需要注意的主要事项是,在交易的签名者数组中,第一个签名者始终负责支付交易费用。如果你没有足够的SOL会怎么样?交易将被取消!


当你在devnet或本地主机上时,你可以使用CLI中的 solana airdrop 来获取devnet SOL。你还可以使用[SPL代币水龙头](https://spl-token-faucet.com/)来获取SPL代币(我们稍后会了解这些是什么:P)。
当你在`devnet``LocalHost`上时,你可以使用CLI中的 Solana airdrop 来获取`devnet SOL`。你还可以使用[SPL代币水龙头](https://spl-token-faucet.com/)来获取`SPL`代币(我们稍后会了解这些是什么:P)。
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ sidebar_class_name: green

# 🎥 构建一个电影评论应用

现在我们已经完成了钱包连接的设置,让我们让我们的ping按钮真正有用起来吧!为了将所有内容整合在一起,我们将构建一个基于区块链的电影评论应用——它将允许任何人提交他们最喜欢的电影的评论,有点类似于烂番茄网站。
现在我们已经完成了钱包连接的设置,让我们让我们的`ping`按钮真正有用起来吧!为了将所有内容整合在一起,我们将构建一个基于区块链的电影评论应用——它将允许任何人提交他们最喜欢的电影的评论,有点类似于烂番茄网站。

在你的Solana工作空间中设置起始代码

Expand All @@ -23,12 +23,12 @@ npm i

这是一个普通的 Next.js 应用程序,安装了一些模板组件和一些 Solana 依赖项,以帮助您节省时间。那里有一些模拟评论,请查看各个组件以感受该应用程序。

您会注意到我们已将钱包上下文提供程序从 `_app.tsx` 移至其自己的组件。它的工作原理是一样的,只是将其与更大的应用程序分开,性能更高。应用程序现在所做的就是将您的评论记录到控制台中,我们将在 `Form.tsx` 中设置 `handleTransactionSubmit` 函数。我们走吧呜呜呜呜
您会注意到我们已将钱包上下文提供程序从 `_app.tsx` 移至其自己的组件。它的工作原理是一样的,只是将其与更大的应用程序分开,性能更高。应用程序现在所做的就是将您的评论记录到控制台中,我们将在 `Form.tsx` 中设置 `handleTransactionSubmit` 函数。我们走吧呜呜呜呜

## 🗺 定义架构


序列化的第一步是为我们要序列化的数据创建一个模式/映射。我们需要告诉Borsh数据将被称为什么以及每个项目的大小
序列化的第一步是为我们要序列化的数据创建一个模式/映射。我们需要告诉`Borsh`数据将被称为什么以及每个项目的大小


首先安装 `borsh` ,在终端中运行:
Expand All @@ -37,7 +37,7 @@ npm i
npm install @project-serum/borsh --force
```

接下来前往 `Movie.ts` 导入 `borsh` 并在 Movie 类中添加架构(不要复制粘贴此内容):
接下来前往 `Movie.ts` 导入 `borsh` 并在 `Movie` 类中添加架构(不要复制粘贴此内容):

```ts
// We're importing borsh
Expand Down Expand Up @@ -74,7 +74,7 @@ export class Movie {

## 🌭 创建serialize方法

现在我们知道数据是什么样子,我们需要编写将其序列化的方法。将其添加到 Movie 类中架构的正下方:
现在我们知道数据是什么样子,我们需要编写将其序列化的方法。将其添加到 `Movie `类中架构的正下方:

```ts
serialize(): Buffer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ sidebar_class_name: green

# 🤔 自定义指令

既然我们已经完成了钱包连接的设置,让我们让我们的ping按钮真正有所作为吧!你现在知道如何读取数据并通过简单的交易写入网络。几乎立即,你会发现自己想要通过交易发送数据。那么让我们看看如何向Solana区块链讲述你的故事。
既然我们已经完成了钱包连接的设置,让我们让我们的`ping`按钮真正有所作为吧!你现在知道如何读取数据并通过简单的交易写入网络。几乎立即,你会发现自己想要通过交易发送数据。那么让我们看看如何向Solana区块链讲述你的故事。

Solana中关于数据的棘手之处在于程序是无状态的。与以太坊等其他区块链中的智能合约不同,程序不存储任何数据,只存储逻辑

Expand Down Expand Up @@ -44,7 +44,7 @@ Solana 程序中绝对不存储任何内容。它不知道所有者是谁,甚
>
> 这是低级别编程的一个常见特性。虽然很多高级编程语言(比如 Python 或 JavaScript)会自动处理这些类型转换,但在低级语言(比如 Rust,这也是 Solana 主要使用的语言)中,你需要自己处理这些转换。然而,有些库,如 Anchor,可以帮助你处理这些转换,让编程更简单。
## 🔨 序列化和borsh
## 🔨 序列化和`borsh`


这就是序列化的作用 - 它是将常规的代码或数据转换为字节数组(机器代码:1和0)。
Expand All @@ -54,7 +54,7 @@ Solana 程序中绝对不存储任何内容。它不知道所有者是谁,甚
让我们通过一个例子来看看它是如何工作的——目标是装备一个链上游戏物品。为此,我们需要三个数据

- `variant` - 我们要调用的命令的名称(即装备或删除)
- `playerId` - 装备该物品的玩家的ID
- `playerId` - 装备该物品的玩家的`ID`
- `itemId` - 我们想要装备的物品

序列化此数据有四个步骤:
Expand All @@ -80,7 +80,7 @@ const equipPlayerSchema = Borsh.struct([
])
```

我们将从为装备物品指令创建一个模式开始。我们正在创建一个包含三个数据片段的borsh结构,它们都是无符号整数,但大小不同 - 8位、16位和256位。
我们将从为装备物品指令创建一个模式开始。我们正在创建一个包含三个数据片段的`borsh`结构,它们都是无符号整数,但大小不同 - 8位、16位和256位。

由于我们的数据将变成一长串的1和0,我们需要知道每个数据项的起始和结束位置。这就是为什么我们给每个项分配一个特定的大小。当程序需要读取这些数据时,它将知道 `variant` 的结束位置和 `playerId` 的起始位置。

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,26 @@ sidebar_class_name: green

# 📡 Run is back - 反序列化

既然我们已经完成了钱包连接的设置,让我们让我们的ping按钮真正有所作为吧!将数据写入网络账户只是战斗的一半,另一半是读取数据。在第一部分中,我们使用了Web3.js库中的内置函数来读取内容。这仅适用于绝对必要的数据,如余额和交易详情。正如我们在上一部分中所看到的,所有好东西都在PDAs中
既然我们已经完成了钱包连接的设置,让我们让我们的`ping`按钮真正有所作为吧!将数据写入网络账户只是战斗的一半,另一半是读取数据。在第一部分中,我们使用了Web3.js库中的内置函数来读取内容。这仅适用于绝对必要的数据,如余额和交易详情。正如我们在上一部分中所看到的,所有好东西都在`PDAs`


## 🧾 程序派生地址

账户是Solana的热门话题。如果你听过账户这个词,你可能听到有人谈论PDA。PDA是Solana上用于存储数据的特殊类型账户。但实际上它并不是一个账户——它们被称为地址而不是账户,因为它们没有私钥。它们只能由创建它们的程序控制。
账户是Solana的热门话题。如果你听过账户这个词,你可能听到有人谈论`PDA``PDA`是Solana上用于存储数据的特殊类型账户。但实际上它并不是一个账户——它们被称为地址而不是账户,因为它们没有私钥。它们只能由创建它们的程序控制。

![](./img/upload_1.png)

常规 Solana 帐户是使用 [Ed25519](https://ed25519.cr.yp.to/?utm_source=buildspace.so&utm_medium=buildspace_project) 签名系统创建的 - 该系统为我们提供了公钥和私钥。由于 PDA 是由程序控制的,因此它们不需要私钥。因此,我们使用不在 Ed25519 曲线上的地址来制作 PDA。
常规 Solana 帐户是使用 [Ed25519](https://ed25519.cr.yp.to/?utm_source=buildspace.so&utm_medium=buildspace_project) 签名系统创建的 - 该系统为我们提供了公钥和私钥。由于 `PDA` 是由程序控制的,因此它们不需要私钥。因此,我们使用不在 `Ed25519` 曲线上的地址来制作 `PDA`

![](./img/upload_2.png)

有时, `findProgramAddress` 给我们一个位于曲线上的密钥(意味着它也有一个私钥),因此我们添加一个可选的“bump”参数以将其移出曲线。
有时, `findProgramAddress` 给我们一个位于曲线上的密钥(意味着它也有一个私钥),因此我们添加一个可选的“`bump`”参数以将其移出曲线。

就是这样。您不需要了解 Ed25519,甚至不需要了解数字签名算法是什么。您只需要知道 PDA 看起来就像常规 Solana 地址并且由程序控制。
就是这样。您不需要了解 `Ed25519`,甚至不需要了解数字签名算法是什么。您只需要知道 `PDA` 看起来就像常规 Solana 地址并且由程序控制。

您需要了解 PDA 工作原理的原因是,它们是链上和链下程序定位数据的确定性方式。把它想象成一个键值存储。 `seeds``programId``bump` 组合起来形成密钥,以及网络在该地址存储的值。如果我们知道密钥是什么,这使我们能够可靠且一致地查找存储在网络上的数据。
您需要了解 `PDA` 工作原理的原因是,它们是链上和链下程序定位数据的确定性方式。把它想象成一个键值存储。 `seeds``programId``bump` 组合起来形成密钥,以及网络在该地址存储的值。如果我们知道密钥是什么,这使我们能够可靠且一致地查找存储在网络上的数据。

多亏了程序派生地址(PDAs),我们拥有一个可以被Solana上所有程序访问的通用数据库。回想一下我们与第一个程序互动的情景——我们向其发送了一个ping请求,然后它递增了一个数字。下面是你可能会找到与所有账户互动的程序共享的数据的方法:
多亏了程序派生地址(`PDAs`),我们拥有一个可以被Solana上所有程序访问的通用数据库。回想一下我们与第一个程序互动的情景——我们向其发送了一个`ping`请求,然后它递增了一个数字。下面是你可能会找到与所有账户互动的程序共享的数据的方法:

```ts
const [pda, bump] = await PublicKey.findProgramAddress(
Expand Down Expand Up @@ -68,11 +68,11 @@ const [pda, bump] = await PublicKey.findProgramAddress(

| FIELD | 描述 |
| --- | --- |
| lamports | 该账户拥有的lamports数量 |
| owner | 该帐户的程序所有者 |
| executable | 该账户是否可以处理指令(可执行) |
| data | 该账户存储的原始数据字节数组 |
| rent_epoch | 这个账户将要支付的下一个时期的租金 |
| `lamports` | 该账户拥有的`lamports`数量 |
| `owner` | 该帐户的程序所有者 |
| `executable` | 该账户是否可以处理指令(可执行) |
| `data` | 该账户存储的原始数据字节数组 |
| `rent_epoch` | 这个账户将要支付的下一个时期的租金 |

数据字段包含了一个庞大的字节数组。就像我们将可读数据转换为字节以进行指令一样,我们在这里要做的是相反的操作:将字节数组转换为我们的应用程序可以处理的数据。这时真正的魔法开始了,你会真切地感受到自己像在玻璃上冲浪一样 😎

Expand Down Expand Up @@ -152,7 +152,7 @@ export class Movie {
看起来很熟悉!好东西在 `deserialize` 中。这里的返回类型可以是 `Movie``null` ,因为帐户可能根本没有任何数据。
最后,我们需要在页面加载时使用此方法从 PDA 获取数据。我们在 `MovieList.tsx` 中执行此操作:
最后,我们需要在页面加载时使用此方法从 `PDA` 获取数据。我们在 `MovieList.tsx` 中执行此操作:
```ts
import { Card } from './Card'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
---
sidebar_position: 9
sidebar_label: Anchor 合约框架实现 <hello, World>
sidebar_label: Anchor 合约框架实现 - hello, World
sidebar_class_name: green
---

# Anchor 合约框架实现 <hello, World>
# Anchor 合约框架实现 - hello, World

让我们通过构建和部署 `Hello World!` 程序来进行练习。

我们将在本地完成所有操作,包括部署到本地测试验证器。在开始之前,请确保您已经安装了Rust和Solana CLI。如果您还没有安装,请参考概述中的说明进行设置。

## Anchor 安装

这里是anchor的[安装官方指南](https://www.anchor-lang.com/docs/installation).
这里是`Anchor`[安装官方指南](https://www.anchor-lang.com/docs/installation).

需要你按照步骤安装好 Anchor。
需要你按照步骤安装好 `Anchor`

安装完成后我们可以通过执行下面的命令,检测 Anchor 是否安装完成✅。
安装完成后我们可以通过执行下面的命令,检测 `Anchor` 是否安装完成✅。

```bash
anchor --version
Expand Down Expand Up @@ -92,7 +92,7 @@ anchor build
anchor deploy
```

solana程序部署将输出您的程序的程序ID。您现在可以在[Solana Explorer](https://explorer.solana.com/?cluster=custom)上查找已部署的程序(对于本地主机,请选择“自定义RPC URL”作为集群)。
Solana程序部署将输出您的程序的程序`ID`。您现在可以在[Solana Explorer](https://explorer.solana.com/?cluster=custom)上查找已部署的程序(对于localhost,请选择“自定义`RPC URL`”作为集群)。


#### 5. 查看程序日志
Expand All @@ -107,6 +107,6 @@ solana logs <PROGRAM_ID>

在测试验证器仍在运行时,尝试使用[此处](https://github.com/DaviRain-Su/all-in-one-solana/tree/main/code/contract/hello_world/app/hello-frontend)的客户端脚本调用您的程序。

这将返回一个Solana Explorer的URL(`Transaction https://explorer.solana.com/tx/${transactionSignature}?cluster=custom`)。将URL复制到浏览器中,在Solana Explorer上查找该交易,并检查程序日志中是否打印了`Hello, world!`。或者,您可以在运行`solana logs`命令的终端中查看程序日志。
这将返回一个[Solana Explorer](https://explorer.solana.com)的URL(`Transaction https://explorer.solana.com/tx/${transactionSignature}?cluster=custom`)。将URL复制到浏览器中,在Solana Explorer上查找该交易,并检查程序日志中是否打印了`Hello, world!`。或者,您可以在运行`solana logs`命令的终端中查看程序日志。

就是这样!您刚刚在本地开发环境中创建并部署了您的第一个程序。
Loading

0 comments on commit ad76bad

Please sign in to comment.