跳转至

Web3 内部

原文:https://web3py.readthedocs.io/en/stable/internals.html

警告

文档的这一部分面向高级用户。如果你不知道你在做什么,你可能应该远离这些 API。

Web3 库在 web3 对象公开的公共 api 和 web3 连接的后端或节点之间有多层抽象。

  • 供应商负责与区块链的实际通信,比如通过 HTTP 或 IPC 套接字发送 JSON-RPC 请求。
  • 中间件提供钩子来监控和修改请求以及来自供应商的响应。这些可以是在所有提供商上运行的全球 T2,也可以是特定于一个提供商的。
  • 管理器提供线程安全和特权,允许异步使用 web3。

下面是您可能想对这些 API 做的一些常见事情。

  • 将某些 RPC 请求重定向到不同的供应商,例如将所有的操作发送到由 Infura 支持的供应商,将所有的操作发送到您控制的 go-ethereum 节点。
  • 透明地拦截通过eth_sendTransaction发送的交易,在本地签名,然后通过eth_sendRawTransaction发送。
  • 修改 RPC 请求的响应,使其以不同的格式返回,例如将所有整数值转换为十六进制表示。
  • 验证 RPC 请求的输入

请求生命周期

每个 web3 RPC 调用以下列方式通过这些层。

 ***********    ************
  | Request |    | Response |
  ***********    ************
      |                ^
      v                |
+-----------------------------+
|            Manager          |
+-----------------------------+
      |                ^
      v                |
+-----------------------------+
|     Global Middlewares      |
+-----------------------------+
      |                ^
      v                |
+-----------------------------+
|    Provider Middlewares     |
+-----------------------------+
      |                ^
      v                |
+-----------------------------+
|          Provider           |
+-----------------------------+ 

您可以将这种关系想象成一个洋葱,以供应商为中心。请求来自洋葱之外的管理者,通过洋葱的每一层向下传递,直到到达中心的供应商。然后,供应商处理请求,产生一个响应,该响应将从洋葱的中心通过每一层传递回来,直到最终被管理器返回。

在 web3 与多个提供商合作的情况下,同样的生命周期适用。管理器将遍历每个供应商,从第一个返回响应的供应商返回响应。

供应商

提供商负责所有直接的区块链交互。在大多数情况下,这意味着通过 HTTP 或 IPC 套接字与以太坊节点的 JSON-RPC 服务器进行交互。然而,没有什么要求供应商是基于 RPC 的,允许供应商为测试目的而设计,使用内存中的 EVM 来完成请求。

编写您自己的提供程序

编写自己的供应商需要实现两个必需的方法,并设置供应商应该使用的中间件。

BaseProvider.make_request(*method*, *params*)

每个供应商类必须实现这个方法。这个方法应该在成功的情况下返回一个带有'result'键的 JSON 对象,或者在失败的情况下返回一个'error'键。

  • method这将是一个表示被调用的 JSON-RPC 方法的字符串,比如'eth_sendTransaction'
  • 这将是被调用的 JSON-RPC 方法的参数列表或其他可迭代的参数。
BaseProvider.isConnected()

该函数应返回TrueFalse,这取决于供应商是否应被视为与连接。例如,如果套接字是打开的,基于 IPC 套接字的供应商应该返回True,如果套接字是关闭的,应该返回False

BaseProvider.middlewares

这应该是一个可迭代的中间件。

您可以通过分配给provider.middlewares来设置一个新的中间件列表,将第一个处理请求的中间件放在列表的开头。

## 中间件

注意

web3 中的中间件 API 大量借鉴了 1.10.0 版本中引入的 Django 中间件 API

中间件为实现 web3 请求的业务逻辑层提供了一个简单而强大的 api。编写中间件很简单。

def simple_middleware(make_request, w3):
    # do one-time setup operations here

    def middleware(method, params):
        # do pre-processing here

        # perform the RPC request, getting the response
        response = make_request(method, params)

        # do post-processing here

        # finally return the response
        return response
    return middleware 

也可以将中间件实现为一个类。

class SimpleMiddleware:
    def __init__(self, make_request, w3):
        self.w3 = w3
        self.make_request = make_request

    def __call__(self, method, params):
        # do pre-processing here

        # perform the RPC request, getting the response
        response = self.make_request(method, params)

        # do post-processing here

        # finally return the response
        return response 

make_request参数是一个可调用的参数,它接受两个位置参数,methodparams,它们对应于被调用的 RPC 方法。不要求调用make_request函数。例如,如果您正在编写一个缓存某些方法响应的中间件,您的中间件可能不会调用make_request方法,而是从某个本地缓存中获取响应。

默认情况下,Web3 将使用web3.middleware.pythonic_middleware。这个中间件为请求和响应执行以下翻译。

  • 数字请求参数将被转换为十六进制表示形式
  • 数字响应将从十六进制表示转换为整数表示。

RequestManager对象公开了middleware_onion对象来管理中间件。为了方便起见,它也暴露在Web3对象上。那个 API 在 配置中间件 中有详细介绍。

经理

管理器充当请求/响应生命周期的看门人。您不太可能需要更改管理器,因为大多数功能都可以在中间件层实现。



回到顶部