使用钱包智能合约的工作
👋 介绍
在开始智能合约开发之前,学习 TON 上的钱包和交易如何工作是必不可少的。这些知识将帮助开发者了解钱包、交易和智能合约之间的交互,以实现特定的开发任务。
在本节中,我们将学习如何创建操作,而不使用预配置的函数,以了解开发工作流程。本教程的所有必要参考资料都位于参考章节。
💡 必要条件
这个教程需要对 JavaScript、TypeScript 和 Golang 有基本的了解。同时至少需要持有 3 个 TON(可以存储在交易所账户、非托管钱包中,或使用电报机器人钱包进行存储)。此外,还需要对 cell(单元)、TON 地址 和区块链的区块链 有基本的了解,以理解本教程。
在 TON 测试网上工作往往会导致部署错误、难以跟踪交易以及不稳定的网络功能。因此,完成大部分开发工作时间可能好处是建议在 TON Mainnet 上完成,以避免这些问题,这可能需要减少交易数量,从而可能减小费用。
源代码
本教程中使用的所有代码示例都可以在以下 GitHub 存储库 中找到。
✍️ 您开始所需的内容
- 确保 NodeJS 已安装。
- 需要特定的 Ton 库,包括:@ton/ton 13.5.1+、@ton/core 0.49.2+ 和 @ton/crypto 3.2.0+。
可选: 如果您喜欢使用 Golang 而不是使用 JS,那么需要安装 tonutils-go 库以及 GoLand IDE,用于进行 TON 开发。本教程中将使用这个库来进行 Golang 版本的操作。
- JavaScript
- Golang
npm i --save @ton/ton @ton/core @ton/crypto
go get github.com/xssnick/tonutils-go
go get github.com/xssnick/tonutils-go/adnl
go get github.com/xssnick/tonutils-go/address
⚙ 设置您的环境
为了创建一个 TypeScript 项目,必须按照以下步骤进行操作:
- 创建一个空文件夹(我们将其命名为 WalletsTutorial)。
- 使用 CLI 打开项目文件夹。
- 使用以下命令来设置项目:
npm init -y
npm install typescript @types/node ts-node nodemon --save-dev
npx tsc --init --rootDir src --outDir build \ --esModuleInterop --target es2020 --resolveJsonModule --lib es6 \ --module commonjs --allowJs true --noImplicitAny false --allowSyntheticDefaultImports true --strict false
为了帮助我们完成下一个流程,我们使用了 ts-node
来直接执行 TypeScript 代码,而无需预编译。当检测到目录中的文件更改时,nodemon
会自动重新启动节点应用程序。
- 删除
tsconfig.json
中的以下行:
"files": [
"\\",
"\\"
]
- 然后,在项目根目录中创建
nodemon.json
配置文件,内容如下:
{
"watch": ["src"],
"ext": ".ts,.js",
"ignore": [],
"exec": "npx ts-node ./src/index.ts"
}
- 在
package.json
中添加以下脚本到 "test" 脚本的位置:
"start:dev": "npx nodemon"
- 在项目根目录中创建
src
文件夹,然后在该文件夹中创建index.ts
文件。 - 接下来,添加以下代码:
async function main() {
console.log("Hello, TON!");
}
main().finally(() => console.log("Exiting..."));
- 使用终端运行以下代码:
npm run start:dev
- 最后,控制台将输出以下内容。
TON 社区创建了一个优秀的工具来自动化所有开发过程(部署、合约编写、测试)称为 Blueprint。然而,我们在本教程中不需要这么强大的工具,所以建议遵循上述说明。
可选: 当使用 Golang 时,请按照以下说明进行操作:
- 安装 GoLand IDE。
- 使用以下内容创建项目文件夹和
go.mod
文件(如果使用的当前版本已过时,则可能需要更改 Go 版本):
module main
go 1.20
- 在终端中输入以下命令:
go get github.com/xssnick/tonutils-go
- 在项目根目录中创建
main.go
文件,内容如下:
package main
import (
"log"
)
func main() {
log.Println("Hello, TON!")
}
- 将
go.mod
中的模块名称更改为main
。 - 运行上述代码,直到在终端中显示输出。
也可以使用其他 IDE,因为 GoLand 不是免费的,但建议使用 GoLand。
所有代码组件都应添加到在⚙ 设置您的环境 部分中创建的 main
函数中。
另外,下面的每个新部分将指定每个新部分所需的特定代码部分,并且需要将新的导入与旧导入合并起来。
🚀 让我们开始!
在本教程中,我们将学习在 TON 区块链上最常使用的钱包(版本 3 和 4),并了解它们的智能合约是如何工作的。这将使开发人员更好地理解 TON 平台上的不同类型的交易,以便更简单地创建交易、将其发送到区块链、部署钱包,并最终能够处理高负载的钱包。
我们的主要任务是使用 @ton/ton、@ton/core、@ton/crypto 的各种对象和函数构建交易,以了解大规模交易是怎样的。为了完成这个过程,我们将使用两个主要的钱包版本(v3 和 v4),因为交易所、非托管钱包和大多数用户仅使用这些特定版本。
在本教程中,可能会有一些细节没有解释。在这些情况下,将在本教程的后续阶段提供更多细节。
重要: 在本教程中,我们使用了 wallet v3 代码 来更好地理解钱包开发过程。需要注意的是,v3 版本有两个子版本:r1 和 r2。目前,只使用第二个版本,这意味着当我们在本文档中提到 v3 时,它指的是 v3r2。
💎 TON 区块 链钱包
在 TON 区块链上运行的所有钱包实际上都是智能合约,与 TON 上的一切都是智能合约的方式相同。与大多数区块链一样,可以在网络上部署智能合约并根据不同的用途自定义它们。由于这个特性,完全自定义的钱包是可能的。 在 TON 上,钱包智能合约帮助平台与其他智能合约类型进行通信。然而,重要的是要考虑钱包通信是如何进行的。
钱包通信
通常,在 TON 区块链上有两种交易类型:internal
和 external
。外部交易允许从外部世界向区块链发送消息,从而与接受此类交易的智能合约进行通信。负责执行此过程的函数如下:
() recv_external(slice in_msg) impure {
;; 一些代码
}
在我们深入研究钱包之前,让我们先看看钱包如何接受外部交易。在 TON 上,所有钱包都持有所有者的 公钥
、seqno
和 subwallet_id
。接收到外部交易时,钱包使用 get_data()
方法从钱包的存储部分中检索数据。然后进行多个验证流程,并决定是否接受此交易。这个过程的完成如下:
() recv_external(slice in_msg) impure {
var signature = in_msg~load_bits(512); ;; 从消息体中获取签名
var cs = in_msg;
var (subwallet_id, valid_until, msg_seqno) = (cs~load_uint(32), cs~load_uint(32), cs~load_uint(32)); ;; 从消息体中获取其他值
throw_if(35, valid_until <= now()); ;; 检查交易的有效性
var ds = get_data().begin_parse(); ;; 从存储获取数据并将其转换为可读取值的切片
var (stored_seqno, stored_subwallet, public_key) = (ds~load_uint(32), ds~load_uint(32), ds~load_uint(256)); ;; 从存储中读取值
ds.end_parse(); ;; 确保变量 ds 中没有任何数据
throw_unless(33, msg_seqno == stored_seqno);
throw_unless(34, subwallet_id == stored_subwallet);
throw_unless(35, check_signature(slice_hash(in_msg), signature, public_key));
accept_message();
💡 有用的链接:
接下来,我们来详细看一下。