您正在查看: Layer2 分类下的文章

cdk-data-availability之TrackSequence参数分析

https://github.com/0xPolygon/cdk-data-availability/blob/e17fe08a81dee451636cadce04e568563d992d38/sequencer/tracker.go#L84-L113

// Start starts the SequencerTracker
func (st *Tracker) Start(parentCtx context.Context) {
    st.startOnce.Do(func() {
        ctx, cancel := context.WithTimeout(parentCtx, st.timeout)
        defer cancel()

        addr, err := st.em.TrustedSequencer(ctx)
        if err != nil {
            log.Fatalf("failed to get sequencer addr: %v", err)
            return
        }

        log.Infof("current sequencer addr: %s", addr.Hex())
        st.setAddr(addr)

        url, err := st.em.TrustedSequencerURL(ctx)
        if err != nil {
            log.Fatalf("failed to get sequencer addr: %v", err)
            return
        }

        log.Infof("current sequencer url: %s", url)
        st.setUrl(url)

        if st.trackChanges {
            log.Info("sequencer tracking enabled")

            go st.trackAddrChanges(parentCtx)
            go st.trackUrlChanges(parentCtx)
        }
    })
}

分析

当TrackSequence设置为true时,会在TrackSequencerPollInterval间隔内,检查L1合约内的TrustedSequencer地址和URL是否有变更,并更新本地

场景

因为TrustedSequencer地址和URL变更频率很低,默认情况下TrackSequence可以设置为false,对比变更比较频繁的场景,可以将TrackSequence改为true
注:当cdk-data-availability服务重启时,会自动对齐配置

使用Kurtosis快速验证Polygon CDK新版本

前置介绍

官方部署:https://docs.polygon.technology/cdk/getting-started/local-deployment/
Polygon CDK Kurtosis 包允许您轻松自定义和实例化 CDK 链的所有组件。它使用Kurtosis工具来协调 Docker 容器中链组件的设置,并使用Starlark脚本(一种 Python 方言)中定义的逻辑来定义设置链的分步过程。

Polygon CDK Kurtosis Package

https://github.com/0xPolygon/kurtosis-cdk
通过kurtosis{用于打包和启动临时后端堆栈的平台},通过Docker和k8s 部署私有、可移植、模块化的Polygon CDK开发网络

软件包将部署:

  1. 本地 L1 链,使用ethereum-package ,完全可定制并支持多客户端。
  2. 本地 L2 链,使用Polygon Chain 开发套件(CDK),具有可定制的组件,例如序列器、序列发送器、聚合器、rpc、证明器、dac 等。它将首先在 L1 链上部署Polygon zkEVM 智能合约,然后再部署不同的组件。
  3. zkEVM桥接基础设施,促进 L1 和 L2 链之间的资产桥接,反之亦然。
  4. Agglayer一种正在开发中的互操作性协议,它允许进行无需信任的跨链代币传输和消息传递,以及 L2 链之间的更复杂操作,并由 zk 证明保护。
  5. 附加服务,如交易垃圾邮件发送者、监控工具、无需权限的节点等。

模块版本对应关系

Fork ID CDK Erigon ZkEVM Prover ZkEVM Contracts Data Availability Bridge
13 v2.60.0-beta4 v9.0.0-RC1-fork.13 v8.1.0-rc.1-fork.13 0.0.10 v0.6.0-RC1
12 v2.1.2 v8.0.0-RC14-fork.12 v8.0.0-rc.4-fork.12 0.0.10 v0.6.0-RC1
11 v2.1.2 v7.0.4-fork.11 v7.0.0-rc.2-fork.11 0.0.10 v0.6.0-RC1
9 v2.1.2 v6.0.8 v6.0.0-rc.1-fork.9 0.0.10 v0.6.0-RC1

当前测试时,默认测试 fork12

部署测试

Kurtosis部署

环境准备

  • Docker
  • Kurtosis
    • echo "deb [trusted=yes] https://apt.fury.io/kurtosis-tech/ /" | sudo tee /etc/apt/sources.list.d/kurtosis.list
      sudo apt update
      sudo apt install kurtosis-cli
  • jq
  • yq (v3)
  • cast
    • curl -L https://foundry.paradigm.xyz | bash
      source ~/.bashrc
      foundryup
  • polycli
    • git clone https://github.com/0xPolygon/polygon-cli.git
      make install
      export PATH="$HOME/go/bin:$PATH"

部署

git clone https://github.com/0xPolygon/kurtosis-cdk.git
sudo su
kurtosis clean --all
ulimit -n 1000000
kurtosis run --enclave cdk .

默认部署包括cdk-erigon作为序列器,以及cdk-node作为序列发送器和聚合器。您可以通过查看 input_parser.star 来验证这些组件的默认版本和默认 fork ID。您可以通过查看input_parser.star来检查已部署组件的默认版本和默认 fork ID
当前cdk-erigon为v2.1.2版本,对应fork ID 12

查看网络布局

kurtosis enclave inspect cdk

L2 RPC 测试调用

export ETH_RPC_URL="$(kurtosis port print cdk cdk-erigon-rpc-001 rpc)"
cast block-number

默认情况下,CDK 处于test模式配置,这意味着地址为 的管理员账户中有一些预先存入的价值

cast balance --ether 0xE34aaF64b29273B7D567FCFc40544c014EEe9970

测试交易

private_key="0x12d7de8621a77640c9241b2595ba78ce443d05e94090365ab3bb5e19df82c625"
cast send --legacy --private-key "$private_key" --value 0.01ether 0x0000000000000000000000000000000000000000
blockHash               0xec514afabfa829f1b4e9339fd72e31fb2a1888a18046fe21743fe38b55bd24c3
blockNumber             45
contractAddress         
cumulativeGasUsed       21000
effectiveGasPrice       1000000000
from                    0xE34aaF64b29273B7D567FCFc40544c014EEe9970
gasUsed                 21000
logs                    []
logsBloom               0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
root                    
status                  1 (success)
transactionHash         0xa58b3383c1b1f53369723fdc537c88daa03585cb6a89aa49ebd493953d519fdf
transactionIndex        0
type                    0
blobGasPrice            
blobGasUsed             
authorizationList       
to                      0x0000000000000000000000000000000000000000

批量交易,需要安装polygon-cli

polycli loadtest --rpc-url "$ETH_RPC_URL" --legacy --private-key "$private_key" --verbosity 700 --requests 50000 --rate-limit 50 --concurrency 5 --mode t
polycli loadtest --rpc-url "$ETH_RPC_URL" --legacy --private-key "$private_key" --verbosity 700 --requests 500 --rate-limit 10 --mode 2
polycli loadtest --rpc-url "$ETH_RPC_URL" --legacy --private-key "$private_key" --verbosity 700 --requests 500 --rate-limit 3  --mode uniswapv3

获取输出日志

kurtosis service logs cdk agglayer --follow

排查错误

kurtosis service shell cdk contracts-001
jq . /opt/zkevm/combined.json

检查系统状态

cast rpc zkevm_batchNumber
cast rpc zkevm_virtualBatchNumber
cast rpc zkevm_verifiedBatchNumber

如果验证批次的数量不断增加,则表明系统运行正常

访问zkevm-bridge用户界面

open "$(kurtosis port print cdk zkevm-bridge-proxy-001 web-ui)"

查看cdk-erigon-rpc-001日志

kurtosis service logs cdk cdk-erigon-rpc-001 --follow

停止本地开发网络并将其删除

kurtosis clean --all

Babylon BTC 质押整合规范

Babylon 的比特币质押协议为比特币持有者提供了一种实用的解决方案,使他们可以直接在其他系统上质押他们的 BTC,而无需第三方托管、桥接或包装。该协议为消费者系统提供由 BTC 支持的经济安全保障。它被设计为通用和模块化插件,使其与各种消费者系统兼容。Babylon 的 BTC 质押协议也是一个支持进一步重新质押协议开发的原语,提供了一种直接且安全的方式来增强比特币在区块链生态系统中的功能。

此页面提供了 BTC 质押集成的完整规范,以指导消费者系统的实施工作。

系统概述

与 Babylon BTC 质押协议集成的消费者将具有以下架构。

在此架构中:

  • Babylon 链与比特币集成,用于 BTC 质押和 BTC 时间戳协议。 义务警员在 Babylon 和比特币之间传递信息,以保持同步。
  • BTC 质押者将其 BTC 委托给 Babylon 链的最终提供者和消费者。
  • 最终提供者参与其相应系统的最终投票轮次。
  • Babylon 链和消费者链通过中继程序交换有关 BTC 质押的信息。 如果消费者是支持 IBC 协议的 Cosmos SDK 链,则中继器可以是标准 IBC 中继器,如果消费者不支持 IBC,则中继器可以是专用中继器。
  • 如果消费者选择不信任 Babylon 链,BTC 质押监视器可以监视 Babylon 链中发生的安全/活跃性问题并向消费者发出警报。

本规范的组织

Babylon 团队开发并维护上述架构中的蓝色部分。

Babylon 和比特币

要将消费者与 BTC 质押协议集成,消费者需要开发以下软件(架构中的灰色部分),在以下每个文档中指定:

消费者系统中的模块

Finality Provider

BTC 质押Relayer

BTC 质押监控器 (WIP)

Babylon 团队将为 CosmWasm 智能合约中的消费者系统模块提供参考实现,以及相应的最终性提供程序。如果带宽允许,Babylon 团队将开发 BTC 质押中继器和 BTC 质押监控器。

术语

在本规范中,

原文:https://emphasized-acoustic-f68.notion.site/Specification-of-BTC-staking-integration-7534996979cc4117bfd0ba093e889308

Babylon OP-stack 链的 BTC 质押集成

上下文

Babylon 提供 比特币质押协议,允许比特币持有者在比特币链上质押 BTC,以保护任何 PoS 链。质押是无需信任的,因为 BTC 位于原生比特币网络上的自托管保险库中,而无需在其他地方进行桥接。

OP 堆栈链可以与 Babylon BTC 质押协议集成,以获得比特币安全性。这带来了以下好处。

  • 更好的经济安全性: 有原生 BTC 质押来保护汇总并提高其经济安全性。这对于采用较少的新 OP 堆栈链来说更为重要。此外,质押的 BTC 实现了 可削减安全性,这是一种强大的安全属性,即使 L2 序列器中的多数派持有相同的质押,L2 序列器的质押也会被追究责任,BTC 质押也是可削减的。
  • 快速终结:改进的经济安全性将使 OP 堆栈链受益,实现快速终结。如果用户愿意信任由 BTC 质押支持的投票,那么用户可以确认交易并做出决策,而无需等待乐观汇总中漫长的挑战期。
  • L2 交易的重组弹性:一旦交易被大多数 BTC 支持的终结性提供者签名的 L2 区块中包含,序列器就不能在 L1 上的同一高度发布不同的 L2 区块。

比特币质押的无分叉汇总 博客文章提供了更多详细信息。

系统架构

下图描述了系统架构。“→”箭头表示数据流;例如,X→Y 表示“Y 从 X 查询数据,数据从 X 流向 Y”。

系统组件

设计涉及以下主要组件:

  • 最终性小工具合约:CosmWasm 智能合约,用于维护从 OP-stack 最终性提供商提交的所有最终性签名。
  • 它将部署在 Babylon 链上。
  • 它将查询 Babylon 以确定最终性提供商的状态和投票权。
  • OP-stack 最终性提供商:守护程序,接收 BTC 质押并将最终性签名提交给 Babylon 上的最终性小工具合约。
  • 它连接到 Babylon 节点以查询自身的投票权。
  • 它连接到 Babylon 节点中的最终性小工具合约以提交最终性签名。
  • 它连接到 OP 节点以获取 L2 区块元数据。
  • 带有最终性小工具的 OP 节点:OP 节点将进一步配备一个最终性小工具,用于统计所有最终性签名、确定 L2 区块的最终状态,并仅将最终确定的 L2 区块通知给 OP-geth。
  • 它连接到 Babylon 节点,用于查询最终性提供者的投票权。
  • 它连接到 Babylon 节点中的最终性小工具合约,用于查询最终性签名。
  • 它连接到以太坊 L1 节点,接收批量数据以派生 L2 区块。

关键工作流程

  • 最终性提供者:不断向最终性小工具合约提交 L2 区块的最终性签名。

在 OP 堆栈链中出现新的 L2 区块时,

  • 获取 L2 区块元数据。
  • 查询 Babylon 链以确定其自身是否在此高度具有投票权。
  • 如果是,则签署最终性签名并将其提交给最终性小工具合约。
  • 最终性小工具合约:验证传入的最终性签名并识别模棱两可之处。

在最终性签名后,最终性小工具合约对其进行验证并检查其是否冲突。

  • 如果有效且与任何现有签名不冲突,则接受。
  • 如果无效,则拒绝。
  • 如果有效但与现有的最终性签名相冲突,则发出事件,以便任何人都可以削减最终性提供者及其下的 BTC 质押。
  • 具有最终性小工具的 OP 节点:持续统计从 L1 派生的 L2 区块,以了解最终性签名和最终性提供者的投票权分布,并确定 L2 区块的 BTC 质押最终状态。派生管道经过修改,因此它仅输出 BTC 质押最终化的 L2 区块。

在从 L1 派生出新的 L2 区块时,OP 节点执行以下操作

  • 查询最终性小工具合约以获取此 L2 区块的所有最终性签名。
  • 查询 Babylon 以获取此消费者的所有最终性提供者/BTC 委托,并使用 L2 区块的时间戳来确定此区块时的投票权表。
  • 统计最终性签名并确定 L2 区块是否获得法定人数。
  • 如果此 L2 区块获得法定人数,且其前缀为 BTC 质押完成,则将此 L2 区块标记为 BTC 质押完成,并将其输出到派生管道中。

实施

我们已经完成了 MVP 的实施。代码库包括

展望未来,我们将实现以下功能:

  • [ ] 削减模棱两可的最终性提供者
  • [ ] BTC 质押者和最终性提供者的奖励机制

原文:https://www.notion.so/BTC-staking-integration-for-OP-stack-chains-1-pager-f0574cd4e624475eb00d64912698a38c#cb340004c6cf48e2b9c9656bc5e59d8b

一文了解 TON 的技术特点与智能合约开发范式

简而言之,TON 的核心设计理念是以一种“自下而上”的方式重构传统的区块链协议,并以舍弃互操作性为代价,实现对高并发和高可扩展性的极致追求。

TON 的核心设计思想——高并发与高可扩展性

可以这么说,TON 中所有复杂的技术选型的目的都来自于对高并发与高可扩展性的追求,当然从其诞生的背景我们也不难理解这一点。TON,即 The Open Network,是一个去中心化的计算网络,包含一个 L1 区块链和多个组件。TON 最初由 Telegram 的创始人 Nikolai Durov 及其团队共同开发,而发展到现在则由全球独立贡献者的社区支持并维护。其诞生要追溯到 2017 年,Telegram 团队开始为自己探索区块链解决方案。由于当时没有现有的 L1 区块链能够支持 Telegram 的九位数用户基础,他们决定设计自己的区块链,当时称为 Telegram Open Network。时间来到了 2018 年,为了获得实现 TON 所需的资源,Telegram 在 2018 年第一季度发起了 Gram 代币(后来改名为 Toncoin)的销售。2020 年由于监管问题,Telegram 团队退出了 TON 项目。随后,一小部分开源开发者和 Telegram 比赛获胜者接手了 TON 的代码库,将项目名称更名为 The Open Network,并继续积极地开发区块链至今,且遵循原始 TON 白皮书中概述的原则。

那么既然是以作为 Telegram 的去中心化执行环境作为设计目标,自然要面对两个问题,高并发请求与海量数据,我们知道随着技术发展到现在,号称 TPS 最高的 Solana 实测最高 TPS 也只有 65000 ,这显然不足以支撑百万级 TPS 要求的 Telegram 生态。与此同时随着 Telegram 的大规模应用,其产生的数据量早已突破天际,而区块链作为一个极度冗余的分布式系统,若要求网络中每个节点都保存一份完整的数据,这也是不现实的。

因此为了解决上述两个问题,TON 对主流的区块链协议做出了两个方面的优化:

  • 通过采用“无限分片范式”(Infinite Sharding Paradigm)设计系统,解决数据冗余问题,使其可以承载大数据,同时缓解性能瓶颈问题;
  • 通过引入基于 Actor 模型的完全并行执行环境,极大的提升网络 TPS;

做区块链的链——通过无限分片能力让每个账户都有一条专属的账户链

当下我们知道,分片(sharding)已经成为了大部分区块链协议提升性能降低成本的主流方案,而 TON 则将这点做到了极致,并提出了无限分片范式,所谓无限分片范式,指的是允许区块链根据网络负载动态地增加或减少分片数量。这种范式使得 TON 能够在保持高性能的同时,处理大规模的交易和智能合约操作,理论上 TON 可以为每个账户都建立一条专属的账户链,并通过一定的规则保证这些链之间的一致性,

抽象的来理解,在 TON 中一共存在四层链结构:

  • 账户链(AccountChain):该层链表示与某个账户相关的一系列交易所组成的链,之所以交易可以组成链式结构,是因为对于一个状态机来说,只要执行规则一致,状态机在接收到相同顺序的指令后得到的结果是一致的,因此所有区块链分布式系统中都需要对交易进行链式排序,TON 也不例外。账户链是 TON 网络中最基本的组成单元,通常情况下账户链是一个虚拟的概念,不太可能真正存在一个独立的账户链。

  • 分片链(ShardChain):在大部分的语境下,分片链才是 TON 中实际的组成单元,所谓分片链,即为一组账户链的集合。

  • 工作链(WorkChain):也可以叫做一组有自定义规则的分片链,例如创建一个基于 EVM 的工作链,在其上运行 Solidity 智能合约。理论上,社区中的每个人都可以创建自己的工作链。事实上,构建它是一个相当复杂的任务,在此之前还要支付创建它的(昂贵)费用,并获得验证者的 2/3 的票数来批准创建你的工作链。

  • 主链(MasterChain):最后在 TON 中有一条特殊的链被称为主链,该链负责为所有分片链带来最终性。一旦分片链的区块的哈希值被合并到主链的区块中,该分片链区块及其所有父区块被认为具有最终性,这意味着它们可以被认为是固定且不可变的内容,而被所有分片链的后续区块引用。

通过采用这样的范式,使 TON 网络具备以下三个特点:

  • 动态分片: TON 可以自动拆分和合并分片链以适应负载的变化。这意味着新块总是快速生成,而交易不会产生很长的等待时间。

  • 高度可扩展: 通过无限分片范式,TON 能够支持几乎无限数量的分片,理论上可以达到 2 的 60 次方个工作链。

  • 自适应性: 当网络中的某个部分负载增加时,该部分可以被细分成更多的分片来处理增加的交易量。相反,当负载减少时,分片可以合并以提高效率。

那么这样一个多链系统,首先需要面临的就是跨链通信问题,尤其是由于具有无限分片的能力,当网络中的分片数量达到一定量级后,链与链之间的信息路由将成为一件困难的事情。试想一下网络中共有 4 个节点,每个节点负责维护 1 条独立的工作链,其中链接关系表示该节点除了负责自身的工作链中交易排序工作之外,还需要监听并处理目标链中状态变化,在 TON 中具体通过监听输出队列的消息实现,

假设工作链 1 中的账户 A 希望向工作链 3 中的账户 C 发送一个消息。则需要设计到消息路由问题,在这个例子中有两条路由路径,工作链 1 -> 工作链 2-> 工作链 3 ,工作链 1 -> 工作链 4 -> 工作链 3 。

当面临更复杂的情况时,就需要一个高效且低成本的路由算法快速完成消息通信,TON 选择了所谓“超立方体路由算法”来实现跨链消息通信路由发现。所谓超立方体结构指的是一种特殊的网络拓扑结构,一个 n 维超立方体是由 2 ^n 个顶点组成的,每个顶点都可以通过一个 n 位的二进制数来唯一标识。在这个结构中,任意两个顶点如果在二进制表示中只有一位不同,那么它们就是相邻的。例如,在一个 3 维超立方体中,顶点 000 和顶点 001 是相邻的,因为它们只在最后一位上不同。而上述例子即是一个 2 维超立方体。

在超立方体路由协议中,消息将从源工作链到目标工作链的路由过程是通过比较源工作链和目标工作链地址的二进制表示来进行的。路由算法会找到这两个地址之间的最小距离(即二进制表示中不同位的数量),并通过相邻工作链逐步转发信息,直到达到目标工作链。这种方法能够确保数据包沿着最短路径传输,从而提高了网络的通信效率。

当然为了简化这个过程,TON 也提出了一个乐观技术方案,当用户可以提供对某个路由路径的有效证明,这通常是某个 merkle trie root,节点即可直接承认该用户提交的消息的可信性,这也被称为即时超立方体路由。

因此我们可以看到 TON 中的地址和其他区块链协议有着明显的区别,其他主流区块链协议大都采用椭圆加密算法生成的公私钥中公钥对应的哈希作为地址,因为地址只是做唯一性区分,而不需要承载路由寻址的功能,而 TON 中的地址有两部分组成,(workchain_id, account_id),其中 workchain_id 即按照超立方体路由算法地址进行编码,在这里就不详细展开了。

还有一个容易产生疑问的点,你可能已经发觉到主链和每个工作链均有链接关系,那么所有跨链信息均通过主链做中继不就可以了么,就像是 cosmos 那样。在 TON 的设计理念中,主链仅用于处理最关键的任务,即维护众多工作链的最终性,将消息通过主链做路由也不是不行,只是由此产生的手续费用将十分昂贵。

最后简单提一下其共识算法,TON 采用了 BFT+PoS 的方式,即任意 staker 均有机会参与区块打包,TON 的选举治理合约会每隔一段时间,从所有 Stakers 中随机选择一个打包的验证者集群,被选中称为验证者的节点将通过 BFT 算法打包出块,若打包错误信息或作恶,其 stake 的 token 将会被罚没,反之将得到出块奖励。这基本上已经是一个比较常见的选择了,因此不在这里展开介绍。

基于 Actor 模型的智能合约和完全并行执行环境

TON 中另一个与主流区块链协议不同的点是其智能合约执行环境。为了突破主流区块链协议 TPS 的限制,TON 采用了自下而上的设计思路,采用 Actor 模型重构了智能合约及其执行方式,使其具备了完全并行执行的能力。

我们知道主流的区块链协议大都采用的是单线程串行的执行环境,以 Ethereum 为例,其执行环境 EVM 是一个以交易作为输入的状态机,当出块节点通过打包区块完成对交易的排序后,将以该顺序通过 EVM 执行交易,整个过程是完全串行并单线程的,即某个时刻只能有一笔被执行,这样做的好处是只要确认了交易顺序,执行的结果在广泛的分布式集群中就具有一致性,与此同时由于同时只有一笔交易被串行执行,这就意味着在执行过程中,不可能存在其他交易对某待访问状态数据进行修改,这样就实现了智能合约之间的互操作性。例如我们通过 Uniswap 使用 USDT 购买 ETH,当该交易被执行时,该交易对中 LP 的分布情况即为一个确定值,这样就可以通过某些数学模型得出对应的结果,但假设情况不是这样的,在执行某 bonding curve 的计算时,有其他 LP 添加了新的流动性,那么计算结果将会是一个过时的结果,这显然是不可接受的。

但是这种架构也有明显的局限性,那就是 TPS 的瓶颈,而这个瓶颈在当前多核处理器下显得很老旧,就像你用一个最新的 PC 去玩一些老的电脑游戏,比如红警,当作战单位多到一定数量后,依然会发现卡的不行,这就是软件架构的问题。

你可能会听到一些协议已经在关注这个问题,并提出了自己的并行方案,以当前号称 TPS 最高的 Solana 为例,也具备并行执行的能力。只不过其设计思路与 TON 不同,在 Solana 中,其核心思想是将所有交易按照执行依赖关系分为几组,不同组之间不共享任何状态数据。即不存在相同的依赖,这样不同组内的交易就可以并行执行而不用担心出现冲突的情况,而对于同组内的交易,则还是沿用传统的串行方式执行。

而在 TON 中,其完全舍弃了串行执行的架构,转而采用了一个专为并行而生的开发范式,Actor 模型来重构执行环境。所谓 Actor 模型是由 Carl Hewitt 在 1973 年首次提出,目的是通过消息传递来解决传统并发程序中共享状态的复杂性问题。每个 Actor 都有自己的私有状态和行为,且与其他 Actor 之间不共享任何状态信息。Actor 模型是一种并发计算的计算模型,它通过消息传递来实现并行计算。在这个模型中,"Actor"是基本的工作单元,它能够处理接收的消息、创建新的 Actor、发送更多消息、决定如何响应接下来的消息。Actor 模型需要具备以下几个特性:

  • 封装和独立性:每个 Actor 在处理消息时都是完全独立的,可以并行处理消息而不会互相干扰。

  • 消息传递:Actor 之间仅通过发送和接收消息进行交互,消息传递是异步的。

  • 动态结构:Actor 可以在运行时创建更多的 Actor,这种动态性使得 Actor 模型能够根据需要扩展系统。

TON 采用了这个架构,来设计智能合约模型,这就意味着在 TON 中,每个智能合约都是一个 Actor 模型,其具备完全独立的存储空间。因为不依赖任何外部数据。除此之外,对同一个智能合约的调用还是按照接收队列中消息的排序进行执行,因此 TON 中的交易将可以被高效的并行执行,而不需要担心冲突问题。

然而这样的设计方案也带来了一些全新的影响,对于 DApp 开发者来说,其习惯的开发范式将被打破,具体如下:

  1. 智能合约之间的异步调用
    在 TON 的智能合约内部是无法原子性的调用外部合约或访问外部合约数据的,我们知道在 Solidity 中,合约 A 的 function 1 中调用合约 B 的 function 2 ,或者通过合约 C 的只读 functio n3 访问某状态数据,整个过程是原子性的,在一笔交易中被执行,这是一件非常容易的事情,然而在 TON 中,这将不可能实现,任何与外部智能合约的交互都将通过打包新的交易异步执行,这种由智能合约发起的交易也被称为内部消息。且执行过程中无法阻塞以获得执行结果。

例如我们开发一个 DEX,如果采用 EVM 中常见的范式,通常会有一个统一的 router 合约用于管理交易路由,而每个 Pool 都单独管理某个交易对相关的 LP 数据,那么假设当前有两个池子 USDT-DAI 和 DAI-ETH。当用户希望通过 USDT 直接购买 ETH,就可以通过 router 合约在一笔交易中顺序请求这两个池子,完成原子性交易。然而在 TON 中就没有这么容易实现了,需要思考新的开发范式,若仍然复用该该范式的话,那信息流可能是这样的,这个请求将伴随一个由用户发起的 external message 和三个 internal messages 完成(注意这是用于说明差异性的,真实的开发中甚至连 ERC 20 的范式也要重新设计)。

  1. 需要仔细考虑跨合约调用时出现执行错误情况的处理流程,为每个合约间调用设计相应的弹回(bounce)函数。
    我们知道在主流的 EVM 中,当交易执行时遇到问题时,整个交易将会被回滚,即被重置到执行最初时的状态。这在串行单线程模型中是容易理解的。然而在 TON 中,由于合约间调用采用了异步的方式执行,即使后续某环节出错,由于前面已经被成功执行的交易已经被执行并确认,这就有可能造成问题。因此 TON 中设置了一种特殊的消息类型,叫做弹回消息,即当某内部消息触发的后续执行过程出现错误时,被触发合约可以通过触发合约预留的弹回函数将触发合约中的某些状态重置。

  2. 在某些复杂情况下,先被接收的交易不一定先被执行完毕,因此不可以预设这种时序关系。
    在这样一个异步和并行智能合约调用的系统中,定义处理操作顺序可能很难。这就是为什么 TON 中的每个消息都有它的逻辑时间 Lamport time(后面简称 lt)。它用于理解哪个事件引发了另一个以及验证者首先需要处理什么。对于一个简单的模型,先被接收的交易一定先被执行完成。


在这个模型中,A 和 B 分别表示两个智能合约,则有如果 msg 1 _lt < msg 2 _lt,则 tx 1 _lt < tx 2 _lt 的时序关系。

然而在较为复杂的情况下,这个规则就会被打破。在官方文档中有这样的例子,假设我们有三个合约 A、B 和 C。在一笔交易中,A 发送两个内部消息 msg 1 和 msg 2 :一个给 B,另一个给 C。尽管它们是按确切顺序创建的(先 msg 1 ,然后是 msg 2),但我们无法确定 msg 1 将在 msg 2 之前被处理。这是因为从 A 到 B 和从 A 到 C 的路由可能在长度和验证者集中有所不同。如果这些合约位于不同的分片链中,其中一条消息可能需要几个区块才能到达目标合约。即我们有两种可能的交易路径,如图所示。

  1. 在 TON 中,其智能合约的持久化存储采用了一个以 Cell 为单元的有向无环图作为数据结构,
    数据将按照编码规则紧凑的压缩为一个 Cell,同时按照有向无环图的方式向下延伸,这与 EVM 中状态数据基于 hashmap 的结构组织不同,由于数据请求算法的不同,TON 中为不同深度的数据处理设置了不同的 Gas 价格,越深的 Cell 数据处理所需要的 Gas 越高,因此在 TON 中存在一种 DOS 攻击的范式,即某些恶意用户通过发送大量垃圾消息占用某个智能合约中所有的浅层 Cell,这就意味着诚实用户的存储成本将越来越高。而在 EVM 中,由于 hashmap 的查询复杂度为 o( 1),因此有着相同的 Gas,不会有类似问题。所以 TON Dapp 开发者应该尽量避免智能合约中出现无界数据类型。当出现无界数据类型时,应通过分片的方式将其打散。

  2. 还有一些特征则不那么特殊了,例如智能合约需要为存储支付租金,在 TON 中智能合约天然是可升级的,以及原生的抽象账户功能,即在 TON 中所有钱包地址均为智能合约,只是未被初始化等,这些需要开发者小心留意。

转载:https://www.chaincatcher.com/article/2128150

其它:https://github.com/UnsignedInt8/TON/tree/master/TON