Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
baas-ide
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
guxukai
baas-ide
Commits
bc35cbe1
Commit
bc35cbe1
authored
Apr 17, 2020
by
yann300
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fetch and compile before debugging
parent
3b365150
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
211 additions
and
25 deletions
+211
-25
compiler-artefacts.js
src/app/compiler/compiler-artefacts.js
+12
-0
compiler-sourceVerifier-fetchAndCompile.js
src/app/compiler/compiler-sourceVerifier-fetchAndCompile.js
+129
-0
compiler-utils.js
src/app/compiler/compiler-utils.js
+5
-0
debugger-tab.js
src/app/tabs/debugger-tab.js
+32
-6
debuggerUI.js
src/app/tabs/debugger/debuggerUI.js
+24
-13
test-tab.js
src/app/tabs/test-tab.js
+3
-4
remixAppManager.js
src/remixAppManager.js
+6
-2
No files found.
src/app/compiler/compiler-artefacts.js
View file @
bc35cbe1
...
@@ -33,4 +33,16 @@ module.exports = class CompilerArtefacts extends Plugin {
...
@@ -33,4 +33,16 @@ module.exports = class CompilerArtefacts extends Plugin {
this
.
compilersArtefacts
[
'__last'
]
=
new
CompilerAbstract
(
languageVersion
,
data
,
source
)
this
.
compilersArtefacts
[
'__last'
]
=
new
CompilerAbstract
(
languageVersion
,
data
,
source
)
})
})
}
}
addResolvedContract
(
address
,
compilerData
)
{
this
.
compilersArtefacts
[
address
]
=
compilerData
}
isResolved
(
address
)
{
return
this
.
compilersArtefacts
[
address
]
!==
undefined
}
get
(
key
)
{
return
this
.
compilersArtefacts
[
key
]
}
}
}
src/app/compiler/compiler-sourceVerifier-fetchAndCompile.js
0 → 100644
View file @
bc35cbe1
import
{
EventEmitter
}
from
'events'
import
{
Compiler
}
from
'remix-solidity'
import
{
canUseWorker
,
urlFromVersion
}
from
'./compiler-utils'
import
CompilerAbstract
from
'./compiler-abstract'
import
remixLib
from
'remix-lib'
class
FetchAndCompile
{
constructor
()
{
this
.
event
=
new
EventEmitter
()
this
.
compiler
=
null
this
.
unresolvedAddresses
=
[]
this
.
firstResolvedAddress
=
null
this
.
sourceVerifierNetWork
=
[
'Main'
,
'Rinkeby'
,
'Ropsten'
,
'Goerli'
]
}
/**
* Fetch compiliation metadata from source-Verify from a given @arg contractAddress - https://github.com/ethereum/source-verify
* Compile the code using Solidity compiler.
* if no contract address are passed, we default to the first resolved address.
*
* @param {string} contractAddress - Address of the contrac to resolve
* @param {string} compilersartefacts - Object containing a mapping of compilation results (byContractAddress and __last)
* @param {object} pluginAccess - any registered plugin (for making the calls)
* @return {CompilerAbstract} - compilation data targeting the given @arg contractAddress
*/
async
resolve
(
contractAddress
,
compilersartefacts
,
pluginAccess
,
targetPath
,
web3
)
{
contractAddress
=
contractAddress
||
this
.
firstResolvedAddress
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
()
if
(
this
.
firstResolvedAddress
)
return
compilersartefacts
.
get
(
this
.
firstResolvedAddress
)
// ^ for the moment we don't add compilation result for each adddress, but just for the root addres ^ . We can add this later.
// usecase is: 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
pluginAccess
.
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
)
this
.
firstResolvedAddress
=
contractAddress
setTimeout
(
_
=>
this
.
event
.
emit
(
'usingLocalCompilation'
,
contractAddress
),
0
)
return
compilation
}
}
let
name
=
network
.
name
.
toLowerCase
()
name
===
'main'
?
'mainnet'
:
name
// source-verifier api expect "mainnet" and not "main"
await
pluginAccess
.
call
(
'manager'
,
'activatePlugin'
,
'source-verification'
)
const
data
=
await
pluginAccess
.
call
(
'source-verification'
,
'fetch'
,
contractAddress
,
name
.
toLowerCase
())
if
(
!
data
||
!
data
.
metadata
)
{
setTimeout
(
_
=>
this
.
event
.
emit
(
'notFound'
,
contractAddress
),
0
)
this
.
unresolvedAddresses
.
push
(
contractAddress
)
return
localCompilation
()
}
// set the solidity contract code using metadata
await
pluginAccess
.
call
(
'fileManager'
,
'setFile'
,
`
${
targetPath
}
/
${
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
pluginAccess
.
call
(
'contentImport'
,
'resolve'
,
stdUrl
)
file
=
file
.
replace
(
'browser/'
,
''
)
// should be fixed in the remix IDE end.
const
path
=
`
${
targetPath
}
/
${
contractAddress
}
/
${
file
}
`
await
pluginAccess
.
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
)
}
return
await
(()
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
setTimeout
(
_
=>
this
.
event
.
emit
(
'compiling'
,
settings
),
0
)
if
(
!
this
.
compiler
)
this
.
compiler
=
new
Compiler
(()
=>
{})
this
.
compiler
.
set
(
'evmVersion'
,
settings
.
evmVersion
)
this
.
compiler
.
set
(
'optimize'
,
settings
.
optimize
)
this
.
compiler
.
loadVersion
(
canUseWorker
(
settings
.
version
),
settings
.
compilerUrl
)
this
.
compiler
.
event
.
register
(
'compilationFinished'
,
(
success
,
compilationData
,
source
)
=>
{
if
(
!
success
)
{
this
.
unresolvedAddresses
.
push
(
contractAddress
)
setTimeout
(
_
=>
this
.
event
.
emit
(
'compilationFailed'
,
compilationData
),
0
)
return
resolve
(
null
)
}
const
compilerData
=
new
CompilerAbstract
(
settings
.
version
,
compilationData
,
source
)
compilersartefacts
.
addResolvedContract
(
contractAddress
,
compilerData
)
this
.
firstResolvedAddress
=
contractAddress
resolve
(
compilerData
)
})
this
.
compiler
.
event
.
register
(
'compilerLoaded'
,
(
version
)
=>
{
this
.
compiler
.
compile
(
compilationTargets
,
''
)
})
})
})()
}
}
const
fetchAndCompile
=
new
FetchAndCompile
()
export
default
fetchAndCompile
src/app/compiler/compiler-utils.js
View file @
bc35cbe1
const
semver
=
require
(
'semver'
)
const
semver
=
require
(
'semver'
)
/* global Worker */
/* global Worker */
export
const
baseUrl
=
'https://solc-bin.ethereum.org/bin'
export
function
urlFromVersion
(
version
)
{
return
`
${
baseUrl
}
/soljson-v
${
version
}
.js`
}
/**
/**
* Checks if the worker can be used to load a compiler.
* Checks if the worker can be used to load a compiler.
* checks a compiler whitelist, browser support and OS.
* checks a compiler whitelist, browser support and OS.
...
...
src/app/tabs/debugger-tab.js
View file @
bc35cbe1
var
yo
=
require
(
'yo-yo'
)
const
yo
=
require
(
'yo-yo'
)
var
css
=
require
(
'./styles/debugger-tab-styles'
)
const
css
=
require
(
'./styles/debugger-tab-styles'
)
var
globalRegistry
=
require
(
'../../global/registry'
)
var
DebuggerUI
=
require
(
'./debugger/debuggerUI'
)
import
fetchAndCompile
from
'../compiler/compiler-sourceVerifier-fetchAndCompile'
import
toaster
from
'../ui/tooltip'
const
DebuggerUI
=
require
(
'./debugger/debuggerUI'
)
import
{
ViewPlugin
}
from
'@remixproject/engine'
import
{
ViewPlugin
}
from
'@remixproject/engine'
import
*
as
packageJson
from
'../../../package.json'
import
*
as
packageJson
from
'../../../package.json'
...
@@ -34,7 +35,32 @@ class DebuggerTab extends ViewPlugin {
...
@@ -34,7 +35,32 @@ class DebuggerTab extends ViewPlugin {
<div class="
${
css
.
debuggerTabView
}
" id="debugView">
<div class="
${
css
.
debuggerTabView
}
" id="debugView">
<div id="debugger" class="
${
css
.
debugger
}
"></div>
<div id="debugger" class="
${
css
.
debugger
}
"></div>
</div>`
</div>`
this
.
debuggerUI
=
new
DebuggerUI
(
this
.
el
.
querySelector
(
'#debugger'
),
this
.
blockchain
)
let
compilers
=
globalRegistry
.
get
(
'compilersartefacts'
).
api
fetchAndCompile
.
event
.
on
(
'compiling'
,
(
settings
)
=>
{
toaster
(
yo
`<div><b>Recompiling and debugging with params</b><pre>
${
JSON
.
stringify
(
settings
,
null
,
'
\
t'
)}
</pre></div>`
)
})
fetchAndCompile
.
event
.
on
(
'compilationFailed'
,
(
data
)
=>
{
toaster
(
yo
`<div><b>Compilation failed...</b> continuing <i>without</i> source code debugging.</div>`
)
})
fetchAndCompile
.
event
.
on
(
'notFound'
,
(
contractAddress
)
=>
{
toaster
(
yo
`<div><b>Contract
${
contractAddress
}
not found in source code repository</b> continuing <i>without</i> source code debugging.</div>`
)
})
fetchAndCompile
.
event
.
on
(
'usingLocalCompilation'
,
(
contractAddress
)
=>
{
toaster
(
yo
`<div><b>Using compilation result from Solidity module</b></div>`
)
})
this
.
debuggerUI
=
new
DebuggerUI
(
this
.
el
.
querySelector
(
'#debugger'
),
this
.
blockchain
,
adddress
=>
fetchAndCompile
.
resolve
(
adddress
,
compilers
,
this
,
'.debug'
,
this
.
blockchain
.
web3
()))
this
.
call
(
'manager'
,
'activatePlugin'
,
'udapp'
)
return
this
.
el
return
this
.
el
}
}
...
...
src/app/tabs/debugger/debuggerUI.js
View file @
bc35cbe1
...
@@ -30,9 +30,10 @@ var css = csjs`
...
@@ -30,9 +30,10 @@ var css = csjs`
class
DebuggerUI
{
class
DebuggerUI
{
constructor
(
container
,
blockchain
)
{
constructor
(
container
,
blockchain
,
fetchContractAndCompile
)
{
this
.
registry
=
globalRegistry
this
.
registry
=
globalRegistry
this
.
blockchain
=
blockchain
this
.
blockchain
=
blockchain
this
.
fetchContractAndCompile
=
fetchContractAndCompile
this
.
event
=
new
EventManager
()
this
.
event
=
new
EventManager
()
this
.
isActive
=
false
this
.
isActive
=
false
...
@@ -77,8 +78,12 @@ class DebuggerUI {
...
@@ -77,8 +78,12 @@ class DebuggerUI {
self
.
isActive
=
isActive
self
.
isActive
=
isActive
})
})
this
.
debugger
.
event
.
register
(
'newSourceLocation'
,
function
(
lineColumnPos
,
rawLocation
)
{
this
.
debugger
.
event
.
register
(
'newSourceLocation'
,
async
function
(
lineColumnPos
,
rawLocation
)
{
self
.
sourceHighlighter
.
currentSourceLocation
(
lineColumnPos
,
rawLocation
)
const
contracts
=
await
self
.
fetchContractAndCompile
()
if
(
contracts
)
{
const
path
=
contracts
.
getSourceName
(
rawLocation
.
file
)
if
(
path
)
self
.
sourceHighlighter
.
currentSourceLocationFromfileName
(
lineColumnPos
,
path
)
}
})
})
this
.
debugger
.
event
.
register
(
'debuggerUnloaded'
,
self
.
unLoad
.
bind
(
this
))
this
.
debugger
.
event
.
register
(
'debuggerUnloaded'
,
self
.
unLoad
.
bind
(
this
))
...
@@ -122,15 +127,18 @@ class DebuggerUI {
...
@@ -122,15 +127,18 @@ class DebuggerUI {
async
startDebugging
(
blockNumber
,
txNumber
,
tx
)
{
async
startDebugging
(
blockNumber
,
txNumber
,
tx
)
{
if
(
this
.
debugger
)
this
.
unLoad
()
if
(
this
.
debugger
)
this
.
unLoad
()
let
compilers
=
this
.
registry
.
get
(
'compilersartefacts'
).
api
let
lastCompilationResult
if
(
compilers
[
'__last'
])
lastCompilationResult
=
compilers
[
'__last'
]
let
web3
=
await
this
.
getDebugWeb3
()
let
web3
=
await
this
.
getDebugWeb3
()
this
.
debugger
=
new
Debugger
({
this
.
debugger
=
new
Debugger
({
web3
,
web3
,
offsetToLineColumnConverter
:
this
.
registry
.
get
(
'offsettolinecolumnconverter'
).
api
,
offsetToLineColumnConverter
:
this
.
registry
.
get
(
'offsettolinecolumnconverter'
).
api
,
compiler
:
{
lastCompilationResult
}
compilationResult
:
async
(
address
)
=>
{
try
{
return
await
this
.
fetchContractAndCompile
(
address
)
}
catch
(
e
)
{
console
.
error
(
e
)
}
return
null
}
})
})
this
.
listenToEvents
()
this
.
listenToEvents
()
...
@@ -147,16 +155,19 @@ class DebuggerUI {
...
@@ -147,16 +155,19 @@ class DebuggerUI {
getTrace
(
hash
)
{
getTrace
(
hash
)
{
return
new
Promise
(
async
(
resolve
,
reject
)
=>
{
return
new
Promise
(
async
(
resolve
,
reject
)
=>
{
const
compilers
=
this
.
registry
.
get
(
'compilersartefacts'
).
api
let
lastCompilationResult
if
(
compilers
[
'__last'
])
lastCompilationResult
=
compilers
[
'__last'
]
const
web3
=
await
this
.
getDebugWeb3
()
const
web3
=
await
this
.
getDebugWeb3
()
const
debug
=
new
Debugger
({
const
debug
=
new
Debugger
({
web3
,
web3
,
offsetToLineColumnConverter
:
this
.
registry
.
get
(
'offsettolinecolumnconverter'
).
api
,
offsetToLineColumnConverter
:
this
.
registry
.
get
(
'offsettolinecolumnconverter'
).
api
,
compiler
:
{
lastCompilationResult
}
compilationResult
:
async
(
address
)
=>
{
try
{
return
await
this
.
fetchContractAndCompile
(
address
)
}
catch
(
e
)
{
console
.
error
(
e
)
}
return
null
}
})
})
debug
.
debugger
.
traceManager
.
traceRetriever
.
getTrace
(
hash
,
(
error
,
trace
)
=>
{
debug
.
debugger
.
traceManager
.
traceRetriever
.
getTrace
(
hash
,
(
error
,
trace
)
=>
{
if
(
error
)
return
reject
(
error
)
if
(
error
)
return
reject
(
error
)
...
...
src/app/tabs/test-tab.js
View file @
bc35cbe1
...
@@ -4,7 +4,7 @@ var tooltip = require('../ui/tooltip')
...
@@ -4,7 +4,7 @@ var tooltip = require('../ui/tooltip')
var
css
=
require
(
'./styles/test-tab-styles'
)
var
css
=
require
(
'./styles/test-tab-styles'
)
var
remixTests
=
require
(
'remix-tests'
)
var
remixTests
=
require
(
'remix-tests'
)
import
{
ViewPlugin
}
from
'@remixproject/engine'
import
{
ViewPlugin
}
from
'@remixproject/engine'
import
{
canUseWorker
}
from
'../compiler/compiler-utils'
import
{
canUseWorker
,
baseUrl
}
from
'../compiler/compiler-utils'
const
TestTabLogic
=
require
(
'./testTab/testTab'
)
const
TestTabLogic
=
require
(
'./testTab/testTab'
)
...
@@ -33,7 +33,6 @@ module.exports = class TestTab extends ViewPlugin {
...
@@ -33,7 +33,6 @@ module.exports = class TestTab extends ViewPlugin {
this
.
runningTestsNumber
=
0
this
.
runningTestsNumber
=
0
this
.
readyTestsNumber
=
0
this
.
readyTestsNumber
=
0
this
.
areTestsRunning
=
false
this
.
areTestsRunning
=
false
this
.
baseurl
=
'https://solc-bin.ethereum.org/bin'
appManager
.
event
.
on
(
'activate'
,
(
name
)
=>
{
appManager
.
event
.
on
(
'activate'
,
(
name
)
=>
{
if
(
name
===
'solidity'
)
this
.
updateRunAction
(
fileManager
.
currentFile
())
if
(
name
===
'solidity'
)
this
.
updateRunAction
(
fileManager
.
currentFile
())
})
})
...
@@ -204,7 +203,7 @@ module.exports = class TestTab extends ViewPlugin {
...
@@ -204,7 +203,7 @@ module.exports = class TestTab extends ViewPlugin {
let
runningTest
=
{}
let
runningTest
=
{}
runningTest
[
path
]
=
{
content
}
runningTest
[
path
]
=
{
content
}
const
{
currentVersion
,
evmVersion
,
optimize
}
=
this
.
compileTab
.
getCurrentCompilerConfig
()
const
{
currentVersion
,
evmVersion
,
optimize
}
=
this
.
compileTab
.
getCurrentCompilerConfig
()
const
currentCompilerUrl
=
this
.
baseu
rl
+
'/'
+
currentVersion
const
currentCompilerUrl
=
baseU
rl
+
'/'
+
currentVersion
const
compilerConfig
=
{
const
compilerConfig
=
{
currentCompilerUrl
,
currentCompilerUrl
,
evmVersion
,
evmVersion
,
...
@@ -230,7 +229,7 @@ module.exports = class TestTab extends ViewPlugin {
...
@@ -230,7 +229,7 @@ module.exports = class TestTab extends ViewPlugin {
const
runningTest
=
{}
const
runningTest
=
{}
runningTest
[
testFilePath
]
=
{
content
}
runningTest
[
testFilePath
]
=
{
content
}
const
{
currentVersion
,
evmVersion
,
optimize
}
=
this
.
compileTab
.
getCurrentCompilerConfig
()
const
{
currentVersion
,
evmVersion
,
optimize
}
=
this
.
compileTab
.
getCurrentCompilerConfig
()
const
currentCompilerUrl
=
this
.
baseu
rl
+
'/'
+
currentVersion
const
currentCompilerUrl
=
baseU
rl
+
'/'
+
currentVersion
const
compilerConfig
=
{
const
compilerConfig
=
{
currentCompilerUrl
,
currentCompilerUrl
,
evmVersion
,
evmVersion
,
...
...
src/remixAppManager.js
View file @
bc35cbe1
...
@@ -10,10 +10,14 @@ const requiredModules = [ // services + layout views + system views
...
@@ -10,10 +10,14 @@ const requiredModules = [ // services + layout views + system views
'terminal'
,
'settings'
,
'pluginManager'
]
'terminal'
,
'settings'
,
'pluginManager'
]
export
function
isNative
(
name
)
{
export
function
isNative
(
name
)
{
const
nativePlugins
=
[
'vyper'
,
'workshops'
,
'ethdoc'
,
'etherscan'
]
const
nativePlugins
=
[
'vyper'
,
'workshops'
]
return
nativePlugins
.
includes
(
name
)
||
requiredModules
.
includes
(
name
)
return
nativePlugins
.
includes
(
name
)
||
requiredModules
.
includes
(
name
)
}
}
export
function
canActivate
(
name
)
{
return
[
'manager'
,
'debugger'
].
includes
(
name
)
}
export
class
RemixAppManager
extends
PluginManager
{
export
class
RemixAppManager
extends
PluginManager
{
constructor
(
plugins
)
{
constructor
(
plugins
)
{
...
@@ -25,7 +29,7 @@ export class RemixAppManager extends PluginManager {
...
@@ -25,7 +29,7 @@ export class RemixAppManager extends PluginManager {
}
}
async
canActivate
(
from
,
to
)
{
async
canActivate
(
from
,
to
)
{
return
from
.
name
===
'manager'
return
canActivate
(
from
.
name
)
}
}
async
canDeactivate
(
from
,
to
)
{
async
canDeactivate
(
from
,
to
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment