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
5c1c75f0
Unverified
Commit
5c1c75f0
authored
Nov 28, 2018
by
yann300
Committed by
GitHub
Nov 28, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #995 from ethereum/move_debugger
move debugger logic from remix-ide to remix-debug
parents
8846f8d4
c4bb550d
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
859 additions
and
234 deletions
+859
-234
index.js
remix-debug/index.js
+2
-0
Ethdebugger.js
remix-debug/src/Ethdebugger.js
+4
-42
SolidityLocals.js
remix-debug/src/debugger/SolidityLocals.js
+65
-0
VmDebugger.js
remix-debug/src/debugger/VmDebugger.js
+241
-0
debugger.js
remix-debug/src/debugger/debugger.js
+131
-0
solidityState.js
remix-debug/src/debugger/solidityState.js
+80
-0
stepManager.js
remix-debug/src/debugger/stepManager.js
+145
-0
util.js
remix-debug/src/solidity-decoder/types/util.js
+0
-1
tests.js
remix-debug/test/tests.js
+190
-190
execution-context.js
remix-lib/src/execution/execution-context.js
+1
-1
No files found.
remix-debug/index.js
View file @
5c1c75f0
'use strict'
'use strict'
var
EthDebugger
=
require
(
'./src/Ethdebugger'
)
var
EthDebugger
=
require
(
'./src/Ethdebugger'
)
var
TransactionDebugger
=
require
(
'./src/debugger/debugger'
)
var
StorageViewer
=
require
(
'./src/storage/storageViewer'
)
var
StorageViewer
=
require
(
'./src/storage/storageViewer'
)
var
StorageResolver
=
require
(
'./src/storage/storageResolver'
)
var
StorageResolver
=
require
(
'./src/storage/storageResolver'
)
...
@@ -19,6 +20,7 @@ var BreakpointManager = remixLib.code.BreakpointManager
...
@@ -19,6 +20,7 @@ var BreakpointManager = remixLib.code.BreakpointManager
*/
*/
module
.
exports
=
{
module
.
exports
=
{
EthDebugger
:
EthDebugger
,
EthDebugger
:
EthDebugger
,
TransactionDebugger
:
TransactionDebugger
,
/**
/**
* constructor
* constructor
*
*
...
...
remix-debug/src/Ethdebugger.js
View file @
5c1c75f0
...
@@ -13,11 +13,7 @@ var remixLib = require('remix-lib')
...
@@ -13,11 +13,7 @@ var remixLib = require('remix-lib')
var
TraceManager
=
remixLib
.
trace
.
TraceManager
var
TraceManager
=
remixLib
.
trace
.
TraceManager
var
CodeManager
=
remixLib
.
code
.
CodeManager
var
CodeManager
=
remixLib
.
code
.
CodeManager
var
traceHelper
=
remixLib
.
helpers
.
trace
var
traceHelper
=
remixLib
.
helpers
.
trace
var
init
=
remixLib
.
init
var
executionContext
=
remixLib
.
execution
.
executionContext
var
EventManager
=
remixLib
.
EventManager
var
EventManager
=
remixLib
.
EventManager
var
Web3Providers
=
remixLib
.
vm
.
Web3Providers
var
DummyProvider
=
remixLib
.
vm
.
DummyProvider
/**
/**
* Ethdebugger is a wrapper around a few classes that helps debugging a transaction
* Ethdebugger is a wrapper around a few classes that helps debugging a transaction
...
@@ -36,17 +32,12 @@ function Ethdebugger (opts) {
...
@@ -36,17 +32,12 @@ function Ethdebugger (opts) {
this
.
opts
=
opts
||
{}
this
.
opts
=
opts
||
{}
if
(
!
this
.
opts
.
compilationResult
)
this
.
opts
.
compilationResult
=
()
=>
{
return
null
}
if
(
!
this
.
opts
.
compilationResult
)
this
.
opts
.
compilationResult
=
()
=>
{
return
null
}
this
.
executionContext
=
opts
.
executionContext
||
executionContext
this
.
web3
=
opts
.
web3
this
.
web3
=
opts
.
web3
||
this
.
executionContext
.
web3
this
.
event
=
new
EventManager
()
this
.
event
=
new
EventManager
()
this
.
tx
this
.
tx
this
.
web3Providers
=
new
Web3Providers
()
this
.
addProvider
(
'DUMMYWEB3'
,
new
DummyProvider
())
this
.
switchProvider
(
'DUMMYWEB3'
)
this
.
traceManager
=
new
TraceManager
({
web3
:
this
.
web3
})
this
.
traceManager
=
new
TraceManager
({
web3
:
this
.
web3
})
this
.
codeManager
=
new
CodeManager
(
this
.
traceManager
)
this
.
codeManager
=
new
CodeManager
(
this
.
traceManager
)
this
.
solidityProxy
=
new
SolidityProxy
(
this
.
traceManager
,
this
.
codeManager
)
this
.
solidityProxy
=
new
SolidityProxy
(
this
.
traceManager
,
this
.
codeManager
)
...
@@ -163,39 +154,10 @@ Ethdebugger.prototype.storageViewAt = function (step, address) {
...
@@ -163,39 +154,10 @@ Ethdebugger.prototype.storageViewAt = function (step, address) {
address
:
address
address
:
address
},
this
.
storageResolver
,
this
.
traceManager
)
},
this
.
storageResolver
,
this
.
traceManager
)
}
}
/* set env */
Ethdebugger
.
prototype
.
web3
=
function
()
{
return
this
.
web3
}
Ethdebugger
.
prototype
.
addProvider
=
function
(
type
,
obj
)
{
Ethdebugger
.
prototype
.
updateWeb3
=
function
(
web3
)
{
this
.
web3Providers
.
addProvider
(
type
,
obj
)
this
.
web3
=
web3
this
.
event
.
trigger
(
'providerAdded'
,
[
type
])
this
.
setManagers
()
}
Ethdebugger
.
prototype
.
switchProvider
=
function
(
type
)
{
var
self
=
this
this
.
web3Providers
.
get
(
type
,
function
(
error
,
obj
)
{
if
(
error
)
{
console
.
log
(
'provider '
+
type
+
' not defined'
)
}
else
{
self
.
web3
=
obj
self
.
setManagers
()
// self.traceManager.web3 = self.web3
self
.
executionContext
.
detectNetwork
((
error
,
network
)
=>
{
if
(
error
||
!
network
)
{
self
.
web3Debug
=
obj
self
.
web3
=
obj
}
else
{
var
webDebugNode
=
init
.
web3DebugNode
(
network
.
name
)
self
.
web3Debug
=
!
webDebugNode
?
obj
:
webDebugNode
self
.
web3
=
!
webDebugNode
?
obj
:
webDebugNode
}
self
.
setManagers
()
})
self
.
event
.
trigger
(
'providerChanged'
,
[
type
])
}
})
}
}
Ethdebugger
.
prototype
.
debug
=
function
(
tx
)
{
Ethdebugger
.
prototype
.
debug
=
function
(
tx
)
{
...
...
remix-debug/src/debugger/SolidityLocals.js
0 → 100644
View file @
5c1c75f0
var
remixLib
=
require
(
'remix-lib'
)
var
EventManager
=
remixLib
.
EventManager
var
localDecoder
=
require
(
'../solidity-decoder/localDecoder'
)
var
StorageViewer
=
require
(
'../storage/storageViewer'
)
class
DebuggerSolidityLocals
{
constructor
(
tx
,
_stepManager
,
_traceManager
,
_internalTreeCall
)
{
this
.
event
=
new
EventManager
()
this
.
stepManager
=
_stepManager
this
.
internalTreeCall
=
_internalTreeCall
this
.
storageResolver
=
null
this
.
traceManager
=
_traceManager
this
.
tx
=
tx
}
init
(
sourceLocation
)
{
const
self
=
this
var
decodeTimeout
=
null
if
(
!
this
.
storageResolver
)
{
return
self
.
event
.
trigger
(
'solidityLocalsMessage'
,
[
'storage not ready'
])
}
if
(
decodeTimeout
)
{
window
.
clearTimeout
(
decodeTimeout
)
}
self
.
event
.
trigger
(
'solidityLocalsUpdating'
)
decodeTimeout
=
setTimeout
(
function
()
{
self
.
decode
(
sourceLocation
)
},
500
)
}
decode
(
sourceLocation
)
{
const
self
=
this
self
.
event
.
trigger
(
'solidityLocalsMessage'
,
[
''
])
self
.
traceManager
.
waterfall
([
self
.
traceManager
.
getStackAt
,
self
.
traceManager
.
getMemoryAt
,
self
.
traceManager
.
getCurrentCalledAddressAt
],
self
.
stepManager
.
currentStepIndex
,
(
error
,
result
)
=>
{
if
(
error
)
{
return
console
.
log
(
error
)
}
var
stack
=
result
[
0
].
value
var
memory
=
result
[
1
].
value
try
{
var
storageViewer
=
new
StorageViewer
({
stepIndex
:
self
.
stepManager
.
currentStepIndex
,
tx
:
self
.
tx
,
address
:
result
[
2
].
value
},
self
.
storageResolver
,
self
.
traceManager
)
localDecoder
.
solidityLocals
(
self
.
stepManager
.
currentStepIndex
,
self
.
internalTreeCall
,
stack
,
memory
,
storageViewer
,
sourceLocation
).
then
((
locals
)
=>
{
if
(
!
locals
.
error
)
{
self
.
event
.
trigger
(
'solidityLocals'
,
[
locals
])
}
if
(
!
Object
.
keys
(
locals
).
length
)
{
self
.
event
.
trigger
(
'solidityLocalsMessage'
,
[
'no locals'
])
}
})
}
catch
(
e
)
{
self
.
event
.
trigger
(
'solidityLocalsMessage'
,
[
e
.
message
])
}
})
}
}
module
.
exports
=
DebuggerSolidityLocals
remix-debug/src/debugger/VmDebugger.js
0 → 100644
View file @
5c1c75f0
var
remixLib
=
require
(
'remix-lib'
)
var
EventManager
=
remixLib
.
EventManager
var
ui
=
remixLib
.
helpers
.
ui
var
StorageResolver
=
require
(
'../storage/storageResolver'
)
var
StorageViewer
=
require
(
'../storage/storageViewer'
)
var
DebuggerSolidityState
=
require
(
'./solidityState'
)
var
DebuggerSolidityLocals
=
require
(
'./solidityLocals'
)
class
VmDebuggerLogic
{
constructor
(
_debugger
,
tx
,
_stepManager
,
_traceManager
,
_codeManager
,
_solidityProxy
,
_callTree
)
{
this
.
event
=
new
EventManager
()
this
.
debugger
=
_debugger
this
.
stepManager
=
_stepManager
this
.
_traceManager
=
_traceManager
this
.
_codeManager
=
_codeManager
this
.
_solidityProxy
=
_solidityProxy
this
.
_callTree
=
_callTree
this
.
storageResolver
=
null
this
.
tx
=
tx
this
.
debuggerSolidityState
=
new
DebuggerSolidityState
(
tx
,
_stepManager
,
_traceManager
,
_codeManager
,
_solidityProxy
)
this
.
debuggerSolidityLocals
=
new
DebuggerSolidityLocals
(
tx
,
_stepManager
,
_traceManager
,
_callTree
)
}
start
()
{
this
.
listenToEvents
()
this
.
listenToCodeManagerEvents
()
this
.
listenToTraceManagerEvents
()
this
.
listenToFullStorageChanges
()
this
.
listenToNewChanges
()
this
.
listenToSolidityStateEvents
()
this
.
listenToSolidityLocalsEvents
()
}
listenToEvents
()
{
const
self
=
this
this
.
debugger
.
event
.
register
(
'traceUnloaded'
,
function
()
{
self
.
event
.
trigger
(
'traceUnloaded'
)
})
this
.
debugger
.
event
.
register
(
'newTraceLoaded'
,
function
()
{
self
.
event
.
trigger
(
'newTraceLoaded'
)
})
}
listenToCodeManagerEvents
()
{
const
self
=
this
this
.
_codeManager
.
event
.
register
(
'changed'
,
function
(
code
,
address
,
index
)
{
self
.
event
.
trigger
(
'codeManagerChanged'
,
[
code
,
address
,
index
])
})
}
listenToTraceManagerEvents
()
{
const
self
=
this
this
.
event
.
register
(
'indexChanged'
,
this
,
function
(
index
)
{
if
(
index
<
0
)
return
if
(
self
.
stepManager
.
currentStepIndex
!==
index
)
return
self
.
event
.
trigger
(
'indexUpdate'
,
[
index
])
self
.
_traceManager
.
getCallDataAt
(
index
,
function
(
error
,
calldata
)
{
if
(
error
)
{
console
.
log
(
error
)
self
.
event
.
trigger
(
'traceManagerCallDataUpdate'
,
[{}])
}
else
if
(
self
.
stepManager
.
currentStepIndex
===
index
)
{
self
.
event
.
trigger
(
'traceManagerCallDataUpdate'
,
[
calldata
])
}
})
self
.
_traceManager
.
getMemoryAt
(
index
,
function
(
error
,
memory
)
{
if
(
error
)
{
console
.
log
(
error
)
self
.
event
.
trigger
(
'traceManagerMemoryUpdate'
,
[{}])
}
else
if
(
self
.
stepManager
.
currentStepIndex
===
index
)
{
self
.
event
.
trigger
(
'traceManagerMemoryUpdate'
,
[
ui
.
formatMemory
(
memory
,
16
)])
}
})
self
.
_traceManager
.
getCallStackAt
(
index
,
function
(
error
,
callstack
)
{
if
(
error
)
{
console
.
log
(
error
)
self
.
event
.
trigger
(
'traceManagerCallStackUpdate'
,
[{}])
}
else
if
(
self
.
stepManager
.
currentStepIndex
===
index
)
{
self
.
event
.
trigger
(
'traceManagerCallStackUpdate'
,
[
callstack
])
}
})
self
.
_traceManager
.
getStackAt
(
index
,
function
(
error
,
callstack
)
{
if
(
error
)
{
console
.
log
(
error
)
self
.
event
.
trigger
(
'traceManagerStackUpdate'
,
[{}])
}
else
if
(
self
.
stepManager
.
currentStepIndex
===
index
)
{
self
.
event
.
trigger
(
'traceManagerStackUpdate'
,
[
callstack
])
}
})
self
.
_traceManager
.
getCurrentCalledAddressAt
(
index
,
(
error
,
address
)
=>
{
if
(
error
)
return
if
(
!
self
.
storageResolver
)
return
var
storageViewer
=
new
StorageViewer
({
stepIndex
:
self
.
stepManager
.
currentStepIndex
,
tx
:
self
.
tx
,
address
:
address
},
self
.
storageResolver
,
self
.
_traceManager
)
storageViewer
.
storageRange
((
error
,
storage
)
=>
{
if
(
error
)
{
console
.
log
(
error
)
self
.
event
.
trigger
(
'traceManagerStorageUpdate'
,
[{}])
}
else
if
(
self
.
stepManager
.
currentStepIndex
===
index
)
{
var
header
=
storageViewer
.
isComplete
(
address
)
?
'completely loaded'
:
'partially loaded...'
self
.
event
.
trigger
(
'traceManagerStorageUpdate'
,
[
storage
,
header
])
}
})
})
self
.
_traceManager
.
getCurrentStep
(
index
,
function
(
error
,
step
)
{
self
.
event
.
trigger
(
'traceCurrentStepUpdate'
,
[
error
,
step
])
})
self
.
_traceManager
.
getMemExpand
(
index
,
function
(
error
,
addmem
)
{
self
.
event
.
trigger
(
'traceMemExpandUpdate'
,
[
error
,
addmem
])
})
self
.
_traceManager
.
getStepCost
(
index
,
function
(
error
,
gas
)
{
self
.
event
.
trigger
(
'traceStepCostUpdate'
,
[
error
,
gas
])
})
self
.
_traceManager
.
getCurrentCalledAddressAt
(
index
,
function
(
error
,
address
)
{
self
.
event
.
trigger
(
'traceCurrentCalledAddressAtUpdate'
,
[
error
,
address
])
})
self
.
_traceManager
.
getRemainingGas
(
index
,
function
(
error
,
remaining
)
{
self
.
event
.
trigger
(
'traceRemainingGasUpdate'
,
[
error
,
remaining
])
})
self
.
_traceManager
.
getReturnValue
(
index
,
function
(
error
,
returnValue
)
{
if
(
error
)
{
self
.
event
.
trigger
(
'traceReturnValueUpdate'
,
[[
error
]])
}
else
if
(
self
.
stepManager
.
currentStepIndex
===
index
)
{
self
.
event
.
trigger
(
'traceReturnValueUpdate'
,
[[
returnValue
]])
}
})
})
}
listenToFullStorageChanges
()
{
const
self
=
this
this
.
address
=
[]
this
.
traceLength
=
0
self
.
debugger
.
event
.
register
(
'newTraceLoaded'
,
function
(
length
)
{
self
.
_traceManager
.
getAddresses
(
function
(
error
,
addresses
)
{
if
(
error
)
return
self
.
event
.
trigger
(
'traceAddressesUpdate'
,
[
addresses
])
self
.
addresses
=
addresses
})
self
.
_traceManager
.
getLength
(
function
(
error
,
length
)
{
if
(
error
)
return
self
.
event
.
trigger
(
'traceLengthUpdate'
,
[
length
])
self
.
traceLength
=
length
})
})
self
.
debugger
.
event
.
register
(
'indexChanged'
,
this
,
function
(
index
)
{
if
(
index
<
0
)
return
if
(
self
.
stepManager
.
currentStepIndex
!==
index
)
return
if
(
!
self
.
storageResolver
)
return
if
(
index
!==
self
.
traceLength
-
1
)
{
return
self
.
event
.
trigger
(
'traceLengthUpdate'
,
[{}])
}
var
storageJSON
=
{}
for
(
var
k
in
self
.
addresses
)
{
var
address
=
self
.
addresses
[
k
]
var
storageViewer
=
new
StorageViewer
({
stepIndex
:
self
.
stepManager
.
currentStepIndex
,
tx
:
self
.
tx
,
address
:
address
},
self
.
storageResolver
,
self
.
_traceManager
)
storageViewer
.
storageRange
(
function
(
error
,
result
)
{
if
(
!
error
)
{
storageJSON
[
address
]
=
result
self
.
event
.
trigger
(
'traceLengthUpdate'
,
[
storageJSON
])
}
})
}
})
}
listenToNewChanges
()
{
const
self
=
this
self
.
debugger
.
event
.
register
(
'newTraceLoaded'
,
this
,
function
()
{
self
.
storageResolver
=
new
StorageResolver
({
web3
:
self
.
debugger
.
web3
})
self
.
debuggerSolidityState
.
storageResolver
=
self
.
storageResolver
self
.
debuggerSolidityLocals
.
storageResolver
=
self
.
storageResolver
self
.
event
.
trigger
(
'newTrace'
,
[])
})
self
.
debugger
.
event
.
register
(
'callTreeReady'
,
function
()
{
if
(
self
.
debugger
.
callTree
.
reducedTrace
.
length
)
{
return
self
.
event
.
trigger
(
'newCallTree'
,
[])
}
})
}
listenToSolidityStateEvents
()
{
const
self
=
this
this
.
event
.
register
(
'indexChanged'
,
this
.
debuggerSolidityState
.
init
.
bind
(
this
.
debuggerSolidityState
))
this
.
debuggerSolidityState
.
event
.
register
(
'solidityState'
,
function
(
state
)
{
self
.
event
.
trigger
(
'solidityState'
,
[
state
])
})
this
.
debuggerSolidityState
.
event
.
register
(
'solidityStateMessage'
,
function
(
message
)
{
self
.
event
.
trigger
(
'solidityStateMessage'
,
[
message
])
})
this
.
debuggerSolidityState
.
event
.
register
(
'solidityStateUpdating'
,
function
()
{
self
.
event
.
trigger
(
'solidityStateUpdating'
,
[])
})
this
.
event
.
register
(
'traceUnloaded'
,
this
.
debuggerSolidityState
.
reset
.
bind
(
this
.
debuggerSolidityState
))
this
.
event
.
register
(
'newTraceLoaded'
,
this
.
debuggerSolidityState
.
reset
.
bind
(
this
.
debuggerSolidityState
))
}
listenToSolidityLocalsEvents
()
{
const
self
=
this
this
.
event
.
register
(
'sourceLocationChanged'
,
this
.
debuggerSolidityLocals
.
init
.
bind
(
this
.
debuggerSolidityLocals
))
this
.
debuggerSolidityLocals
.
event
.
register
(
'solidityLocals'
,
function
(
state
)
{
self
.
event
.
trigger
(
'solidityLocals'
,
[
state
])
})
this
.
debuggerSolidityLocals
.
event
.
register
(
'solidityLocalsMessage'
,
function
(
message
)
{
self
.
event
.
trigger
(
'solidityLocalsMessage'
,
[
message
])
})
this
.
debuggerSolidityLocals
.
event
.
register
(
'solidityLocalsUpdating'
,
function
()
{
self
.
event
.
trigger
(
'solidityLocalsUpdating'
,
[])
})
this
.
debuggerSolidityLocals
.
event
.
register
(
'traceReturnValueUpdate'
,
function
(
data
,
header
)
{
self
.
event
.
trigger
(
'traceReturnValueUpdate'
,
[
data
,
header
])
})
}
}
module
.
exports
=
VmDebuggerLogic
remix-debug/src/debugger/debugger.js
0 → 100644
View file @
5c1c75f0
'use strict'
var
Ethdebugger
=
require
(
'../Ethdebugger'
)
var
remixLib
=
require
(
'remix-lib'
)
var
EventManager
=
remixLib
.
EventManager
var
traceHelper
=
remixLib
.
helpers
.
trace
var
StepManager
=
require
(
'./stepManager'
)
var
VmDebuggerLogic
=
require
(
'./VmDebugger'
)
function
Debugger
(
options
)
{
var
self
=
this
this
.
event
=
new
EventManager
()
this
.
offsetToLineColumnConverter
=
options
.
offsetToLineColumnConverter
this
.
compiler
=
options
.
compiler
this
.
debugger
=
new
Ethdebugger
({
web3
:
options
.
web3
,
compilationResult
:
()
=>
{
var
compilationResult
=
this
.
compiler
.
lastCompilationResult
if
(
compilationResult
)
{
return
compilationResult
.
data
}
return
null
}
})
this
.
breakPointManager
=
new
remixLib
.
code
.
BreakpointManager
(
this
.
debugger
,
(
sourceLocation
)
=>
{
return
self
.
offsetToLineColumnConverter
.
offsetToLineColumn
(
sourceLocation
,
sourceLocation
.
file
,
this
.
compiler
.
lastCompilationResult
.
source
.
sources
,
this
.
compiler
.
lastCompilationResult
.
data
.
sources
)
},
(
step
)
=>
{
self
.
event
.
trigger
(
'breakpointStep'
,
[
step
])
})
this
.
debugger
.
setBreakpointManager
(
this
.
breakPointManager
)
this
.
debugger
.
event
.
register
(
'newTraceLoaded'
,
this
,
function
()
{
self
.
event
.
trigger
(
'debuggerStatus'
,
[
true
])
})
this
.
debugger
.
event
.
register
(
'traceUnloaded'
,
this
,
function
()
{
self
.
event
.
trigger
(
'debuggerStatus'
,
[
false
])
})
this
.
event
.
register
(
'breakpointStep'
,
function
(
step
)
{
self
.
step_manager
.
jumpTo
(
step
)
})
}
Debugger
.
prototype
.
registerAndHighlightCodeItem
=
function
(
index
)
{
const
self
=
this
// register selected code item, highlight the corresponding source location
if
(
!
self
.
compiler
.
lastCompilationResult
)
return
self
.
debugger
.
traceManager
.
getCurrentCalledAddressAt
(
index
,
(
error
,
address
)
=>
{
if
(
error
)
return
console
.
log
(
error
)
self
.
debugger
.
callTree
.
sourceLocationTracker
.
getSourceLocationFromVMTraceIndex
(
address
,
index
,
self
.
compiler
.
lastCompilationResult
.
data
.
contracts
,
function
(
error
,
rawLocation
)
{
if
(
!
error
&&
self
.
compiler
.
lastCompilationResult
&&
self
.
compiler
.
lastCompilationResult
.
data
)
{
var
lineColumnPos
=
self
.
offsetToLineColumnConverter
.
offsetToLineColumn
(
rawLocation
,
rawLocation
.
file
,
self
.
compiler
.
lastCompilationResult
.
source
.
sources
,
self
.
compiler
.
lastCompilationResult
.
data
.
sources
)
self
.
event
.
trigger
(
'newSourceLocation'
,
[
lineColumnPos
,
rawLocation
])
}
else
{
self
.
event
.
trigger
(
'newSourceLocation'
,
[
null
])
}
})
})
}
Debugger
.
prototype
.
updateWeb3
=
function
(
web3
)
{
this
.
debugger
.
web3
=
web3
}
Debugger
.
prototype
.
debug
=
function
(
blockNumber
,
txNumber
,
tx
,
loadingCb
)
{
const
self
=
this
let
web3
=
this
.
debugger
.
web3
if
(
this
.
debugger
.
traceManager
.
isLoading
)
{
return
}
if
(
tx
)
{
if
(
!
tx
.
to
)
{
tx
.
to
=
traceHelper
.
contractCreationToken
(
'0'
)
}
return
self
.
debugTx
(
tx
,
loadingCb
)
}
try
{
if
(
txNumber
.
indexOf
(
'0x'
)
!==
-
1
)
{
return
web3
.
eth
.
getTransaction
(
txNumber
,
function
(
_error
,
result
)
{
let
tx
=
result
self
.
debugTx
(
tx
,
loadingCb
)
})
}
web3
.
eth
.
getTransactionFromBlock
(
blockNumber
,
txNumber
,
function
(
_error
,
result
)
{
let
tx
=
result
self
.
debugTx
(
tx
,
loadingCb
)
})
}
catch
(
e
)
{
console
.
error
(
e
.
message
)
}
}
Debugger
.
prototype
.
debugTx
=
function
(
tx
,
loadingCb
)
{
const
self
=
this
this
.
step_manager
=
new
StepManager
(
this
.
debugger
,
this
.
debugger
.
traceManager
)
this
.
debugger
.
codeManager
.
event
.
register
(
'changed'
,
this
,
(
code
,
address
,
instIndex
)
=>
{
self
.
debugger
.
callTree
.
sourceLocationTracker
.
getSourceLocationFromVMTraceIndex
(
address
,
this
.
step_manager
.
currentStepIndex
,
this
.
debugger
.
solidityProxy
.
contracts
,
(
error
,
sourceLocation
)
=>
{
if
(
!
error
)
{
self
.
vmDebuggerLogic
.
event
.
trigger
(
'sourceLocationChanged'
,
[
sourceLocation
])
}
})
})
this
.
vmDebuggerLogic
=
new
VmDebuggerLogic
(
this
.
debugger
,
tx
,
this
.
step_manager
,
this
.
debugger
.
traceManager
,
this
.
debugger
.
codeManager
,
this
.
debugger
.
solidityProxy
,
this
.
debugger
.
callTree
)
this
.
step_manager
.
event
.
register
(
'stepChanged'
,
this
,
function
(
stepIndex
)
{
self
.
debugger
.
codeManager
.
resolveStep
(
stepIndex
,
tx
)
self
.
step_manager
.
event
.
trigger
(
'indexChanged'
,
[
stepIndex
])
self
.
vmDebuggerLogic
.
event
.
trigger
(
'indexChanged'
,
[
stepIndex
])
self
.
registerAndHighlightCodeItem
(
stepIndex
)
})
loadingCb
()
this
.
debugger
.
debug
(
tx
)
}
Debugger
.
prototype
.
unload
=
function
()
{
this
.
debugger
.
unLoad
()
this
.
event
.
trigger
(
'debuggerUnloaded'
)
}
module
.
exports
=
Debugger
remix-debug/src/debugger/solidityState.js
0 → 100644
View file @
5c1c75f0
var
remixLib
=
require
(
'remix-lib'
)
var
EventManager
=
remixLib
.
EventManager
var
stateDecoder
=
require
(
'../solidity-decoder/stateDecoder'
)
var
StorageViewer
=
require
(
'../storage/storageViewer'
)
class
DebuggerSolidityState
{
constructor
(
tx
,
_stepManager
,
_traceManager
,
_codeManager
,
_solidityProxy
)
{
this
.
event
=
new
EventManager
()
this
.
storageResolver
=
null
this
.
stepManager
=
_stepManager
this
.
traceManager
=
_traceManager
this
.
codeManager
=
_codeManager
this
.
solidityProxy
=
_solidityProxy
this
.
stateVariablesByAddresses
=
{}
this
.
tx
=
tx
}
init
(
index
)
{
var
self
=
this
var
decodeTimeout
=
null
if
(
index
<
0
)
{
return
self
.
event
.
trigger
(
'solidityStateMessage'
,
[
'invalid step index'
])
}
if
(
self
.
stepManager
.
currentStepIndex
!==
index
)
return
if
(
!
self
.
solidityProxy
.
loaded
())
{
return
self
.
event
.
trigger
(
'solidityStateMessage'
,
[
'invalid step index'
])
}
if
(
!
self
.
storageResolver
)
{
return
}
if
(
decodeTimeout
)
{
window
.
clearTimeout
(
decodeTimeout
)
}
self
.
event
.
trigger
(
'solidityStateUpdating'
)
decodeTimeout
=
setTimeout
(
function
()
{
self
.
decode
(
index
)
},
500
)
}
reset
()
{
this
.
stateVariablesByAddresses
=
{}
}
decode
(
index
)
{
const
self
=
this
self
.
traceManager
.
getCurrentCalledAddressAt
(
self
.
stepManager
.
currentStepIndex
,
function
(
error
,
address
)
{
if
(
error
)
{
return
self
.
event
.
trigger
(
'solidityState'
,
[{}])
}
if
(
self
.
stateVariablesByAddresses
[
address
])
{
return
self
.
extractStateVariables
(
self
.
stateVariablesByAddresses
[
address
],
address
)
}
self
.
solidityProxy
.
extractStateVariablesAt
(
index
,
function
(
error
,
stateVars
)
{
if
(
error
)
{
return
self
.
event
.
trigger
(
'solidityState'
,
[{}])
}
self
.
stateVariablesByAddresses
[
address
]
=
stateVars
self
.
extractStateVariables
(
stateVars
,
address
)
})
})
}
extractStateVariables
(
stateVars
,
address
)
{
const
self
=
this
var
storageViewer
=
new
StorageViewer
({
stepIndex
:
self
.
stepManager
.
currentStepIndex
,
tx
:
self
.
tx
,
address
:
address
},
self
.
storageResolver
,
self
.
traceManager
)
stateDecoder
.
decodeState
(
stateVars
,
storageViewer
).
then
((
result
)
=>
{
self
.
event
.
trigger
(
'solidityStateMessage'
,
[
''
])
if
(
result
.
error
)
{
return
self
.
event
.
trigger
(
'solidityStateMessage'
,
[
result
.
error
])
}
self
.
event
.
trigger
(
'solidityState'
,
[
result
])
})
}
}
module
.
exports
=
DebuggerSolidityState
remix-debug/src/debugger/stepManager.js
0 → 100644
View file @
5c1c75f0
var
remixLib
=
require
(
'remix-lib'
)
var
EventManager
=
remixLib
.
EventManager
class
DebuggerStepManager
{
constructor
(
_debugger
,
traceManager
)
{
this
.
event
=
new
EventManager
()
this
.
debugger
=
_debugger
this
.
traceManager
=
traceManager
this
.
currentStepIndex
=
0
this
.
traceLength
=
0
this
.
revertionPoint
=
null
this
.
listenToEvents
()
}
listenToEvents
()
{
const
self
=
this
this
.
debugger
.
event
.
register
(
'newTraceLoaded'
,
this
,
function
()
{
self
.
traceManager
.
getLength
(
function
(
error
,
newLength
)
{
if
(
error
)
{
return
console
.
log
(
error
)
}
if
(
self
.
traceLength
!==
newLength
)
{
self
.
event
.
trigger
(
'traceLengthChanged'
,
[
newLength
])
self
.
traceLength
=
newLength
}
self
.
jumpTo
(
0
)
})
})
this
.
debugger
.
callTree
.
event
.
register
(
'callTreeReady'
,
()
=>
{
if
(
self
.
debugger
.
callTree
.
functionCallStack
.
length
)
{
self
.
jumpTo
(
self
.
debugger
.
callTree
.
functionCallStack
[
0
])
}
})
this
.
event
.
register
(
'indexChanged'
,
this
,
(
index
)
=>
{
if
(
index
<
0
)
return
if
(
self
.
currentStepIndex
!==
index
)
return
self
.
traceManager
.
buildCallPath
(
index
,
(
error
,
callsPath
)
=>
{
if
(
error
)
{
console
.
log
(
error
)
return
self
.
event
.
trigger
(
'revertWarning'
,
[
''
])
}
self
.
currentCall
=
callsPath
[
callsPath
.
length
-
1
]
if
(
self
.
currentCall
.
reverted
)
{
let
revertedReason
=
self
.
currentCall
.
outofgas
?
'outofgas'
:
''
self
.
revertionPoint
=
self
.
currentCall
.
return
return
self
.
event
.
trigger
(
'revertWarning'
,
[
revertedReason
])
}
for
(
var
k
=
callsPath
.
length
-
2
;
k
>=
0
;
k
--
)
{
var
parent
=
callsPath
[
k
]
if
(
!
parent
.
reverted
)
continue
self
.
revertionPoint
=
parent
.
return
self
.
event
.
trigger
(
'revertWarning'
,
[
'parenthasthrown'
])
}
self
.
event
.
trigger
(
'revertWarning'
,
[
''
])
})
})
}
triggerStepChanged
(
step
)
{
const
self
=
this
this
.
traceManager
.
getLength
(
function
(
error
,
length
)
{
let
stepState
=
'valid'
if
(
error
)
{
stepState
=
'invalid'
}
else
if
(
step
<=
0
)
{
stepState
=
'initial'
}
else
if
(
step
>=
length
-
1
)
{
stepState
=
'end'
}
let
jumpOutDisabled
=
(
step
===
self
.
traceManager
.
findStepOut
(
step
))
self
.
event
.
trigger
(
'stepChanged'
,
[
step
,
stepState
,
jumpOutDisabled
])
})
}
stepIntoBack
()
{
if
(
!
this
.
traceManager
.
isLoaded
())
return
var
step
=
this
.
currentStepIndex
-
1
this
.
currentStepIndex
=
step
if
(
!
this
.
traceManager
.
inRange
(
step
))
{
return
}
this
.
event
.
trigger
(
'stepChanged'
,
[
step
])
}
stepIntoForward
()
{
if
(
!
this
.
traceManager
.
isLoaded
())
return
var
step
=
this
.
currentStepIndex
+
1
this
.
currentStepIndex
=
step
if
(
!
this
.
traceManager
.
inRange
(
step
))
{
return
}
this
.
event
.
trigger
(
'stepChanged'
,
[
step
])
}
stepOverBack
()
{
if
(
!
this
.
traceManager
.
isLoaded
())
return
var
step
=
this
.
traceManager
.
findStepOverBack
(
this
.
currentStepIndex
)
this
.
currentStepIndex
=
step
this
.
event
.
trigger
(
'stepChanged'
,
[
step
])
}
stepOverForward
()
{
if
(
!
this
.
traceManager
.
isLoaded
())
return
var
step
=
this
.
traceManager
.
findStepOverForward
(
this
.
currentStepIndex
)
this
.
currentStepIndex
=
step
this
.
event
.
trigger
(
'stepChanged'
,
[
step
])
}
jumpOut
()
{
if
(
!
this
.
traceManager
.
isLoaded
())
return
var
step
=
this
.
traceManager
.
findStepOut
(
this
.
currentStepIndex
)
this
.
currentStepIndex
=
step
this
.
event
.
trigger
(
'stepChanged'
,
[
step
])
}
jumpTo
(
step
)
{
if
(
!
this
.
traceManager
.
inRange
(
step
))
return
this
.
currentStepIndex
=
step
this
.
event
.
trigger
(
'stepChanged'
,
[
step
])
}
jumpToException
()
{
this
.
jumpTo
(
this
.
revertionPoint
)
}
jumpNextBreakpoint
()
{
this
.
debugger
.
breakpointManager
.
jumpNextBreakpoint
(
this
.
currentStepIndex
,
true
)
}
jumpPreviousBreakpoint
()
{
this
.
debugger
.
breakpointManager
.
jumpPreviousBreakpoint
(
this
.
currentStepIndex
,
true
)
}
}
module
.
exports
=
DebuggerStepManager
remix-debug/src/solidity-decoder/types/util.js
View file @
5c1c75f0
...
@@ -67,7 +67,6 @@ async function extractHexValue (location, storageResolver, byteLength) {
...
@@ -67,7 +67,6 @@ async function extractHexValue (location, storageResolver, byteLength) {
try
{
try
{
slotvalue
=
await
readFromStorage
(
location
.
slot
,
storageResolver
)
slotvalue
=
await
readFromStorage
(
location
.
slot
,
storageResolver
)
}
catch
(
e
)
{
}
catch
(
e
)
{
console
.
log
(
e
)
return
'0x'
return
'0x'
}
}
return
extractHexByteSlice
(
slotvalue
,
byteLength
,
location
.
offset
)
return
extractHexByteSlice
(
slotvalue
,
byteLength
,
location
.
offset
)
...
...
remix-debug/test/tests.js
View file @
5c1c75f0
'use strict'
//
'use strict'
var
tape
=
require
(
'tape'
)
//
var tape = require('tape')
var
remixLib
=
require
(
'remix-lib'
)
//
var remixLib = require('remix-lib')
var
compilerInput
=
remixLib
.
helpers
.
compiler
.
compilerInput
//
var compilerInput = remixLib.helpers.compiler.compilerInput
var
vmCall
=
require
(
'./vmCall'
)
//
var vmCall = require('./vmCall')
var
Debugger
=
require
(
'../src/Ethdebugger'
)
//
var Debugger = require('../src/Ethdebugger')
var
compiler
=
require
(
'solc'
)
//
var compiler = require('solc')
//
require
(
'./decoder/decodeInfo.js'
)
//
require('./decoder/decodeInfo.js')
require
(
'./decoder/storageLocation.js'
)
//
require('./decoder/storageLocation.js')
require
(
'./decoder/storageDecoder.js'
)
//
require('./decoder/storageDecoder.js')
require
(
'./decoder/localDecoder.js'
)
//
require('./decoder/localDecoder.js')
//
var
BreakpointManager
=
remixLib
.
code
.
BreakpointManager
//
var BreakpointManager = remixLib.code.BreakpointManager
//
tape
(
'debug contract'
,
function
(
t
)
{
//
tape('debug contract', function (t) {
t
.
plan
(
12
)
//
t.plan(12)
var
privateKey
=
Buffer
.
from
(
'dae9801649ba2d95a21e688b56f77905e5667c44ce868ec83f82e838712a2c7a'
,
'hex'
)
//
var privateKey = Buffer.from('dae9801649ba2d95a21e688b56f77905e5667c44ce868ec83f82e838712a2c7a', 'hex')
var
vm
=
vmCall
.
initVM
(
t
,
privateKey
)
//
var vm = vmCall.initVM(t, privateKey)
var
output
=
compiler
.
compile
(
compilerInput
(
ballot
))
//
var output = compiler.compile(compilerInput(ballot))
output
=
JSON
.
parse
(
output
)
//
output = JSON.parse(output)
var
web3VM
=
new
remixLib
.
vm
.
Web3VMProvider
()
//
var web3VM = new remixLib.vm.Web3VMProvider()
web3VM
.
setVM
(
vm
)
//
web3VM.setVM(vm)
vmCall
.
sendTx
(
vm
,
{
nonce
:
0
,
privateKey
:
privateKey
},
null
,
0
,
output
.
contracts
[
'test.sol'
][
'Ballot'
].
evm
.
bytecode
.
object
,
(
error
,
txHash
)
=>
{
//
vmCall.sendTx(vm, {nonce: 0, privateKey: privateKey}, null, 0, output.contracts['test.sol']['Ballot'].evm.bytecode.object, (error, txHash) => {
if
(
error
)
{
//
if (error) {
t
.
end
(
error
)
//
t.end(error)
}
else
{
//
} else {
web3VM
.
eth
.
getTransaction
(
txHash
,
(
error
,
tx
)
=>
{
//
web3VM.eth.getTransaction(txHash, (error, tx) => {
if
(
error
)
{
//
if (error) {
t
.
end
(
error
)
//
t.end(error)
}
else
{
//
} else {
var
debugManager
=
new
Debugger
({
//
var debugManager = new Debugger({
compilationResult
:
function
()
{
//
compilationResult: function () {
return
output
//
return output
}
//
}
})
//
})
//
debugManager
.
addProvider
(
'web3vmprovider'
,
web3VM
)
//
debugManager.addProvider('web3vmprovider', web3VM)
debugManager
.
switchProvider
(
'web3vmprovider'
)
//
debugManager.switchProvider('web3vmprovider')
//
debugManager
.
callTree
.
event
.
register
(
'callTreeReady'
,
()
=>
{
//
debugManager.callTree.event.register('callTreeReady', () => {
testDebugging
(
t
,
debugManager
)
//
testDebugging(t, debugManager)
})
//
})
//
debugManager
.
debug
(
tx
)
//
debugManager.debug(tx)
}
//
}
})
//
})
}
//
}
})
//
})
})
//
})
//
//
function
testDebugging
(
t
,
debugManager
)
{
//
function testDebugging (t, debugManager) {
// stack
//
// stack
debugManager
.
traceManager
.
getStackAt
(
4
,
(
error
,
callstack
)
=>
{
//
debugManager.traceManager.getStackAt(4, (error, callstack) => {
if
(
error
)
return
t
.
end
(
error
)
//
if (error) return t.end(error)
t
.
equal
(
JSON
.
stringify
(
callstack
),
JSON
.
stringify
([
'0x0000000000000000000000000000000000000000000000000000000000000000'
]))
//
t.equal(JSON.stringify(callstack), JSON.stringify([ '0x0000000000000000000000000000000000000000000000000000000000000000' ]))
})
//
})
//
debugManager
.
traceManager
.
getStackAt
(
41
,
(
error
,
callstack
)
=>
{
//
debugManager.traceManager.getStackAt(41, (error, callstack) => {
if
(
error
)
return
t
.
end
(
error
)
//
if (error) return t.end(error)
//
/*
//
/*
t.equal(JSON.stringify(callstack), JSON.stringify(['0x0000000000000000000000000000000000000000000000000000000000000000', '0x0000000000000000000000004b0897b0513fdc7c541b6d9d7e929c4e5364d2db', '0x0000000000000000000000000000000000000000000000000000000000000000', '0x0000000000000000000000000000000000000000000000000000000000000001', '0x000000000000000000000000000000000000000000000000000000000000002d']))
//
t.equal(JSON.stringify(callstack), JSON.stringify(['0x0000000000000000000000000000000000000000000000000000000000000000', '0x0000000000000000000000004b0897b0513fdc7c541b6d9d7e929c4e5364d2db', '0x0000000000000000000000000000000000000000000000000000000000000000', '0x0000000000000000000000000000000000000000000000000000000000000001', '0x000000000000000000000000000000000000000000000000000000000000002d']))
*/
//
*/
})
//
})
//
// storage
//
// storage
debugManager
.
traceManager
.
getCurrentCalledAddressAt
(
38
,
(
error
,
address
)
=>
{
//
debugManager.traceManager.getCurrentCalledAddressAt(38, (error, address) => {
if
(
error
)
return
t
.
end
(
error
)
//
if (error) return t.end(error)
var
storageView
=
debugManager
.
storageViewAt
(
38
,
address
)
//
var storageView = debugManager.storageViewAt(38, address)
storageView
.
storageRange
((
error
,
storage
)
=>
{
//
storageView.storageRange((error, storage) => {
if
(
error
)
return
t
.
end
(
error
)
//
if (error) return t.end(error)
t
.
equal
(
JSON
.
stringify
(
storage
),
JSON
.
stringify
({
'0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563'
:
{
key
:
'0x0000000000000000000000000000000000000000000000000000000000000000'
,
value
:
'0x0000000000000000000000004b0897b0513fdc7c541b6d9d7e929c4e5364d2db'
}
}))
//
t.equal(JSON.stringify(storage), JSON.stringify({ '0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563': { key: '0x0000000000000000000000000000000000000000000000000000000000000000', value: '0x0000000000000000000000004b0897b0513fdc7c541b6d9d7e929c4e5364d2db' } }))
})
//
})
})
//
})
//
debugManager
.
extractStateAt
(
116
,
(
error
,
state
)
=>
{
//
debugManager.extractStateAt(116, (error, state) => {
if
(
error
)
return
t
.
end
(
error
)
//
if (error) return t.end(error)
debugManager
.
decodeStateAt
(
116
,
state
,
(
error
,
decodedState
)
=>
{
//
debugManager.decodeStateAt(116, state, (error, decodedState) => {
if
(
error
)
return
t
.
end
(
error
)
//
if (error) return t.end(error)
t
.
equal
(
decodedState
[
'chairperson'
].
value
,
'0x4B0897B0513FDC7C541B6D9D7E929C4E5364D2DB'
)
//
t.equal(decodedState['chairperson'].value, '0x4B0897B0513FDC7C541B6D9D7E929C4E5364D2DB')
t
.
equal
(
decodedState
[
'chairperson'
].
type
,
'address'
)
//
t.equal(decodedState['chairperson'].type, 'address')
t
.
equal
(
decodedState
[
'proposals'
].
value
[
0
].
value
.
voteCount
.
value
,
'0'
)
//
t.equal(decodedState['proposals'].value[0].value.voteCount.value, '0')
t
.
equal
(
decodedState
[
'proposals'
].
value
[
0
].
value
.
voteCount
.
type
,
'uint256'
)
//
t.equal(decodedState['proposals'].value[0].value.voteCount.type, 'uint256')
t
.
equal
(
decodedState
[
'proposals'
].
value
[
0
].
type
,
'struct Ballot.Proposal'
)
//
t.equal(decodedState['proposals'].value[0].type, 'struct Ballot.Proposal')
t
.
equal
(
decodedState
[
'proposals'
].
length
,
'0x1'
)
//
t.equal(decodedState['proposals'].length, '0x1')
t
.
equal
(
decodedState
[
'proposals'
].
type
,
'struct Ballot.Proposal[]'
)
//
t.equal(decodedState['proposals'].type, 'struct Ballot.Proposal[]')
})
//
})
})
//
})
//
debugManager
.
traceManager
.
getCurrentCalledAddressAt
(
104
,
(
error
,
address
)
=>
{
//
debugManager.traceManager.getCurrentCalledAddressAt(104, (error, address) => {
if
(
error
)
return
t
.
end
(
error
)
//
if (error) return t.end(error)
debugManager
.
sourceLocationFromVMTraceIndex
(
address
,
104
,
(
error
,
location
)
=>
{
//
debugManager.sourceLocationFromVMTraceIndex(address, 104, (error, location) => {
if
(
error
)
return
t
.
end
(
error
)
//
if (error) return t.end(error)
debugManager
.
decodeLocalsAt
(
104
,
location
,
(
error
,
decodedlocals
)
=>
{
//
debugManager.decodeLocalsAt(104, location, (error, decodedlocals) => {
if
(
error
)
return
t
.
end
(
error
)
//
if (error) return t.end(error)
t
.
equal
(
JSON
.
stringify
(
decodedlocals
),
JSON
.
stringify
({
'p'
:
{
'value'
:
'45'
,
'type'
:
'uint256'
},
'addressLocal'
:
{
'value'
:
'0x4B0897B0513FDC7C541B6D9D7E929C4E5364D2DB'
,
'type'
:
'address'
},
'proposalsLocals'
:
{
'value'
:
[{
'value'
:
{
'voteCount'
:
{
'value'
:
'0'
,
'type'
:
'uint256'
}},
'type'
:
'struct Ballot.Proposal'
}],
'length'
:
'0x1'
,
'type'
:
'struct Ballot.Proposal[]'
}}))
//
t.equal(JSON.stringify(decodedlocals), JSON.stringify({'p': {'value': '45', 'type': 'uint256'}, 'addressLocal': {'value': '0x4B0897B0513FDC7C541B6D9D7E929C4E5364D2DB', 'type': 'address'}, 'proposalsLocals': {'value': [{'value': {'voteCount': {'value': '0', 'type': 'uint256'}}, 'type': 'struct Ballot.Proposal'}], 'length': '0x1', 'type': 'struct Ballot.Proposal[]'}}))
})
//
})
})
//
})
})
//
})
//
var
sourceMappingDecoder
=
new
remixLib
.
SourceMappingDecoder
()
//
var sourceMappingDecoder = new remixLib.SourceMappingDecoder()
var
breakPointManager
=
new
BreakpointManager
(
debugManager
,
(
rawLocation
)
=>
{
//
var breakPointManager = new BreakpointManager(debugManager, (rawLocation) => {
return
sourceMappingDecoder
.
convertOffsetToLineColumn
(
rawLocation
,
sourceMappingDecoder
.
getLinebreakPositions
(
ballot
))
//
return sourceMappingDecoder.convertOffsetToLineColumn(rawLocation, sourceMappingDecoder.getLinebreakPositions(ballot))
})
//
})
//
breakPointManager
.
add
({
fileName
:
'test.sol'
,
row
:
23
})
//
breakPointManager.add({fileName: 'test.sol', row: 23})
//
breakPointManager
.
event
.
register
(
'breakpointHit'
,
function
(
sourceLocation
,
step
)
{
//
breakPointManager.event.register('breakpointHit', function (sourceLocation, step) {
console
.
log
(
'breakpointHit'
)
//
console.log('breakpointHit')
t
.
equal
(
JSON
.
stringify
(
sourceLocation
),
JSON
.
stringify
({
start
:
587
,
length
:
1
,
file
:
0
,
jump
:
'-'
}))
//
t.equal(JSON.stringify(sourceLocation), JSON.stringify({ start: 587, length: 1, file: 0, jump: '-' }))
t
.
equal
(
step
,
74
)
//
t.equal(step, 74)
})
//
})
//
breakPointManager
.
event
.
register
(
'noBreakpointHit'
,
function
()
{
//
breakPointManager.event.register('noBreakpointHit', function () {
t
.
end
(
'noBreakpointHit'
)
//
t.end('noBreakpointHit')
console
.
log
(
'noBreakpointHit'
)
//
console.log('noBreakpointHit')
})
//
})
breakPointManager
.
jumpNextBreakpoint
(
0
,
true
)
//
breakPointManager.jumpNextBreakpoint(0, true)
}
//
}
//
var
ballot
=
`pragma solidity ^0.5.0;
//
var ballot = `pragma solidity ^0.5.0;
contract Ballot {
//
contract Ballot {
//
struct Voter {
//
struct Voter {
uint weight;
//
uint weight;
bool voted;
//
bool voted;
uint8 vote;
//
uint8 vote;
address delegate;
//
address delegate;
}
//
}
struct Proposal {
//
struct Proposal {
uint voteCount;
//
uint voteCount;
}
//
}
//
address chairperson;
//
address chairperson;
mapping(address => Voter) voters;
//
mapping(address => Voter) voters;
Proposal[] proposals;
//
Proposal[] proposals;
//
/// Create a new ballot with $(_numProposals) different proposals.
//
/// Create a new ballot with $(_numProposals) different proposals.
constructor() public {
//
constructor() public {
uint p = 45;
//
uint p = 45;
chairperson = msg.sender;
//
chairperson = msg.sender;
address addressLocal = msg.sender; // copy of state variable
//
address addressLocal = msg.sender; // copy of state variable
voters[chairperson].weight = 1;
//
voters[chairperson].weight = 1;
proposals.length = 1;
//
proposals.length = 1;
Proposal[] storage proposalsLocals = proposals; // copy of state variable
//
Proposal[] storage proposalsLocals = proposals; // copy of state variable
}
//
}
//
/// Give $(toVoter) the right to vote on this ballot.
//
/// Give $(toVoter) the right to vote on this ballot.
/// May only be called by $(chairperson).
//
/// May only be called by $(chairperson).
function giveRightToVote(address toVoter) public {
//
function giveRightToVote(address toVoter) public {
if (msg.sender != chairperson || voters[toVoter].voted) return;
//
if (msg.sender != chairperson || voters[toVoter].voted) return;
voters[toVoter].weight = 1;
//
voters[toVoter].weight = 1;
}
//
}
//
/// Delegate your vote to the voter $(to).
//
/// Delegate your vote to the voter $(to).
function delegate(address to) public {
//
function delegate(address to) public {
Voter storage sender = voters[msg.sender]; // assigns reference
//
Voter storage sender = voters[msg.sender]; // assigns reference
if (sender.voted) return;
//
if (sender.voted) return;
while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender)
//
while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender)
to = voters[to].delegate;
//
to = voters[to].delegate;
if (to == msg.sender) return;
//
if (to == msg.sender) return;
sender.voted = true;
//
sender.voted = true;
sender.delegate = to;
//
sender.delegate = to;
Voter storage delegateTo = voters[to];
//
Voter storage delegateTo = voters[to];
if (delegateTo.voted)
//
if (delegateTo.voted)
proposals[delegateTo.vote].voteCount += sender.weight;
//
proposals[delegateTo.vote].voteCount += sender.weight;
else
//
else
delegateTo.weight += sender.weight;
//
delegateTo.weight += sender.weight;
}
//
}
//
/// Give a single vote to proposal $(toProposal).
//
/// Give a single vote to proposal $(toProposal).
function vote(uint8 toProposal) public {
//
function vote(uint8 toProposal) public {
Voter storage sender = voters[msg.sender];
//
Voter storage sender = voters[msg.sender];
if (sender.voted || toProposal >= proposals.length) return;
//
if (sender.voted || toProposal >= proposals.length) return;
sender.voted = true;
//
sender.voted = true;
sender.vote = toProposal;
//
sender.vote = toProposal;
proposals[toProposal].voteCount += sender.weight;
//
proposals[toProposal].voteCount += sender.weight;
}
//
}
//
function winningProposal() public view returns (uint8 _winningProposal) {
//
function winningProposal() public view returns (uint8 _winningProposal) {
uint256 winningVoteCount = 0;
//
uint256 winningVoteCount = 0;
for (uint8 prop = 0; prop < proposals.length; prop++)
//
for (uint8 prop = 0; prop < proposals.length; prop++)
if (proposals[prop].voteCount > winningVoteCount) {
//
if (proposals[prop].voteCount > winningVoteCount) {
winningVoteCount = proposals[prop].voteCount;
//
winningVoteCount = proposals[prop].voteCount;
_winningProposal = prop;
//
_winningProposal = prop;
}
//
}
}
//
}
}`
//
}`
remix-lib/src/execution/execution-context.js
View file @
5c1c75f0
...
@@ -67,7 +67,7 @@ var vm = new EthJSVM({
...
@@ -67,7 +67,7 @@ var vm = new EthJSVM({
vm
.
stateManager
=
stateManager
vm
.
stateManager
=
stateManager
vm
.
blockchain
=
stateManager
.
blockchain
vm
.
blockchain
=
stateManager
.
blockchain
vm
.
trie
=
stateManager
.
trie
vm
.
trie
=
stateManager
.
trie
vm
.
stateManager
.
checkpoint
()
vm
.
stateManager
.
checkpoint
(
()
=>
{}
)
var
web3VM
=
new
Web3VMProvider
()
var
web3VM
=
new
Web3VMProvider
()
web3VM
.
setVM
(
vm
)
web3VM
.
setVM
(
vm
)
...
...
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