1

I have a function that returns the name of ether units. My problem is that it doesn't work in the cases when the decimal value is 4 or 8. The decimal value belongs to a token, and I need the correct unit name to call a web3.toWei(token_balance, decimal_(token_decimal)) convert function. My question is that is there any official unit name for decimal 4 and 8 (I couldn't find)? If there are no unit names, what is the correct implementation to convert a value with 4 or 8 decimals to wei?

def decimal_(decimal):
    decimal_value = int("1" + str("0" * decimal))
    d = {"wei": 1,
                    "kwei": 1000,
                    "babbage": 1000,
                    "femtoether": 1000,
                    "mwei": 1000000,
                    "lovelace": 1000000,
                    "picoether": 1000000,
                    "gwei": 1000000000,
                    "shannon": 1000000000,
                    "nanoether": 1000000000,
                    "nano": 1000000000,
                    "szabo": 1000000000000,
                    "microether": 1000000000000,
                    "micro": 1000000000000,
                    "finney": 1000000000000000,
                    "milliether": 1000000000000000,
                    "milli": 1000000000000000,
                    "ether": 1000000000000000000,
                    "kether": 1000000000000000000000,
                    "grand": 1000000000000000000000,
                    "mether": 1000000000000000000000000,
                    "gether": 1000000000000000000000000000,
                    "tether": 1000000000000000000000000000000}

    key_list = list(d.keys())
    value_list = list(d.values())
    position = value_list.index(decimal_value )
    return key_list[position]

1 Answer 1

2

You can achieve this by updating the dictionary units located in the eth_utils/units.py file in the eth_utils that is a dependency of the web3 codebase.

For me it lives here C:\Python38\Lib\site-packages\eth_utils\units.py

It contains only the units dict of decimal places.

You can add the decimals you require like so..

from eth_utils.units import units, decimal

units.update(
    {
        "4_dec": decimal.Decimal("10000"),  # # Add in 4 decimals
        "8_dec": decimal.Decimal("100000000"),  # Add in 8 decimals
    }
)


After which, you do not need a duplicate dict in the function.

so then the code becomes:

from eth_utils.units import units, decimal

units.update(
    {
        "4_dec": decimal.Decimal("10000"),  # # Add in 4 decimals
        "8_dec": decimal.Decimal("100000000"),  # Add in 8 decimals
    }
)

def decimal_(decimal):
    for name, places in units.items():
        if places == (10 ** decimal):
            return name
    return 'Unit Not Found'

token_balance = 0.12345678
token_decimal = 8

places_name = decimal_(token_decimal)
print(places_name)
>>> 8_dec

wei_amount = w3.toWei(token_balance, places_name)
print(wei_amount)
>>> 12345678

If you put in an incorrect number, you will see the new items in the error message.

ValueError: Unknown unit.  Must be one of wei/.../4_dec/8_dec/.../tether

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.