简体   繁体   中英

How to check or know that a wallet has tokens in web3 python

I am trying to find out if its possible to know or check in python web3 if a certain bsc address has tokens or transactions.

I can check if an address has bnb or bsc transactions using nonce = web3.eth.getTransactionCount(address) but what I want to know is if a certain address has tokens aside from bnb or bsc.

For example, this address 0x7DBbA1e788b169139F5602CCb734137F45a59aa9 has a token but no bnb or bsc transaction.

In the broadest sense, it is computationally very hard to check if an address has any arbitrary tokens. Even if we just limit to ERC-20 (or BEP-20, or similar) token's it's still tricky.

Why? The way ERC-20 (and similar tokens) are implemented mean that the token balances are stored in the token's address, not the address containing the token. For instance, OpenZeppelin implementation of ECR20 has this variable used for storing balances:

mapping(address => uint256) private _balances;

It is computationally efficient to look for all addresses that has the token if you know the address of the token, but it is not possible to efficiently search for all tokens that contain a specific address in their balances.

If on the other hand you know the address of the token, it's as easy as calling the balanceOf function of the token , with the target account address as the argument:

uint256 userBalance = IERC20(tokenAddress).balanceOf(account);

To my understanding, public services such as Etherscan typically have keep lists of ERC20 and similar tokens and go through these lists to show the balances of "all" tokens in an address. For instance, BscScan has an indexed list of all smart contracts on the BSC that implement the BEP-20 interface (2,450,333 Token Contracts according to the website ). Getting the whole list somehow and going through it is one option. Just looking at a more limited set of "top" tokens is another.

See this sample PY code. I don't remember if it's working properly.

import json
from web3 import Web3, HTTPProvider

# truffle development blockchain address
blockchain_address = 'http//:127.0.0.1:7545'
#client instance to interact with the blockchain
web3 = Web3(HTTPProvider(blockchain_address))

compiled_contract_path = 'build/contracts/FirstContract.json'
deployed_contract_address = '0x'

with open(compiled_contract_path) as file:
    contract_json = json.load(file) #load contract info as JSON
    contract_abi = contract_json['abi']

contract = web3.eth.contract(address=deployed_contract_address, abi=contract_abi)

result = contract.functions.setValue(10).transact() #use transact to store value in blockchain
print(result)
print(result.hex())
message = contract.functions.getValue().call()
print(message)


abi = '[]'

See the line:

message = contract.functions.getValue().call()

The message variable receives information from the PY getValue() function. You can implement the erc20 balanceOf ABI and call this function directly in the token contract.

As for the way BSCscan and Etherscan show the balances, they don't query balanceOf of the token contract. They simply pull the Emit Transfer event histories and do the sending and receiving calculations to display balances. This is a laborious, strange and non-trivial way and I don't know exactly why they prefer to work this way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM