ethereum / ethereum/py-solc

Unable to load Solidity contract using `compile_standard` function due to error `Second argument needs to be a buffer`

Open
#42 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
195
Forks
77
PR merge metrics
No merged PRs in 30d

Description

* `py-solc` Version: 2.1.0 (shown when running `pip list`)
* `solc` Version: 0.4.18+commit.9cf6e910.Emscripten.clang (shown when running `solc --version`)
* Python Version: 3.6.4rc1 (shown when running `python --version`)
* OS: osx - macOS 10.12.6

### What was wrong?

I used PyEnv to install and switch to the latest Python version 3.6.4rc1 https://github.com/pyenv/pyenv. I then installed the following Python packages:
* https://pypi.python.org/pypi/py-solc/2.1.0
* https://pypi.python.org/pypi/web3/4.0.0b5
* https://pypi.python.org/pypi/ethereum/2.1.5

```
pyenv install 3.6.4rc1
pyenv versions
pyenv global 3.6.4rc1
python -m pip install py-solc==2.1.0
python -m solc.install v0.4.18
python -m pip install web3==4.0.0b5
python -m pip install ethereum==2.1.5
python scripts/main.py
```
I then created and executed a Python file i.e. main.py with `python main.py`:
**main.py**
```
import solc
from solc import compile_files
compiled_sol = compile_files(["FixedSupplyToken.sol"])
```

Note that the Solidity file I am using is in my repo here https://github.com/ltfschoen/geth-node/blob/master/contracts/FixedSupplyToken.sol, and it compiles successfully with solc v0.4.18, as I've done so in MIST and deployed it to a Private Network previously already.

I'm trying to replicate using Web3.py and py-solc the same functionality that worked when I used Web3.js and solc-js here: https://github.com/ltfschoen/geth-node/blob/master/scripts/main.js

In the file I use py-solc to compile Solidity source code from a file using the function `compile_files`, but I get a full output error in Bash terminal as follows:

```
$ python main.py
Traceback (most recent call last):
File "main.py", line 3, in
compiled_sol = compile_files(["FixedSupplyToken.sol"])
File "/Users/Ls/.pyenv/versions/3.6.4rc1/lib/python3.6/site-packages/solc/main.py", line 133, in compile_files
stdoutdata, stderrdata, command, proc = solc_wrapper(**compiler_kwargs)
File "/Users/Ls/.pyenv/versions/3.6.4rc1/lib/python3.6/site-packages/solc/utils/string.py", line 85, in inner
return force_obj_to_text(fn(*args, **kwargs))
File "/Users/Ls/.pyenv/versions/3.6.4rc1/lib/python3.6/site-packages/solc/wrapper.py", line 165, in solc_wrapper
stderr_data=stderrdata,
solc.exceptions.SolcError: An error occurred during execution
> command: `solc --combined-json abi,asm,ast,bin,bin-runtime,clone-bin,devdoc,interface,opcodes,userdoc FixedSupplyToken.sol`
> return code: `1`
> stderr:

> stdout:
Invalid option selected, must specify either --bin or --abi
```

I then looked closer at the Py-Solc documentation here: https://github.com/ethereum/py-solc#standard-json-compilation, and changed my code to use the same syntax as the second example under the heading "Standard JSON Compilation":
**main.py**
```
import solc
from solc import compile_standard
compiled_sol = compile_standard({
'language': 'Solidity',
'sources': {'FixedSupplyToken.sol': 'urls': ["./contracts/FixedSupplyToken.sol"]},
}, allow_paths="./contracts/")
```

But when I run this it gives another error in the Bash terminal, which is because the example is missing a `{` just before `'urls'`:
```
$ python main.py
File "main.py", line 5
'sources': {'FixedSupplyToken.sol': 'urls': ["FixedSupplyToken.sol"]},
^
SyntaxError: invalid syntax
```

So I added the missing `{`, and I used a JSON Validator to make sure the argument was valid json format:

**main.py**
```
import solc
from solc import compile_standard
compiled_sol = compile_standard({
"language": "Solidity",
"sources": {
"FixedSupplyToken.sol": {
"urls": ["file:///Users/Ls/code/blockchain/geth-node/contracts/FixedSupplyToken.sol"]
}
}
}, allow_paths="file:///Users/Ls/code/blockchain/geth-node/contracts/")
```

But then it gave me error:
```
$ python main.py
Traceback (most recent call last):
File "main.py", line 10, in
}, allow_paths="./contracts/")
File "/Users/Ls/.pyenv/versions/3.6.4rc1/lib/python3.6/site-packages/solc/main.py", line 161, in compile_standard
**kwargs
File "/Users/Ls/.pyenv/versions/3.6.4rc1/lib/python3.6/site-packages/solc/utils/string.py", line 85, in inner
return force_obj_to_text(fn(*args, **kwargs))
File "/Users/Ls/.pyenv/versions/3.6.4rc1/lib/python3.6/site-packages/solc/wrapper.py", line 165, in solc_wrapper
stderr_data=stderrdata,
solc.exceptions.SolcError: An error occurred during execution
> command: `solc --allow-paths file:///Users/Ls/code/blockchain/geth-node/contracts/ --standard-json`
> return code: `1`
> stderr:

> stdout:
/Users/Ls/.nvm/versions/node/v8.7.0/lib/node_modules/solc/node_modules/graceful-fs/polyfills.js:144
throw er
^

TypeError: Second argument needs to be a buffer
at Object.fs.readSync (fs.js:682:18)
at Object.readSync (/Users/Ls/.nvm/versions/node/v8.7.0/lib/node_modules/solc/node_modules/graceful-fs/polyfills.js:138:28)
at Object. (/Users/Ls/.nvm/versions/node/v8.7.0/lib/node_modules/solc/solcjs:65:18)
at Module._compile (module.js:624:30)
at Object.Module._extensions..js (module.js:635:10)
at Module.load (module.js:545:32)
at tryModuleLoad (module.js:508:12)
at Function.Module._load (module.js:500:3)
at Function.Module.runMain (module.js:665:10)
at startup (bootstrap_node.js:187:16)
```

So then I clicked the link that says "Solidity Documentation for Standard JSON input and ouptup format" (FYI, note the typo here in the word "output") http://solidity.readthedocs.io/en/develop/using-the-compiler.html#compiler-input-and-output-json-description, specifically the section http://solidity.readthedocs.io/en/develop/using-the-compiler.html#input-description.

It highlighted that that object we are passing to `compile_standard` is an Input JSON Description, which the compiler API expects to be in JSON format, and it outputs the compilation result in a JSON formatted output.

When looked more closely at the error, which says `solc --allow-paths file:///Users/Ls/code/blockchain/geth-node/contracts/ --standard-json`, it's clearly missing a JSON file as an input argument at the end.
Is this something that the compiler is supposed to automatically generate? A similar error was raised in the solc-js repo issues here https://github.com/ethereum/solc-js/issues/126

I tried experimenting a bit more trying to find an alternative and found that I'm able to manually created ABI files in Bash terminal with the command: `solc --abi FixedSupplyToken.sol --output-dir ./build`, which generates the following in the ./build/ folder:
* __FixedSupplyToken_sol_ERC20Interface.abi
* __FixedSupplyToken_sol_FixedSupplyToken.abi

But I don't know how to load these generated ABI files into the variable `contract_interface` in main.py. Currently my code is `contract_interface = compiled_sol[':FixedSupplyToken']`,

I then tried copying the JSON argument into a file called test.json.
**test.json**
```
{
"language": "Solidity",
"sources": {
"FixedSupplyToken.sol": {
"urls": ["file:///Users/Ls/code/blockchain/geth-node/contracts/FixedSupplyToken.sol"]
}
}
}
```
I then ran the following:
```
solc --standard-json test.json --output-dir ./build
```
But it just returned the following;
```
Empty input was read
```
So I don't even understand how to use the CLI.
Any help greatly appreciated
I've pushed my latest code here: https://github.com/ltfschoen/geth-node/blob/master/scripts/main.py

#### Cute Animal Picture

[![Python](https://cdn.pixabay.com/photo/2016/11/29/02/53/animal-1866944_960_720.jpg)](https://cdn.pixabay.com/photo/2016/11/29/02/53/animal-1866944_960_720.jpg)

Contributor guide

Open the contributing guide

Research direction

Start with solc/main.py's compile_standard path and solc/wrapper.py, then reproduce the reported command using test.json and the shown Solidity source URL. Compare how the wrapper invokes `solc --standard-json` with the CLI's expected input handling; done means standard JSON compilation works without the buffer error and the resulting contract interface can be loaded.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, python, solidity
Domain
compilers, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.