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