Migrating your code from v3 to v4
Web3.py follows Semantic Versioning, which means that version 4 introduced backwards-incompatible changes. If your project depends on Web3.py v3, then you’ll probably need to make some changes.
Here are the most common required updates:
Python 2 to Python 3
Only Python 3 is supported in v4. If you are running in Python 2, it’s time to upgrade. We recommend using 2to3 which can make most of your code compatible with Python 3, automatically.
The most important update, relevant to Web3.py, is the new bytes
type. It is used regularly, throughout the library, whenever dealing with data
that is not guaranteed to be text.
Many different methods in Web3.py accept text or binary data, like contract methods,
transaction details, and cryptographic functions. The following example
uses sha3()
, but the same pattern applies elsewhere.
In v3 & Python 2, you might have calculated the hash of binary data this way:
>>> Web3.sha3('I\xe2\x99\xa5SF')
'0x50a826df121f4d076a3686d74558f40082a8e70b3469d8e9a16ceb2a79102e5e'
Or, you might have calculated the hash of text data this way:
>>> Web3.sha3(text=u'I♥SF')
'0x50a826df121f4d076a3686d74558f40082a8e70b3469d8e9a16ceb2a79102e5e'
After switching to Python 3, these would instead be executed as:
>>> Web3.sha3(b'I\xe2\x99\xa5SF')
HexBytes('0x50a826df121f4d076a3686d74558f40082a8e70b3469d8e9a16ceb2a79102e5e')
>>> Web3.sha3(text='I♥SF')
HexBytes('0x50a826df121f4d076a3686d74558f40082a8e70b3469d8e9a16ceb2a79102e5e')
Note that the return value is different too: you can treat hexbytes.main.HexBytes
like any other bytes value, but the representation on the console shows you the hex encoding of
those bytes, for easier visual comparison.
It takes a little getting used to, but the new py3 types are much better. We promise.
Filters
Filters usually don’t work quite the way that people want them to.
The first step toward fixing them was to simplify them by removing the polling logic. Now, you must request an update on your filters explicitly. That means that any exceptions during the request will bubble up into your code.
In v3, those exceptions (like “filter is not found”) were swallowed silently in the automated polling logic. Here was the invocation for printing out new block hashes as they appear:
>>> def new_block_callback(block_hash):
... print(f"New Block: {block_hash}")
...
>>> new_block_filter = web3.eth.filter('latest')
>>> new_block_filter.watch(new_block_callback)
In v4, that same logic:
>>> new_block_filter = web3.eth.filter('latest')
>>> for block_hash in new_block_filter.get_new_entries():
... print(f"New Block: {block_hash}")
The caller is responsible for polling the results from get_new_entries()
.
See Asynchronous Filter Polling for examples of filter-event handling with web3 v4.
TestRPCProvider and EthereumTesterProvider
These providers are fairly uncommon. If you don’t recognize the names, you can probably skip the section.
However, if you were using web3.py for testing contracts, you might have been using TestRPCProvider or EthereumTesterProvider.
In v4 there is a new EthereumTesterProvider
, and the old v3 implementation has been
removed. Web3.py v4 uses eth_tester.main.EthereumTester
under the hood, instead
of eth-testrpc. While eth-tester
is still in beta, many parts are
already in better shape than testrpc, so we decided to replace it in v4.
If you were using TestRPC, or were explicitly importing EthereumTesterProvider, like:
from web3.providers.tester import EthereumTesterProvider
, then you will need to update.
With v4 you should import with from web3 import EthereumTesterProvider
. As before, you’ll
need to install Web3.py with the tester
extra to get these features, like:
$ pip install web3[tester]
Changes to base API convenience methods
Web3.toDecimal()
In v4 Web3.toDecimal()
is renamed: toInt()
for improved clarity. It does not return a decimal.Decimal
, it returns an int
.
Removed Methods
Web3.toUtf8
was removed fortoText()
.Web3.fromUtf8
was removed fortoHex()
.Web3.toAscii
was removed fortoBytes()
.Web3.fromAscii
was removed fortoHex()
.Web3.fromDecimal
was removed fortoHex()
.
Provider Access
In v4, w3.currentProvider
was removed, in favor of w3.providers
.
Disambiguating String Inputs
There are a number of places where an arbitrary string input might be either
a byte-string that has been hex-encoded, or unicode characters in text.
These are named hexstr
and text
in Web3.py.
You specify which kind of str
you have by using the appropriate
keyword argument. See examples in Encoding and Decoding Helpers.
In v3, some methods accepted a str
as the first positional argument.
In v4, you must pass strings as one of hexstr
or text
keyword arguments.
Notable methods that no longer accept ambiguous strings:
sha3()
toBytes()
Contracts
Personal API
w3.personal.signAndSendTransaction
is no longer available. Use
w3.personal.sendTransaction()
instead.