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

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

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

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

1. 中间件

What

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

When

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

How

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

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

<center>- 使用函数语法的中间件模板 -</center>

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

2. 自定义方法

What

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

When

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

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

How

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

from web3.method import Method

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

w3.eth.create_access_list(...)

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

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

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

When

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

How

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

# 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()

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

4. 自定义Provider

What

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

When

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

How

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

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 补丁没有包括在这篇文章中。如果你走上了那条路……一切都好吗?说真的,如果你的定制需要用到 monkey 补丁的另一个向量,请在这里创建Issue。

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

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
一个程序猿
一个程序猿
江湖只有他的大名,没有他的介绍。