使用 Web3.py 模式进行定制化

2022-11-07 10:05:31 浏览数 (1)

本文作者:一个程序猿[1]

如果你想让 Web3.py 来定制一些基础功能之外的工作,最少有这几个选择:中间件、自定义方法、外部模块和自定义 provider。这篇文章将逐个介绍这些分别是什么,什么时候会涉及到,以及如何开始。

1. 中间件

What

中间件[2]允许你在发出请求之前或收到结果之后向现有方法添加一些行为。

When

如果你希望每次执行某个 RPC 调用或一组调用时都发生某些事情,如记录日志、数据可视化、数据转换等,请使用中间件。

How

Web3.py 有一组标配的默认中间件[3],还有很多可选中间件[4]。但是,如果你需要编写一些自定义中间件,有几个语法选择:使用函数或类[5]。对于一些简单的情况,使用函数语法是很典型的。

代码语言:javascript复制
def example_middleware(make_request, w3):
    # do one-time setup operations here

    def middleware(method, params):
        # 在这里做前置预处理

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

        # 在这里做后置处理

        # finally return the response
        return response
    return middleware

- 使用函数语法的中间件模板 -

中间件是按特定顺序层次执行的,API[6]允许将新的中间件添加(add)到列表的末尾,也可以插入(inject),替换( replace )或者 移除(remove )一层, 或者清除clear整个中间件堆栈。

2. 自定义方法

What

可以将任意 RPC 方法添加到现有模块中。

When

如果你正在使用具有非标准 RPC 命令的客户端或在分叉客户端中测试某些自定义功能,那么注册自定义方法会很方便。

如果你想应用自己的请求或结果格式化程序,自定义方法也可用于覆盖现有方法。

How

attach_methods函数在每个模块上都可用,并接受带有方法名称和对应Method的字典:

代码语言:javascript复制
from web3.method import Method

w3.eth.attach_methods({"create_access_list": Method("eth_createAccessList")})

w3.eth.create_access_list(...)

你可以选择性的包含自定义输入处理方法、请求和结果格式化程序

代码语言:javascript复制
from web3.method import Method

w3.eth.attach_methods({
 "example": Method(
  "eth_example",
  mungers=[...],
  request_formatters=[...],
  result_formatters=[...],
  is_property=False,
 ),
})

w3.eth.example()

- 向Eth模块添加自定义eth_example方法 -

如果你想使用属性而不用函数方法,可以将is_property设置为True来添加属性。

3. 外部模块

What

外部模块[7]允许在一个主题下导入一组 API ,从而提供更大的灵活性。回想一下:插件。

When

在引入一整个 L2 API 或者一个客户端支持的多个非标准 RPC 方法时,外部模块可能会很有用。如Erigon[8]的特定方法像erigon_getHeaderByHash, erigon_getHeaderByNumber等。

How

模块只需要是类并且可以引用父 Web3 实例。在Web3实例化时使用关键字external_modules参数或在任何时候通过attach_modules方法配置你的外部模块:

代码语言:javascript复制
# add modules at instantiation:
w3 = Web3(
   HTTPProvider(...),
   external_modules={"example": ExampleModule}
)

# add modules after instantiation:
w3.attach_modules({"example": ExampleModule})

# invoking external modules:
w3.example.example_method()

更多上下文,包括嵌套模块示例,可在这里[9]获得。

4. 自定义 Provider

What

provider[10] 的核心是定义如何执行请求。

When

构建自定义 provider[11] 仅适用于插入自定义测试框架或类似的极少数情况。如果你只是想连接到另一个 EVM 区块链、侧链或 rollup,通常只需配置一个现有选项:HTTPProvider[12], IPCProvider[13], 或 WebsocketProvider[14].

How

Provider 只需要两个方法,make_requestisConnected,以及一个自定义middlewares.

代码语言:javascript复制
from web3.providers.base import BaseProvider

class CustomProvider(BaseProvider):
    middlewares = ()

    def make_request(self, method, params):
        return {"result": {"welp": "lol"}}

    def isConnected(self):
        print(True)

w3 = Web3(CustomProvider())

w3.eth.get_block("latest")
# AttributeDict({"welp": "lol"})

总结

上面的选项粗略的按灵活性从小到大排序。在实践中,我认为中间件和外部模块能够发挥最大的作用,特别是当受信任的外部模块变成司空见惯的事。

还有一个monkey 补丁[15]没有包括在这篇文章中。如果你走上了那条路……一切都好吗?说真的,如果你的定制需要用到 monkey 补丁的另一个向量,请在这里[16]创建 Issue。

原文链接:https://snakecharmers.ethereum.org/web3-py-patterns-customizations/

参考资料

[1]

一个程序猿: https://learnblockchain.cn/people/9

[2]

中间件: https://web3py.readthedocs.io/en/stable/middleware.html

[3]

默认中间件: https://web3py.readthedocs.io/en/stable/middleware.html#default-middleware

[4]

可选中间件: https://web3py.readthedocs.io/en/stable/middleware.html#optional-middleware

[5]

函数或类: https://web3py.readthedocs.io/en/stable/internals.html#middlewares

[6]

API: https://web3py.readthedocs.io/en/stable/middleware.html#middleware-stack-api

[7]

外部模块: https://learnblockchain.cn/article/4053

[8]

Erigon: https://github.com/ledgerwatch/erigon

[9]

这里: https://snakecharmers.ethereum.org/web3-py-patterns-external-modules/

[10]

provider: https://web3py.readthedocs.io/en/latest/providers.html

[11]

自定义provider: https://web3py.readthedocs.io/en/latest/internals.html#providers

[12]

HTTPProvider: https://web3py.readthedocs.io/en/latest/providers.html#httpprovider

[13]

IPCProvider: https://web3py.readthedocs.io/en/latest/providers.html#ipcprovider

[14]

WebsocketProvider: https://web3py.readthedocs.io/en/latest/providers.html#websocketprovider

[15]

monkey 补丁: https://en.wikipedia.org/wiki/Monkey_patch

[16]

这里: https://github.com/ethereum/web3.py/issues

0 人点赞