|
|
@ -24,12 +24,12 @@ export class CompilerArtefacts extends Plugin { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
onActivation () { |
|
|
|
onActivation () { |
|
|
|
const saveCompilationPerFileResult = (file, source, languageVersion, data) => { |
|
|
|
const saveCompilationPerFileResult = (file, source, languageVersion, data, input?) => { |
|
|
|
this.compilersArtefactsPerFile[file] = new CompilerAbstract(languageVersion, data, source) |
|
|
|
this.compilersArtefactsPerFile[file] = new CompilerAbstract(languageVersion, data, source, input) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.on('solidity', 'compilationFinished', (file, source, languageVersion, data) => { |
|
|
|
this.on('solidity', 'compilationFinished', (file, source, languageVersion, data, input, version) => { |
|
|
|
this.compilersArtefacts.__last = new CompilerAbstract(languageVersion, data, source) |
|
|
|
this.compilersArtefacts.__last = new CompilerAbstract(languageVersion, data, source, input) |
|
|
|
saveCompilationPerFileResult(file, source, languageVersion, data) |
|
|
|
saveCompilationPerFileResult(file, source, languageVersion, data) |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
@ -48,16 +48,24 @@ export class CompilerArtefacts extends Plugin { |
|
|
|
saveCompilationPerFileResult(file, source, languageVersion, data) |
|
|
|
saveCompilationPerFileResult(file, source, languageVersion, data) |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
this.on('solidityUnitTesting', 'compilationFinished', (file, source, languageVersion, data) => { |
|
|
|
this.on('solidityUnitTesting', 'compilationFinished', (file, source, languageVersion, data, input, version) => { |
|
|
|
this.compilersArtefacts.__last = new CompilerAbstract(languageVersion, data, source) |
|
|
|
this.compilersArtefacts.__last = new CompilerAbstract(languageVersion, data, source, input) |
|
|
|
saveCompilationPerFileResult(file, source, languageVersion, data) |
|
|
|
saveCompilationPerFileResult(file, source, languageVersion, data, input) |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Get artefacts for last compiled contract
|
|
|
|
|
|
|
|
* * @returns last compiled contract compiler abstract |
|
|
|
|
|
|
|
*/ |
|
|
|
getLastCompilationResult () { |
|
|
|
getLastCompilationResult () { |
|
|
|
return this.compilersArtefacts.__last |
|
|
|
return this.compilersArtefacts.__last |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Get compilation output for contracts compiled during a session of Remix IDE |
|
|
|
|
|
|
|
* @returns compilatin output |
|
|
|
|
|
|
|
*/ |
|
|
|
getAllContractDatas () { |
|
|
|
getAllContractDatas () { |
|
|
|
const contractsData = {} |
|
|
|
const contractsData = {} |
|
|
|
Object.keys(this.compilersArtefactsPerFile).map((targetFile) => { |
|
|
|
Object.keys(this.compilersArtefactsPerFile).map((targetFile) => { |
|
|
@ -72,51 +80,85 @@ export class CompilerArtefacts extends Plugin { |
|
|
|
return contractsData |
|
|
|
return contractsData |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async getArtefactsFromFE (path, contractName) { |
|
|
|
/** |
|
|
|
|
|
|
|
* Get a particular contract output/artefacts from a compiler output of a Solidity file compilation |
|
|
|
|
|
|
|
* @param compilerOutput compiler output
|
|
|
|
|
|
|
|
* @param contractName contract name |
|
|
|
|
|
|
|
* @returns arefacts object, with fully qualified name (e.g; contracts/1_Storage.sol:Storage) as key |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
_getAllContractArtefactsfromOutput (compilerOutput, contractName) { |
|
|
|
|
|
|
|
const contractArtefacts = {} |
|
|
|
|
|
|
|
for (const filename in compilerOutput) { |
|
|
|
|
|
|
|
if(Object.keys(compilerOutput[filename]).includes(contractName)) contractArtefacts[filename + ':' + contractName] = compilerOutput[filename][contractName] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return contractArtefacts |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Populate resultant object with a particular contract output/artefacts by processing all the artifacts stored in file explorer |
|
|
|
|
|
|
|
* @param path path to start looking from |
|
|
|
|
|
|
|
* @param contractName contract to be looked for |
|
|
|
|
|
|
|
* @param contractArtefacts populated resultant artefacts object, with fully qualified name (e.g: contracts/1_Storage.sol:Storage) as key |
|
|
|
|
|
|
|
* Once method execution completes, contractArtefacts object will hold all possible artefacts for contract |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
async _populateAllContractArtefactsFromFE (path, contractName, contractArtefacts) { |
|
|
|
const dirList = await this.call('fileManager', 'dirList', path) |
|
|
|
const dirList = await this.call('fileManager', 'dirList', path) |
|
|
|
if(dirList && dirList.length) { |
|
|
|
if(dirList && dirList.length) { |
|
|
|
if(dirList.includes(path + '/artifacts')) { |
|
|
|
for (const dirPath of dirList) { |
|
|
|
const fileList = await this.call('fileManager', 'fileList', path + '/artifacts') |
|
|
|
// check if directory contains an 'artifacts' folder and a 'build-info' folder inside 'artifacts'
|
|
|
|
const artefactsFilePaths = fileList.filter(filePath => { |
|
|
|
if(dirPath === path + '/artifacts' && await this.call('fileManager', 'exists', dirPath + '/build-info')) { |
|
|
|
const filenameArr = filePath.split('/') |
|
|
|
const buildFileList = await this.call('fileManager', 'fileList', dirPath + '/build-info') |
|
|
|
const filename = filenameArr[filenameArr.length - 1] |
|
|
|
// process each build-info file to populate the artefacts for contractName
|
|
|
|
if (filename === `${contractName}.json` || filename === `${contractName}_metadata.json`) return true |
|
|
|
for (const buildFile of buildFileList) { |
|
|
|
}) |
|
|
|
let content = await this.call('fileManager', 'readFile', buildFile) |
|
|
|
if (artefactsFilePaths && artefactsFilePaths.length) { |
|
|
|
if (content) content = JSON.parse(content) |
|
|
|
const content = await this.call('fileManager', 'readFile', artefactsFilePaths[1]) |
|
|
|
const compilerOutput = content.output.contracts |
|
|
|
const artifacts = JSON.parse(content) |
|
|
|
const artefacts = this._getAllContractArtefactsfromOutput(compilerOutput, contractName) |
|
|
|
return { abi: artifacts.abi, bytecode: artifacts.data.bytecode.object } |
|
|
|
// populate the resultant object with artefacts
|
|
|
|
} else { |
|
|
|
Object.assign(contractArtefacts, artefacts) |
|
|
|
for (const dirPath of dirList) { |
|
|
|
|
|
|
|
const result = await this.getArtefactsFromFE (dirPath, contractName) |
|
|
|
|
|
|
|
if (result) return result |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else await this._populateAllContractArtefactsFromFE (dirPath, contractName, contractArtefacts) |
|
|
|
} else { |
|
|
|
}
|
|
|
|
for (const dirPath of dirList) { |
|
|
|
|
|
|
|
const result = await this.getArtefactsFromFE (dirPath, contractName) |
|
|
|
|
|
|
|
if (result) return result |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else return |
|
|
|
} else return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async getArtefactsByContractName (contractName) { |
|
|
|
/** |
|
|
|
|
|
|
|
* Get artefacts for a contract (called by script-runner) |
|
|
|
|
|
|
|
* @param name contract name or fully qualified name i.e. <filename>:<contractname> e.g: contracts/1_Storage.sol:Storage
|
|
|
|
|
|
|
|
* @returns artefacts for the contract |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
async getArtefactsByContractName (name) { |
|
|
|
const contractsDataByFilename = this.getAllContractDatas() |
|
|
|
const contractsDataByFilename = this.getAllContractDatas() |
|
|
|
const contractsData = Object.values(contractsDataByFilename) |
|
|
|
// check if name is a fully qualified name
|
|
|
|
if (contractsData && contractsData.length) { |
|
|
|
if (name.includes(':')) { |
|
|
|
const index = contractsData.findIndex((contractsObj) => Object.keys(contractsObj).includes(contractName)) |
|
|
|
const fullyQualifiedName = name |
|
|
|
if (index !== -1) return { abi: contractsData[index][contractName].abi, bytecode: contractsData[index][contractName].evm.bytecode.object } |
|
|
|
const nameArr = fullyQualifiedName.split(':') |
|
|
|
|
|
|
|
const filename = nameArr[0] |
|
|
|
|
|
|
|
const contract = nameArr[1] |
|
|
|
|
|
|
|
if(Object.keys(contractsDataByFilename).includes(filename) && contractsDataByFilename[filename][contract])
|
|
|
|
|
|
|
|
return contractsDataByFilename[filename][contract] |
|
|
|
else { |
|
|
|
else { |
|
|
|
const result = await this.getArtefactsFromFE ('contracts', contractName) |
|
|
|
const allContractsData = {} |
|
|
|
if (result) return result |
|
|
|
await this._populateAllContractArtefactsFromFE ('contracts', contract, allContractsData) |
|
|
|
else throw new Error(`Could not find artifacts for ${contractName}. Compile contract to generate artifacts.`) |
|
|
|
if(allContractsData[fullyQualifiedName]) return allContractsData[fullyQualifiedName] |
|
|
|
|
|
|
|
else throw new Error(`Could not find artifacts for ${fullyQualifiedName}. Compile contract to generate artifacts.`) |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
const result = await this.getArtefactsFromFE ('contracts', contractName) |
|
|
|
const contractName = name |
|
|
|
if (result) return result |
|
|
|
const contractArtefacts = this._getAllContractArtefactsfromOutput(contractsDataByFilename, contractName) |
|
|
|
else throw new Error(`Could not find artifacts for ${contractName}. Compile contract to generate artifacts.`) |
|
|
|
let keys = Object.keys(contractArtefacts) |
|
|
|
}
|
|
|
|
if (!keys.length) { |
|
|
|
|
|
|
|
await this._populateAllContractArtefactsFromFE ('contracts', contractName, contractArtefacts) |
|
|
|
|
|
|
|
keys = Object.keys(contractArtefacts) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (keys.length === 1) return contractArtefacts[keys[0]] |
|
|
|
|
|
|
|
else if (keys.length > 1) { |
|
|
|
|
|
|
|
throw new Error(`There are multiple artifacts for contract "${contractName}", please use a fully qualified name.\n
|
|
|
|
|
|
|
|
Please replace ${contractName} for one of these options wherever you are trying to read its artifact: \n |
|
|
|
|
|
|
|
${keys.join()}\n |
|
|
|
|
|
|
|
OR just compile the required contract again`)
|
|
|
|
|
|
|
|
} else throw new Error(`Could not find artifacts for ${contractName}. Compile contract to generate artifacts.`) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
getCompilerAbstract (file) { |
|
|
|
getCompilerAbstract (file) { |
|
|
|