区块链芝士丨在以太坊上开发dApp的瓶颈和门槛有哪些?(2)
主要的局限性包括:
1、观测到的 state 信息不一致
为了扩展到单个节点的容量之上同时提供更高的可靠性,作为服务平台的节点是通过负载平衡器提供对节点池的访问的。
由于这些节点中是都作为以太坊网络中的对等节点自主运行的,因此当信息在通过网络传播的某一个时刻,不同的节点可能处于不同的区块高度上,甚至处于不同的分叉上。这意味着 Dapp 可能收到区块链状态的信息是不一致的,因为它的请求获得的结果是由负载均衡器背后的不同节点提供的。
节点服务平台通常试图通过负载平衡器上的会话粘性来解决此问题,总是会去尝试将指定前端的查询发送到同一个后端节点,但是这种方法在多种情况下会失败:
- 当前端产生的请求多于单个后端节点能负担的处理量时;
- 当网络问题导致前端与后端断开连接时,而且必须重新连接;
- 多个节点服务平台会将不同类型的前端请求(例如,发送交易或搜索链历史记录)路由到针对该查询类型优化的不同后端节点组。
那么由于前端经常访问多个后端节点,而这些后端节点获取的区块链状态与彼此不一致,因此 Dapp 很难处理链重组。向后追溯链历史的时候,Dapp 可能突然发现它想找的父区块不存在了(原因是它现在正在与在不同分叉上的另一个节点交互)。那么 Dapp 开发者就不得不去专门写代码来解决这个问题(方法通常是通过反复地重连,直到它找到一个节点)。这样给 Dapp 增加了不必要的复杂性,并且可能导致呈现给用户的信息有出入。
2、在区块链上搜索信息很慢、有局限性
Dapp 搜索交易或链上历史的能力受限,因为标准以太坊节点不适合支持精确搜索或执行实时数据的筛选式监听。想要以高性能的方式进行操作,我们需要对数百万个区块和交易做大量的索引,但是:
- 以太坊节点仅索引交易执行发出的日志中的某些字段(要索引的字段必须在部署合约时由开发者标记出来)
- 以太坊节点不索引内部交易(当智能合约调用另一合约的方法时发生)的数据
- 开发者不愿意添加额外的索引字段,因为每多一个索引字段每个交易的成本都会相对增加,会给合约的用户带来额外的费用
- 以太坊节点使用 Bloom 过滤器执行搜索,因此它始终是模糊搜索,并且会产生伪阳性的匹配。精确匹配需要前端进行额外的处理,前端必须获取模糊匹配的整个区块或交易,对其再次检索而找到精确匹配的结果。这不仅需要开发者的精力,而且浪费了前端和节点之间的带宽
- 可用的搜索语法非常有限——仅支持基本的选择以及简单的替换
- 获取搜索结果的速度很慢——在大范围的区块中执行搜索可能需要几个小时
- JSON-RPC 非常浪费带宽——返回的数据远远超出你所真正所需。GraphQL 接口使用的带宽较少,但不提供串流传输功能(前端必须进行轮询更新)
3、缺乏原子性
在大多数现代环境中,例如关系数据库,交易一般是原子操作,但在以太坊(或其他区块链)上不是。每个交易都会经过一系列状态的转换,在这个过程中可能遇到多种问题或失败。Dapp 必须调用多个 API,查询许多不同的数据源(区块、mempool、网络状态)以便跟踪交易的生命周期,直至其完成。
同样,这个负担就落在了前端代码上,通过重复轮询来弄清楚具体发生了什么,而 Dapp 的用户会因为 Dapp 执行所有这些额外的工作而经历延迟和需要刷新。
4、节点是被动的
以太坊节点是被动的,这意味着它们无法生成事件或回调和调用 Webhooks。所有操作必须由前端来启动,而前端还必须轮询节点以获得更新的信息。以太坊节点的事件串流读取功能太有限,无法满足大多数 Dapp 的需求,并且仅在 JSON-RPC 接口中可用,在 GraphQL 接口上不可用。