1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
import { FallthroughResolver, FSResolver, NPMResolver, RelativeFSResolver, URLResolver } from '@0x/sol-resolver';
import { logUtils } from '@0x/utils';
import { CompilerOptions, ContractArtifact } from 'ethereum-types';
import * as fs from 'fs';
import * as glob from 'glob';
import * as _ from 'lodash';
import * as path from 'path';
import { ContractData, SourceCodes, Sources } from '../types';
import { AbstractArtifactAdapter } from './abstract_artifact_adapter';
const CONFIG_FILE = 'compiler.json';
export class SolCompilerArtifactAdapter extends AbstractArtifactAdapter {
private readonly _artifactsPath: string;
private readonly _sourcesPath: string;
private readonly _resolver: FallthroughResolver;
/**
* Instantiates a SolCompilerArtifactAdapter
* @param artifactsPath Path to your artifacts directory
* @param sourcesPath Path to your contract sources directory
*/
constructor(artifactsPath?: string, sourcesPath?: string) {
super();
const config: CompilerOptions = fs.existsSync(CONFIG_FILE)
? JSON.parse(fs.readFileSync(CONFIG_FILE).toString())
: {};
if (_.isUndefined(artifactsPath) && _.isUndefined(config.artifactsDir)) {
throw new Error(`artifactsDir not found in ${CONFIG_FILE}`);
}
this._artifactsPath = (artifactsPath || config.artifactsDir) as string;
if (_.isUndefined(sourcesPath) && _.isUndefined(config.contractsDir)) {
throw new Error(`contractsDir not found in ${CONFIG_FILE}`);
}
this._sourcesPath = (sourcesPath || config.contractsDir) as string;
this._resolver = new FallthroughResolver();
this._resolver.appendResolver(new URLResolver());
const packagePath = path.resolve('');
this._resolver.appendResolver(new NPMResolver(packagePath));
this._resolver.appendResolver(new RelativeFSResolver(this._sourcesPath));
this._resolver.appendResolver(new FSResolver());
}
public async collectContractsDataAsync(): Promise<ContractData[]> {
const artifactsGlob = `${this._artifactsPath}/**/*.json`;
const artifactFileNames = glob.sync(artifactsGlob, { absolute: true });
const contractsData: ContractData[] = [];
for (const artifactFileName of artifactFileNames) {
const artifact: ContractArtifact = JSON.parse(fs.readFileSync(artifactFileName).toString());
if (_.isUndefined(artifact.compilerOutput.evm)) {
logUtils.warn(`${artifactFileName} doesn't contain bytecode. Skipping...`);
continue;
}
const sources: Sources = {};
const sourceCodes: SourceCodes = {};
_.map(artifact.sources, (value: { id: number }, relativeFilePath: string) => {
const source = this._resolver.resolve(relativeFilePath);
sources[value.id] = source.absolutePath;
sourceCodes[value.id] = source.source;
});
const contractData = {
sourceCodes,
sources,
bytecode: artifact.compilerOutput.evm.bytecode.object,
sourceMap: artifact.compilerOutput.evm.bytecode.sourceMap,
runtimeBytecode: artifact.compilerOutput.evm.deployedBytecode.object,
sourceMapRuntime: artifact.compilerOutput.evm.deployedBytecode.sourceMap,
};
const isInterfaceContract = contractData.bytecode === '0x' && contractData.runtimeBytecode === '0x';
if (isInterfaceContract) {
continue;
}
contractsData.push(contractData);
}
return contractsData;
}
}
|