ethereum / web3.py

A python interface for interacting with the Ethereum blockchain and ecosystem.
http://web3py.readthedocs.io
MIT License
4.97k stars 1.69k forks source link

ens base registrar instance is returning incorrect values - possible bug #2669

Closed 0xlucyy closed 1 year ago

0xlucyy commented 1 year ago
aiohttp==3.8.1
aiosignal==1.2.0
alembic==1.8.1
arrow==1.2.3
async-timeout==4.0.2
attrs==22.1.0
base58==2.1.1
bitarray==2.6.0
cached-property==1.5.2
certifi==2022.6.15
charset-normalizer==2.1.1
click==8.1.3
coverage==6.4.4
cytoolz==0.12.0
eth-abi==2.2.0
eth-account==0.5.9
eth-bloom==1.0.4
eth-hash==0.3.3
eth-keyfile==0.5.1
eth-keys==0.3.4
eth-rlp==0.2.1
eth-typing==2.3.0
eth-utils==1.10.0
flake8==5.0.4
Flask==2.2.2
Flask-Cors==3.0.10
Flask-SQLAlchemy==2.5.1
frozenlist==1.3.1
greenlet==1.1.3
hexbytes==0.3.0
idna==3.3
importlib-metadata==4.12.0
importlib-resources==5.9.0
iniconfig==1.1.1
ipfshttpclient==0.8.0a2
itsdangerous==2.1.2
Jinja2==3.1.2
jsonschema==4.15.0
lru-dict==1.1.8
Mako==1.2.2
MarkupSafe==2.1.1
mccabe==0.7.0
multiaddr==0.0.9
multidict==6.0.2
mypy-extensions==0.4.3
mysqlclient==2.1.1
netaddr==0.8.0
packaging==21.3
parsimonious==0.8.1
pkgutil_resolve_name==1.3.10
pluggy==1.0.0
protobuf==3.20.1
py==1.11.0
py-ecc==6.0.0
py-evm==0.6.0a1
pycodestyle==2.9.1
pycryptodome==3.15.0
pyethash==0.1.27
pyflakes==2.5.0
pyparsing==3.0.9
pyrsistent==0.18.1
pysha3==1.0.2
pytest==7.1.3
pytest-cov==3.0.0
python-box==6.0.2
python-dateutil==2.8.2
python-dotenv==0.21.0
requests==2.28.1
rlp==2.0.1
six==1.16.0
sortedcontainers==2.4.0
SQLAlchemy==1.4.41
tomli==2.0.1
toolz==0.12.0
trie==2.0.2
urllib3==1.26.12
varint==1.0.2
web3==5.30.0
websockets==9.1
Werkzeug==2.2.2
yarl==1.8.1
zipp==3.8.1

What was wrong?

My local ENS: Base Registrar instance is returning different data than etherscan. Notice variables expires & owner.

from web3 import Web3

w3 = Web3(HTTPProvider(GETH_MAINNET_PROVIDER))
if w3.isConnected() == False:
    raise Exception('Provider is not online.')

# Get abi & bytecode from https://etherscan.io/address/0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85#code
abi = COPY_ABI_FROM_ETHERSCAN

contract_instance = w3.eth.contract(
    abi=abi,
    address=Web3.toChecksumAddress("0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85"),
    ContractFactoryClass=ConciseContract
)

# This is now ENS sees 'mlstickets'
_hash = 79798792360514604897274867475268942709375420329084632479380508457991614511774

# Return 1655715014 !!
expires = contract_instance.nameExpires(_hash)

# Function throws !!
owner = contract_instance.ownerOf(_hash)

Local contract instance returns 1655715014 while read_contract on etherscan returns 1696587563.

Screen Shot 2022-10-06 at 11 45 01 PM Screen Shot 2022-10-06 at 11 45 19 PM

Local contract instance reverts while read_contract on etherscan returns 0xFC2DdF666D313614041e52E2cc18aEEDB1ba9348

Screen Shot 2022-10-06 at 11 47 43 PM Screen Shot 2022-10-06 at 11 50 16 PM

Looking inside contract_instance

Screen Shot 2022-10-07 at 12 01 38 AM

Node

DappNode 
Geth RPC API
Version: 0.1.34
Fully synced

How can it be fixed?

Any ideas?


Note: We prefer to use issues to track our work. If you think you've encountered a bug in web3py or have a feature request, you're in the right place. If you have implementation or usage questions, please refer to our documentation and/or join the conversation on discord.

fselmo commented 1 year ago

@0xlucyfer ConciseContract is deprecated and was completely removed in v6. I'm not sure if that's why you're getting your errors but I get the same values as etherscan with the following:

CONTRACT_ADDRESS = "0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85"
abi = _get_contract_abi(CONTRACT_ADDRESS)  # get abi using etherscan's API

contract_instance = w3.eth.contract(
    abi=abi,
    address=CONTRACT_ADDRESS,
)

_hash = 79798792360514604897274867475268942709375420329084632479380508457991614511774

expires = contract_instance.functions.nameExpires(_hash).call()
owner = contract_instance.functions.ownerOf(_hash).call()

I'm going to close this since I can't reproduce it but feel free to reply here if it still is not working right and you think we have a bug. I can re-open. Best of luck!

fselmo commented 1 year ago

@0xlucyfer for the record, I did try with the deprecated ConciseContract class and I still get the correct results (as I would expect). I feel like something else is going on in your setup if you are not getting the correct results. Is your Web3 instance connected to mainnet? Often times the same contract address is shared across chains and if you are connected to another chain you will get different results.

0xlucyy commented 1 year ago

I am running a geth dappnode, seems that geth is unable to update, so it is 2 versions behind. That is likely the cause of this issue. When I use my infuria provider, I get the same outputs locally as etherescan returns.

When is v6 coming out? Might be a good idea to add a deprecated tag to the function. It is a lot more sloppy to have to call this contract_instance.functions.METHOD().call() instead of contract_instance.METHOD()

fselmo commented 1 year ago

Might be a good idea to add a deprecated tag to the function.

Do you mean in the docs? It has had a deprecation message for about 4 years. Would be good to know if that isn't coming through correctly.

It is a lot more sloppy to have to call this contract_instance.functions.METHOD().call() instead of contract_instance.METHOD()

It sure isn't as nice. The preferred way to more concisely call a contract function is to use the ContractCaller API:

expires = contract_instance.caller.nameExpires(_hash)

edit: The docs seem to be updated as well here

0xlucyy commented 1 year ago

Why is the ContractCaller api preferred over ContractFunction api?

I prefer to have the transaction object in the back of the contract instance declaration. ContractCaller, I believe the transaction object goes in the middle of the code, syntactically.

ContractCaller

myContract.\
   caller(BASIC_TRANSACTION(w3, account.address)).\
   contract_func(x, y)

ContractFunction

myContract.functions.\
   contract_func(x, y).\
   buildTransaction(BASIC_TRANSACTION(w3, account.address))

Turns out I was getting bad data from my local geth node because I had not launched a beacon client. I launched lighthouse, and then my geth client started returning accurate data once more.