You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过py-solc编译包含相对导入的Solidity文件?

解决py-solc编译包含相对导入的Solidity文件问题

我明白你现在遇到的问题:直接用compile_source编译带有相对导入的Solidity文件时,solc找不到依赖的合约文件。下面结合你的最简示例,一步步给出解决方案。

先明确你的完整场景

目录结构

my-project/
├── main.py
├── bar.sol
└── baz.sol

各文件内容

baz.sol

pragma solidity ^0.4.0;
contract baz {
    function baz(){ }
}

bar.sol(补全你未写完的导入逻辑)

pragma solidity ^0.4.0;
// 相对导入同目录下的baz.sol
import "./baz.sol";

contract bar {
    baz public myBaz;
    function bar() {
        myBaz = new baz();
    }
}

原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)

问题原因

compile_source是把Solidity代码作为**标准输入(stdin)**传给solc编译器的,solc不知道这段代码来自哪个文件路径,自然无法解析./baz.sol这种相对导入的路径,导致找不到依赖文件。

解决方案

方案1:使用compile_files替代compile_source(推荐)

compile_files直接传递文件路径给solc,编译器会根据文件的实际位置自动解析相对导入,这是最省心的方式。

修改后的main.py:

from solc import compile_files

# 传入要编译的文件路径列表,solc会自动处理依赖
compiled_sol = compile_files(["bar.sol"])

# 获取编译后的bar合约(格式为"文件名:合约名")
bar_contract = compiled_sol["bar.sol:bar"]

# 输出ABI和字节码(按需使用)
print("ABI:", bar_contract['abi'])
print("Bytecode:", bar_contract['bin'])

方案2:给compile_source添加导入回调

如果你必须使用compile_source,可以通过import_callback参数自定义导入逻辑,告诉solc去哪里找依赖文件。

修改后的main.py:

from solc import compile_source
import os

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

def import_callback(import_path):
    # 把相对导入路径转换为当前目录的绝对路径
    full_path = os.path.join(os.getcwd(), import_path)
    if os.path.exists(full_path):
        with open(full_path, "r") as f:
            return f.read()
    # 找不到文件时抛出异常
    raise FileNotFoundError(f"无法找到导入文件:{import_path}")

contract_source_code = get_contract_source("bar.sol")
compiled_sol = compile_source(
    contract_source_code,
    import_callback=import_callback
)

# 注意这里合约的键是"<stdin>:bar",因为代码是从stdin传入的
bar_contract = compiled_sol["<stdin>:bar"]
print("ABI:", bar_contract['abi'])
print("Bytecode:", bar_contract['bin'])

额外注意事项

  • 确保你的py-solc版本与solc编译器版本匹配,比如你用的是solc 0.4.x,建议安装py-solc==3.2.0(更高版本的py-solc可能不再支持旧版solc)。
  • 如果你的项目有更深的目录结构,只需要调整import_callback中的路径处理逻辑,或者在compile_files中传入正确的文件路径即可。

内容的提问来源于stack exchange,提问作者Paymahn Moghadasian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:19:31