本文将描述 TON 区块链上智能合约地址的细节。同时还将解释参与者(Actors)如何成为 TON 上智能合约的代名词。
一、一切都是智能合约
在 TON 区块链上,智能合约是使用 Actor 模型构建的。事实上,TON 中的参与者在技术上表现为智能合约。这意味着即使你的钱包也是一个简单的参与者(和智能合约)。
Actor 说起来比较抽象,可以简单理解为面向对象编程(OOP)中的一个对象实例 (Instance)。
通常,参与者处理传入消息(inbound msg),更改其内部状态,并最终生成出站消息(outbound msg)。这就是为什么 TON 区块链上的每个参与者(即一个智能合约实例)都必须有一个地址,以便它能够接收来自其他参与者的消息。
对比以太坊虚拟机
在以太坊虚拟机(EVM)上,地址与智能合约不是一一对应的,比如钱包地址 EOA(Externally Owned Account)就独立于智能合约。详细请阅读 Tal Kol 撰写的文章“ TON 区块链的六个独特方面将让 Solidity 开发人员感到惊讶”,了解更多关于这些差异的信息。
二、智能合约地址
在 TON 上运行的智能合约地址通常由两个主要部分组成:
- workchain_id :表示工作链ID(有符号的32位整数)
- account_id : 表示账户的地址(64-512位,不同的工作链可以自定义不同长度id)。
workchain_id:account_id
2.1 工作链 ID 和账户 ID
2.1.1 工作链 ID(Workchain ID )
你可能听过,在 TON 区块链可以创建多达 2^32 (4294967296)个工作链。因此我们还注意到 32 位前缀智能合约地址如何识别并链接到不同工作链中的智能合约地址。这允许智能合约向 TON 区块链上的不同工作链发送和接收消息。
目前,TON区块链上的交易量还是非常少,因此只有 Masterchain (workchain_id=-1) 和基础工作链 (workchain_id=0) 在运行。
Masterchain和基础工作链Base Workchain(BaseChain)都是256位 account_id 地址,因此,我们假设workchain_id为0或-1,并且工作链内的地址恰好是256位。
2.2.2 Account ID 账户ID
在 Masterchain 和 Basechain(或基本工作链)上 TON 的所有账户 ID 都使用 256 位地址。
事实上,账户 ID (account_id) 定义为智能合约对象的哈希函数( SHA-256)。在 TON 区块链上运行的每个智能合约都存储两个主要组件。这些包括:
- 编译好的代码。以字节码形式编译的智能合约逻辑。
- 初始状态。合约在链上部署时的初始值。
最后,为了准确推导合约的地址,需要计算pair(初始代码code,初始状态state)对象对应的哈希值。目前,我们不会深入探讨 TVM 的工作原理,但重要的是要了解 TON 上的帐户 ID 是使用以下公式确定的:account_id = hash(初始代码,初始状态)
随着时间的推移,我们将在本文档中更深入地探讨 TVM 和 TL-B 方案的技术规范和概述。现在我们已经熟悉了 account_id 的生成及其与 TON 上智能合约地址的交互,让我们解释一下原始地址和用户友好地址。
三、原始(Raw)和用户友好的地址
在简要概述 TON 上的智能合约地址如何利用工作链和账户 ID(特别是 Masterchain 和 Basechain)之后,了解这些地址以两种主要格式表示非常重要:
- 原始地址(Raw addresses):智能合约地址的原始完整表示。
- 用户友好的地址(User-friendly addresses):用户友好的地址是原始地址的增强格式,具有更好的安全性和易用性。
下面,我们将详细解释这两种地址类型之间的差异,并深入探讨 TON 上使用用户友好地址的原因。
3.1 原始地址(Raw address)
原始智能合约地址由工作链 ID 和账户 ID(workchain_id、account_id)组成,并以以下格式显示:
- [十进制workchain_id]:[十六进制的account_id]
下面展示的是使用工作链 ID 和账户 ID 的原始智能合约地址(表示为 workchain_id 和 account_id)
-1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260
请注意地址字符串开头的 -1 ,它表示属于 Masterchain 的 workchain_id。
原始地址的问题
使用原始地址表单存在两个主要问题:
- 使用原始地址格式时,无法在发送交易之前验证地址以消除错误。这意味着,如果您在发送交易之前不小心添加或删除了地址字符串中的字符,您的交易将被发送到错误的目的地,从而导致资金损失。
- 使用原始地址格式时,不可能添加特殊标志,例如发送使用用户友好地址的交易时使用的标志。为了帮助您更好地理解这个概念,我们将在下面解释可以使用哪些标志。
3.2 用户友好的地址
用户友好的地址的推行,是为了保护和简化在互联网以及现实世界中,共享地址的 TON 用户的体验。
3.2.1 用户友好的地址结构
用户友好地址总共由 36 (4+32)个字节组成,由以下部分按顺序生成得到:
- [flags - 1 byte] - 固定到地址的标志会改变智能合约对收到消息的反应方式。采用用户友好地址格式的标志类型包括:
- 可回退的(isBounceable)标志位:表示可退回或不可退回的地址类型。 (0x11 表示“可退回”,0x51 表示“不可退回”)
- 仅限测试网(isTestnetOnly)标志位:表示仅用于测试网目的的地址类型。生产网络上运行的软件不应接受以 0x80 开头的地址
- URL安全标志(isUrlSafe):已弃用的标志,该标志被定义为地址的 URL 安全。所有地址都被视为 URL 安全的。
- [workchain_id - 1 字节] — 工作链 ID (workchain_id) 由带符号的 8 位整数 workchain_id 定义。
- (BaseChain 为 0x00,MasterChain 为 0xff)
译者备注:因此最多只有128个工作链是有地址的,当然因为account_id已经很大了,地址也已经解决无限多。
- [account_id - 32 字节] — 帐户 ID 由工作链中的(大端)256 位地址组成。
- [地址验证 - 2 个字节] — 在用户友好的地址中,地址验证由前 34 个字节的 CRC16-CCITT 签名组成。 (示例)事实上,有关用户友好地址验证的想法与 Luhn 算法非常相似,该算法用于所有信用卡,以防止用户错误地输入不存在的卡号。
这 4 个主要组件的添加意味着:总共 1 + 1 + 32 + 2 = 36 字节(每个用户友好地址)。
要生成用户友好的地址,开发人员必须使用以下任一方法对所有 36 个字节进行编码:
- base64(即包含数字、大写和小写拉丁字母、“/”和“+”)
- base64url(用“_”和“-”代替“/”和“+”)
此过程完成后,就完成了长度为 48 个非空格字符的用户友好地址的生成。
DNS 地址标志
在 TON 上,有时会使用 mywallet.ton 等 DNS 地址来代替原始且用户友好的地址。事实上,DNS 地址由用户友好的地址组成,并包含所有必需的标志,允许开发人员访问 TON 域内 DNS 记录中的所有标志。
3.2.2 用户友好的地址编码示例
例如,“测试给予者”智能合约(驻留在测试网主链中的特殊智能合约,向请求者发送 2 个测试代币)使用以下原始地址:
-1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260
上述“测试给予者”原始地址必须转换为用户友好的地址形式。这是使用 base64 或 base64url 形式(我们之前介绍过的)获得的,如下所示:
- kf/8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15+KsQHFLbKSMiYIny (base64) kf/8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15+KsQHFLbKSMiYIny (base64)
- kf_8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15-KsQHFLbKSMiYIny (base64url) kf_8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15-KsQHFLbKSMiYIny (base64url)
备注信息
请注意,这两种形式(base64 和 base64url)都是有效的并且必须被接受!
3.2.3 可退回地址与不可退回地址
可退回地址标志背后的核心思想是发件人的资金安全。
例如,如果目的地智能合约不存在,或者交易过程中发生某些问题,消息将被“弹回”给发送者,并构成交易原始价值的剩余部分(减去所有转账和汽油费) )。这可以确保发件人不会丢失意外发送到无法接受交易的地址的资金。
具体与可退回地址相关:
- 如果 bounceable=false 通常意味着接收者是钱包。
- 如果 bounceable=true 通常表示具有自己的应用程序逻辑的自定义智能合约(例如,DEX)。在此示例中,出于安全原因,不应发送不可退回的消息。
请随时在我们的文档中阅读有关此主题的更多信息,以更好地了解不可退回消息。
3.2.4 转换用户友好地址和原始地址
转换用户友好的原始地址的最简单方法是使用多个 TON API 之一和其他工具,包括:
此外,还有两种方法可以使用 JavaScript 转换用户友好的钱包地址和原始地址:
- Convert address from/to user-friendly or raw form using ton.js
- Convert address from/to user-friendly or raw form using tonweb
当然还可以通过 SDK 做相应地处理
原文:Smart Contract Addresses | The Open Network
本文由TON心粉社区(Telegram: Contact @tonx_news)翻译,做了必要的不影响阅读的删减和调整。