首页 > 其他分享 >Ton 区块链的官方 类ERC20-Token 智能合约代码-Transfer部分解析

Ton 区块链的官方 类ERC20-Token 智能合约代码-Transfer部分解析

时间:2024-06-12 12:32:23浏览次数:23  
标签:body slice Transfer jetton Token Ton address msg store

作者:林冠宏 / 指尖下的幽灵。转载者,请: 务必标明出处。

掘金:https://juejin.im/user/1785262612681997

GitHub : https://github.com/af913337456/

出版的书籍:


Ton 区块链的官方 类ERC20-Token 智能合约代码-Transfer部分解析

最近在学习 Ton 链的智能合约,由于我之前的经验思维主要是集中在以太坊这条链的,即Solidity那套,所以带着长久偏向的思维去阅读 Ton 的合约时发现格格不入,Ton 的合约设计与EVM体系的属于天壤之别。

首先 Ton 的合约是分片的,遵循 Parent-Child 的规则,这里详细了解见:

https://blog.ton.org/how-to-shard-your-ton-smart-contract-and-why-studying-the-anatomy-of-tons-jettons

其次是合约开发的语言,Ton 有三种,用得最多的是 FunC,这是一种完全的非主流语言,在 GitHub 上都没有特点标识的那种。


按照最快了解 Token 智能合约的方式,寻找到官方的合约代码项目。由于Ton 的经济 Token 代码目前还没有类似以太坊的各种模型协议,只能把对应以太坊ERC-20的那部分取下来进行阅读。

下面我将结合Token的转账核心操作的源码来对其整个调用链路 进行细致的分析讲解,所选代码片段也有注释。

先了解合约模式
  • Ton 的合约是分片的,拿 Token 类型的合约做例子,其做法是将一份主合约,被称为 Master 或 Minter 的合约独一份进行部署,再将和 User 的子合约在转账进行时进行新建形式的一一对应部署。
  • 比如说,发布一份名叫 NOT 的 Token 合约,它的 Master 合约将被部署在链上,然后对于后续每一位收到 NOT token 的用户地址,若不存在就都会创建一份与该地址对应的子合约,称为 Wallet 合约。
  • 在 Token 类型的合约中,Master 合约中存储了 Token 的公共信息,比如 Name,Metaurl,Supply 等,而Transfer 转账行为却都发生在各自的 Wallet 合约里面。
  • 为 User 创建 Wallet 合约都要经过 Master 进行。
  • 合约允许各自内部调用,A 合约调用 B 合约的函数。

客户端-发起转账 Token 的流程

例子取于 Golang 客户端项目代码。

func main() {
   ...
   // 初始化自己的钱包
   w, _ := wallet.FromSeed(api, words, wallet.V3R2)
   // 根据该 Token 的 Master 合约地址初始化 Token
   token := jetton.NewJettonMasterClient(api, address.MustParseAddr("EQD0vdS......"))
   // 调用 Master 的合约函数获取转账者的 Wallet 合约
   tokenWallet, _ := token.GetJettonWallet(ctx, w.WalletAddress())
   tokenBalance, _ := tokenWallet.GetBalance(ctx)
   amountTokens := tlb.MustFromDecimal("0.1", 9)
   // 转账附带的信息
   comment, _ := wallet.CreateCommentCell("Hello from tonutils-go!")
   // 初始化收款者的地址,这不是 Wallet 地址
   to := address.MustParseAddr("EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N")
   // 在 BuildTransferPayloadV2 里指定了 OP = Transfer
   transferPayload, _ := tokenWallet.BuildTransferPayloadV2(to, to, amountTokens, tlb.ZeroCoins, comment, nil)
   // 构造链上请求的消息结构
   msg := wallet.SimpleMessage(tokenWallet.Address(), tlb.MustFromTON("0.05"), transferPayload)
   // 发送转账交易,然后结束
   tx, _, _ := w.SendWaitTransaction(ctx, msg)
   log.Println("transaction confirmed, hash:", base64.StdEncoding.EncodeToString(tx.Hash))
}

上述代码可以看到在发起转账的时候,收款地址并不是 User 的钱包地址,而是其对应的 Wallet 合约地址。这一点就和包括以太坊在内的绝大部分公链都不一样。

合约端对应的转账入口代码解析

内部消息的入口函数,根据 op 参数指定调用入口。

() recv_internal(int my_balance, int msg_value, cell in_msg_full, slice in_msg_body) impure {
  if (in_msg_body.slice_empty?()) { ;; ignore empty messages
    return ();
  }

  slice cs = in_msg_full.begin_parse();
  int flags = cs~load_uint(4);
  if (flags & 1) {
    on_bounce(in_msg_body);
    return ();
  }
  slice sender_address = cs~load_msg_addr();
  cs~load_msg_addr(); ;; skip dst
  cs~load_coins(); ;; skip value
  cs~skip_bits(1); ;; skip extracurrency collection
  cs~load_coins(); ;; skip ihr_fee
  int fwd_fee = muldiv(cs~load_coins(), 3, 2); ;; we use message fwd_fee for estimation of forward_payload costs

  int op = in_msg_body~load_uint(32);

  if (op == op::transfer()) { ;; outgoing transfer
    ;; sender_address 是一开始的转账者
    ;; msg_value 是改次转账中的 Ton 数额
    send_tokens(in_msg_body, sender_address, msg_value, fwd_fee);
    return ();
  }

  if (op == op::internal_transfer()) { ;; incoming transfer
    ;; my_balance 是当前所执行的合约所有者的 Ton 余额
    receive_tokens(in_msg_body, sender_address, my_balance, fwd_fee, msg_value);
    return ();
  }

  if (op == op::burn()) { ;; burn
    burn_tokens(in_msg_body, sender_address, msg_value, fwd_fee);
    return ();
  }

  throw(0xffff);
}
  • recv_internal 是系统内置的函数入口,相当于 main;
  • 系统函数还有:load_datasave_data,加载的是当前合约的数据,存储也是存储到当前合约。代码中的变量 jetton_master_address 地址永远是父合约地址
  • 转账发起时,指定 op 是 transfer,走到代码处理点 op == op::transfer,进入到 send_tokens
  • send_tokens函数源码及其解析注释内容见下

    标签:body,slice,Transfer,jetton,Token,Ton,address,msg,store
    From: https://www.cnblogs.com/linguanh/p/18243703

相关文章

  • [ToneTuneToolkit][023]UGUI的去色,使UI元素变为灰色
    #regionEnvironmentWindows1022H2Unity2022.3.30f1LTSVSCode1.90.0//ToneTuneToolkit下载地址// https://github.com/MirzkisD1Ex0/ToneTuneToolkit.git#endregion 把UGUI的元素去色!变成灰色!!!超级方便!//该项功能已包含至ToneTuneToolkit插件  01.新建场景,新建......
  • ValueError: Tokenizer class LLaMATokenizer does not exist or is not currently im
    ValueError:TokenizerclassLLaMATokenizerdoesnotexistorisnotcurrentlyimported.解决方案:全面解析问题概述当您使用Transformers库处理与LLaMA模型相关任务时,遇到ValueError:TokenizerclassLLaMATokenizerdoesnotexistorisnotcurrentlyimported.......
  • ValueError: Tokenizer class Qwen2Tokenizer does not exist or is not currently po
    ValueError:TokenizerclassQwen2Tokenizerdoesnotexistorisnotcurrentlyported.解决方案:全面解析问题概述当您使用Qwen模型或Qwen技术相关库时,遇到ValueError:TokenizerclassQwen2Tokenizerdoesnotexistorisnotcurrentlyported.错误时,这意味着......
  • 记一次密码重置之token参数可逆练习及思路技巧
    杂个人漏洞实战练习记录密码重置之token参数可逆文章目录杂个人漏洞实战练习记录前言一、实验过程:1.首先访问页面,如下图所示:2.分别重置用户aaaa,admin,bbb三个用户密码,通过抓包查看数据并分析,如下图所示:3.分析:aaaa,bbb重置密码分别带有32位加密的key,初步猜测位md5加......
  • 6.9找回机制接口安全&验证码token接口
    响应包responseburp截取拦截,改相应包;思路:此处应该若是修改密码,先抓到修改成功数据包(截取验证关键字),在替换为需要绕过的数据包,截取response数据包,修改验证成功关键字达到绕过效果;1.发送验证码2.验证3.重制密码1-3跳过2;短信轰炸实例接口调用发包;应用程序注册模块没用添加......
  • 将stanfordcorenlp的tokenizer换成自定义的(或用stanfordcorenlp对自定义tokenizer分词
    本文是基于中文语料做的,对于英文语料应该也是同理,即同样适用的。分析stanfordcorenlp的分词结果,可以发现,它好像是对最小的中文词进行分词,即其对中文的分词粒度很小,这对于某些nlp场景可能就不太合适了,自然的就想到能不能将stanfordcorenlp中用于分词的tokenizer替换掉,替换成自......
  • HTTP 请求中 Token 参数带引号导致后台无法识别问题
    HTTP请求中Token参数带引号导致后台无法识别问题在使用HttpClient对check_login接口进行测试时,意外地在请求头的token部分添加了引号”s4PrKYfu”,导致后台无法正确识别该参数。错误的请求如下所示:POST{{server_host}}/user/check_logintoken:"s4PrKYfu"Content-Typ......
  • WPF RepeatButton
    是一个特殊的按钮,用于在用户长按或连续点击时重复执行特定动作。它通常用于需要重复执行某个操作的场景。常用属性描述Delay用于获取或设置RepeatButton在开始重复之前被按下时等待的时间(以毫秒为单位)。该值必须为非负数。Interval用于获取或设置开始重复后重复之......
  • WPF button mouseover background change color
    <Applicationx:Class="WpfApp142.App"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-nam......
  • 视频监控管理平台LntonCVS视频汇聚平台充电桩视频监控应用方案
    随着新能源汽车的广泛使用,公众对充电设施的安全性和可靠性日益重视。为了提高充电桩的安全管理和站点运营效率,LntonCVS公司推出了一套全面的新能源汽车充电桩视频监控与管理解决方案。该方案通过安装高分辨率摄像头,对充电桩及其周边区域进行不间断监控,确保充电环境的安全无虞......