Ton链开发入门系列 —— Tact介绍

  • 小符
  • 更新于 2024-08-21 18:21
  • 阅读 2353

TON是一个高性能区块链,旨在支持去中心化应用程序(dApps)、快速支付、微支付和其他Web3应用场景。

TON 生态(The Open Network Ecosystem)是由 Telegram 开发的区块链平台。TON 最初是 Telegram Open Network 的缩写,是一个高性能区块链,旨在支持去中心化应用程序 (dApps)、快速支付、微支付和其他 Web3 应用场景。

image.png

Tact 是 TON 生态系统中的一种新兴智能合约编程语言。与 Fift 和 FunC 相比,Tact 提供了更高级、更友好的语法,旨在简化智能合约的开发过程,本节主要介绍如何使用Ton生态合约开发语言Tact开发合约并部署。

一、安装Ton钱包 Tonkeeper

Tonkeeper是一个流行的Ton钱包插件,可以在官网进行安装,安装好后按照以下步骤切换到测试网。

image.png

在图中图标处连续点击5次既可进行切换。

image.png

二、领取测试币

ton生态中可以找到常用的水龙头,在Telegram中按提示进行领取,一次可以领取5个 $TON。

image.png

三、开发合约

可以在Tact官网了解Tact语言,Tact提供了简单的模版代码库可供快速入门。

克隆仓库

$ git clone git@github.com:tact-lang/tact-template.git
$ tree -L 1
.
├── jest.config.js
├── jest.setup.js
├── jest.teardown.js
├── node_modules
├── package.json
├── README.md
├── sources
├── tact.config.json
├── tsconfig.json
└── yarn.lock

配置文件

tact.config.json 中配置源文件和输出目录。

{                                                                                                                                  
    "projects": [{                                                                 
        "name": "sample",                                                          
        "path": "./sources/contract.tact",                                      
        "output": "./sources/output",                                           
        "options":{                                                             

        }                                                                       
    }]                                                                          
}    

package.json 中配置命令和依赖。

{                                                                                                                                  
  "private": true,                                                                 
  "scripts": {                                                                     
    "build": "tact --config ./tact.config.json",                                
    "test": "jest",                                                             
    "deploy": "ts-node ./sources/contract.deploy.ts",                           
    "read": "ts-node ./sources/contract.read.ts"                                
  },                                                                            
  "dependencies": {                
  ......

编写合约文件

合约文件在 sources 文件夹中。

$ cd sources
$ tree -L 1
.
├── contract.deploy.ts      # 部署合约
├── contract.read.ts        # 读合约
├── contract.spec.ts        # 测试
├── contract.tact           # Tact合约
└── output                  # 编译输出

contract.tact 编写合约主要的逻辑功能,先简单看下Tact合约的结构,本系列的后面章节会介绍Tact的语法。

import "@stdlib/deploy";                                                                                                                                                                                                                                              

message Add {                                                                   
    amount: Int as uint32;                                                      
}                                                                               

contract SampleTactContract with Deployable {                                   

    owner: Address;                                                             
    counter: Int as uint32;                                                     

    init(owner: Address) {                                                      
        self.owner = owner;                                                     
        self.counter = 0;                                                       
    }                                                                           

    fun add(v: Int) {                                                           

        // Check sender                                                         
        let ctx: Context = context();                                           
        require(ctx.sender == self.owner, "Invalid sender");                    

        // Update counter                                                       
        self.counter += v;                                                      
    }                                                                           

    receive(msg: Add) {                                                         
        self.add(msg.amount);                                                   
    }                                                                           

    receive("increment") {                                                      
        self.add(1);                                                            
        self.reply("incremented".asComment());                                  
    }                                                                           

    get fun counter(): Int {                                                    
        return self.counter;                                                    
    }                                                                           
}                                                                               

contract.read.ts 中调用合约函数,注意切换 Owner地址 为自己的钱包地址。

import { Address, contractAddress} from "@ton/core";                            
import { TonClient4 } from "@ton/ton";                                                                                                                   
import { SampleTactContract } from "./output/sample_SampleTactContract";        

(async () => {                                                                  
    const client = new TonClient4({                                             
        endpoint: "https://sandbox-v4.tonhubapi.com", // 🔴 Test-net API endpoint
    });                                                                         

    // Parameters                                                               
    let owner = Address.parse("0QDixtmWuXpmConuFpl1rtRXyJyUh9JaoUxNufua6q-gSF-r"); 
    let init = await SampleTactContract.init(owner);                            
    let contract_address = contractAddress(0, init);                            

    // Prepareing                                                               
    console.log("Reading Contract Info...");                                    
    console.log(contract_address);                                              

    // Input the contract address                                               
    let contract = await SampleTactContract.fromAddress(contract_address);         
    let contract_open = await client.open(contract);                            
    console.log("Counter Value: " + (await contract_open.getCounter()));        
})();                                                                           
~                                                                                                                                                        
~   

contract.deploy.ts 中实现部署功能,注意切换 Owner地址 为自己的钱包地址。

import * as fs from "fs";                                                                                                                                
import * as path from "path";                                                   
import { Address, contractAddress } from "@ton/core";                           
import { SampleTactContract } from "./output/sample_SampleTactContract";        
import { prepareTactDeployment } from "@tact-lang/deployer";                    

(async () => {                                                                  
    // Parameters                                                               
    let testnet = true;                                                         
    let packageName = "sample_SampleTactContract.pkg";                          
    let owner = Address.parse("0QDixtmWuXpmConuFpl1rtRXyJyUh9JaoUxNufua6q-gSF-r");
    let init = await SampleTactContract.init(owner);                            

    // Load required data                                                       
    let address = contractAddress(0, init);                                     
    let data = init.data.toBoc();                                               
    let pkg = fs.readFileSync(path.resolve(__dirname, "output", packageName));  

    // Prepareing                                                               
    console.log("Uploading package...");                                        
    let prepare = await prepareTactDeployment({ pkg, data, testnet });          

    // Deploying                                                                
    console.log("==============================================");
    console.log("Contract Address");                                            
    console.log("==============================================");
    console.log();                                                              
    console.log(address.toString({ testOnly: testnet }));                       
    console.log();                                                              
    console.log("==============================================");
    console.log("Please, follow deployment link");                              
    console.log("==============================================");
    console.log();                                                              
    console.log(prepare);                                                       
    console.log();                                                              
    console.log("==============================================");
})();

部署

部署前先需要使用yarn 安装依赖,然后进行编辑再部署。

$ yarn install
$ yarn build
$ yarn deploy
yarn run v1.22.5                                                                                                                                         
$ ts-node ./sources/contract.deploy.ts                                                                                                                   
Uploading package...                                                                                                                                     
========================================================================                                                        
Contract Address                                                                                                                                         
=========================================================================                                               

kQDOi1omEsS6D3hyU3f0cgCHMFfbpYmpNHm6u9poBOopTDKf                                                                                                         

========================================================================                                              
Please, follow deployment link                                                                                                                           
========================================================================                                                          

https://verifier.ton.org/tactDeployer/QmQThDT1sk8XrxAiPnND3AVz9gPEr1pUy6JbXWWUVC5GqV?testnet                                                             

========================================================================                                                 
Done in 4.73s. 

tact.gif

部署时会生成合约地址和验证链接,在浏览器中打开链接连接钱包。

image.png

点击“Deploy”按钮后在钱包中签名确认交易完成部署。 image.png

四、检查交易

完成部署后可以在ton官方区块链浏览器Tonviewer中查看部署结果。

image.png

可以看到部署的合约信息

image.png

五、总结

本节主要演示如何快速在ton链上部署合约,不着眼于Tact合约的具体细节,介绍了Tact项目的项目结构以及一些相关的文件所包含的功能,以方便快速了解如何在Ton链上从零开始进行开发,本系列的后续章节会详细介绍Tact的语法和开发实践。

点赞 1
收藏 2
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

3 条评论

请先 登录 后评论
小符
小符
0x6737...76B6
web3 builder