智能合约地址
本节将描述TON区块链上智能合约地址的特点,并解释在TON上,actor与智能合约是如何等同的。
一切皆为智能合约
在TON上,智能合约是使用Actor模型构建的。实际上,在TON中的actor在技术上是以智能合约的形式表示的。这意味着,即使您的钱包也是一个简单的actor(以及一个智能合约)。
通常,actor处理传入消息,改变其内部状态,并生成传出消息。这就是为什么TON区块链上的每一个actor(即智能合约)都必须有一个地址,以便能够从其他actor接收消息。
在以太坊虚拟机(EVM)上,地址与智能合约完全分离。欢迎阅读Tal Kol的文章"TON 区块链的六个独特之处,会让 Solidity 开发者感到惊讶" 了解更多差异。
智能合约的地址
在TON上运行的智能合约地址通常包含两个主要组成部分:
-
(workchain_id):代表工作链ID(一个有符号的32位整数)
-
(account_id) 代表账户的地址(根据工作链不同,为64-512位,)
在本文档的原始地址概述部分,我们将讨论**(workchain_id, account_id)** 是如何呈现。
工作链ID和账户ID
工作链ID
正如我们之前所见,在TON区块链上可以创建多达2^32
个工作链。我们还注意到,32位前缀的智能合约地址用于识别并链接到不同工作链中的智能合约地址。这允许智能合约在TON区块链的不同工作链之间发送和 接收消息。
如今,TON区块链中仅运行主链(workchain_id=-1)和不定期地运行基本工作链(workchain_id=0)。
它们都有256位地址,因此,我们假设workchain_id是0或-1,工作链中的地址正好是256位。
账户ID
TON的所有账户ID都在主链和基本链(或基本工作链)上使用256位地址。
实际上,账户ID (account_id) 被定义为智能合约对象的哈希函数(专指SHA-256)。每个在TON区块链上运行的智能合约都存储两个主要组件。这些包括:
- 编译后的代码。智能合约的逻辑以字节码形式编译。
- 初始状态。合约在链上部署时的值。
最后,为了准确地推导出合约的地址,需要计算与**(初始代码,初始状态)** 对象相对应的哈希。目前,我们不会深入研究TVM的工作方式,但重要的是要理解TON上的账户ID是使用这个公式确定的: : account_id = hash(初始代码,初始状态)
随着本文档的深入,我们将进一步深入技术规格和TVM及TL-B方案的概述。现在我们熟悉了account_id的生成以及它们与TON上智能合约地址的交互,接下来让我们解释什么是原始地址和用户友好地址。
原始地址和用户友好地址
在简要概述了TON上的智能合约地址是如何利用工作链和账户ID(特别是对于主链和基本链 )之后,那重要的是要理解这些地址以下面两种主要格式表示:
- 原始地址:智能合约地址的原始完整表示。
- 用户友好地址:用户友好地址是原始地址的增强格式,有更好的安全性和易用性。
active
- 地址拥有智能合约代码、持久数据和余额。在此状态下,它可以在交易过程中执行一些逻辑,并更改其持久数据。当地址处于uninit
状态,且有带 state_init 参数的消息传入时,它就会进入此状态(注意,要部署此地址,state_init
和code
的哈希值必须等于地址)。frozen
- 地址不能执行任何操作,此状态只包含前一状态的两个哈希值(分别是代码 cell 和状态 cell )。当地址的存储费用超过余额时,就会进入这种状态。要解冻它,可以发送带有state_init
和code
的内部信息,其中存储了前面描述的哈希值和一些 Toncoin。要恢复它可能会很困难,所以你不应该允许这种情况发生。有一个解冻地址的项目,你可以在 这里 找到。
简单易用的地址
在简要介绍了 TON 上的智能合约地址如何利用工作链和账户 ID(具体针对主链和底层链)之后,我们有必要了解这些地址主要有两种格式:
- 原始地址:智能合约地址的原始完整表示。
- 用户友好地址:用户友好地址是一种原始地址的增强格式,具有更好的安全性和易用性。
下面,我们将详细介绍这两种地址类型的区别,并深入探讨 TON 使用用户友好地址的原因。
原始地址
-1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260
- [十进制workchain_id]:[64个十六进制数字的account_id]
以下是一个使用工作链ID和账户ID的原始智能合约地址示例(表示为workchain_id和account_id):
-1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260
使用原始地址形式存在两个主要问题:
地址字符串中可以使用大写字母(如 'A'、'B'、'C'、'D'等)替代其小写的对应字母(如 'a'、'b'、'c' 'd'等)。
用户友好地址
用户友好地址是为了保护和简化在互联网上(例如,在公共消息平台上或通过电子邮件服务提供商)以及现实世界中分享地址的TON用户的体验而开发的。
- 在使用原始地址格式时,无法在发送交易前验证地址以消除错误。 这意味着,如果您在发送交易前不小心在地址字符串中添加或删除字符,您的交易将被发送到错误的目的地,导致资金损失。
- 在使用原始地址格式时,无法添加像使用用户友好地址时发送交易所用的特殊标志位。 为了帮助您更好地理解这个概念,我们将在下面解释可以使用哪些标志位。
用户友好的地址
用户友好地址是为了保护和简化在互联网上(例如,在公共消息平台上或通过电子邮件服务提供商)以及现实世界中分享地址的TON用户的体验而开发的。
用户友好地址结构
要生成用户友好地址,开发者必须使用以下方式对所有36个字节进行编码:
-
base64(即数字、大小写拉丁字母、'/' 和 '+')
- isBounceable。表示可弹回或不可弹回的地址类型。(0x11 表示“可弹回”,0x51 表示“不可弹回”)
- isTestnetOnly。表示仅用于测试网的地址类型。以_0x80_ 开头的地址不应被生产网络上运行的软件接受
- isUrlSafe。表示已定义为地址的URL安全的已弃用标志位。所有地址都被认为是URL安全的。
-
base64url(用 '_' 和 '-' 代替 '/' 和 '+')
-
[account_id - 32字节] — 账户ID由工作链中的256位(大端序)地址组成。
-
[地址验证 - 2字节] — 在用户友好地址中,地址验证由前34个字节的CRC16-CCITT签名组成。(示例) 实际上,用户友好地址的验证思想与所有信用卡上使用的Luhn算法类似,以防止用户错误输入不存在的卡号。
完成这个过程后,会生成一个长度为48个非空格字符的用户友好地址。
要生成用户友好地址,开发者必须使用以下方式对所有36个字节进行编码:
- base64(即数字、大小写拉丁字母、'/' 和 '+')
- base64url(用 '_' 和 '-' 代替 '/' 和 '+')
例如,“测试赠予者”智能合约(一个特殊的智能合约,位于测试网主链中,向任何请求者发送2个测试代币)使用以下原始地址:
在TON上,有时使用诸如mywallet.ton之类的DNS地址,而不是原始和用户友好地址。实际上,DNS地址由用户友好地址组成,并包括所有必需的标志位,允许开发者从TON域中的DNS记录访问所有标志位。
用户友好地址编码示例
例如,“测试赠予者”智能合约(一个特殊的智能合约,位于测试网主链中,向任何请求者发送2个测试代币)使用以下原始地址:
-1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260
上述“测试赠予者”的原始地址必须转换为用户友好地址形式。这可以通过使用之前介绍的base64或base64url形式来获得,如下所示:
kf/8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15+KsQHFLbKSMiYIny
(base64)kf_8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15-KsQHFLbKSMiYIny
(base64url)
注意,base64 和 base64url 两种形式都是有效的,都会被接受!