Merge pull request #2633 from ethereum/ipfs-tooltip

Deploy Code To IPFS
pull/1/head
yann300 5 years ago committed by GitHub
commit 8bc274b1c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      src/app.js
  2. 55
      src/app/tabs/compile-tab.js
  3. 63
      src/app/tabs/runTab/contractDropdown.js
  4. 3
      src/app/tabs/runTab/model/dropdownlogic.js
  5. 3
      src/app/udapp/run-tab.js
  6. 5
      src/blockchain/blockchain.js
  7. 47
      src/publishToStorage.js
  8. 2
      test-browser/commands/renameFile.js
  9. 2
      test-browser/tests/generalSettings.js
  10. 1
      test-browser/tests/terminal.js

@ -360,7 +360,8 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
filePanel,
registry.get('compilersartefacts').api,
networkModule,
mainview
mainview,
registry.get('fileproviders/browser').api,
)
const analysis = new AnalysisTab(registry)
const debug = new DebuggerTab(blockchain)

@ -9,8 +9,6 @@ const modalDialog = require('../ui/modaldialog')
const copyToClipboard = require('../ui/copy-to-clipboard')
const modalDialogCustom = require('../ui/modal-dialog-custom')
const parseContracts = require('./compileTab/contractParser')
const publishOnSwarm = require('../../lib/publishOnSwarm')
const publishOnIpfs = require('../../lib/publishOnIpfs')
const addTooltip = require('../ui/tooltip')
const globalRegistry = require('../../global/registry')
@ -21,6 +19,7 @@ const CompilerContainer = require('./compileTab/compilerContainer.js')
import { ViewPlugin } from '@remixproject/engine'
import * as packageJson from '../../../package.json'
import publishToStorage from '../../publishToStorage'
const profile = {
name: 'solidity',
@ -255,12 +254,12 @@ class CompileTab extends ViewPlugin {
<label class="${css.compilerLabel} form-check-label" for="compiledContracts">Contract</label>
${selectEl}
</div>
<div>
<button id="publishOnSwarm" class="btn btn-secondary btn-block" title="Publish on Swarm" onclick="${() => { this.publish('swarm') }}">
<article class="px-2 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="${swarmImg}">
</button>
<button id="publishOnIpfs" class="btn btn-secondary btn-block" title="Publish on Ipfs" onclick="${() => { this.publish('ipfs') }}">
<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="${ipfsImg}">
</button>
@ -313,52 +312,6 @@ class CompileTab extends ViewPlugin {
this.selectedContract = contractName
}
publish (storage) {
if (this.selectedContract) {
var contract = this.data.contractsDetails[this.selectedContract]
if (contract.metadata === undefined || contract.metadata.length === 0) {
modalDialogCustom.alert('This contract may be abstract, may not implement an abstract parent\'s methods completely or not invoke an inherited contract\'s constructor correctly.')
} else {
if (storage === 'swarm') {
publishOnSwarm(contract, this.fileManager, function (err, uploaded) {
if (err) {
try {
err = JSON.stringify(err)
} catch (e) {}
modalDialogCustom.alert(yo`<span>Failed to publish metadata file to swarm, please check the Swarm gateways is available ( swarm-gateways.net ).<br />
${err}</span>`)
} else {
var result = yo`<div>${uploaded.map((value) => {
return yo`<div><b>${value.filename}</b> : <pre>${value.output.url}</pre></div>`
})}</div>`
modalDialogCustom.alert(`Published ${contract.name}'s Metadata`, yo`<span>Metadata of "${contract.name.toLowerCase()}" was published successfully.<br> <pre>${result}</pre> </span>`)
}
}, (item) => { // triggered each time there's a new verified publish (means hash correspond)
this.fileProvider.addExternal('swarm/' + item.hash, item.content)
})
} else {
publishOnIpfs(contract, this.fileManager, function (err, uploaded) {
if (err) {
try {
err = JSON.stringify(err)
} catch (e) {}
modalDialogCustom.alert(yo`<span>Failed to publish metadata file to ${storage}, please check the ${storage} gateways is available.<br />
${err}</span>`)
} else {
var result = yo`<div>${uploaded.map((value) => {
return yo`<div><b>${value.filename}</b> : <pre>${value.output.url}</pre></div>`
})}</div>`
modalDialogCustom.alert(`Published ${contract.name}'s Metadata`, yo`<span>Metadata of "${contract.name.toLowerCase()}" was published successfully.<br> <pre>${result}</pre> </span>`)
}
}, (item) => { // triggered each time there's a new verified publish (means hash correspond)
this.fileProvider.addExternal('ipfs/' + item.hash, item.content)
})
}
}
}
}
details () {
const help = {
'Assembly': 'Assembly opcodes describing the contract including corresponding solidity source code',

@ -7,6 +7,8 @@ var confirmDialog = require('../../ui/confirmDialog')
var modalDialog = require('../../ui/modaldialog')
var MultiParamManager = require('../../ui/multiParamManager')
import publishToStorage from '../../../publishToStorage'
class ContractDropdownUI {
constructor (blockchain, dropdownLogic, logCallback, runView) {
this.blockchain = blockchain
@ -16,6 +18,9 @@ class ContractDropdownUI {
this.event = new EventManager()
this.listenToEvents()
this.ipfsCheckedState = false
this.exEnvironment = blockchain.getProvider()
this.listenToContextChange()
}
listenToEvents () {
@ -43,16 +48,66 @@ class ContractDropdownUI {
})
}
listenToContextChange () {
this.blockchain.event.register('contextChanged', () => {
this.blockchain.updateNetwork((err, {name} = {}) => {
if (err) {
console.log(`can't detect network`)
return
}
this.exEnvironment = this.blockchain.getProvider()
this.networkName = name
const savedConfig = window.localStorage.getItem(`ipfs/${this.exEnvironment}/${this.networkName}`)
// check if an already selected option exist else use default workflow
if (savedConfig !== null) {
this.setCheckedState(savedConfig)
} else {
this.setCheckedState(this.networkName === 'Main')
}
})
})
}
setCheckedState (value) {
value = value === 'true' ? true : value === 'false' ? false : value
this.ipfsCheckedState = value
document.getElementById('deployAndRunPublishToIPFS').checked = value
}
toggleCheckedState () {
if (this.exEnvironment === 'vm') this.networkName = 'VM'
this.ipfsCheckedState = !this.ipfsCheckedState
window.localStorage.setItem(`ipfs/${this.exEnvironment}/${this.networkName}`, this.ipfsCheckedState)
}
render () {
this.compFails = yo`<i title="No contract compiled yet or compilation failed. Please check the compile tab for more information." class="m-1 fas fa-times-circle ${css.errorIcon}" ></i>`
var info = yo`<i class="fas fa-info ${css.infoDeployAction}" aria-hidden="true" title="*.sol files allows deploying and accessing contracts. *.abi files only allows accessing contracts."></i>`
this.atAddress = yo`<button class="${css.atAddress} btn btn-sm btn-info" disabled id="runAndDeployAtAdressButton" onclick=${this.loadFromAddress.bind(this)}>At Address</button>`
this.atAddressButtonInput = yo`<input class="${css.input} ${css.ataddressinput} ataddressinput form-control" placeholder="Load contract from Address" title="address of contract" oninput=${this.atAddressChanged.bind(this)} />`
this.selectContractNames = yo`<select class="${css.contractNames} custom-select" disabled></select>`
if (this.exEnvironment === 'vm') this.networkName = 'VM'
const savedConfig = window.localStorage.getItem(`ipfs/${this.exEnvironment}/${this.networkName}`)
this.ipfsCheckedState = savedConfig === 'true' ? true : false // eslint-disable-line
const ipfsCheckbox = this.ipfsCheckedState === true
? yo`<input id="deployAndRunPublishToIPFS" class="mr-2" checked type="checkbox" onchange=${this.toggleCheckedState.bind(this)} >`
: yo`<input id="deployAndRunPublishToIPFS" class="mr-2" type="checkbox" onchange=${this.toggleCheckedState.bind(this)} >`
this.deployCheckBox = yo`
<div class="mt-2 text-left">
${ipfsCheckbox}
<label for="deployAndRunPublishToIPFS" class="text-dark p-0 m-0">PUBLISH TO IPFS</label>
<i class="fas fa-info ml-2" aria-hidden="true" title="Publishing the source code and ABI to IPFS facilitates source code verification and will greatly foster contract adoption (auditing, debugging, calling it, etc...)"></i>
</div>
`
this.createPanel = yo`<div class="${css.deployDropdown}"></div>`
this.orLabel = yo`<div class="${css.orLabel}">or</div>`
this.orLabel = yo`<div class="${css.orLabel} mt-2">or</div>`
let el = yo`
<div class="${css.container}" data-id="contractDropdownContainer">
<label class="${css.settingsLabel}">Contract</label>
@ -122,6 +177,7 @@ class ContractDropdownUI {
selectedContract.bytecodeObject
)
this.createPanel.appendChild(createConstructorInstance.render())
this.createPanel.appendChild(this.deployCheckBox)
}
getSelectedContract () {
@ -175,6 +231,9 @@ class ContractDropdownUI {
}
this.event.trigger('newContractInstanceAdded', [contractObject, address, contractObject.name])
if (this.ipfsCheckedState) {
publishToStorage('ipfs', this.runView.fileProvider, this.runView.fileManager, selectedContract)
}
}
let contractMetadata

@ -93,7 +93,8 @@ class DropdownLogic {
isOverSizeLimit: () => {
var deployedBytecode = contract.object.evm.deployedBytecode
return (deployedBytecode && deployedBytecode.object.length / 2 > 24576)
}
},
metadata: contract.object.metadata
}
}

@ -33,7 +33,7 @@ const profile = {
export class RunTab extends LibraryPlugin {
constructor (blockchain, pluginUDapp, config, fileManager, editor, filePanel, compilersArtefacts, networkModule, mainView) {
constructor (blockchain, pluginUDapp, config, fileManager, editor, filePanel, compilersArtefacts, networkModule, mainView, fileProvider) {
super(pluginUDapp, profile)
this.event = new EventManager()
this.config = config
@ -44,6 +44,7 @@ export class RunTab extends LibraryPlugin {
this.filePanel = filePanel
this.compilersArtefacts = compilersArtefacts
this.networkModule = networkModule
this.fileProvider = fileProvider
}
renderContainer () {

@ -196,17 +196,12 @@ class Blockchain {
}
updateNetwork (cb) {
this.networkcallid++
((callid) => {
this.executionContext.detectNetwork((err, { id, name } = {}) => {
if (this.networkcallid > callid) return
this.networkcallid++
if (err) {
return cb(err)
}
cb(null, {id, name})
})
})(this.networkcallid)
}
detectNetwork (cb) {

@ -0,0 +1,47 @@
const yo = require('yo-yo')
const publishOnSwarm = require('./lib/publishOnSwarm')
const publishOnIpfs = require('./lib/publishOnIpfs')
const modalDialogCustom = require('./app/ui/modal-dialog-custom')
export default function publish (storage, fileProvider, fileManager, contract) {
if (contract) {
if (contract.metadata === undefined || contract.metadata.length === 0) {
modalDialogCustom.alert('This contract may be abstract, may not implement an abstract parent\'s methods completely or not invoke an inherited contract\'s constructor correctly.')
} else {
if (storage === 'swarm') {
publishOnSwarm(contract, fileManager, function (err, uploaded) {
if (err) {
try {
err = JSON.stringify(err)
} catch (e) {}
console.log(`Failed to publish metadata file to swarm, please check the Swarm gateways is available ( swarm-gateways.net ) ${err}`)
} else {
var result = yo`<div>${uploaded.map((value) => {
return yo`<div><b>${value.filename}</b> : <pre>${value.output.url}</pre></div>`
})}</div>`
modalDialogCustom.alert(`Published ${contract.name}'s Metadata`, yo`<span>Metadata of "${contract.name.toLowerCase()}" was published successfully.<br> <pre>${result}</pre> </span>`)
}
}, (item) => { // triggered each time there's a new verified publish (means hash correspond)
fileProvider.addExternal('swarm/' + item.hash, item.content)
})
} else {
publishOnIpfs(contract, fileManager, function (err, uploaded) {
if (err) {
try {
err = JSON.stringify(err)
} catch (e) {}
modalDialogCustom.alert(yo`<span>Failed to publish metadata file to ${storage}, please check the ${storage} gateways is available.<br />
${err}</span>`)
} else {
var result = yo`<div>${uploaded.map((value) => {
return yo`<div><b>${value.filename}</b> : <pre>${value.output.url}</pre></div>`
})}</div>`
modalDialogCustom.alert(`Published ${contract.name}'s Metadata`, yo`<span>Metadata of "${contract.name.toLowerCase()}" was published successfully.<br> <pre>${result}</pre> </span>`)
}
}, (item) => { // triggered each time there's a new verified publish (means hash correspond)
fileProvider.addExternal('ipfs/' + item.hash, item.content)
})
}
}
}
}

@ -40,7 +40,7 @@ function renameFile (browser, path, newFileName, renamedPath, done) {
})
})
.click('body') // blur
.waitForElementVisible('#modal-footer-ok', 2000)
.waitForElementVisible('#modal-footer-ok', 10000)
.pause(2000)
.click('#modal-footer-ok')
.waitForElementNotPresent('[data-path="' + path + '"]')

@ -97,7 +97,7 @@ module.exports = {
'Should load Cerulean theme': function (browser) {
browser.waitForElementVisible('*[data-id="verticalIconsKindsettings"]')
.click('*[data-id="settingsTabThemeCerulean"]')
.pause(2000)
.pause(5000)
.checkElementStyle(':root', '--primary', remixIdeThemes.curelean.primary)
.checkElementStyle(':root', '--secondary', remixIdeThemes.curelean.secondary)
.checkElementStyle(':root', '--success', remixIdeThemes.curelean.success)

@ -70,6 +70,7 @@ module.exports = {
.switchFile('browser/asyncAwaitWithFileManagerAccess.js')
.pause(5000)
.executeScript(`remix.execute('browser/asyncAwaitWithFileManagerAccess.js')`)
.pause(2000)
.journalLastChildIncludes('contract Ballot {')
.end()
},

Loading…
Cancel
Save