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,32 +59,33 @@ declare module 'solc' {
 | 
			
		||||
        | 'evm.gasEstimates'
 | 
			
		||||
        | 'ewasm.wast'
 | 
			
		||||
        | 'ewasm.wasm';
 | 
			
		||||
    export interface CompilerSettings {
 | 
			
		||||
        remappings?: string[];
 | 
			
		||||
        optimizer?: {
 | 
			
		||||
            enabled: boolean;
 | 
			
		||||
            runs?: number;
 | 
			
		||||
        };
 | 
			
		||||
        evmVersion?: 'homestead' | 'tangerineWhistle' | 'spuriousDragon' | 'byzantium' | 'constantinople';
 | 
			
		||||
        metadata?: {
 | 
			
		||||
            useLiteralContent: true;
 | 
			
		||||
        };
 | 
			
		||||
        libraries?: {
 | 
			
		||||
            [fileName: string]: {
 | 
			
		||||
                [libName: string]: string;
 | 
			
		||||
            };
 | 
			
		||||
        };
 | 
			
		||||
        outputSelection: {
 | 
			
		||||
            [fileName: string]: {
 | 
			
		||||
                [contractName: string]: OutputField[];
 | 
			
		||||
            };
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
    export interface StandardInput {
 | 
			
		||||
        language: 'Solidity' | 'serpent' | 'lll' | 'assembly';
 | 
			
		||||
        sources: {
 | 
			
		||||
            [fileName: string]: Source;
 | 
			
		||||
        };
 | 
			
		||||
        settings: {
 | 
			
		||||
            remappings?: string[];
 | 
			
		||||
            optimizer?: {
 | 
			
		||||
                enabled: boolean;
 | 
			
		||||
                runs?: number;
 | 
			
		||||
            };
 | 
			
		||||
            evmVersion?: 'homestead' | 'tangerineWhistle' | 'spuriousDragon' | 'byzantium' | 'constantinople';
 | 
			
		||||
            metadata?: {
 | 
			
		||||
                useLiteralContent: true;
 | 
			
		||||
            };
 | 
			
		||||
            libraries?: {
 | 
			
		||||
                [fileName: string]: {
 | 
			
		||||
                    [libName: string]: string;
 | 
			
		||||
                };
 | 
			
		||||
            };
 | 
			
		||||
            outputSelection: {
 | 
			
		||||
                [fileName: string]: {
 | 
			
		||||
                    [contractName: string]: OutputField[];
 | 
			
		||||
                };
 | 
			
		||||
            };
 | 
			
		||||
        };
 | 
			
		||||
        settings: CompilerSettings;
 | 
			
		||||
    }
 | 
			
		||||
    export type ErrorType =
 | 
			
		||||
        | 'JSONError'
 | 
			
		||||
@@ -114,6 +115,19 @@ declare module 'solc' {
 | 
			
		||||
        formattedMessage?: string;
 | 
			
		||||
    }
 | 
			
		||||
    import { ContractAbi } from '@0xproject/types';
 | 
			
		||||
    export interface StandardContractOutput {
 | 
			
		||||
        abi: ContractAbi;
 | 
			
		||||
        evm: {
 | 
			
		||||
            bytecode: {
 | 
			
		||||
                object: string;
 | 
			
		||||
                sourceMap: string;
 | 
			
		||||
            };
 | 
			
		||||
            deployedBytecode: {
 | 
			
		||||
                object: string;
 | 
			
		||||
                sourceMap: string;
 | 
			
		||||
            };
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
    export interface StandardOutput {
 | 
			
		||||
        errors: Error[];
 | 
			
		||||
        sources: {
 | 
			
		||||
@@ -125,19 +139,7 @@ declare module 'solc' {
 | 
			
		||||
        };
 | 
			
		||||
        contracts: {
 | 
			
		||||
            [fileName: string]: {
 | 
			
		||||
                [contractName: string]: {
 | 
			
		||||
                    abi: ContractAbi;
 | 
			
		||||
                    evm: {
 | 
			
		||||
                        bytecode: {
 | 
			
		||||
                            object: string;
 | 
			
		||||
                            sourceMap: string;
 | 
			
		||||
                        };
 | 
			
		||||
                        deployedBytecode: {
 | 
			
		||||
                            object: string;
 | 
			
		||||
                            sourceMap: string;
 | 
			
		||||
                        };
 | 
			
		||||
                    };
 | 
			
		||||
                };
 | 
			
		||||
                [contractName: string]: StandardContractOutput;
 | 
			
		||||
            };
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user