parent
da95163c7b
commit
edeb2f139f
@ -1,2 +1,2 @@ |
||||
export * from './lib/solidity-compiler' |
||||
export * from './lib/compileTabLogic' |
||||
export * from './lib/logic' |
||||
|
@ -1,6 +1,6 @@ |
||||
import { Plugin } from '@remixproject/engine' |
||||
|
||||
const packageJson = require('../../../../../package.json') |
||||
const packageJson = require('../../../../../../package.json') |
||||
const Compiler = require('@remix-project/remix-solidity').Compiler |
||||
const EventEmitter = require('events') |
||||
const profile = { |
@ -0,0 +1,51 @@ |
||||
'use strict' |
||||
import * as remixLib from '@remix-project/remix-lib' |
||||
|
||||
const txHelper = remixLib.execution.txHelper |
||||
|
||||
export class CompilerAbstract { |
||||
public languageversion: string |
||||
public data: Record<string, any> |
||||
public source: Record<string, any> |
||||
|
||||
constructor (languageversion, data, source) { |
||||
this.languageversion = languageversion |
||||
this.data = data |
||||
this.source = source // source code
|
||||
} |
||||
|
||||
getContracts () { |
||||
return this.data.contracts |
||||
} |
||||
|
||||
getContract (name) { |
||||
return txHelper.getContract(name, this.data.contracts) |
||||
} |
||||
|
||||
visitContracts (calllback) { |
||||
return txHelper.visitContracts(this.data.contracts, calllback) |
||||
} |
||||
|
||||
getData () { |
||||
return this.data |
||||
} |
||||
|
||||
getAsts () { |
||||
return this.data.sources // ast
|
||||
} |
||||
|
||||
getSourceName (fileIndex) { |
||||
if (this.data && this.data.sources) { |
||||
return Object.keys(this.data.sources)[fileIndex] |
||||
} else if (Object.keys(this.source.sources).length === 1) { |
||||
// if we don't have ast, we return the only one filename present.
|
||||
const sourcesArray = Object.keys(this.source.sources) |
||||
return sourcesArray[0] |
||||
} |
||||
return null |
||||
} |
||||
|
||||
getSourceCode () { |
||||
return this.source |
||||
} |
||||
} |
@ -0,0 +1,22 @@ |
||||
'use strict' |
||||
import { canUseWorker, urlFromVersion } from './compiler-utils' |
||||
import { Compiler } from '@remix-project/remix-solidity' |
||||
import { CompilerAbstract } from './compiler-abstract' |
||||
|
||||
export const compile = async (compilationTargets, settings, contentResolverCallback) => { |
||||
const res = await (() => { |
||||
return new Promise((resolve, reject) => { |
||||
const compiler = new Compiler(contentResolverCallback) |
||||
compiler.set('evmVersion', settings.evmVersion) |
||||
compiler.set('optimize', settings.optimize) |
||||
compiler.set('language', settings.language) |
||||
compiler.set('runs', settings.runs) |
||||
compiler.loadVersion(canUseWorker(settings.version), urlFromVersion(settings.version)) |
||||
compiler.event.register('compilationFinished', (success, compilationData, source) => { |
||||
resolve(new CompilerAbstract(settings.version, compilationData, source)) |
||||
}) |
||||
compiler.event.register('compilerLoaded', _ => compiler.compile(compilationTargets, '')) |
||||
}) |
||||
})() |
||||
return res |
||||
} |
@ -0,0 +1,46 @@ |
||||
const semver = require('semver') |
||||
const minixhr = require('minixhr') |
||||
/* global Worker */ |
||||
|
||||
export const baseURLBin = 'https://binaries.soliditylang.org/bin' |
||||
export const baseURLWasm = 'https://binaries.soliditylang.org/wasm' |
||||
|
||||
export const pathToURL = {} |
||||
|
||||
/** |
||||
* Retrieves the URL of the given compiler version |
||||
* @param version is the version of compiler with or without 'soljson-v' prefix and .js postfix |
||||
*/ |
||||
export function urlFromVersion (version) { |
||||
if (!version.startsWith('soljson-v')) version = 'soljson-v' + version |
||||
if (!version.endsWith('.js')) version = version + '.js' |
||||
return `${pathToURL[version]}/${version}` |
||||
} |
||||
|
||||
/** |
||||
* Checks if the worker can be used to load a compiler. |
||||
* checks a compiler whitelist, browser support and OS. |
||||
*/ |
||||
export function canUseWorker (selectedVersion) { |
||||
const version = semver.coerce(selectedVersion) |
||||
const isNightly = selectedVersion.includes('nightly') |
||||
return browserSupportWorker() && ( |
||||
// All compiler versions (including nightlies) after 0.6.3 are wasm compiled
|
||||
semver.gt(version, '0.6.3') || |
||||
// Only releases are wasm compiled starting with 0.3.6
|
||||
(semver.gte(version, '0.3.6') && !isNightly) |
||||
) |
||||
} |
||||
|
||||
function browserSupportWorker () { |
||||
return document.location.protocol !== 'file:' && Worker !== undefined |
||||
} |
||||
|
||||
// returns a promise for minixhr
|
||||
export function promisedMiniXhr (url) { |
||||
return new Promise((resolve, reject) => { |
||||
minixhr(url, (json, event) => { |
||||
resolve({ json, event }) |
||||
}) |
||||
}) |
||||
} |
@ -0,0 +1,119 @@ |
||||
'use strict' |
||||
import * as solcTranslate from 'solc/translate' |
||||
import * as remixLib from '@remix-project/remix-lib' |
||||
|
||||
const txHelper = remixLib.execution.txHelper |
||||
|
||||
export function parseContracts (contractName, contract, source) { |
||||
const detail: Record<string, any> = {} |
||||
|
||||
detail.name = contractName |
||||
detail.metadata = contract.metadata |
||||
if (contract.evm.bytecode.object) { |
||||
detail.bytecode = contract.evm.bytecode.object |
||||
} |
||||
|
||||
detail.abi = contract.abi |
||||
|
||||
if (contract.evm.bytecode.object) { |
||||
detail.bytecode = contract.evm.bytecode |
||||
detail.web3Deploy = gethDeploy(contractName.toLowerCase(), contract.abi, contract.evm.bytecode.object) |
||||
|
||||
detail.metadataHash = retrieveMetadataHash(contract.evm.bytecode.object) |
||||
if (detail.metadataHash) { |
||||
detail.swarmLocation = 'bzzr://' + detail.metadataHash |
||||
} |
||||
} |
||||
|
||||
detail.functionHashes = {} |
||||
for (const fun in contract.evm.methodIdentifiers) { |
||||
detail.functionHashes[contract.evm.methodIdentifiers[fun]] = fun |
||||
} |
||||
|
||||
detail.gasEstimates = formatGasEstimates(contract.evm.gasEstimates) |
||||
|
||||
detail.devdoc = contract.devdoc |
||||
detail.userdoc = contract.userdoc |
||||
|
||||
if (contract.evm.deployedBytecode && contract.evm.deployedBytecode.object.length > 0) { |
||||
detail['Runtime Bytecode'] = contract.evm.deployedBytecode |
||||
} |
||||
|
||||
if (source && contract.assembly !== null) { |
||||
detail.Assembly = solcTranslate.prettyPrintLegacyAssemblyJSON(contract.evm.legacyAssembly, source.content) |
||||
} |
||||
|
||||
return detail |
||||
} |
||||
|
||||
const retrieveMetadataHash = function (bytecode) { |
||||
var match = /a165627a7a72305820([0-9a-f]{64})0029$/.exec(bytecode) |
||||
if (!match) { |
||||
match = /a265627a7a72305820([0-9a-f]{64})6c6578706572696d656e74616cf50037$/.exec(bytecode) |
||||
} |
||||
if (match) { |
||||
return match[1] |
||||
} |
||||
} |
||||
|
||||
const gethDeploy = function (contractName, jsonInterface, bytecode) { |
||||
let code = '' |
||||
const funABI = txHelper.getConstructorInterface(jsonInterface) |
||||
|
||||
funABI.inputs.forEach(function (inp) { |
||||
code += 'var ' + inp.name + ' = /* var of type ' + inp.type + ' here */ ;\n' |
||||
}) |
||||
|
||||
contractName = contractName.replace(/[:./]/g, '_') |
||||
code += 'var ' + contractName + 'Contract = new web3.eth.Contract(' + JSON.stringify(jsonInterface).replace('\n', '') + ');' + |
||||
'\nvar ' + contractName + ' = ' + contractName + 'Contract.deploy({' + |
||||
"\n data: '0x" + bytecode + "', " + |
||||
'\n arguments: [' |
||||
|
||||
funABI.inputs.forEach(function (inp) { |
||||
code += '\n ' + inp.name + ',' |
||||
}) |
||||
|
||||
code += '\n ]' + |
||||
'\n}).send({' + |
||||
'\n from: web3.eth.accounts[0], ' + |
||||
"\n gas: '4700000'" + |
||||
'\n }, function (e, contract){' + |
||||
'\n console.log(e, contract);' + |
||||
"\n if (typeof contract.address !== 'undefined') {" + |
||||
"\n console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);" + |
||||
'\n }' + |
||||
'\n })' |
||||
|
||||
return code |
||||
} |
||||
|
||||
const formatGasEstimates = function (data) { |
||||
if (!data) return {} |
||||
if (data.creation === undefined && data.external === undefined && data.internal === undefined) return {} |
||||
|
||||
const gasToText = function (g) { |
||||
return g === null ? 'unknown' : g |
||||
} |
||||
|
||||
const ret: Record<string, any> = {} |
||||
let fun |
||||
if ('creation' in data) { |
||||
ret.Creation = data.creation |
||||
} |
||||
|
||||
if ('external' in data) { |
||||
ret.External = {} |
||||
for (fun in data.external) { |
||||
ret.External[fun] = gasToText(data.external[fun]) |
||||
} |
||||
} |
||||
|
||||
if ('internal' in data) { |
||||
ret.Internal = {} |
||||
for (fun in data.internal) { |
||||
ret.Internal[fun] = gasToText(data.internal[fun]) |
||||
} |
||||
} |
||||
return ret |
||||
} |
@ -0,0 +1,5 @@ |
||||
export * from './compileTabLogic' |
||||
export * from './compiler-abstract' |
||||
export * from './compiler-helpers' |
||||
export * from './compiler-utils' |
||||
export * from './contract-parser' |
Loading…
Reference in new issue