Ошибка Rinkeby с web3.py - не удалось отформатировать значение «0x ...» как поле «extraData»

Я пытаюсь подключиться к Ринкеби, используя web3.py. Но когда я вызываю метод, например w3.version.node, он выдает исключение, оканчивающееся на:

...
  File "/home/hacker/venv/lib/python3.5/site-packages/web3/utils/formatters.py", line 69, in apply_formatters_to_dict
    raise type(exc)("Could not format value %r as field %r" % (item, key)) from exc
ValueError: Could not format value '0x{LONG_HEX}' as field 'extraData'

(Где многоLONG_HEX шестнадцатеричных символов , например 194)

Как мне исправить мое соединение, чтобы получить данные блока?

Версии:

  • geth1.8.2
  • web3.pyv4.0.0-бета.13

Примечание. В дополнение к сети Rinkeby я получаю такое же исключение после подключения к узлу, начатому сgeth --dev

Ответы (2)

Решение

Вставьте специальное промежуточное ПО в web3.py v5+ для обработки подтверждения полномочий в стиле geth, например :

py> from web3 import Web3, IPCProvider

# connect to the default geth --dev IPC location
py> w3 = Web3(IPCProvider('/tmp/geth.ipc'))

py> from web3.middleware import geth_poa_middleware

# inject the poa compatibility middleware to the innermost layer
py> w3.middleware_onion.inject(geth_poa_middleware, layer=0)

# confirm that the connection succeeded
py> w3.version.node
'Geth/v1.8.2-stable-b8b9f7f4/linux-amd64/go1.9.4'

Почему geth_poa_middlewareнеобходимо?

Слегка измененная версия документации web3.py :

В сообществе пока нет четкого консенсуса по единому стандарту Proof-of-Authority (PoA). Однако на некоторых узлах проводятся успешные эксперименты. Одним из них является go-ethereum (geth), который использует прототип PoA для режима разработки и тестовую сеть Rinkeby.

К сожалению, прототип отличается от спецификации желтой бумаги, которая ограничивает extraDataполе в каждом блоке максимальным размером 32 байта. PoA Geth использует более 32 байтов, что приводит к сбою проверки в web3.py. Это промежуточное ПО изменяет данные блока, чтобы extraDataнемного сократить их перед возвратом.

Дополнение к предыдущему ответу: в web3py версии 5.xx вы должны изменить его следующим образом:

    # inject the poa compatibility middleware to the innermost layer
    w3.middleware_stack.inject(geth_poa_middleware, layer=0)

к этому:

    # inject the poa compatibility middleware to the innermost layer
    w3.middleware_onion.inject(geth_poa_middleware, layer=0)

Я имею в виду, middleware_stackбыл переименован в: middleware_onion.

Спасибо за предложение улучшения! При улучшении существующего ответа его лучше структурировать как комментарий к этому ответу.
Верно, но для этого нужно иметь 50 очков репутации, чего у меня нет! :-) (жестокий мир) Действительно, что оптимально, только что понял, кажется, я действительно могу отредактировать ваш ответ .. в следующий раз .. урок усвоен.