如果你想让 Web3.py 来定制一些基础功能之外的工作,最少有这几个选择:中间件、自定义方法、外部模块和自定义provider。这篇文章将逐个介绍这些分别是什么,什么时候会涉及到,以及如何开始。
如果你想让 Web3.py 来定制一些基础功能之外的工作,最少有这几个选择:中间件、自定义方法、外部模块和自定义provider。这篇文章将逐个介绍这些分别是什么,什么时候会涉及到,以及如何开始。
中间件允许你在发出请求之前或收到结果之后向现有方法添加一些行为。
如果你希望每次执行某个 RPC 调用或一组调用时都发生某些事情,如记录日志、数据可视化、数据转换等,请使用中间件。
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
整个中间件堆栈。
可以将任意 RPC 方法添加到现有模块中。
如果你正在使用具有非标准 RPC 命令的客户端或在分叉客户端中测试某些自定义功能,那么注册自定义方法会很方便。
如果你想应用自己的请求或结果格式化程序,自定义方法也可用于覆盖现有方法。
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
来添加属性。
外部模块允许在一个主题下导入一组 API ,从而提供更大的灵活性。回想一下:插件。
在引入一整个L2 API 或者一个客户端支持的多个非标准 RPC 方法时,外部模块可能会很有用。如Erigon的特定方法像erigon_getHeaderByHash
, erigon_getHeaderByNumber
等。
模块只需要是类并且可以引用父 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()
更多上下文,包括嵌套模块示例,可在这里获得。
provider 的核心是定义如何执行请求。
构建自定义provider 仅适用于插入自定义测试框架或类似的极少数情况。如果你只是想连接到另一个 EVM 区块链、侧链或rollup,通常只需配置一个现有选项: HTTPProvider, IPCProvider, 或 WebsocketProvider.
Provider 只需要两个方法,make_request
和isConnected
,以及一个自定义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/
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!