Py-solc and solidity imports

Question:

How can I compile solidity files which perform relative imports through py-solc? Here’s a minimal example:

Directory structure

my-project
   - main.py
   - bar.sol
   - baz.sol

main.py:

from solc import compile_source

def get_contract_source(file_name):
    with open(file_name) as f:
        return f.read()

contract_source_code = get_contract_source("bar.sol")

compiled_sol = compile_source(contract_source_code)  # Compiled source code

baz.sol:

pragma solidity ^0.4.0;

contract baz {
    function baz(){

    }
}

bar.sol:

pragma solidity ^0.4.0;

import "./baz" as baz;

contract bar {
    function bar(){

    }
}

When I try to run the python file I get the following error:

solc.exceptions.SolcError: An error occurred during execution
        > command: `solc --combined-json abi,asm,ast,bin,bin-runtime,clone-bin,devdoc,interface,opcodes,userdoc`
        > return code: `1`
        > stderr:

        > stdout:
        :17:1: Error: Source "baz" not found: File outside of allowed directories.
import "./baz" as baz;
^----------------------^

I’m still not 100% clear on how imports work. I’ve reviewed the docs and it seems like I need to pass some extra arguments to the compile_source command. I’ve found some potentially useful docs here and I think I need to play around with allow_paths or compile_files which I will. If I find a solution before I get an answer I will post what I find.

Answers:

Ok, turns out compile_files is exactly what I need.

The new compile command is

import os

PROJECT_ROOT = os.path.dirname(os.path.dirname(__file__))
compiled_sol = compile_files([os.path.join(self.PROJECT_ROOT, "bar.sol"), os.path.join(self.PROJECT_ROOT, "baz.sol")])

and it turns out my import was wrong. I need to import baz like import "./baz.sol" as baz; – I was missing the .sol extension.

Answered By: Paymahn Moghadasian

Assume we have a smart contract man.sol, and it contains two contract in a file, like this:

pragma solidity ^0.8.0;
import "./SafeERC20.sol";
contract mainContract {
  ... (Any code can be here ...)
}contract childContract {
 ... (Other code here)}

So we have a directory like this:

  • main.sol
    -SafeERC20.sol
    -deploy.py

Deploy.py :

import json
import os

import web3.eth
from web3 import Web3, HTTPProvider

from solcx import install_solc, set_solc_version,compile_standard
from dotenv import load_dotenv#here install solidity version
install_solc('v0.8.0')
set_solc_version('v0.8.0')


file_path = "."
name = "main.sol"
input = {
    'language': 'Solidity',
    'sources': {
        name: {'urls': [file_path + "/" + name]}},
    'settings': {
        'outputSelection': {
            '*': {
                '*': ["abi", "metadata", "evm.bytecode", "evm.bytecode.sourceMap"],
            },
            'def': {name: ["abi", "evm.bytecode.opcodes"]},
        }
    }
}

output = compile_standard(input, allow_paths=file_path)

contracts = output["contracts"]

with open('compiled_code.json', "w") as file:
    json.dump(output, file)

bytecode = contracts["SC-.sol"]["mainContract"]["evm"]["bytecode"]["object"]

abi = contracts["main.sol"]["mainContract"]["abi"]


# Deploy on local ganache# w3 = Web3(Web3.HTTPProvider("HTTP://127.0.0.1:7545"))
# chainId = 1337
# myAddress = "0x6235207DE426B0E3739529F1c53c14aaA271D..."
# privateKey = "0xdbe7f5a9c95ea2df023ad9......."

#Deploy on rinkeby infura rinkebyw3 = Web3(Web3.HTTPProvider("https://rinkeby.infura.io/v3/......"))
chainId = 4

myAddress = "0xBa842323C4747609CeCEd164d61896d2Cf4..."
privateKey ="0x99de2de028a52668d3e94a00d47c4500db0afed3fe8e40..."

SCOnline = w3.eth.contract(abi=abi, bytecode=bytecode)

nonce = w3.eth.getTransactionCount(myAddress)

transaction = SCOnline.constructor().buildTransaction({
    "gasPrice": w3.eth.gas_price, "chainId": chainId, "from": myAddress, "nonce": nonce
})

signedTrx = w3.eth.account.sign_transaction(transaction, private_key= privateKey)



txHash = w3.eth.send_raw_transaction(signedTrx.rawTransaction)

txReceipt = w3.eth.wait_for_transaction_receipt(txHash)
Answered By: Hamid Naghipour
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.