Closed ammarqureshi closed 5 years ago
You seem to be using the "combined-json" way for compiling. This is a legacy feature we do not fully support anymore. The "clone binary" (clone-bin
) option was removed a while ago, for example.
Please take a look at the py-solc documentation and look for Standard JSON Compilation
.
Please reopen if you encounter further problems.
@chriseth I tried following the doc you provided. With standard JSON compilation, I have:
from solc import compile_standard
compile_standard({
'language': 'Solidity',
'sources': {'Foo.sol': 'content':
"
pragma solidity ^0.4.21;
contract Greeter {
string public greeting;
function Greeter() public {
greeting = 'Hello';
}
function setGreeting(string _greeting) public {
greeting = _greeting;
}
function greet() view public returns (string) {
return greeting;
}
}
"
}
})
I get the following error:
'sources': {'Foo.sol': 'content':
^
SyntaxError: invalid syntax
@ammarqureshi Try:
{
"language": "Solidity",
"sources": {
"Foo.sol": {
"content": "
pragma solidity ^0.4.21;
contract Greeter {
string public greeting;
function Greeter() public {
greeting = 'Hello';
}
function setGreeting(string _greeting) public {
greeting = _greeting;
}
function greet() view public returns (string) {
return greeting;
}
}
"
}
}
}
@ekpyron I've tried running your code:
from solc import compile_standard
compile_standard(
{
"language": "Solidity",
"sources": {
"Foo.sol": {
"content": "
pragma solidity ^0.4.21;
contract Greeter {
string public greeting;
function Greeter() public {
greeting = 'Hello';
}
function setGreeting(string _greeting) public {
greeting = _greeting;
}
function greet() view public returns (string) {
return greeting;
}
}
"
}
}
}
)
Seems to give the same issue:
(env) Ammars-MacBook-Pro:envs ammarqureshi$ python contract.py
File "contract.py", line 7
"content": "
^
SyntaxError: EOL while scanning string literal
Ah, sorry, I hadn't read the issue carefully and didn't realize that you're referring to python. You need a proper python multiline string, try:
from solc import compile_standard
compile_standard(
{
"language": "Solidity",
"sources": {
"Foo.sol": {
"content": '''
pragma solidity ^0.4.21;
contract Greeter {
string public greeting;
function Greeter() public {
greeting = 'Hello';
}
function setGreeting(string _greeting) public {
greeting = _greeting;
}
function greet() view public returns (string) {
return greeting;
}
}
'''
}
}
}
)
@ekpyron got another error:
Ammars-MacBook-Pro:Contracts ammarqureshi$ python contract.py
Traceback (most recent call last):
File "contract.py", line 25, in <module>
'''
File "/Users/ammarqureshi/anaconda/lib/python3.6/site-packages/solc/main.py", line 181, in compile_standard
message=error_message,
solc.exceptions.SolcError: Foo.sol:4:1: ParserError: Source file requires different compiler version (current compiler is 0.5.4+commit.9549d8ff.Darwin.appleclang - note that nightly builds are considered to be strictly less than the released version
contract Greeter {
^------^
> command: `solc --standard-json`
> return code: `0`
> stderr:
{"errors":[{"component":"general","formattedMessage":"Foo.sol:4:1: ParserError: Source file requires different compiler version (current compiler is 0.5.4+commit.9549d8ff.Darwin.appleclang - note that nightly builds are considered to be strictly less than the released version\ncontract Greeter {\n^------^\n","message":"Source file requires different compiler version (current compiler is 0.5.4+commit.9549d8ff.Darwin.appleclang - note that nightly builds are considered to be strictly less than the released version","severity":"error","sourceLocation":{"end":35,"file":"Foo.sol","start":27},"type":"ParserError"}],"sources":{}}
> stdout:
The contract code:
from solc import compile_standard
compile_standard(
{
"language": "Solidity",
"sources": {
"Foo.sol": {
"content": '''
pragma solidity ^0.4.21;
contract Greeter {
string public greeting;
function Greeter() public {
greeting = 'Hello';
}
function setGreeting(string _greeting) public {
greeting = _greeting;
}
function greet() view public returns (string) {
return greeting;
}
}
'''
}
}
}
)
When I run pip install py-solc
I got:
Ammars-MacBook-Pro:Contracts ammarqureshi$ pip install py-solc
Collecting py-solc
Using cached https://files.pythonhosted.org/packages/47/74/d36abca3f36ccdcd04976c50f83502c870623e5beb4a4ec96c7bad4bb9e8/py_solc-3.2.0-py3-none-any.whl
Requirement already satisfied: semantic-version>=2.6.0 in /Users/ammarqureshi/anaconda/lib/python3.6/site-packages (from py-solc) (2.6.0)
ethpm 0.1.4a10 has requirement web3[tester]<6,>=5.0.0a3, but you'll have web3 4.8.2 which is incompatible.
Installing collected packages: py-solc
Successfully installed py-solc-3.2.0
Well, you need to use the right compiler version - which one are you aiming for? solc --version
should tell you that. Or you replace pragma solidity ^0.4.21;
by pragma solidity >0.0.0;
to match all compiler versions. Depending on the version you're using you might have to update the Code to be compatible with it as well (e.g. starting from 0.5.0
you need to use constructor()
instead of function Greeter()
, etc.).
From the error message it looks like you're using solc version 0.5.4, so you need to change the contract code to:
pragma solidity ^0.5.0;
contract Greeter {
string public greeting;
constructor() public {
greeting = 'Hello';
}
function setGreeting(string memory _greeting) public {
greeting = _greeting;
}
function greet() view public returns (string memory) {
return greeting;
}
}
@ekpyron Thanks for the above response, learning quite a bit here.
Now that the previous way of compiling is not fully supported, how would we go about getting the abi and the bytecode?
The web3.py docs example shows:
contract_interface = compiled_sol['<stdin>:Greeter']
# web3.py instance
w3 = Web3(Web3.EthereumTesterProvider())
# set pre-funded account as sender
w3.eth.defaultAccount = w3.eth.accounts[0]
# Instantiate and deploy contract
Greeter = w3.eth.contract(abi=contract_interface['abi'], bytecode=contract_interface['bin'])
After compiling the script:
from solc import compile_standard
compiled_sol = compile_standard(
{
"language": "Solidity",
"sources": {
"Foo.sol": {
"content": '''
pragma solidity ^0.5.0;
contract Greeter {
string public greeting;
constructor() public {
greeting = 'Hello';
}
function setGreeting(string memory _greeting) public {
greeting = _greeting;
}
function greet() view public returns (string memory) {
return greeting;
}
}
'''
}
}
}
)
print('compiled sol', compiled_sol);
I get:
Ammars-MacBook-Pro:Contracts ammarqureshi$ python contract.py
compiled sol {'sources': {'Foo.sol': {'id': 0}}}
For that you can refer to the documentation of the standard-json interface: https://solidity.readthedocs.io/en/v0.5.4/using-the-compiler.html#compiler-input-and-output-json-description
Especially the part concerning outputSelection
. You should find all the information you need to adjust the query to your needs there.
Thanks for the response. I have managed to retrieve the bytecode object with:
bytecode = compiled_sol['contracts']['Foo.sol']['Greeter']['evm']['bytecode']['object']
However, having bit of a trouble with retrieving abi.
This is what I get back with compiled_sol['contracts']['Foo.sol']['Greeter']['metadata']
{"compiler":{"version":"0.5.4+commit.9549d8ff"},"language":"Solidity","output":{"abi":[{"constant":false,"inputs":[{"name":"_greeting","type":"string"}],"name":"setGreeting","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"greeting","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}],"devdoc":{"methods":{}},"userdoc":{"methods":{}}},"settings":{"compilationTarget":{"Foo.sol":"Greeter"},"evmVersion":"byzantium","libraries":{},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"Foo.sol":{"keccak256":"0x88fcdcf7813c0d045fe2d0f76bac1065d9a5bc04ed41d8bfd7df06c9b0dc9cb0","urls":["bzzr://4be12bc0e7b38c04cac900a11d775ffc953ee16b6ab87f2e5239d9102c5be727"]}},"version":1}
I thought to get abi it would be similar to getting the bytecode object.
compiled_sol['contracts']['Foo.sol']['Greeter']['metadata']['compiler]['output']
but instead I get:
Traceback (most recent call last):
File "contract.py", line 56, in <module>
print('compiled ABI', compiled_sol['contracts']['Foo.sol']['Greeter']['metadata']['compiler']);
TypeError: string indices must be integers
You should count the brackets in the output ;-).
@ekpyron
compiled_sol['contracts']['Foo.sol']['Greeter']['metadata']['output']
I still get the same error:
print('compiled ABI: {}'.format(compiled_sol['contracts']['Foo.sol']['Greeter']['metadata']['output']))
TypeError: string indices must be integers
Actually this is the wrong place to ask these questions, since the issues you're having are specific to py-solc, resp. python, not to solidity :-). That being said I guess that the python API just passes you the metadata as string and does not parse it as a python data structure, so you can't access it using ['...']
, but you have to use some other means to parse it (which is another issue that's unrelated to solidity - you can probably use the json library shipped with python to decode the string).
my bad I did not know. Anyways, thanks for the previous help! 👍
OS: MacOs Mojave I am new to solidity and was following the docs to install the solidity compiler. I successfully installed the solidity compiler. However, when following one the web3.py example:
I encounter the following error: