ethers.js/packages/cli/lib.esm/solc.js

125 lines
3.9 KiB
JavaScript
Raw Permalink Normal View History

'use strict';
import fs from "fs";
2020-01-29 21:43:56 -05:00
import _module from "module";
import { dirname, resolve } from "path";
import { ethers } from "ethers";
;
2020-01-29 21:43:56 -05:00
function populateOptions(options) {
options = ethers.utils.shallowCopy(options || {});
if (options.filename && !options.basedir) {
options.basedir = dirname(options.filename);
}
if (!options.filename) {
options.filename = "_contract.sol";
}
if (!options.basedir) {
options.basedir = ".";
}
2020-01-29 21:43:56 -05:00
return options;
}
function getInput(source, options) {
const sources = {};
sources[options.filename] = { content: source };
2020-01-29 21:43:56 -05:00
const input = {
language: "Solidity",
sources: sources,
settings: {
outputSelection: {
"*": {
"*": ["*"]
}
}
}
};
if (options.optimize) {
input.settings.optimizer = {
enabled: true,
runs: 200
};
}
2020-01-29 21:43:56 -05:00
return input;
}
function _compile(_solc, source, options) {
const compilerVersion = _solc.version();
const ver = compilerVersion.match(/(\d+)\.(\d+)\.(\d+)/);
if (!ver || ver[1] !== "0") {
throw new Error("unknown version");
}
const version = parseFloat(ver[2] + "." + ver[3]);
//if (version < 4.11 || version >= 7) {
if (version < 5.0 || version >= 7.0) {
throw new Error(`unsupported version: ${ver[1]}.${ver[2]}.${ver[3]}`);
}
options = populateOptions(options);
const input = getInput(source, options);
let findImport = (filename) => {
try {
return {
2019-11-20 18:57:38 +09:00
contents: fs.readFileSync(resolve(options.basedir, filename)).toString()
};
}
catch (error) {
return { error: error.message };
}
};
2020-01-29 21:43:56 -05:00
if (version >= 6) {
findImport = { import: findImport };
}
const outputJson = _solc.compile(JSON.stringify(input), findImport);
const output = JSON.parse(outputJson);
const errors = (output.errors || []).filter((x) => (x.severity === "error" || options.throwWarnings)).map((x) => x.formattedMessage);
if (errors.length) {
2020-01-29 21:43:56 -05:00
const error = new Error("compilation error");
error.errors = errors;
throw error;
}
2020-01-29 21:43:56 -05:00
const result = [];
for (let filename in output.contracts) {
for (let name in output.contracts[filename]) {
let contract = output.contracts[filename][name];
2020-01-29 21:43:56 -05:00
// Skip empty contracts
if (!contract.evm.bytecode.object) {
continue;
}
result.push({
name: name,
interface: new ethers.utils.Interface(contract.abi),
bytecode: "0x" + contract.evm.bytecode.object,
2020-01-29 21:43:56 -05:00
runtime: "0x" + contract.evm.deployedBytecode.object,
compiler: compilerVersion
});
}
}
return result;
}
2020-01-29 21:43:56 -05:00
// Creates a require which will first search from the current location,
// and for solc will fallback onto the version included in @ethersproject/cli
export function customRequire(path) {
2020-02-12 15:55:09 -05:00
// Node 8.x does not support createRequireFromPath
const createRequire = (_module.createRequireFromPath || (function (path) {
return require;
}));
const pathRequire = createRequire(resolve(path, "./sandbox.js"));
const libRequire = createRequire(resolve(__filename));
2020-01-29 21:43:56 -05:00
return function (name) {
try {
return pathRequire(name);
}
catch (error) {
if (name === "solc") {
try {
return libRequire(name);
}
catch (error) { }
}
throw error;
}
};
}
export function wrapSolc(_solc) {
return function (source, options) {
return _compile(_solc, source, options || {});
};
}
export const compile = wrapSolc(customRequire(".")("solc"));