Using an enum in library ABI causes a ParseError
- Dominant language
- Python
- Stars
- 256
- Forks
- 117
- Avg merge
- 4m
- Merged PRs (30d)
- 1
Description
## What was wrong?
`eth-abi` fails to properly parse/use the ABI generated by `solc` for a library. One example of this is that for contracts the `type` of an enum is reported as an integer type (`uint8` if enum has 256 of less entries) while for libraries it's `enum L.E` (where `L` is a library name and `E` is some enum).
An attempt to use such an `enum` with `eth-abi` results in an error:
```
ParseError: Parse error at '.E' (column 3) in type string '(L.E)'
```
### Code that produced the error
Repro using [Brownie](https://github.com/eth-brownie).
Assuming you have it installed, just run these commands in shell in an empty directory:
```bash
brownie init
cat << EOF > contracts/L.sol
pragma solidity =0.7.1;
library L {
enum BOOL {NO, YES}
function f(BOOL b) public pure returns (BOOL) {
return b;
}
}
EOF
cat << EOF > scripts/trigger_bug.py
from brownie import L, accounts
l = L.deploy({'from': accounts[0]})
l.f(1)
EOF
brownie compile
brownie run trigger_bug
```
### Full error output
```sh
Brownie v1.11.10 - Python development framework for Ethereum
FProject is the active project.
Launching 'ganache-cli --accounts 10 --hardfork istanbul --gasLimit 12000000 --mnemonic brownie --port 8545'...
Transaction sent: 0x5723c43998c3eaad6eabeb2e840843db80b028a4e024a7ea7fe96f6ec0dad640
Gas price: 0.0 gwei Gas limit: 12000000
L.constructor confirmed - Block: 1 Gas used: 90940 (0.76%)
L deployed at: 0x3194cBDC3dbcd3E11a07892e7bA5c3394048Cc87
File "brownie/_cli/run.py", line 49, in main
return_value = run(args[""], method_name=args[""] or "main")
File "brownie/project/scripts.py", line 52, in run
module = _import_from_path(script)
File "brownie/project/scripts.py", line 110, in _import_from_path
_import_cache[import_str] = importlib.import_module(import_str)
File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "
l.f(1)
File "brownie/network/contract.py", line 1232, in __call__
return self.call(*args, block_identifier=block_identifier)
File "brownie/network/contract.py", line 1033, in call
tx.update({"to": self._address, "data": self.encode_input(*args)})
File "brownie/network/contract.py", line 1113, in encode_input
data = format_input(self.abi, args)
File "brownie/convert/normalize.py", line 16, in format_input
abi_types = _get_abi_types(abi["inputs"])
File "brownie/convert/normalize.py", line 112, in _get_abi_types
tuple_type = parse(type_str)
File "eth_abi/grammar.py", line 125, in parse
raise ParseError(e.text, e.pos, e.expr)
ParseError: Parse error at '.BOOL' (column 3) in type string '(L.BOOL)'
Terminating local RPC client...
```
### Environment
```sh
Python version:
3.8.6 (default, Sep 30 2020, 04:00:38)
[GCC 10.2.0]
Operating System: Linux-5.9.1-arch1-1-x86_64-with-glibc2.2.5
pip freeze result:
aiohttp==3.6.2
aiohttp-socks==0.4.2
aiorpcX==0.18.4
alabaster==0.7.12
anki==2.1.26
ankirspy==2.1.26
ansible==2.10.1
ansible-base==2.10.2
appdirs==1.4.4
aqt==2.1.26
argcomplete==1.11.1
argh==0.26.2
asn1crypto==1.4.0
async-timeout==3.0.1
attrs==20.2.0
Babel==2.8.0
backcall==0.2.0
bcrypt==3.2.0
beautifulsoup4==4.9.3
bitstring==3.1.7
btrfsutil==1.2.0
CacheControl==0.12.6
certifi==2020.6.20
cffi==1.14.3
chardet==3.0.4
click==7.1.2
colorama==0.4.4
contextlib2==0.6.0.post1
cryptography==3.1.1
decorator==4.4.2
discid==1.2.0
distlib==0.3.1
distro==1.5.0
dnspython==2.0.0
docutils==0.16
ecdsa==0.16.0
Electrum==4.0.3
file-magic==0.4.0
filelock==3.0.12
fuse-python==1.0.0
git-cola==3.7
grpcio==1.34.0.dev0
gunicorn==20.0.4
html5lib==1.1
idna==2.10
imagesize==1.2.0
importlib-metadata==2.0.0
iotop==0.6
ipdb==0.13.4
ipython==7.18.1
ipython-genutils==0.1.0
isc==2.0
jedi==0.17.2
Jinja2==2.11.2
jmespath==0.10.0
jsonrpclib-pelix==0.4.1
jsonschema==3.2.0
lensfun==0.3.95
libmsym==0.2.4
louis==3.15.0
lxml==4.6.1
Markdown==3.3
MarkupSafe==1.1.1
meld==3.20.2
mps-youtube==0.2.8
msgpack==1.0.0
multidict==4.7.6
mutagen==1.45.1
namcap==3.2.10
numpy==1.19.2
opensnitch-ui==1.0.1
ordered-set==4.0.2
packaging==20.4
pafy==0.5.5
paramiko==2.7.2
parso==0.7.1
pathtools==0.1.2
pbkdf2==1.3
pep517==0.8.2
pexpect==4.8.0
picard==2.5
pickleshare==0.7.5
Pillow==7.2.0
pipenv==2020.8.13
pipx==0.15.6.0
ply==3.11
progress==1.5
prompt-toolkit==3.0.8
protobuf==3.12.4
ptyprocess==0.6.0
pwquality==1.4.4
pyaes==1.6.1
pyalpm==0.9.1
PyAudio==0.2.11
pycairo==1.20.0
pycparser==2.20
pycryptodomex==3.9.7
pyelftools==0.26
pyenchant==3.1.1
Pygments==2.7.2
PyGObject==3.38.0
pyinotify==0.9.6
PyNaCl==1.4.0
pyparsing==2.4.7
PyQt5==5.15.1
PyQt5-sip==12.8.1
PyQtWebEngine==5.15.1
pyrsistent==0.17.3
PySocks==1.7.1
pyspread==1.99.4
python-dateutil==2.8.1
python-slugify==4.0.1
pytz==2020.1
pyxattr==0.7.1
PyYAML==5.3.1
qrcode==6.1
ranger-fm==1.9.3
rednotebook==2.20
requests==2.24.0
resolvelib==0.4.0
retrying==1.3.3
s3cmd==2.1.0
Send2Trash==1.5.0
six==1.15.0
snowballstemmer==2.0.0
soupsieve==2.0.1
Sphinx==3.2.1
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==1.0.3
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.4
stevedore==3.2.2
team==1.0
text-unidecode==1.3
toml==0.10.1
traitlets==4.3.3
typing-extensions==3.7.4.3
urllib3==1.25.10
userpath==1.4.1
virtualenv==20.0.32
virtualenv-clone==0.5.4
virtualenvwrapper==4.8.4
watchdog==0.10.3
wcwidth==0.2.5
webencodings==0.5.1
websocket-client==0.57.0
yarl==1.5.1
youtube-dl==2020.9.20
zipp==3.3.2
```
## How can it be fixed?
The inconsistent ABI for libraries is actually a problem in the compiler and is likely to be fixed in the near future (feedback welcome in https://github.com/ethereum/solidity/issues/9278). It affects other tools too: https://github.com/ethereum-ts/TypeChain/issues/216, https://github.com/ethers-io/ethers.js/issues/1126.
In the meantime (and for older versions when it's fixed), tools need to handle it differently than in contracts.
Contributor guide
Assessment
This issue has not been assessed yet.