commit
4b5222d3b1
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,20 @@ |
|||||||
|
'use strict' |
||||||
|
import { canUseWorker } from './compiler-utils' |
||||||
|
import { Compiler } from 'remix-solidity' |
||||||
|
import CompilerAbstract from './compiler-abstract' |
||||||
|
|
||||||
|
export const compile = async (compilationTargets, settings) => { |
||||||
|
return await (() => { |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
const compiler = new Compiler(() => {}) |
||||||
|
compiler.set('evmVersion', settings.evmVersion) |
||||||
|
compiler.set('optimize', settings.optimize) |
||||||
|
compiler.loadVersion(canUseWorker(settings.version), settings.compilerUrl) |
||||||
|
compiler.event.register('compilationFinished', (success, compilationData, source) => { |
||||||
|
if (!success) return reject(compilationData) |
||||||
|
resolve(new CompilerAbstract(settings.version, compilationData, source)) |
||||||
|
}) |
||||||
|
compiler.event.register('compilerLoaded', _ => compiler.compile(compilationTargets, '')) |
||||||
|
}) |
||||||
|
})() |
||||||
|
} |
@ -0,0 +1,125 @@ |
|||||||
|
const ethutil = require('ethereumjs-util') |
||||||
|
import * as packageJson from '../../../package.json' |
||||||
|
import { Plugin } from '@remixproject/engine' |
||||||
|
import { urlFromVersion } from './compiler-utils' |
||||||
|
import { compile } from './compiler-helpers' |
||||||
|
import globalRegistry from '../../global/registry' |
||||||
|
|
||||||
|
import remixLib from 'remix-lib' |
||||||
|
|
||||||
|
const profile = { |
||||||
|
name: 'fetchAndCompile', |
||||||
|
methods: ['resolve'], |
||||||
|
version: packageJson.version |
||||||
|
} |
||||||
|
|
||||||
|
export default class FetchAndCompile extends Plugin { |
||||||
|
|
||||||
|
constructor () { |
||||||
|
super(profile) |
||||||
|
this.unresolvedAddresses = [] |
||||||
|
this.sourceVerifierNetWork = ['Main', 'Rinkeby', 'Ropsten', 'Goerli'] |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Fetch compiliation metadata from source-Verify from a given @arg contractAddress - https://github.com/ethereum/source-verify
|
||||||
|
* Put the artifacts in the file explorer |
||||||
|
* Compile the code using Solidity compiler |
||||||
|
* Returns compilation data |
||||||
|
* |
||||||
|
* @param {string} contractAddress - Address of the contrac to resolve |
||||||
|
* @param {string} compilersartefacts - Object containing a mapping of compilation results (byContractAddress and __last) |
||||||
|
* @return {CompilerAbstract} - compilation data targeting the given @arg contractAddress |
||||||
|
*/ |
||||||
|
async resolve (contractAddress, targetPath, web3) { |
||||||
|
contractAddress = ethutil.toChecksumAddress(contractAddress) |
||||||
|
const compilersartefacts = globalRegistry.get('compilersartefacts').api |
||||||
|
|
||||||
|
const localCompilation = () => compilersartefacts.get('__last') ? compilersartefacts.get('__last') : null |
||||||
|
|
||||||
|
const resolved = compilersartefacts.get(contractAddress) |
||||||
|
if (resolved) return resolved |
||||||
|
if (this.unresolvedAddresses.includes(contractAddress)) return localCompilation() |
||||||
|
|
||||||
|
// sometimes when doing an internal call, the only available artifact is the Solidity interface.
|
||||||
|
// resolving addresses of internal call would allow to step over the source code, even if the declaration was made using an Interface.
|
||||||
|
|
||||||
|
let network |
||||||
|
try { |
||||||
|
network = await this.call('network', 'detectNetwork') |
||||||
|
} catch (e) { |
||||||
|
return localCompilation() |
||||||
|
} |
||||||
|
if (!network) return localCompilation() |
||||||
|
if (!this.sourceVerifierNetWork.includes(network.name)) return localCompilation() |
||||||
|
|
||||||
|
// check if the contract if part of the local compilation result
|
||||||
|
const codeAtAddress = await web3.eth.getCode(contractAddress) |
||||||
|
const compilation = localCompilation() |
||||||
|
if (compilation) { |
||||||
|
let found = false |
||||||
|
compilation.visitContracts((contract) => { |
||||||
|
found = remixLib.util.compareByteCode('0x' + contract.object.evm.deployedBytecode.object, codeAtAddress) |
||||||
|
return found |
||||||
|
}) |
||||||
|
if (found) { |
||||||
|
compilersartefacts.addResolvedContract(contractAddress, compilation) |
||||||
|
setTimeout(_ => this.emit('usingLocalCompilation', contractAddress), 0) |
||||||
|
return compilation |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
let name = network.name.toLowerCase() |
||||||
|
name === 'main' ? 'mainnet' : name // source-verifier api expect "mainnet" and not "main"
|
||||||
|
let data |
||||||
|
try { |
||||||
|
data = await this.call('source-verification', 'fetch', contractAddress, name.toLowerCase()) |
||||||
|
} catch (e) { |
||||||
|
setTimeout(_ => this.emit('sourceVerificationNotAvailable'), 0) |
||||||
|
this.unresolvedAddresses.push(contractAddress) |
||||||
|
return localCompilation() |
||||||
|
} |
||||||
|
if (!data || !data.metadata) { |
||||||
|
setTimeout(_ => this.emit('notFound', contractAddress), 0) |
||||||
|
this.unresolvedAddresses.push(contractAddress) |
||||||
|
return localCompilation() |
||||||
|
} |
||||||
|
|
||||||
|
// set the solidity contract code using metadata
|
||||||
|
await this.call('fileManager', 'setFile', `${targetPath}/${name}/${contractAddress}/metadata.json`, JSON.stringify(data.metadata, null, '\t')) |
||||||
|
let compilationTargets = {} |
||||||
|
for (let file in data.metadata.sources) { |
||||||
|
const urls = data.metadata.sources[file].urls |
||||||
|
for (let url of urls) { |
||||||
|
if (url.includes('ipfs')) { |
||||||
|
let stdUrl = `ipfs://${url.split('/')[2]}` |
||||||
|
const source = await this.call('contentImport', 'resolve', stdUrl) |
||||||
|
file = file.replace('browser/', '') // should be fixed in the remix IDE end.
|
||||||
|
const path = `${targetPath}/${name}/${contractAddress}/${file}` |
||||||
|
await this.call('fileManager', 'setFile', path, source.content) |
||||||
|
compilationTargets[path] = { content: source.content } |
||||||
|
break |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// compile
|
||||||
|
const settings = { |
||||||
|
version: data.metadata.compiler.version, |
||||||
|
languageName: data.metadata.language, |
||||||
|
evmVersion: data.metadata.settings.evmVersion, |
||||||
|
optimize: data.metadata.settings.optimizer.enabled, |
||||||
|
compilerUrl: urlFromVersion(data.metadata.compiler.version) |
||||||
|
} |
||||||
|
try { |
||||||
|
setTimeout(_ => this.emit('compiling', settings), 0) |
||||||
|
const compData = await compile(compilationTargets, settings) |
||||||
|
compilersartefacts.addResolvedContract(contractAddress, compData) |
||||||
|
return compData |
||||||
|
} catch (e) { |
||||||
|
this.unresolvedAddresses.push(contractAddress) |
||||||
|
setTimeout(_ => this.emit('compilationFailed'), 0) |
||||||
|
return localCompilation() |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue