Implement new artifacts format
This commit is contained in:
@@ -108,8 +108,8 @@ for (const abiFileName of abiFileNames) {
|
||||
ABI = parsedContent; // ABI file
|
||||
} else if (!_.isUndefined(parsedContent.abi)) {
|
||||
ABI = parsedContent.abi; // Truffle artifact
|
||||
} else if (!_.isUndefined(parsedContent.networks) && !_.isUndefined(parsedContent.networks[args.networkId])) {
|
||||
ABI = parsedContent.networks[args.networkId].abi; // 0x contracts package artifact
|
||||
} else if (!_.isUndefined(parsedContent.compilerOutput.abi)) {
|
||||
ABI = parsedContent.compilerOutput.abi; // 0x artifact
|
||||
}
|
||||
if (_.isUndefined(ABI)) {
|
||||
logUtils.log(`${chalk.red(`ABI not found in ${abiFileName}.`)}`);
|
||||
|
||||
33
packages/contracts/compiler.json
Normal file
33
packages/contracts/compiler.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"artifactsDir": "../migrations/src/artifacts",
|
||||
"contractsDir": "src/contracts",
|
||||
"compilerSettings": {
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"*": [
|
||||
"abi",
|
||||
"evm.bytecode.object",
|
||||
"evm.bytecode.sourceMap",
|
||||
"evm.deployedBytecode.object",
|
||||
"evm.deployedBytecode.sourceMap"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"contracts": [
|
||||
"Exchange",
|
||||
"DummyToken",
|
||||
"ZRXToken",
|
||||
"Token",
|
||||
"WETH9",
|
||||
"TokenTransferProxy",
|
||||
"MultiSigWallet",
|
||||
"MultiSigWalletWithTimeLock",
|
||||
"MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress",
|
||||
"MaliciousToken",
|
||||
"TokenRegistry",
|
||||
"Arbitrage",
|
||||
"EtherDelta",
|
||||
"AccountLevels"
|
||||
]
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
|
||||
"run_mocha": "mocha 'lib/test/**/*.js' --timeout 100000 --bail --exit",
|
||||
"compile:comment": "Yarn workspaces do not link binaries correctly so we need to reference them directly https://github.com/yarnpkg/yarn/issues/3846",
|
||||
"compile": "node ../deployer/lib/src/cli.js compile --contracts ${npm_package_config_contracts} --contracts-dir src/contracts --artifacts-dir ../migrations/src/artifacts",
|
||||
"compile": "node ../deployer/lib/src/cli.js compile",
|
||||
"clean": "shx rm -rf ./lib",
|
||||
"generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis ${npm_package_config_abis} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers && prettier --write 'src/contract_wrappers/generated/**.ts'",
|
||||
"lint": "tslint --project . 'migrations/**/*.ts' 'test/**/*.ts' 'util/**/*.ts' 'deploy/**/*.ts'",
|
||||
@@ -26,8 +26,7 @@
|
||||
"test:circleci": "yarn test:coverage"
|
||||
},
|
||||
"config": {
|
||||
"abis": "../migrations/src/artifacts/@(DummyToken|TokenTransferProxy|Exchange|TokenRegistry|MultiSigWallet|MultiSigWalletWithTimeLock|MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress|TokenRegistry|ZRXToken|Arbitrage|EtherDelta|AccountLevels).json",
|
||||
"contracts": "Exchange,DummyToken,ZRXToken,Token,WETH9,TokenTransferProxy,MultiSigWallet,MultiSigWalletWithTimeLock,MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress,MaliciousToken,TokenRegistry,Arbitrage,EtherDelta,AccountLevels"
|
||||
"abis": "../migrations/src/artifacts/@(DummyToken|TokenTransferProxy|Exchange|TokenRegistry|MultiSigWallet|MultiSigWalletWithTimeLock|MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress|TokenRegistry|ZRXToken|Arbitrage|EtherDelta|AccountLevels).json"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -17,7 +17,7 @@ import { chaiSetup } from './utils/chai_setup';
|
||||
import { deployer } from './utils/deployer';
|
||||
import { provider, web3Wrapper } from './utils/web3_wrapper';
|
||||
|
||||
const MULTI_SIG_ABI = artifacts.MultiSigWalletWithTimeLockArtifact.networks[constants.TESTRPC_NETWORK_ID].abi;
|
||||
const MULTI_SIG_ABI = artifacts.MultiSigWalletWithTimeLockArtifact.compilerOutput.abi;
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
||||
|
||||
@@ -17,10 +17,9 @@ import { ContractName, SubmissionContractEventArgs, TransactionDataParams } from
|
||||
import { chaiSetup } from './utils/chai_setup';
|
||||
import { deployer } from './utils/deployer';
|
||||
import { provider, web3Wrapper } from './utils/web3_wrapper';
|
||||
const PROXY_ABI = artifacts.TokenTransferProxyArtifact.networks[constants.TESTRPC_NETWORK_ID].abi;
|
||||
const PROXY_ABI = artifacts.TokenTransferProxyArtifact.compilerOutput.abi;
|
||||
const MUTISIG_WALLET_WITH_TIME_LOCK_EXCEPT_REMOVE_AUTHORIZED_ADDRESS_ABI =
|
||||
artifacts.MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressArtifact.networks[constants.TESTRPC_NETWORK_ID]
|
||||
.abi;
|
||||
artifacts.MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressArtifact.compilerOutput.abi;
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { ContractArtifact } from '@0xproject/deployer';
|
||||
|
||||
import * as DummyTokenArtifact from '../src/artifacts/DummyToken.json';
|
||||
import * as ExchangeArtifact from '../src/artifacts/Exchange.json';
|
||||
import * as MaliciousTokenArtifact from '../src/artifacts/MaliciousToken.json';
|
||||
@@ -9,17 +11,15 @@ import * as TokenTransferProxyArtifact from '../src/artifacts/TokenTransferProxy
|
||||
import * as EtherTokenArtifact from '../src/artifacts/WETH9.json';
|
||||
import * as ZRXArtifact from '../src/artifacts/ZRXToken.json';
|
||||
|
||||
import { Artifact } from './types';
|
||||
|
||||
export const artifacts = {
|
||||
ZRXArtifact: (ZRXArtifact as any) as Artifact,
|
||||
DummyTokenArtifact: (DummyTokenArtifact as any) as Artifact,
|
||||
TokenArtifact: (TokenArtifact as any) as Artifact,
|
||||
ExchangeArtifact: (ExchangeArtifact as any) as Artifact,
|
||||
EtherTokenArtifact: (EtherTokenArtifact as any) as Artifact,
|
||||
TokenRegistryArtifact: (TokenRegistryArtifact as any) as Artifact,
|
||||
MaliciousTokenArtifact: (MaliciousTokenArtifact as any) as Artifact,
|
||||
TokenTransferProxyArtifact: (TokenTransferProxyArtifact as any) as Artifact,
|
||||
MultiSigWalletWithTimeLockArtifact: (MultiSigWalletWithTimeLockArtifact as any) as Artifact,
|
||||
MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressArtifact: (MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressArtifact as any) as Artifact,
|
||||
ZRXArtifact: (ZRXArtifact as any) as ContractArtifact,
|
||||
DummyTokenArtifact: (DummyTokenArtifact as any) as ContractArtifact,
|
||||
TokenArtifact: (TokenArtifact as any) as ContractArtifact,
|
||||
ExchangeArtifact: (ExchangeArtifact as any) as ContractArtifact,
|
||||
EtherTokenArtifact: (EtherTokenArtifact as any) as ContractArtifact,
|
||||
TokenRegistryArtifact: (TokenRegistryArtifact as any) as ContractArtifact,
|
||||
MaliciousTokenArtifact: (MaliciousTokenArtifact as any) as ContractArtifact,
|
||||
TokenTransferProxyArtifact: (TokenTransferProxyArtifact as any) as ContractArtifact,
|
||||
MultiSigWalletWithTimeLockArtifact: (MultiSigWalletWithTimeLockArtifact as any) as ContractArtifact,
|
||||
MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressArtifact: (MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressArtifact as any) as ContractArtifact,
|
||||
};
|
||||
|
||||
@@ -100,19 +100,3 @@ export enum ContractName {
|
||||
EtherDelta = 'EtherDelta',
|
||||
Arbitrage = 'Arbitrage',
|
||||
}
|
||||
|
||||
export interface Artifact {
|
||||
contract_name: ContractName;
|
||||
networks: {
|
||||
[networkId: number]: {
|
||||
abi: ContractAbi;
|
||||
solc_version: string;
|
||||
keccak256: string;
|
||||
optimizer_enabled: number;
|
||||
unlinked_binary: string;
|
||||
updated_at: number;
|
||||
address: string;
|
||||
constructor_args: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import { constants } from './utils/constants';
|
||||
import { consoleReporter } from './utils/error_reporter';
|
||||
import { CliOptions, CompilerOptions, DeployerOptions } from './utils/types';
|
||||
|
||||
const DEFAULT_OPTIMIZER_ENABLED = false;
|
||||
const DEFAULT_CONTRACTS_DIR = path.resolve('src/contracts');
|
||||
const DEFAULT_ARTIFACTS_DIR = path.resolve('src/artifacts');
|
||||
const DEFAULT_NETWORK_ID = 50;
|
||||
@@ -28,10 +27,8 @@ const DEFAULT_CONTRACTS_LIST = '*';
|
||||
async function onCompileCommandAsync(argv: CliOptions): Promise<void> {
|
||||
const opts: CompilerOptions = {
|
||||
contractsDir: argv.contractsDir,
|
||||
networkId: argv.networkId,
|
||||
optimizerEnabled: argv.shouldOptimize,
|
||||
artifactsDir: argv.artifactsDir,
|
||||
specifiedContracts: getContractsSetFromList(argv.contracts),
|
||||
contracts: argv.contracts === '*' ? argv.contracts : argv.contracts.split(','),
|
||||
};
|
||||
await commands.compileAsync(opts);
|
||||
}
|
||||
@@ -46,10 +43,8 @@ async function onDeployCommandAsync(argv: CliOptions): Promise<void> {
|
||||
const networkId = await web3Wrapper.getNetworkIdAsync();
|
||||
const compilerOpts: CompilerOptions = {
|
||||
contractsDir: argv.contractsDir,
|
||||
networkId,
|
||||
optimizerEnabled: argv.shouldOptimize,
|
||||
artifactsDir: argv.artifactsDir,
|
||||
specifiedContracts: getContractsSetFromList(argv.contracts),
|
||||
contracts: argv.contracts === '*' ? argv.contracts : argv.contracts.split(','),
|
||||
};
|
||||
await commands.compileAsync(compilerOpts);
|
||||
|
||||
@@ -58,7 +53,7 @@ async function onDeployCommandAsync(argv: CliOptions): Promise<void> {
|
||||
from: argv.account,
|
||||
};
|
||||
const deployerOpts: DeployerOptions = {
|
||||
artifactsDir: argv.artifactsDir,
|
||||
artifactsDir: argv.artifactsDir || DEFAULT_ARTIFACTS_DIR,
|
||||
jsonrpcUrl: argv.jsonrpcUrl,
|
||||
networkId,
|
||||
defaults,
|
||||
@@ -67,27 +62,17 @@ async function onDeployCommandAsync(argv: CliOptions): Promise<void> {
|
||||
const deployerArgs = deployerArgsString.split(',');
|
||||
await commands.deployAsync(argv.contract as string, deployerArgs, deployerOpts);
|
||||
}
|
||||
/**
|
||||
* Creates a set of contracts to compile.
|
||||
* @param contracts Comma separated list of contracts to compile
|
||||
*/
|
||||
function getContractsSetFromList(contracts: string): Set<string> {
|
||||
const specifiedContracts = new Set();
|
||||
if (contracts === '*') {
|
||||
return new Set(['*']);
|
||||
}
|
||||
const contractsArray = contracts.split(',');
|
||||
_.forEach(contractsArray, contractName => {
|
||||
specifiedContracts.add(contractName);
|
||||
});
|
||||
return specifiedContracts;
|
||||
}
|
||||
/**
|
||||
* Provides extra required options for deploy command.
|
||||
* @param yargsInstance yargs instance provided in builder function callback.
|
||||
*/
|
||||
function deployCommandBuilder(yargsInstance: any) {
|
||||
return yargsInstance
|
||||
.option('network-id', {
|
||||
type: 'number',
|
||||
default: DEFAULT_NETWORK_ID,
|
||||
description: 'mainnet=1, kovan=42, testrpc=50',
|
||||
})
|
||||
.option('contract', {
|
||||
type: 'string',
|
||||
description: 'name of contract to deploy, exluding .sol extension',
|
||||
@@ -96,7 +81,35 @@ function deployCommandBuilder(yargsInstance: any) {
|
||||
type: 'string',
|
||||
description: 'comma separated list of constructor args to deploy contract with',
|
||||
})
|
||||
.demandOption(['contract', 'args'])
|
||||
.option('jsonrpc-url', {
|
||||
type: 'string',
|
||||
default: DEFAULT_JSONRPC_URL,
|
||||
description: 'url of JSON RPC',
|
||||
})
|
||||
.option('account', {
|
||||
type: 'string',
|
||||
description: 'account to use for deploying contracts',
|
||||
})
|
||||
.option('gas-price', {
|
||||
type: 'string',
|
||||
default: DEFAULT_GAS_PRICE,
|
||||
description: 'gasPrice to be used for transactions',
|
||||
})
|
||||
.demandOption(['contract', 'args', 'account'])
|
||||
.help().argv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides extra required options for compile command.
|
||||
* @param yargsInstance yargs instance provided in builder function callback.
|
||||
*/
|
||||
function compileCommandBuilder(yargsInstance: any) {
|
||||
return yargsInstance
|
||||
.option('contracts', {
|
||||
type: 'string',
|
||||
default: DEFAULT_CONTRACTS_LIST,
|
||||
description: 'comma separated list of contracts to compile',
|
||||
})
|
||||
.help().argv;
|
||||
}
|
||||
|
||||
@@ -105,44 +118,14 @@ function deployCommandBuilder(yargsInstance: any) {
|
||||
return yargs
|
||||
.option('contracts-dir', {
|
||||
type: 'string',
|
||||
default: DEFAULT_CONTRACTS_DIR,
|
||||
description: 'path of contracts directory to compile',
|
||||
})
|
||||
.option('network-id', {
|
||||
type: 'number',
|
||||
default: DEFAULT_NETWORK_ID,
|
||||
description: 'mainnet=1, kovan=42, testrpc=50',
|
||||
})
|
||||
.option('should-optimize', {
|
||||
type: 'boolean',
|
||||
default: DEFAULT_OPTIMIZER_ENABLED,
|
||||
description: 'enable optimizer',
|
||||
})
|
||||
.option('artifacts-dir', {
|
||||
type: 'string',
|
||||
default: DEFAULT_ARTIFACTS_DIR,
|
||||
description: 'path to write contracts artifacts to',
|
||||
})
|
||||
.option('jsonrpc-url', {
|
||||
type: 'string',
|
||||
default: DEFAULT_JSONRPC_URL,
|
||||
description: 'url of JSON RPC',
|
||||
})
|
||||
.option('gas-price', {
|
||||
type: 'string',
|
||||
default: DEFAULT_GAS_PRICE,
|
||||
description: 'gasPrice to be used for transactions',
|
||||
})
|
||||
.option('account', {
|
||||
type: 'string',
|
||||
description: 'account to use for deploying contracts',
|
||||
})
|
||||
.option('contracts', {
|
||||
type: 'string',
|
||||
default: DEFAULT_CONTRACTS_LIST,
|
||||
description: 'comma separated list of contracts to compile',
|
||||
})
|
||||
.command('compile', 'compile contracts', identityCommandBuilder, consoleReporter(onCompileCommandAsync))
|
||||
.demandCommand(1)
|
||||
.command('compile', 'compile contracts', compileCommandBuilder, consoleReporter(onCompileCommandAsync))
|
||||
.command(
|
||||
'deploy',
|
||||
'deploy a single contract with provided arguments',
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
FSResolver,
|
||||
NameResolver,
|
||||
NPMResolver,
|
||||
RelativeFSResolver,
|
||||
Resolver,
|
||||
URLResolver,
|
||||
} from '@0xproject/sol-resolver';
|
||||
@@ -38,11 +39,25 @@ import {
|
||||
ContractNetworks,
|
||||
ContractSourceData,
|
||||
ContractSpecificSourceData,
|
||||
ContractVersionData,
|
||||
} from './utils/types';
|
||||
import { utils } from './utils/utils';
|
||||
|
||||
const ALL_CONTRACTS_IDENTIFIER = '*';
|
||||
const SOLC_BIN_DIR = path.join(__dirname, '..', '..', 'solc_bin');
|
||||
const DEFAULT_CONTRACTS_DIR = path.resolve('contracts');
|
||||
const DEFAULT_ARTIFACTS_DIR = path.resolve('artifacts');
|
||||
const DEFAULT_COMPILER_SETTINGS: solc.CompilerSettings = {
|
||||
optimizer: {
|
||||
enabled: false,
|
||||
},
|
||||
outputSelection: {
|
||||
'*': {
|
||||
'*': ['abi', 'evm.bytecode.object'],
|
||||
},
|
||||
},
|
||||
};
|
||||
const CONFIG_FILE = 'compiler.json';
|
||||
|
||||
/**
|
||||
* The Compiler facilitates compiling Solidity smart contracts and saves the results
|
||||
@@ -52,26 +67,27 @@ export class Compiler {
|
||||
private _resolver: Resolver;
|
||||
private _nameResolver: NameResolver;
|
||||
private _contractsDir: string;
|
||||
private _networkId: number;
|
||||
private _optimizerEnabled: boolean;
|
||||
private _compilerSettings: solc.CompilerSettings;
|
||||
private _artifactsDir: string;
|
||||
private _specifiedContracts: Set<string> = new Set();
|
||||
private _specifiedContracts: string[] | '*';
|
||||
/**
|
||||
* Instantiates a new instance of the Compiler class.
|
||||
* @param opts Options specifying directories, network, and optimization settings.
|
||||
* @return An instance of the Compiler class.
|
||||
*/
|
||||
constructor(opts: CompilerOptions) {
|
||||
this._contractsDir = opts.contractsDir;
|
||||
this._networkId = opts.networkId;
|
||||
this._optimizerEnabled = opts.optimizerEnabled;
|
||||
this._artifactsDir = opts.artifactsDir;
|
||||
this._specifiedContracts = opts.specifiedContracts;
|
||||
const config: CompilerOptions = fs.existsSync(CONFIG_FILE)
|
||||
? JSON.parse(fs.readFileSync(CONFIG_FILE).toString())
|
||||
: {};
|
||||
this._contractsDir = opts.contractsDir || config.contractsDir || DEFAULT_CONTRACTS_DIR;
|
||||
this._compilerSettings = opts.compilerSettings || config.compilerSettings || DEFAULT_COMPILER_SETTINGS;
|
||||
this._artifactsDir = opts.artifactsDir || config.artifactsDir || DEFAULT_ARTIFACTS_DIR;
|
||||
this._specifiedContracts = opts.contracts || config.contracts || '*';
|
||||
this._nameResolver = new NameResolver(path.resolve(this._contractsDir));
|
||||
const resolver = new FallthroughResolver();
|
||||
resolver.appendResolver(new URLResolver());
|
||||
const packagePath = path.resolve('');
|
||||
resolver.appendResolver(new NPMResolver(packagePath));
|
||||
resolver.appendResolver(new RelativeFSResolver(this._contractsDir));
|
||||
resolver.appendResolver(new FSResolver());
|
||||
resolver.appendResolver(this._nameResolver);
|
||||
this._resolver = resolver;
|
||||
@@ -83,13 +99,13 @@ export class Compiler {
|
||||
await createDirIfDoesNotExistAsync(this._artifactsDir);
|
||||
await createDirIfDoesNotExistAsync(SOLC_BIN_DIR);
|
||||
let contractNamesToCompile: string[] = [];
|
||||
if (this._specifiedContracts.has(ALL_CONTRACTS_IDENTIFIER)) {
|
||||
if (this._specifiedContracts === ALL_CONTRACTS_IDENTIFIER) {
|
||||
const allContracts = this._nameResolver.getAll();
|
||||
contractNamesToCompile = _.map(allContracts, contractSource =>
|
||||
path.basename(contractSource.path, constants.SOLIDITY_FILE_EXTENSION),
|
||||
);
|
||||
} else {
|
||||
contractNamesToCompile = Array.from(this._specifiedContracts.values());
|
||||
contractNamesToCompile = this._specifiedContracts;
|
||||
}
|
||||
for (const contractNameToCompile of contractNamesToCompile) {
|
||||
await this._compileContractAsync(contractNameToCompile);
|
||||
@@ -101,17 +117,18 @@ export class Compiler {
|
||||
*/
|
||||
private async _compileContractAsync(contractName: string): Promise<void> {
|
||||
const contractSource = this._resolver.resolve(contractName);
|
||||
const absoluteContractPath = path.join(this._contractsDir, contractSource.path);
|
||||
const currentArtifactIfExists = await getContractArtifactIfExistsAsync(this._artifactsDir, contractName);
|
||||
const sourceTreeHashHex = `0x${this._getSourceTreeHash(contractSource.path).toString('hex')}`;
|
||||
|
||||
const sourceTreeHashHex = `0x${this._getSourceTreeHash(absoluteContractPath).toString('hex')}`;
|
||||
let shouldCompile = false;
|
||||
if (_.isUndefined(currentArtifactIfExists)) {
|
||||
shouldCompile = true;
|
||||
} else {
|
||||
const currentArtifact = currentArtifactIfExists as ContractArtifact;
|
||||
shouldCompile =
|
||||
currentArtifact.networks[this._networkId].optimizer_enabled !== this._optimizerEnabled ||
|
||||
currentArtifact.networks[this._networkId].source_tree_hash !== sourceTreeHashHex;
|
||||
currentArtifact.schemaVersion !== '2.0.0' ||
|
||||
!_.isEqual(currentArtifact.compiler.settings, this._compilerSettings) ||
|
||||
currentArtifact.sourceTreeHashHex !== sourceTreeHashHex;
|
||||
}
|
||||
if (!shouldCompile) {
|
||||
return;
|
||||
@@ -139,30 +156,14 @@ export class Compiler {
|
||||
|
||||
logUtils.log(`Compiling ${contractName} with Solidity v${solcVersion}...`);
|
||||
const source = contractSource.source;
|
||||
const absoluteFilePath = contractSource.path;
|
||||
const standardInput: solc.StandardInput = {
|
||||
language: 'Solidity',
|
||||
sources: {
|
||||
[absoluteFilePath]: {
|
||||
urls: [`file://${absoluteFilePath}`],
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
optimizer: {
|
||||
enabled: this._optimizerEnabled,
|
||||
},
|
||||
outputSelection: {
|
||||
'*': {
|
||||
'*': [
|
||||
'abi',
|
||||
'evm.bytecode.object',
|
||||
'evm.bytecode.sourceMap',
|
||||
'evm.deployedBytecode.object',
|
||||
'evm.deployedBytecode.sourceMap',
|
||||
],
|
||||
},
|
||||
[contractSource.path]: {
|
||||
content: contractSource.source,
|
||||
},
|
||||
},
|
||||
settings: this._compilerSettings,
|
||||
};
|
||||
const compiled: solc.StandardOutput = JSON.parse(
|
||||
solcInstance.compileStandardWrapper(JSON.stringify(standardInput), importPath => {
|
||||
@@ -188,34 +189,28 @@ export class Compiler {
|
||||
});
|
||||
}
|
||||
}
|
||||
const compiledData = compiled.contracts[absoluteFilePath][contractName];
|
||||
const compiledData = compiled.contracts[contractSource.path][contractName];
|
||||
if (_.isUndefined(compiledData)) {
|
||||
throw new Error(
|
||||
`Contract ${contractName} not found in ${absoluteFilePath}. Please make sure your contract has the same name as it's file name`,
|
||||
`Contract ${contractName} not found in ${
|
||||
contractSource.path
|
||||
}. Please make sure your contract has the same name as it's file name`,
|
||||
);
|
||||
}
|
||||
const abi: ContractAbi = compiledData.abi;
|
||||
const bytecode = `0x${compiledData.evm.bytecode.object}`;
|
||||
const runtimeBytecode = `0x${compiledData.evm.deployedBytecode.object}`;
|
||||
const sourceMap = compiledData.evm.bytecode.sourceMap;
|
||||
const sourceMapRuntime = compiledData.evm.deployedBytecode.sourceMap;
|
||||
const unresolvedSourcePaths = _.keys(compiled.sources);
|
||||
const sources = _.map(
|
||||
unresolvedSourcePaths,
|
||||
unresolvedSourcePath => this._resolver.resolve(unresolvedSourcePath).path,
|
||||
const sourceCodes = _.mapValues(
|
||||
compiled.sources,
|
||||
(_1, sourceFilePath) => this._resolver.resolve(sourceFilePath).source,
|
||||
);
|
||||
const updated_at = Date.now();
|
||||
const contractNetworkData: ContractNetworkData = {
|
||||
solc_version: solcVersion,
|
||||
source_tree_hash: sourceTreeHashHex,
|
||||
optimizer_enabled: this._optimizerEnabled,
|
||||
abi,
|
||||
bytecode,
|
||||
runtime_bytecode: runtimeBytecode,
|
||||
updated_at,
|
||||
source_map: sourceMap,
|
||||
source_map_runtime: sourceMapRuntime,
|
||||
sources,
|
||||
const contractVersion: ContractVersionData = {
|
||||
compilerOutput: compiledData,
|
||||
sources: compiled.sources,
|
||||
sourceCodes,
|
||||
sourceTreeHashHex,
|
||||
compiler: {
|
||||
name: 'solc',
|
||||
version: solcVersion,
|
||||
settings: this._compilerSettings,
|
||||
},
|
||||
};
|
||||
|
||||
let newArtifact: ContractArtifact;
|
||||
@@ -223,17 +218,14 @@ export class Compiler {
|
||||
const currentArtifact = currentArtifactIfExists as ContractArtifact;
|
||||
newArtifact = {
|
||||
...currentArtifact,
|
||||
networks: {
|
||||
...currentArtifact.networks,
|
||||
[this._networkId]: contractNetworkData,
|
||||
},
|
||||
...contractVersion,
|
||||
};
|
||||
} else {
|
||||
newArtifact = {
|
||||
contract_name: contractName,
|
||||
networks: {
|
||||
[this._networkId]: contractNetworkData,
|
||||
},
|
||||
schemaVersion: '2.0.0',
|
||||
contractName,
|
||||
...contractVersion,
|
||||
networks: {},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { AbiType, ConstructorAbi, ContractAbi, Provider, TxData } from '@0xproje
|
||||
import { logUtils } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import * as _ from 'lodash';
|
||||
import * as solc from 'solc';
|
||||
import * as Web3 from 'web3';
|
||||
|
||||
import { Contract } from './utils/contract';
|
||||
@@ -28,7 +29,20 @@ export class Deployer {
|
||||
private _artifactsDir: string;
|
||||
private _networkId: number;
|
||||
private _defaults: Partial<TxData>;
|
||||
|
||||
/**
|
||||
* Gets data for current version stored in artifact.
|
||||
* @param contractArtifact The contract artifact.
|
||||
* @return Version specific contract data.
|
||||
*/
|
||||
private static _getContractCompilerOutputFromArtifactIfExists(
|
||||
contractArtifact: ContractArtifact,
|
||||
): solc.StandardContractOutput {
|
||||
const compilerOutputIfExists = contractArtifact.compilerOutput;
|
||||
if (_.isUndefined(compilerOutputIfExists)) {
|
||||
throw new Error(`Compiler output not found in artifact for contract: ${contractArtifact.contractName}`);
|
||||
}
|
||||
return compilerOutputIfExists;
|
||||
}
|
||||
/**
|
||||
* Instantiate a new instance of the Deployer class.
|
||||
* @param opts Deployer options, including either an RPC url or Provider instance.
|
||||
@@ -58,10 +72,8 @@ export class Deployer {
|
||||
*/
|
||||
public async deployAsync(contractName: string, args: any[] = []): Promise<Web3.ContractInstance> {
|
||||
const contractArtifactIfExists: ContractArtifact = this._loadContractArtifactIfExists(contractName);
|
||||
const contractNetworkDataIfExists: ContractNetworkData = this._getContractNetworkDataFromArtifactIfExists(
|
||||
contractArtifactIfExists,
|
||||
);
|
||||
const data = contractNetworkDataIfExists.bytecode;
|
||||
const compilerOutput = Deployer._getContractCompilerOutputFromArtifactIfExists(contractArtifactIfExists);
|
||||
const data = compilerOutput.evm.bytecode.object;
|
||||
const from = await this._getFromAddressAsync();
|
||||
const gas = await this._getAllowableGasEstimateAsync(data);
|
||||
const txData = {
|
||||
@@ -70,7 +82,7 @@ export class Deployer {
|
||||
data,
|
||||
gas,
|
||||
};
|
||||
const abi = contractNetworkDataIfExists.abi;
|
||||
const abi = compilerOutput.abi;
|
||||
const constructorAbi = _.find(abi, { type: AbiType.Constructor }) as ConstructorAbi;
|
||||
const constructorArgs = _.isUndefined(constructorAbi) ? [] : constructorAbi.inputs;
|
||||
if (constructorArgs.length !== args.length) {
|
||||
@@ -138,15 +150,13 @@ export class Deployer {
|
||||
args: any[],
|
||||
): Promise<void> {
|
||||
const contractArtifactIfExists: ContractArtifact = this._loadContractArtifactIfExists(contractName);
|
||||
const contractNetworkDataIfExists: ContractNetworkData = this._getContractNetworkDataFromArtifactIfExists(
|
||||
contractArtifactIfExists,
|
||||
);
|
||||
const abi = contractNetworkDataIfExists.abi;
|
||||
const compilerOutput = Deployer._getContractCompilerOutputFromArtifactIfExists(contractArtifactIfExists);
|
||||
const abi = compilerOutput.abi;
|
||||
const encodedConstructorArgs = encoder.encodeConstructorArgsFromAbi(args, abi);
|
||||
const newContractData = {
|
||||
...contractNetworkDataIfExists,
|
||||
const newContractData: ContractNetworkData = {
|
||||
address: contractAddress,
|
||||
constructor_args: encodedConstructorArgs,
|
||||
links: {},
|
||||
constructorArgs: encodedConstructorArgs,
|
||||
};
|
||||
const newArtifact = {
|
||||
...contractArtifactIfExists,
|
||||
@@ -173,18 +183,6 @@ export class Deployer {
|
||||
throw new Error(`Artifact not found for contract: ${contractName} at ${artifactPath}`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Gets data for current networkId stored in artifact.
|
||||
* @param contractArtifact The contract artifact.
|
||||
* @return Network specific contract data.
|
||||
*/
|
||||
private _getContractNetworkDataFromArtifactIfExists(contractArtifact: ContractArtifact): ContractNetworkData {
|
||||
const contractNetworkDataIfExists = contractArtifact.networks[this._networkId];
|
||||
if (_.isUndefined(contractNetworkDataIfExists)) {
|
||||
throw new Error(`Data not found in artifact for contract: ${contractArtifact.contract_name}`);
|
||||
}
|
||||
return contractNetworkDataIfExists;
|
||||
}
|
||||
/**
|
||||
* Gets the address to use for sending a transaction.
|
||||
* @return The default from address. If not specified, returns the first address accessible by web3.
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export { Deployer } from './deployer';
|
||||
export { Compiler } from './compiler';
|
||||
export { ContractArtifact, ContractNetworks } from './utils/types';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ContractAbi, Provider, TxData } from '@0xproject/types';
|
||||
import * as solc from 'solc';
|
||||
import * as Web3 from 'web3';
|
||||
import * as yargs from 'yargs';
|
||||
|
||||
@@ -9,28 +10,40 @@ export enum AbiType {
|
||||
Fallback = 'fallback',
|
||||
}
|
||||
|
||||
export interface ContractArtifact {
|
||||
contract_name: string;
|
||||
export interface ContractArtifact extends ContractVersionData {
|
||||
schemaVersion: '2.0.0';
|
||||
contractName: string;
|
||||
networks: ContractNetworks;
|
||||
}
|
||||
|
||||
export interface ContractVersionData {
|
||||
compiler: {
|
||||
name: 'solc';
|
||||
version: string;
|
||||
settings: solc.CompilerSettings;
|
||||
};
|
||||
sources: {
|
||||
[sourceName: string]: {
|
||||
id: number;
|
||||
};
|
||||
};
|
||||
sourceCodes: {
|
||||
[sourceName: string]: string;
|
||||
};
|
||||
sourceTreeHashHex: string;
|
||||
compilerOutput: solc.StandardContractOutput;
|
||||
}
|
||||
|
||||
export interface ContractNetworks {
|
||||
[key: number]: ContractNetworkData;
|
||||
[networkId: number]: ContractNetworkData;
|
||||
}
|
||||
|
||||
export interface ContractNetworkData {
|
||||
solc_version: string;
|
||||
optimizer_enabled: boolean;
|
||||
source_tree_hash: string;
|
||||
abi: ContractAbi;
|
||||
bytecode: string;
|
||||
runtime_bytecode: string;
|
||||
address?: string;
|
||||
constructor_args?: string;
|
||||
updated_at: number;
|
||||
source_map: string;
|
||||
source_map_runtime: string;
|
||||
sources: string[];
|
||||
address: string;
|
||||
links: {
|
||||
[linkName: string]: string;
|
||||
};
|
||||
constructorArgs: string;
|
||||
}
|
||||
|
||||
export interface SolcErrors {
|
||||
@@ -42,7 +55,6 @@ export interface CliOptions extends yargs.Arguments {
|
||||
contractsDir: string;
|
||||
jsonrpcUrl: string;
|
||||
networkId: number;
|
||||
shouldOptimize: boolean;
|
||||
gasPrice: string;
|
||||
account?: string;
|
||||
contract?: string;
|
||||
@@ -50,11 +62,10 @@ export interface CliOptions extends yargs.Arguments {
|
||||
}
|
||||
|
||||
export interface CompilerOptions {
|
||||
contractsDir: string;
|
||||
networkId: number;
|
||||
optimizerEnabled: boolean;
|
||||
artifactsDir: string;
|
||||
specifiedContracts: Set<string>;
|
||||
contractsDir?: string;
|
||||
artifactsDir?: string;
|
||||
compilerSettings?: solc.CompilerSettings;
|
||||
contracts?: string[] | '*';
|
||||
}
|
||||
|
||||
export interface BaseDeployerOptions {
|
||||
|
||||
@@ -18,9 +18,7 @@ describe('#Compiler', function() {
|
||||
const compilerOpts: CompilerOptions = {
|
||||
artifactsDir,
|
||||
contractsDir,
|
||||
networkId: constants.networkId,
|
||||
optimizerEnabled: constants.optimizerEnabled,
|
||||
specifiedContracts: new Set(constants.specifiedContracts),
|
||||
contracts: constants.contracts,
|
||||
};
|
||||
const compiler = new Compiler(compilerOpts);
|
||||
beforeEach((done: DoneCallback) => {
|
||||
@@ -38,9 +36,8 @@ describe('#Compiler', function() {
|
||||
};
|
||||
const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts);
|
||||
const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString);
|
||||
const exchangeContractData: ContractNetworkData = exchangeArtifact.networks[constants.networkId];
|
||||
// The last 43 bytes of the binaries are metadata which may not be equivalent
|
||||
const unlinkedBinaryWithoutMetadata = exchangeContractData.bytecode.slice(0, -86);
|
||||
const unlinkedBinaryWithoutMetadata = exchangeArtifact.compilerOutput.evm.bytecode.object.slice(0, -86);
|
||||
const exchangeBinaryWithoutMetadata = exchange_binary.slice(0, -86);
|
||||
expect(unlinkedBinaryWithoutMetadata).to.equal(exchangeBinaryWithoutMetadata);
|
||||
});
|
||||
|
||||
@@ -19,9 +19,7 @@ describe('#Deployer', () => {
|
||||
const compilerOpts: CompilerOptions = {
|
||||
artifactsDir,
|
||||
contractsDir,
|
||||
networkId: constants.networkId,
|
||||
optimizerEnabled: constants.optimizerEnabled,
|
||||
specifiedContracts: new Set(constants.specifiedContracts),
|
||||
contracts: constants.contracts,
|
||||
};
|
||||
const compiler = new Compiler(compilerOpts);
|
||||
const deployerOpts = {
|
||||
@@ -55,8 +53,7 @@ describe('#Deployer', () => {
|
||||
const exchangeContractData: ContractNetworkData = exchangeArtifact.networks[constants.networkId];
|
||||
const exchangeAddress = exchangeContractInstance.address;
|
||||
expect(exchangeAddress).to.not.equal(undefined);
|
||||
expect(exchangeContractData.address).to.equal(undefined);
|
||||
expect(exchangeContractData.constructor_args).to.equal(undefined);
|
||||
expect(exchangeContractData).to.equal(undefined);
|
||||
});
|
||||
});
|
||||
describe('#deployAndSaveAsync', () => {
|
||||
@@ -71,7 +68,7 @@ describe('#Deployer', () => {
|
||||
const exchangeContractData: ContractNetworkData = exchangeArtifact.networks[constants.networkId];
|
||||
const exchangeAddress = exchangeContractInstance.address;
|
||||
expect(exchangeAddress).to.be.equal(exchangeContractData.address);
|
||||
expect(constructor_args).to.be.equal(exchangeContractData.constructor_args);
|
||||
expect(constructor_args).to.be.equal(exchangeContractData.constructorArgs);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -7,5 +7,5 @@ export const constants = {
|
||||
timeoutMs: 30000,
|
||||
zrxTokenAddress: '0xe41d2489571d322189246dafa5ebde1f4699f498',
|
||||
tokenTransferProxyAddress: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4',
|
||||
specifiedContracts: '*',
|
||||
contracts: '*' as '*',
|
||||
};
|
||||
|
||||
15
packages/metacoin/compiler.json
Normal file
15
packages/metacoin/compiler.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"compilerSettings": {
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"*": [
|
||||
"abi",
|
||||
"evm.bytecode.object",
|
||||
"evm.bytecode.sourceMap",
|
||||
"evm.deployedBytecode.object",
|
||||
"evm.deployedBytecode.sourceMap"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,13 +12,13 @@
|
||||
"build": "tsc",
|
||||
"test": "run-s build run_mocha",
|
||||
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
|
||||
"run_mocha": "mocha lib/test/**/*.js --bail --exit",
|
||||
"run_mocha": "mocha lib/test/**/*_test.js lib/test/global_hooks.js --bail --exit",
|
||||
"generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'artifacts/Metacoin.json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers --backend ethers && prettier --write 'src/contract_wrappers/**.ts'",
|
||||
"coverage:report:text": "istanbul report text",
|
||||
"coverage:report:html": "istanbul report html && open coverage/index.html",
|
||||
"coverage:report:lcov": "istanbul report lcov",
|
||||
"test:circleci": "yarn test:coverage",
|
||||
"compile": "node ../deployer/lib/src/cli.js compile --contracts Metacoin --contracts-dir contracts --artifacts-dir artifacts"
|
||||
"compile": "node ../deployer/lib/src/cli.js compile"
|
||||
},
|
||||
"author": "",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -8,25 +8,22 @@ import { ContractData } from './types';
|
||||
export const collectContractsData = (artifactsPath: string, sourcesPath: string, networkId: number) => {
|
||||
const artifactsGlob = `${artifactsPath}/**/*.json`;
|
||||
const artifactFileNames = glob.sync(artifactsGlob, { absolute: true });
|
||||
const contractsDataIfExists: Array<ContractData | {}> = _.map(artifactFileNames, artifactFileName => {
|
||||
const contractsData: ContractData[] = [];
|
||||
_.forEach(artifactFileNames, artifactFileName => {
|
||||
const artifact = JSON.parse(fs.readFileSync(artifactFileName).toString());
|
||||
const sources = artifact.networks[networkId].sources;
|
||||
const contractName = artifact.contract_name;
|
||||
const sources = _.keys(artifact.sources);
|
||||
const contractName = artifact.contractName;
|
||||
// We don't compute coverage for dependencies
|
||||
const sourceCodes = _.map(sources, (source: string) => fs.readFileSync(source).toString());
|
||||
if (_.isUndefined(artifact.networks[networkId])) {
|
||||
throw new Error(`No ${contractName} artifacts found for networkId ${networkId}`);
|
||||
}
|
||||
const contractData = {
|
||||
sourceCodes,
|
||||
sources,
|
||||
sourceMap: artifact.networks[networkId].source_map,
|
||||
sourceMapRuntime: artifact.networks[networkId].source_map_runtime,
|
||||
runtimeBytecode: artifact.networks[networkId].runtime_bytecode,
|
||||
bytecode: artifact.networks[networkId].bytecode,
|
||||
bytecode: artifact.compilerOutput.evm.bytecode.object,
|
||||
sourceMap: artifact.compilerOutput.evm.bytecode.sourceMap,
|
||||
runtimeBytecode: artifact.compilerOutput.evm.deployedBytecode.object,
|
||||
sourceMapRuntime: artifact.compilerOutput.evm.deployedBytecode.sourceMap,
|
||||
};
|
||||
return contractData;
|
||||
contractsData.push(contractData);
|
||||
});
|
||||
const contractsData = _.filter(contractsDataIfExists, contractData => !_.isEmpty(contractData)) as ContractData[];
|
||||
return contractsData;
|
||||
};
|
||||
|
||||
@@ -130,7 +130,10 @@ export class CoverageManager {
|
||||
for (const traceInfo of this._traceInfos) {
|
||||
if (traceInfo.address !== constants.NEW_CONTRACT) {
|
||||
// Runtime transaction
|
||||
const runtimeBytecode = (traceInfo as TraceInfoExistingContract).runtimeBytecode;
|
||||
let runtimeBytecode = (traceInfo as TraceInfoExistingContract).runtimeBytecode;
|
||||
if (runtimeBytecode.startsWith('0x')) {
|
||||
runtimeBytecode = runtimeBytecode.slice(2);
|
||||
}
|
||||
const contractData = _.find(this._contractsData, { runtimeBytecode }) as ContractData;
|
||||
if (_.isUndefined(contractData)) {
|
||||
throw new Error(`Transaction to an unknown address: ${traceInfo.address}`);
|
||||
@@ -154,7 +157,10 @@ export class CoverageManager {
|
||||
}
|
||||
} else {
|
||||
// Contract creation transaction
|
||||
const bytecode = (traceInfo as TraceInfoNewContract).bytecode;
|
||||
let bytecode = (traceInfo as TraceInfoNewContract).bytecode;
|
||||
if (bytecode.startsWith('0x')) {
|
||||
bytecode = bytecode.slice(2);
|
||||
}
|
||||
const contractData = _.find(this._contractsData, contractDataCandidate =>
|
||||
bytecode.startsWith(contractDataCandidate.bytecode),
|
||||
) as ContractData;
|
||||
|
||||
@@ -3,6 +3,7 @@ export { FallthroughResolver } from './resolvers/fallthrough_resolver';
|
||||
export { URLResolver } from './resolvers/url_resolver';
|
||||
export { NPMResolver } from './resolvers/npm_resolver';
|
||||
export { FSResolver } from './resolvers/fs_resolver';
|
||||
export { RelativeFSResolver } from './resolvers/relative_fs_resolver';
|
||||
export { NameResolver } from './resolvers/name_resolver';
|
||||
export { EnumerableResolver } from './resolvers/enumerable_resolver';
|
||||
export { Resolver } from './resolvers/resolver';
|
||||
|
||||
@@ -18,7 +18,7 @@ export class NameResolver extends EnumerableResolver {
|
||||
const onFile = (filePath: string) => {
|
||||
const contractName = path.basename(filePath, SOLIDITY_FILE_EXTENSION);
|
||||
if (contractName === lookupContractName) {
|
||||
const source = fs.readFileSync(filePath).toString();
|
||||
const source = fs.readFileSync(path.join(this._contractsDir, filePath)).toString();
|
||||
contractSource = {
|
||||
source,
|
||||
path: filePath,
|
||||
@@ -35,7 +35,7 @@ export class NameResolver extends EnumerableResolver {
|
||||
const contractSources: ContractSource[] = [];
|
||||
const onFile = (filePath: string) => {
|
||||
const contractName = path.basename(filePath, SOLIDITY_FILE_EXTENSION);
|
||||
const source = fs.readFileSync(filePath).toString();
|
||||
const source = fs.readFileSync(path.join(this._contractsDir, filePath)).toString();
|
||||
const contractSource = {
|
||||
source,
|
||||
path: filePath,
|
||||
@@ -54,9 +54,10 @@ export class NameResolver extends EnumerableResolver {
|
||||
throw new Error(`No directory found at ${dirPath}`);
|
||||
}
|
||||
for (const fileName of dirContents) {
|
||||
const entryPath = path.join(dirPath, fileName);
|
||||
const isDirectory = fs.lstatSync(entryPath).isDirectory();
|
||||
const isComplete = isDirectory ? this._traverseContractsDir(entryPath, onFile) : onFile(entryPath);
|
||||
const absoluteEntryPath = path.join(dirPath, fileName);
|
||||
const isDirectory = fs.lstatSync(absoluteEntryPath).isDirectory();
|
||||
const entryPath = path.relative(this._contractsDir, absoluteEntryPath);
|
||||
const isComplete = isDirectory ? this._traverseContractsDir(absoluteEntryPath, onFile) : onFile(entryPath);
|
||||
if (isComplete) {
|
||||
return isComplete;
|
||||
}
|
||||
|
||||
26
packages/sol-resolver/src/resolvers/relative_fs_resolver.ts
Normal file
26
packages/sol-resolver/src/resolvers/relative_fs_resolver.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
import { ContractSource } from '../types';
|
||||
|
||||
import { Resolver } from './resolver';
|
||||
|
||||
export class RelativeFSResolver extends Resolver {
|
||||
private _contractsDir: string;
|
||||
constructor(contractsDir: string) {
|
||||
super();
|
||||
this._contractsDir = contractsDir;
|
||||
}
|
||||
// tslint:disable-next-line:prefer-function-over-method
|
||||
public resolveIfExists(importPath: string): ContractSource | undefined {
|
||||
const filePath = path.join(this._contractsDir, importPath);
|
||||
if (fs.existsSync(filePath)) {
|
||||
const fileContent = fs.readFileSync(filePath).toString();
|
||||
return {
|
||||
source: fileContent,
|
||||
path: importPath,
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -59,12 +59,7 @@ declare module 'solc' {
|
||||
| 'evm.gasEstimates'
|
||||
| 'ewasm.wast'
|
||||
| 'ewasm.wasm';
|
||||
export interface StandardInput {
|
||||
language: 'Solidity' | 'serpent' | 'lll' | 'assembly';
|
||||
sources: {
|
||||
[fileName: string]: Source;
|
||||
};
|
||||
settings: {
|
||||
export interface CompilerSettings {
|
||||
remappings?: string[];
|
||||
optimizer?: {
|
||||
enabled: boolean;
|
||||
@@ -84,7 +79,13 @@ declare module 'solc' {
|
||||
[contractName: string]: OutputField[];
|
||||
};
|
||||
};
|
||||
}
|
||||
export interface StandardInput {
|
||||
language: 'Solidity' | 'serpent' | 'lll' | 'assembly';
|
||||
sources: {
|
||||
[fileName: string]: Source;
|
||||
};
|
||||
settings: CompilerSettings;
|
||||
}
|
||||
export type ErrorType =
|
||||
| 'JSONError'
|
||||
@@ -114,18 +115,7 @@ declare module 'solc' {
|
||||
formattedMessage?: string;
|
||||
}
|
||||
import { ContractAbi } from '@0xproject/types';
|
||||
export interface StandardOutput {
|
||||
errors: Error[];
|
||||
sources: {
|
||||
[fileName: string]: {
|
||||
id: number;
|
||||
ast?: object;
|
||||
legacyAST?: object;
|
||||
};
|
||||
};
|
||||
contracts: {
|
||||
[fileName: string]: {
|
||||
[contractName: string]: {
|
||||
export interface StandardContractOutput {
|
||||
abi: ContractAbi;
|
||||
evm: {
|
||||
bytecode: {
|
||||
@@ -137,8 +127,20 @@ declare module 'solc' {
|
||||
sourceMap: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
export interface StandardOutput {
|
||||
errors: Error[];
|
||||
sources: {
|
||||
[fileName: string]: {
|
||||
id: number;
|
||||
ast?: object;
|
||||
legacyAST?: object;
|
||||
};
|
||||
};
|
||||
contracts: {
|
||||
[fileName: string]: {
|
||||
[contractName: string]: StandardContractOutput;
|
||||
};
|
||||
};
|
||||
}
|
||||
export interface SolcInstance {
|
||||
|
||||
Reference in New Issue
Block a user