|
|
|
@ -3,7 +3,6 @@ import React from 'react' // eslint-disable-line |
|
|
|
|
import ReactDOM from 'react-dom' |
|
|
|
|
import { SolidityCompiler, CompileTab as CompileTabLogic } from '@remix-ui/solidity-compiler' // eslint-disable-line
|
|
|
|
|
import { ViewPlugin } from '@remixproject/engine-web' |
|
|
|
|
import { Renderer } from '@remix-ui/renderer' |
|
|
|
|
import * as packageJson from '../../../../../package.json' |
|
|
|
|
import publishToStorage from '../../publishToStorage' |
|
|
|
|
import { compile } from '@remix-project/remix-solidity' |
|
|
|
@ -11,17 +10,11 @@ import { compile } from '@remix-project/remix-solidity' |
|
|
|
|
const EventEmitter = require('events') |
|
|
|
|
const $ = require('jquery') |
|
|
|
|
const yo = require('yo-yo') |
|
|
|
|
const copy = require('copy-to-clipboard') |
|
|
|
|
var QueryParams = require('../../lib/query-params') |
|
|
|
|
const modalDialogCustom = require('../ui/modal-dialog-custom') |
|
|
|
|
const parseContracts = require('./compileTab/contractParser') |
|
|
|
|
const addTooltip = require('../ui/tooltip') |
|
|
|
|
// const Renderer = require('../ui/renderer')
|
|
|
|
|
const globalRegistry = require('../../global/registry') |
|
|
|
|
|
|
|
|
|
var css = require('./styles/compile-tab-styles') |
|
|
|
|
// const CompilerContainer = require('./compileTab/compilerContainer.js')
|
|
|
|
|
|
|
|
|
|
const profile = { |
|
|
|
|
name: 'solidity', |
|
|
|
|
displayName: 'Solidity compiler', |
|
|
|
@ -80,12 +73,8 @@ class CompileTab extends ViewPlugin { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
resetResults () { |
|
|
|
|
if (this._view.errorContainer) { |
|
|
|
|
this._view.errorContainer.innerHTML = '' |
|
|
|
|
} |
|
|
|
|
this.currentFile = '' |
|
|
|
|
this.contractsDetails = {} |
|
|
|
|
yo.update(this._view.contractSelection, this.contractSelection()) |
|
|
|
|
this.emit('statusChanged', { key: 'none' }) |
|
|
|
|
this.renderComponent() |
|
|
|
|
} |
|
|
|
@ -120,9 +109,6 @@ class CompileTab extends ViewPlugin { |
|
|
|
|
this.compiler.event.register('compilerLoaded', this.data.eventHandlers.onCompilerLoaded) |
|
|
|
|
|
|
|
|
|
this.data.eventHandlers.onStartingCompilation = () => { |
|
|
|
|
if (this._view.errorContainer) { |
|
|
|
|
this._view.errorContainer.innerHTML = '' |
|
|
|
|
} |
|
|
|
|
this.emit('statusChanged', { key: 'loading', title: 'compiling...', type: 'info' }) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -148,7 +134,7 @@ class CompileTab extends ViewPlugin { |
|
|
|
|
this.fileManager.events.on('noFileSelected', this.data.eventHandlers.onNoFileSelected) |
|
|
|
|
|
|
|
|
|
this.data.eventHandlers.onCompilationFinished = (success, data, source) => { |
|
|
|
|
// this._view.errorContainer.appendChild(yo`<span data-id="compilationFinishedWith_${this.getCurrentVersion()}"></span>`)
|
|
|
|
|
this.compileErrors = data |
|
|
|
|
if (success) { |
|
|
|
|
// forwarding the event to the appManager infra
|
|
|
|
|
this.emit('compilationFinished', source.target, source, 'soljson', data) |
|
|
|
@ -175,35 +161,6 @@ class CompileTab extends ViewPlugin { |
|
|
|
|
// Update contract Selection
|
|
|
|
|
this.contractMap = {} |
|
|
|
|
if (success) this.compiler.visitContracts((contract) => { this.contractMap[contract.name] = contract }) |
|
|
|
|
// const contractSelection = this.contractSelection(contractMap)
|
|
|
|
|
// yo.update(this._view.contractSelection, contractSelection)
|
|
|
|
|
|
|
|
|
|
if (data.error) { |
|
|
|
|
// this.renderer.error(
|
|
|
|
|
// data.error.formattedMessage || data.error,
|
|
|
|
|
// this._view.errorContainer,
|
|
|
|
|
// { type: data.error.severity || 'error', errorType: data.error.type }
|
|
|
|
|
// )
|
|
|
|
|
if (data.error.mode === 'panic') { |
|
|
|
|
return modalDialogCustom.alert(yo` |
|
|
|
|
<div><i class="fas fa-exclamation-circle ${css.panicError}" aria-hidden="true"></i> |
|
|
|
|
The compiler returned with the following internal error: <br> <b>${data.error.formattedMessage}.<br> |
|
|
|
|
The compiler might be in a non-sane state, please be careful and do not use further compilation data to deploy to mainnet. |
|
|
|
|
It is heavily recommended to use another browser not affected by this issue (Firefox is known to not be affected).</b><br> |
|
|
|
|
Please join <a href="https://gitter.im/ethereum/remix" target="blank" >remix gitter channel</a> for more information.</div>`) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (data.errors && data.errors.length) { |
|
|
|
|
data.errors.forEach((err) => { |
|
|
|
|
if (this.config.get('hideWarnings')) { |
|
|
|
|
if (err.severity !== 'warning') { |
|
|
|
|
// this.renderer.error(err.formattedMessage, this._view.errorContainer, { type: err.severity, errorType: err.type })
|
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
// this.renderer.error(err.formattedMessage, this._view.errorContainer, { type: err.severity, errorType: err.type })
|
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
this.renderComponent() |
|
|
|
|
} |
|
|
|
|
this.compiler.event.register('compilationFinished', this.data.eventHandlers.onCompilationFinished) |
|
|
|
@ -259,11 +216,6 @@ class CompileTab extends ViewPlugin { |
|
|
|
|
return res |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// This function is used for passing the compiler remix-tests
|
|
|
|
|
getCurrentVersion () { |
|
|
|
|
return this.compilerContainer.data.selectedVersion |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// This function is used for passing the compiler configuration to 'remix-tests'
|
|
|
|
|
getCurrentCompilerConfig () { |
|
|
|
|
return { |
|
|
|
@ -296,82 +248,6 @@ class CompileTab extends ViewPlugin { |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/********* |
|
|
|
|
* SUB-COMPONENTS |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Section to select the compiled contract |
|
|
|
|
* @param {string[]} contractList Names of the compiled contracts |
|
|
|
|
*/ |
|
|
|
|
// contractSelection (contractMap) {
|
|
|
|
|
// // Return the file name of a path: ex "browser/ballot.sol" -> "ballot.sol"
|
|
|
|
|
// const getFileName = (path) => {
|
|
|
|
|
// const part = path.split('/')
|
|
|
|
|
// return part[part.length - 1]
|
|
|
|
|
// }
|
|
|
|
|
// const contractList = contractMap ? Object.keys(contractMap).map((key) => ({
|
|
|
|
|
// name: key,
|
|
|
|
|
// file: getFileName(contractMap[key].file)
|
|
|
|
|
// })) : []
|
|
|
|
|
// const selectEl = yo`
|
|
|
|
|
// <select
|
|
|
|
|
// onchange="${e => this.selectContract(e.target.value)}"
|
|
|
|
|
// data-id="compiledContracts" id="compiledContracts" class="custom-select"
|
|
|
|
|
// >
|
|
|
|
|
// ${contractList.map(({ name, file }) => yo`<option value="${name}">${name} (${file})</option>`)}
|
|
|
|
|
// </select>
|
|
|
|
|
// `
|
|
|
|
|
// // define swarm logo
|
|
|
|
|
|
|
|
|
|
// const result = contractList.length
|
|
|
|
|
// ? yo`<section class="${css.compilerSection} pt-3">
|
|
|
|
|
// <!-- Select Compiler Version -->
|
|
|
|
|
// <div class="mb-3">
|
|
|
|
|
// <label class="${css.compilerLabel} form-check-label" for="compiledContracts">Contract</label>
|
|
|
|
|
// ${selectEl}
|
|
|
|
|
// </div>
|
|
|
|
|
// <article class="mt-2 pb-0">
|
|
|
|
|
// <button id="publishOnSwarm" class="btn btn-secondary btn-block" title="Publish on Swarm" onclick="${() => { publishToStorage('swarm', this.fileProvider, this.fileManager, this.data.contractsDetails[this.selectedContract]) }}">
|
|
|
|
|
// <span>Publish on Swarm</span>
|
|
|
|
|
// <img id="swarmLogo" class="${css.storageLogo} ml-2" src="assets/img/swarm.webp">
|
|
|
|
|
// </button>
|
|
|
|
|
// <button id="publishOnIpfs" class="btn btn-secondary btn-block" title="Publish on Ipfs" onclick="${() => { publishToStorage('ipfs', this.fileProvider, this.fileManager, this.data.contractsDetails[this.selectedContract]) }}">
|
|
|
|
|
// <span>Publish on Ipfs</span>
|
|
|
|
|
// <img id="ipfsLogo" class="${css.storageLogo} ml-2" src="assets/img/ipfs.webp">
|
|
|
|
|
// </button>
|
|
|
|
|
// <button data-id="compilation-details" class="btn btn-secondary btn-block" title="Display Contract Details" onclick="${() => { this.details() }}">
|
|
|
|
|
// Compilation Details
|
|
|
|
|
// </button>
|
|
|
|
|
// <!-- Copy to Clipboard -->
|
|
|
|
|
// <div class="${css.contractHelperButtons}">
|
|
|
|
|
// <div class="input-group">
|
|
|
|
|
// <div class="btn-group" role="group" aria-label="Copy to Clipboard">
|
|
|
|
|
// <button class="btn ${css.copyButton}" title="Copy ABI to clipboard" onclick="${() => { this.copyABI() }}">
|
|
|
|
|
// <i class="${css.copyIcon} far fa-copy" aria-hidden="true"></i>
|
|
|
|
|
// <span>ABI</span>
|
|
|
|
|
// </button>
|
|
|
|
|
// <button class="btn ${css.copyButton}" title="Copy Bytecode to clipboard" onclick="${() => { this.copyBytecode() }}">
|
|
|
|
|
// <i class="${css.copyIcon} far fa-copy" aria-hidden="true"></i>
|
|
|
|
|
// <span>Bytecode</span>
|
|
|
|
|
// </button>
|
|
|
|
|
// </div>
|
|
|
|
|
// </div>
|
|
|
|
|
// </div>
|
|
|
|
|
// </div>
|
|
|
|
|
// </section>`
|
|
|
|
|
// : yo`<section class="${css.container} clearfix"><article class="px-2 mt-2 pb-0 d-flex">
|
|
|
|
|
// <span class="mt-2 mx-3 w-100 alert alert-warning" role="alert">No Contract Compiled Yet</span>
|
|
|
|
|
// </article></section>`
|
|
|
|
|
|
|
|
|
|
// if (contractList.length) {
|
|
|
|
|
// this.selectedContract = selectEl.value
|
|
|
|
|
// } else {
|
|
|
|
|
// delete this.selectedContract
|
|
|
|
|
// }
|
|
|
|
|
// return result
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// TODO : Add success alert when compilation succeed
|
|
|
|
|
contractCompiledSuccess () { |
|
|
|
|
return yo`<div></div>` |
|
|
|
@ -390,105 +266,6 @@ class CompileTab extends ViewPlugin { |
|
|
|
|
this.selectedContract = contractName |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// details () {
|
|
|
|
|
// const help = {
|
|
|
|
|
// Assembly: 'Assembly opcodes describing the contract including corresponding solidity source code',
|
|
|
|
|
// Opcodes: 'Assembly opcodes describing the contract',
|
|
|
|
|
// 'Runtime Bytecode': 'Bytecode storing the state and being executed during normal contract call',
|
|
|
|
|
// bytecode: 'Bytecode being executed during contract creation',
|
|
|
|
|
// functionHashes: 'List of declared function and their corresponding hash',
|
|
|
|
|
// gasEstimates: 'Gas estimation for each function call',
|
|
|
|
|
// metadata: 'Contains all informations related to the compilation',
|
|
|
|
|
// metadataHash: 'Hash representing all metadata information',
|
|
|
|
|
// abi: 'ABI: describing all the functions (input/output params, scope, ...)',
|
|
|
|
|
// name: 'Name of the compiled contract',
|
|
|
|
|
// swarmLocation: 'Swarm url where all metadata information can be found (contract needs to be published first)',
|
|
|
|
|
// web3Deploy: 'Copy/paste this code to any JavaScript/Web3 console to deploy this contract'
|
|
|
|
|
// }
|
|
|
|
|
// if (!this.selectedContract) throw new Error('No contract compiled yet')
|
|
|
|
|
// const contractProperties = this.contractsDetails[this.selectedContract]
|
|
|
|
|
// const log = yo`<div class="${css.detailsJSON}"></div>`
|
|
|
|
|
// Object.keys(contractProperties).map(propertyName => {
|
|
|
|
|
// const copyDetails = yo`<span class="${css.copyDetails}">${copyToClipboard(() => contractProperties[propertyName])}</span>`
|
|
|
|
|
// const questionMark = yo`<span class="${css.questionMark}"><i title="${help[propertyName]}" class="fas fa-question-circle" aria-hidden="true"></i></span>`
|
|
|
|
|
// log.appendChild(yo`<div class=${css.log}>
|
|
|
|
|
// <div class="${css.key}">${propertyName} ${copyDetails} ${questionMark}</div>
|
|
|
|
|
// ${this.insertValue(contractProperties, propertyName)}
|
|
|
|
|
// </div>`)
|
|
|
|
|
// })
|
|
|
|
|
// modalDialog(this.selectedContract, log, { label: '' }, { label: 'Close' })
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// insertValue (details, propertyName) {
|
|
|
|
|
// var node
|
|
|
|
|
// if (propertyName === 'web3Deploy' || propertyName === 'name' || propertyName === 'Assembly') {
|
|
|
|
|
// node = yo`<pre>${details[propertyName]}</pre>`
|
|
|
|
|
// } else if (propertyName === 'abi' || propertyName === 'metadata') {
|
|
|
|
|
// const treeView = new TreeView({
|
|
|
|
|
// extractData: function (item, parent, key) {
|
|
|
|
|
// var ret = {}
|
|
|
|
|
// if (item instanceof Array) {
|
|
|
|
|
// ret.children = item.map((item, index) => ({ key: index, value: item }))
|
|
|
|
|
// ret.self = ''
|
|
|
|
|
// } else if (item instanceof Object) {
|
|
|
|
|
// ret.children = Object.keys(item).map((key) => ({ key: key, value: item[key] }))
|
|
|
|
|
// ret.self = ''
|
|
|
|
|
// } else {
|
|
|
|
|
// ret.self = item
|
|
|
|
|
// ret.children = []
|
|
|
|
|
// }
|
|
|
|
|
// return ret
|
|
|
|
|
// }
|
|
|
|
|
// })
|
|
|
|
|
// if (details[propertyName] !== '') {
|
|
|
|
|
// try {
|
|
|
|
|
// node = yo`
|
|
|
|
|
// <div>
|
|
|
|
|
// ${treeView.render(typeof details[propertyName] === 'object' ? details[propertyName] : JSON.parse(details[propertyName]))}
|
|
|
|
|
// </div>` // catch in case the parsing fails.
|
|
|
|
|
// } catch (e) {
|
|
|
|
|
// node = yo`<div>Unable to display "${propertyName}": ${e.message}</div>`
|
|
|
|
|
// }
|
|
|
|
|
// } else {
|
|
|
|
|
// node = yo`<div> - </div>`
|
|
|
|
|
// }
|
|
|
|
|
// } else {
|
|
|
|
|
// node = yo`<div>${JSON.stringify(details[propertyName], null, 4)}</div>`
|
|
|
|
|
// }
|
|
|
|
|
// return yo`<pre class="${css.value}">${node || ''}</pre>`
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
getContractProperty (property) { |
|
|
|
|
if (!this.selectedContract) throw new Error('No contract compiled yet') |
|
|
|
|
const contractProperties = this.contractsDetails[this.selectedContract] |
|
|
|
|
return contractProperties[property] || null |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
copyContractProperty (property) { |
|
|
|
|
let content = this.getContractProperty(property) |
|
|
|
|
if (!content) { |
|
|
|
|
addTooltip('No content available for ' + property) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
if (typeof content !== 'string') { |
|
|
|
|
content = JSON.stringify(content, null, '\t') |
|
|
|
|
} |
|
|
|
|
} catch (e) {} |
|
|
|
|
|
|
|
|
|
copy(content) |
|
|
|
|
addTooltip('Copied value to clipboard') |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
copyABI () { |
|
|
|
|
this.copyContractProperty('abi') |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
copyBytecode () { |
|
|
|
|
this.copyContractProperty('bytecode') |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
render () { |
|
|
|
|
this.renderComponent() |
|
|
|
|
return this.el |
|
|
|
@ -509,6 +286,7 @@ class CompileTab extends ViewPlugin { |
|
|
|
|
contractsDetails={this.contractsDetails} |
|
|
|
|
setHardHatCompilation={this.setHardHatCompilation} |
|
|
|
|
contractMap={this.contractMap} |
|
|
|
|
compileErrors={this.compileErrors || {}} |
|
|
|
|
/> |
|
|
|
|
, this.el) |
|
|
|
|
} |
|
|
|
@ -534,7 +312,6 @@ class CompileTab extends ViewPlugin { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
onDeactivation () { |
|
|
|
|
this.compilerContainer.deactivate() |
|
|
|
|
this.editor.event.unregister('contentChanged', this.data.eventHandlers.onContentChanged) |
|
|
|
|
this.compiler.event.unregister('loadingCompiler', this.data.eventHandlers.onLoadingCompiler) |
|
|
|
|
this.compiler.event.unregister('compilerLoaded', this.data.eventHandlers.onCompilerLoaded) |
|
|
|
|