commit
55b3adb678
@ -0,0 +1,59 @@ |
|||||||
|
export const fetchContractFromEtherscan = async (plugin, network, contractAddress, targetPath) => { |
||||||
|
let data |
||||||
|
const compilationTargets = {} |
||||||
|
|
||||||
|
const etherscanKey = await plugin.call('config', 'getAppParameter', 'etherscan-access-token') |
||||||
|
if (etherscanKey) { |
||||||
|
const endpoint = network.id == 1 ? 'api.etherscan.io' : 'api-' + network.name + '.etherscan.io' |
||||||
|
data = await fetch('https://' + endpoint + '/api?module=contract&action=getsourcecode&address=' + contractAddress + '&apikey=' + etherscanKey) |
||||||
|
data = await data.json() |
||||||
|
// etherscan api doc https://docs.etherscan.io/api-endpoints/contracts
|
||||||
|
if (data.message === 'OK' && data.status === "1") { |
||||||
|
if (data.result.length) { |
||||||
|
if (data.result[0].SourceCode === '') throw new Error('contract not verified') |
||||||
|
if (data.result[0].SourceCode.startsWith('{')) { |
||||||
|
data.result[0].SourceCode = JSON.parse(data.result[0].SourceCode.replace(/(?:\r\n|\r|\n)/g, '').replace(/^{{/,'{').replace(/}}$/,'}')) |
||||||
|
} |
||||||
|
}
|
||||||
|
} else throw new Error('unable to retrieve contract data ' + data.message) |
||||||
|
} else throw new Error('unable to try fetching the source code from etherscan: etherscan access token not found. please go to the Remix settings page and provide an access token.') |
||||||
|
|
||||||
|
if (!data || !data.result) { |
||||||
|
return null |
||||||
|
} |
||||||
|
|
||||||
|
if (typeof data.result[0].SourceCode === 'string') { |
||||||
|
const fileName = `${targetPath}/${network.id}/${contractAddress}/${data.result[0].ContractName}.sol` |
||||||
|
await plugin.call('fileManager', 'setFile', fileName , data.result[0].SourceCode) |
||||||
|
compilationTargets[fileName] = { content: data.result[0].SourceCode } |
||||||
|
} else if (data.result[0].SourceCode && typeof data.result[0].SourceCode == 'object') { |
||||||
|
const sources = data.result[0].SourceCode.sources |
||||||
|
for (let [file, source] of Object.entries(sources)) { // eslint-disable-line
|
||||||
|
file = file.replace('browser/', '') // should be fixed in the remix IDE end.
|
||||||
|
file = file.replace(/^\//g, '') // remove first slash.
|
||||||
|
if (await plugin.call('contentImport', 'isExternalUrl', file)) { |
||||||
|
// nothing to do, the compiler callback will handle those
|
||||||
|
} else {
|
||||||
|
const path = `${targetPath}/${network.id}/${contractAddress}/${file}` |
||||||
|
const content = (source as any).content |
||||||
|
await plugin.call('fileManager', 'setFile', path, content) |
||||||
|
compilationTargets[path] = { content } |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
let runs = 0 |
||||||
|
try { |
||||||
|
runs = parseInt(data.result[0].Runs) |
||||||
|
} catch (e) {} |
||||||
|
const settings = { |
||||||
|
version: data.result[0].CompilerVersion.replace(/^v/, ''), |
||||||
|
language: 'Solidity', |
||||||
|
evmVersion: data.result[0].EVMVersion.toLowerCase(), |
||||||
|
optimize: data.result[0].OptimizationUsed === '1', |
||||||
|
runs |
||||||
|
} |
||||||
|
return { |
||||||
|
settings, |
||||||
|
compilationTargets |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,46 @@ |
|||||||
|
export const fetchContractFromSourcify = async (plugin, network, contractAddress, targetPath) => { |
||||||
|
let data |
||||||
|
const compilationTargets = {} |
||||||
|
|
||||||
|
try { |
||||||
|
data = await plugin.call('sourcify', 'fetchByNetwork', contractAddress, network.id) |
||||||
|
} catch (e) { |
||||||
|
console.log(e) |
||||||
|
} |
||||||
|
|
||||||
|
if (!data || !data.metadata) { |
||||||
|
return null |
||||||
|
} |
||||||
|
|
||||||
|
// set the solidity contract code using metadata
|
||||||
|
await plugin.call('fileManager', 'setFile', `${targetPath}/${network.id}/${contractAddress}/metadata.json`, JSON.stringify(data.metadata, null, '\t')) |
||||||
|
for (let file in data.metadata.sources) { |
||||||
|
const urls = data.metadata.sources[file].urls |
||||||
|
for (const url of urls) { |
||||||
|
if (url.includes('ipfs')) { |
||||||
|
const stdUrl = `ipfs://${url.split('/')[2]}` |
||||||
|
const source = await plugin.call('contentImport', 'resolve', stdUrl) |
||||||
|
file = file.replace('browser/', '') // should be fixed in the remix IDE end.
|
||||||
|
if (await plugin.call('contentImport', 'isExternalUrl', file)) { |
||||||
|
// nothing to do, the compiler callback will handle those
|
||||||
|
} else { |
||||||
|
const path = `${targetPath}/${network.id}/${contractAddress}/${file}` |
||||||
|
await plugin.call('fileManager', 'setFile', path, source.content) |
||||||
|
compilationTargets[path] = { content: source.content } |
||||||
|
} |
||||||
|
break |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
const settings = { |
||||||
|
version: data.metadata.compiler.version, |
||||||
|
language: data.metadata.language, |
||||||
|
evmVersion: data.metadata.settings.evmVersion, |
||||||
|
optimize: data.metadata.settings.optimizer.enabled, |
||||||
|
runs: data.metadata.settings.optimizer.runs |
||||||
|
} |
||||||
|
return { |
||||||
|
settings, |
||||||
|
compilationTargets |
||||||
|
} |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue