Unable to load Solidity contract using `compile_standard` function due to error `Second argument needs to be a buffer`
- 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
[](https://cdn.pixabay.com/photo/2016/11/29/02/53/animal-1866944_960_720.jpg)
Contributor 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