Web3.py第4版的第一个测试版于2017年11月中旬发布,此后又发布了5个版本,目前已经稳定发布到4.6。主要版本变化意味着一些向后兼容的更改,以及这些更改启用的一些全新功能。感兴趣的话请继续阅读本概述。
如何安装
等不及要玩了吗?现在用pip安装。Pip默认不会安装测试版,因此请使用--pre标志立即获取v4:
pip install --pre web3
Python3.5以上
其中一个更重要的变化是现在需要Python 3.5。你的项目仍然停留在py2上吗?立即升级代码。它比你想象的要快2to3。Python 3提供了许多有用的功能和库,并且它消除了bytes
和str
的歧义,这为升级铺平了道路。
更直观的参数和返回类型
全局特征
如果浏览在v3中返回十六进制字符串的函数,你会发现它们中的大多数在v4中返回类似bytes
的对象。下面示例中的HexBytes
类是内置字bytes
型的子类,因此可以在bytes
所在的任何位置使用。
>>> from web3.auto import w3
>>> block_hash = w3.eth.getBlock(4359745).hash
HexBytes('0x03087766bf68e78671d1ea436ae087da74a12761dac020011a9eddc4900bf13b')
# get the first byte:
>>> block_hash[0]
3
# show how many bytes are in the hash
>>> len(block_hash)
32
# hex-encode the hash
>>> w3.toHex(block_hash)
'0x03087766bf68e78671d1ea436ae087da74a12761dac020011a9eddc4900bf13b'
# cast back to the basic `bytes` type
>>> bytes(block_hash)
b"\x03\x08wf\xbfh\xe7\x86q\xd1\xeaCj\xe0\x87\xdat\xa1'a\xda\xc0 \x01\x1a\x9e\xdd\xc4\x90\x0b\xf1;"
合约参数
如果合约返回ABI bytes
类型,那么将获得python bytes值。如果它返回ABI 字符串
类型,那么你将得到一个python str。同样,合约函数的参数也会匹配对应。
如果提供的参数类型与相应的ABI类型不完全匹配,则将尝试转换它。 例如:
- 发送到ABI字符串类型的字节值将是UTF-8解码的
- 发送到ABI字节类型的str值将被转换为十六进制
合约函数
合同函数的v3 API有点违反直觉,在指定函数之前指定如何处理函数,例如:contract.call().balanceOf(...)
。我们使用类似web3.js的格式转换这些格式:v1:contract.functions.balanceOf(...).call()
。
使用私钥签署消息和交易
现在可以在没有任何客户端连接的情况下对消息和原始交易进行签名以及验证它们。
以下是签署一个信息的的示例:
>>> from web3 import Account, Web3
>>> msg = "I♥SF"
>>> key = b"\xb2..."
>>> Account.sign(message_text=msg, private_key=key)
{'message': b'I\xe2\x99\xa5SF',
'messageHash': HexBytes('0x1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750'),
...
'signature': HexBytes('0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb33e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce1c')}
还有很多其他私钥功能。有关更多信息,请参阅web3.eth.account文档。
准备签名的交易
在v3中,没有很好的方法来创建合约交易对象。这并不重要,因为除了广播这个交易之外别无他法,这已经很容易了。但是,在第4版中,我们可能希望在广播之前在本地签署该交易对象。所以添加了buildTransaction()
选项,如下所示:
>>> from web3.auto import w3
>>> token = w3.eth.contract(abi=...)
>>> transfer = token.functions.transfer("ethereumfoundation.eth", 1).buildTransaction()
>>> signed = w3.eth.account.signTransaction(transfer, key)
>>> w3.eth.sendRawTransaction(signed.rawTransaction)
更可预测的过滤器
在第3版中,过滤器从未按照人们想要的方式运行。标准JSON-RPC API仅支持轮询更新筛选器。因此,为了模拟回调机制,Web3.py必须以线程为主,并支持多种方法(如stdlib或gevent)。它很麻烦,容易出现故障。这些失败很难在运行时调试和捕获。
在v4中,Web3.py将用户的选择添加到监视线程,并在你的应用程序合适时调用get_new_entries()
。这允许你捕获可能引发的Exception
,并调试你的过滤器。新系统更可靠,更容易追踪正在发生的事情,但还有更多的改进空间。因此,请注意v4中的更多过滤更新以及v5中的更新。
无处不在以太坊名称服务
在可以输入地址的任何地方,v4都接受作为一个名称。然后Web3.py将为你查找该地址。有关以太坊名称服务的更多详细信息,请参阅此文章,了解ENS如何适合Web3.py。
例如,我们可以在ethereumfoundation.eth
获得地址的余额:
>>> from web3.auto import w3
>>> w3.eth.getBalance('ethereumfoundation.eth')
2963803006730275571720
自动初始化
猜测连接到普通客户端需要哪些参数并不难。然而,在第3版中,有必要指定使用哪个接口,例如:
from web3 import Web3, IPCProvider
w3 = Web3(IPCProvider())
也许你从之前的例子中注意到,在v4中,这可以通过单行实现:
from web3.auto import w3
此外,可以在没有任何接口的情况下初始化Web3,这具有相同的效果:
from web3 import Web3
w3 = Web3()
自动接口检测可以猜测生产网络的常见IPC和HTTP连接设置。它还会检查你是否设置了环境变量。
地址校验无处不在
EIP55定义了十六进制地址的校验和机制,它将一些十六进制字符转换为大写字母。Web3.py
选择支持该机制有一段时间,它现在是所有地址所必需的。全小写十六进制地址将被拒绝为无效(除了在校验和产生全小写十六进制地址的极少数情况下)。
此外,现在从所有方法返回校验地址。这样做的好处是地址相等性测试可以简单地使用addr1 == addr2
,因为只有一个EIP 55地址的有效表示。
gas价格估算
感谢https://ethgasstation.info/发布他们的算法。我们将其中的一个版本合并到Web3.py中的新gas价格估算的后端代码中。这样:
from web3 import Web3, middleware
from web3.gas_strategies.time_based import medium_gas_price_strategy
w3 = Web3()
w3.eth.setGasPriceStrategy(medium_gas_price_strategy)
w3.middleware_stack.add(middleware.time_based_cache_middleware)
w3.middleware_stack.add(middleware.latest_block_based_cache_middleware)
w3.middleware_stack.add(middleware.simple_cache_middleware)
w3.eth.generateGasPrice()
你肯定会想要那些新的缓存中间件,因为它会对你的节点进行大量调用。只有在自动获得更好的价格估算时才进行此设置,这至关重要,值得花点儿时间。第一次估计测试计算大约50秒。
要查看完整的更改列表,请访问v4发行说明。
当然,python用web3.py库开发以太坊来说非常的方便,有兴趣的用户可以关注我们的python以太坊教程,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
这里是原文