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
79ae4bf9
Commit
79ae4bf9
authored
May 19, 2016
by
yann300
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
modularisation
parent
cfe1903a
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
771 additions
and
471 deletions
+771
-471
asmCode.js
src/asmCode.js
+83
-0
assemblyItemsBrowser.js
src/assemblyItemsBrowser.js
+37
-320
buttonNavigator.js
src/buttonNavigator.js
+5
-1
codeResolver.js
src/codeResolver.js
+67
-0
debugger.js
src/debugger.js
+39
-20
slider.js
src/slider.js
+9
-1
stepManager.js
src/stepManager.js
+98
-0
sticker.js
src/sticker.js
+77
-4
storageResolver.js
src/storageResolver.js
+0
-113
traceManager.js
src/traceManager.js
+340
-0
txBrowser.js
src/txBrowser.js
+16
-12
No files found.
src/asmCode.js
0 → 100644
View file @
79ae4bf9
'use strict'
var
React
=
require
(
'react'
)
var
style
=
require
(
'./basicStyles'
)
var
codeResolver
=
require
(
'./codeResolver'
)
module
.
exports
=
React
.
createClass
({
contextTypes
:
{
traceManager
:
React
.
PropTypes
.
object
,
tx
:
React
.
PropTypes
.
object
,
web3
:
React
.
PropTypes
.
object
},
getInitialState
:
function
()
{
return
{
code
:
[],
selected
:
-
1
,
address
:
''
// selected instruction in the asm
}
},
getDefaultProps
:
function
()
{
return
{
currentStepIndex
:
-
1
}
},
render
:
function
()
{
return
(
<
select
size
=
'10'
ref
=
'itemsList'
style
=
{
style
.
instructionsList
}
value
=
{
this
.
state
.
selected
}
>
{
this
.
renderAssemblyItems
()}
<
/select
>
)
},
renderAssemblyItems
:
function
()
{
if
(
this
.
state
.
code
)
{
return
this
.
state
.
code
.
map
(
function
(
item
,
i
)
{
return
<
option
key
=
{
i
}
value
=
{
i
}
>
{
item
}
<
/option
>
})
}
},
componentWillReceiveProps
:
function
(
nextProps
)
{
console
.
log
(
'asm'
+
JSON
.
stringify
(
nextProps
))
if
(
nextProps
.
currentStepIndex
<
0
)
return
codeResolver
.
setWeb3
(
this
.
context
.
web3
)
var
self
=
this
this
.
context
.
traceManager
.
getCurrentCalledAddressAt
(
nextProps
.
currentStepIndex
,
function
(
address
)
{
self
.
ensureCodeLoaded
(
address
,
nextProps
.
currentStepIndex
)
})
},
ensureCodeLoaded
:
function
(
address
,
currentStep
)
{
if
(
address
!==
this
.
state
.
address
)
{
this
.
setState
({
code
:
[
'loading...'
]
})
var
self
=
this
codeResolver
.
resolveCode
(
address
,
currentStep
,
this
.
context
.
tx
,
function
(
address
,
code
)
{
self
.
setState
({
code
:
code
,
address
:
address
})
self
.
setInstructionIndex
(
address
,
currentStep
)
})
}
else
{
this
.
setInstructionIndex
(
this
.
state
.
address
,
currentStep
)
}
},
setInstructionIndex
:
function
(
address
,
step
)
{
var
self
=
this
this
.
context
.
traceManager
.
getCurrentPC
(
step
,
function
(
instIndex
)
{
self
.
setState
({
selected
:
codeResolver
.
getInstructionIndex
(
address
,
instIndex
)
})
})
}
})
src/assemblyItemsBrowser.js
View file @
79ae4bf9
...
@@ -2,40 +2,28 @@
...
@@ -2,40 +2,28 @@
var
React
=
require
(
'react'
)
var
React
=
require
(
'react'
)
var
BasicPanel
=
require
(
'./basicPanel'
)
var
BasicPanel
=
require
(
'./basicPanel'
)
var
Sticker
=
require
(
'./sticker'
)
var
Sticker
=
require
(
'./sticker'
)
var
ButtonNavigator
=
require
(
'./vmTraceButtonNavigator'
)
var
codeUtils
=
require
(
'./codeUtils'
)
var
style
=
require
(
'./basicStyles'
)
var
style
=
require
(
'./basicStyles'
)
var
Slider
=
require
(
'./slider'
)
var
ASMCode
=
require
(
'./asmCode'
)
var
StorageResolver
=
require
(
'./storageResolver.js'
)
module
.
exports
=
React
.
createClass
({
module
.
exports
=
React
.
createClass
({
contextTypes
:
{
contextTypes
:
{
traceManager
:
React
.
PropTypes
.
object
,
web3
:
React
.
PropTypes
.
object
web3
:
React
.
PropTypes
.
object
},
},
getInitialState
:
function
()
{
getInitialState
:
function
()
{
return
{
return
{
currentSelected
:
-
1
,
// current selected item in the vmTrace
selectedInst
:
-
1
,
// current selected item in the contract assembly code
currentAddress
:
null
,
currentAddress
:
null
,
currentStack
:
null
,
currentStack
:
null
,
currentLevels
:
null
,
currentStorage
:
null
,
currentStorage
:
null
,
currentMemory
:
null
,
currentMemory
:
null
,
currentCallData
:
null
,
currentCallData
:
null
currentStepInfo
:
null
,
codes
:
{},
// assembly items instructions list by contract addesses
executingCode
:
[],
// code currently loaded in the debugger
instructionsIndexByBytesOffset
:
{},
// mapping between bytes offset and instructions index.
callStack
:
{},
storageStates
:
{}
}
}
},
},
getDefaultProps
:
function
()
{
getDefaultProps
:
function
()
{
return
{
return
{
vmTrace
:
null
,
currentStepIndex
:
-
1
// index of the selected item in the vmtrace
transaction
:
null
}
}
},
},
...
@@ -46,35 +34,13 @@ module.exports = React.createClass({
...
@@ -46,35 +34,13 @@ module.exports = React.createClass({
<
span
style
=
{
style
.
address
}
>
Current
code
:
{
this
.
state
.
currentAddress
}
<
/span
>
<
span
style
=
{
style
.
address
}
>
Current
code
:
{
this
.
state
.
currentAddress
}
<
/span
>
<
/div
>
<
/div
>
<
div
style
=
{
style
.
container
}
>
<
div
style
=
{
style
.
container
}
>
<
Slider
ref
=
'slider'
onChange
=
{
this
.
selectState
}
min
=
'0'
max
=
{
this
.
props
.
vmTrace
?
this
.
props
.
vmTrace
.
length
:
0
}
/
>
<
ButtonNavigator
vmTraceLength
=
{
this
.
props
.
vmTrace
?
this
.
props
.
vmTrace
.
length
:
0
}
step
=
{
this
.
state
.
currentSelected
}
stepIntoBack
=
{
this
.
stepIntoBack
}
stepIntoForward
=
{
this
.
stepIntoForward
}
stepOverBack
=
{
this
.
stepOverBack
}
stepOverForward
=
{
this
.
stepOverForward
}
jumpToNextCall
=
{
this
.
jumpToNextCall
}
/
>
<
/div
>
<
StorageResolver
ref
=
'storageResolver'
transaction
=
{
this
.
props
.
transaction
}
/
>
<
div
style
=
{
style
.
container
}
>
<
table
>
<
table
>
<
tbody
>
<
tbody
>
<
tr
>
<
tr
>
<
td
>
<
td
>
<
select
<
ASMCode
currentStepIndex
=
{
this
.
props
.
currentStepIndex
}
/
>
size
=
'10'
ref
=
'itemsList'
style
=
{
style
.
instructionsList
}
value
=
{
this
.
state
.
selectedInst
}
>
{
this
.
renderAssemblyItems
()}
<
/select
>
<
div
style
=
{
Object
.
assign
(
style
.
inline
,
style
.
sticker
)}
>
<
div
style
=
{
Object
.
assign
(
style
.
inline
,
style
.
sticker
)}
>
<
Sticker
data
=
{
this
.
state
.
currentStepInfo
}
/
>
<
Sticker
currentStepIndex
=
{
this
.
props
.
currentStepIndex
}
/
>
<
/div
>
<
/div
>
<
/td
>
<
/td
>
<
td
>
<
td
>
...
@@ -144,295 +110,46 @@ module.exports = React.createClass({
...
@@ -144,295 +110,46 @@ module.exports = React.createClass({
return
ret
return
ret
},
},
loadCode
:
function
(
address
,
callback
)
{
console
.
log
(
'loading new code from web3 '
+
address
)
this
.
context
.
web3
.
eth
.
getCode
(
address
,
function
(
error
,
result
)
{
if
(
error
)
{
console
.
log
(
error
)
}
else
{
callback
(
result
)
}
})
},
cacheExecutingCode
:
function
(
address
,
hexCode
)
{
var
code
=
codeUtils
.
nameOpCodes
(
new
Buffer
(
hexCode
.
substring
(
2
),
'hex'
))
this
.
state
.
codes
[
address
]
=
code
[
0
]
this
.
state
.
instructionsIndexByBytesOffset
[
address
]
=
code
[
1
]
return
{
code
:
code
[
0
],
instructionsIndexByBytesOffset
:
code
[
1
]
}
},
getExecutingCodeFromCache
:
function
(
address
)
{
if
(
this
.
state
.
codes
[
address
])
{
return
{
code
:
this
.
state
.
codes
[
address
],
instructionsIndexByBytesOffset
:
this
.
state
.
instructionsIndexByBytesOffset
[
address
]
}
}
else
{
return
null
}
},
renderAssemblyItems
:
function
()
{
if
(
this
.
props
.
vmTrace
&&
this
.
state
.
executingCode
)
{
return
this
.
state
.
executingCode
.
map
(
function
(
item
,
i
)
{
return
<
option
key
=
{
i
}
value
=
{
i
}
>
{
item
}
<
/option
>
})
}
},
componentWillReceiveProps
:
function
(
nextProps
)
{
componentWillReceiveProps
:
function
(
nextProps
)
{
this
.
setState
(
this
.
getInitialState
())
console
.
log
(
"asse "
+
JSON
.
stringify
(
nextProps
))
if
(
!
nextProps
.
vmTrace
)
{
if
(
nextProps
.
currentStepIndex
<
0
)
return
return
}
this
.
buildCallStack
(
nextProps
.
vmTrace
)
this
.
updateState
(
nextProps
,
0
)
},
buildCallStack
:
function
(
vmTrace
)
{
var
self
=
this
if
(
!
vmTrace
)
return
this
.
context
.
traceManager
.
getCallDataAt
(
nextProps
.
currentStepIndex
,
function
(
calldata
)
{
var
callStack
=
[]
self
.
setState
({
var
callStackFrame
=
{}
currentCallData
:
calldata
var
depth
=
-
1
})
this
.
refs
.
storageResolver
.
init
(
this
.
props
.
transaction
)
for
(
var
k
=
0
;
k
<
vmTrace
.
length
;
k
++
)
{
var
trace
=
vmTrace
[
k
]
if
(
trace
.
depth
===
undefined
||
trace
.
depth
===
depth
)
continue
if
(
trace
.
depth
>
depth
)
{
if
(
k
===
0
)
{
callStack
.
push
(
'0x'
+
vmTrace
[
k
].
address
)
// new context
}
else
{
// getting the address from the stack
var
callTrace
=
vmTrace
[
k
-
1
]
var
address
=
callTrace
.
stack
[
callTrace
.
stack
.
length
-
2
]
callStack
.
push
(
address
)
// new context
}
}
else
if
(
trace
.
depth
<
depth
)
{
callStack
.
pop
()
// returning from context
}
depth
=
trace
.
depth
callStackFrame
[
k
]
=
callStack
.
slice
(
0
)
this
.
refs
.
storageResolver
.
trackStorageChange
(
k
,
trace
)
}
this
.
setState
({
'callStack'
:
callStackFrame
})
},
updateState
:
function
(
props
,
vmTraceIndex
)
{
if
(
!
props
.
vmTrace
||
!
props
.
vmTrace
[
vmTraceIndex
])
return
var
previousIndex
=
this
.
state
.
currentSelected
var
stateChanges
=
{}
var
stack
if
(
props
.
vmTrace
[
vmTraceIndex
].
stack
)
{
// there's always a stack
stack
=
props
.
vmTrace
[
vmTraceIndex
].
stack
.
slice
(
0
)
stack
.
reverse
()
Object
.
assign
(
stateChanges
,
{
'currentStack'
:
stack
})
}
var
newContextLoaded
=
false
var
depthIndex
=
this
.
shouldUpdateStateProperty
(
'depth'
,
vmTraceIndex
,
previousIndex
,
props
.
vmTrace
)
if
(
depthIndex
>
-
1
)
{
Object
.
assign
(
stateChanges
,
{
'currentCallStack'
:
this
.
state
.
callStack
[
depthIndex
]})
// updating exectution context:
var
address
=
this
.
resolveAddress
(
depthIndex
,
props
)
if
(
address
!==
this
.
state
.
currentAddress
)
{
var
self
=
this
this
.
ensureExecutingCodeUpdated
(
address
,
vmTraceIndex
,
props
,
function
(
code
)
{
if
(
self
.
state
.
currentAddress
!==
address
)
{
console
.
log
(
'updating executing code '
+
self
.
state
.
currentAddress
+
' -> '
+
address
)
self
.
setState
(
{
'selectedInst'
:
code
.
instructionsIndexByBytesOffset
[
props
.
vmTrace
[
vmTraceIndex
].
pc
],
'executingCode'
:
code
.
code
,
'currentAddress'
:
address
})
}
})
newContextLoaded
=
true
}
}
if
(
!
newContextLoaded
)
{
Object
.
assign
(
stateChanges
,
{
'selectedInst'
:
this
.
getExecutingCodeFromCache
(
this
.
state
.
currentAddress
).
instructionsIndexByBytesOffset
[
props
.
vmTrace
[
vmTraceIndex
].
pc
]
})
}
Object
.
assign
(
stateChanges
,
{
'currentSelected'
:
vmTraceIndex
})
this
.
refs
.
storageResolver
.
rebuildStorageAt
(
vmTraceIndex
,
props
.
transaction
,
function
(
storage
)
{
Object
.
assign
(
stateChanges
,
{
'currentStorage'
:
storage
})
})
})
var
memoryIndex
=
this
.
shouldUpdateStateProperty
(
'memory'
,
vmTraceIndex
,
previousIndex
,
props
.
vmTrace
)
this
.
context
.
traceManager
.
getCallStackAt
(
nextProps
.
currentStepIndex
,
function
(
callstack
)
{
if
(
memoryIndex
>
-
1
)
{
self
.
setState
({
Object
.
assign
(
stateChanges
,
{
'currentMemory'
:
this
.
formatMemory
(
props
.
vmTrace
[
memoryIndex
].
memory
,
16
)
})
currentCallStack
:
callstack
}
})
var
callDataIndex
=
this
.
shouldUpdateStateProperty
(
'calldata'
,
vmTraceIndex
,
previousIndex
,
props
.
vmTrace
)
if
(
callDataIndex
>
-
1
)
{
Object
.
assign
(
stateChanges
,
{
'currentCallData'
:
[
props
.
vmTrace
[
callDataIndex
].
calldata
]
})
}
stateChanges
[
'currentStepInfo'
]
=
[
'Current Step: '
+
props
.
vmTrace
[
vmTraceIndex
].
steps
,
'Adding Memory: '
+
(
props
.
vmTrace
[
vmTraceIndex
].
memexpand
?
props
.
vmTrace
[
vmTraceIndex
].
memexpand
:
''
),
'Step Cost: '
+
props
.
vmTrace
[
vmTraceIndex
].
gascost
,
'Remaining Gas: '
+
props
.
vmTrace
[
vmTraceIndex
].
gas
]
this
.
refs
.
slider
.
setValue
(
vmTraceIndex
)
this
.
setState
(
stateChanges
)
},
ensureExecutingCodeUpdated
:
function
(
address
,
vmTraceIndex
,
props
,
callBack
)
{
this
.
resolveCode
(
address
,
vmTraceIndex
,
props
,
function
(
address
,
code
)
{
callBack
(
code
)
})
})
},
resolveAddress
:
function
(
vmTraceIndex
,
props
)
{
var
address
=
props
.
vmTrace
[
vmTraceIndex
].
address
if
(
vmTraceIndex
>
0
)
{
var
stack
=
this
.
state
.
callStack
[
vmTraceIndex
]
// callcode, delegatecall, ...
address
=
stack
[
stack
.
length
-
1
]
}
return
address
},
resolveCode
:
function
(
address
,
vmTraceIndex
,
props
,
callBack
)
{
this
.
context
.
traceManager
.
getMemoryAt
(
nextProps
.
currentStepIndex
,
function
(
memory
)
{
var
cache
=
this
.
getExecutingCodeFromCache
(
address
)
self
.
setState
({
if
(
cache
)
{
currentMemory
:
self
.
formatMemory
(
memory
,
16
)
callBack
(
address
,
cache
)
})
return
}
if
(
vmTraceIndex
===
0
&&
props
.
transaction
.
to
===
null
)
{
// start of the trace
callBack
(
address
,
this
.
cacheExecutingCode
(
address
,
props
.
transaction
.
input
))
return
}
var
self
=
this
this
.
loadCode
(
address
,
function
(
code
)
{
callBack
(
address
,
self
.
cacheExecutingCode
(
address
,
code
))
})
})
},
shouldUpdateStateProperty
:
function
(
vmTraceName
,
nextIndex
,
previousIndex
,
vmTrace
)
{
var
propIndex
=
-
1
if
(
previousIndex
+
1
===
nextIndex
)
{
propIndex
=
nextIndex
}
else
{
propIndex
=
this
.
retrieveLastSeenProperty
(
nextIndex
,
vmTraceName
,
vmTrace
)
}
if
(
propIndex
>
-
1
&&
vmTrace
[
propIndex
][
vmTraceName
]
!==
undefined
)
{
return
propIndex
}
else
{
return
-
1
}
},
retrieveLastSeenProperty
:
function
(
currentIndex
,
propertyName
,
vmTrace
)
{
var
index
=
currentIndex
while
(
index
>
0
)
{
if
(
vmTrace
[
index
][
propertyName
])
{
break
}
index
--
}
return
index
},
jumpToNextCall
:
function
()
{
var
i
=
this
.
state
.
currentSelected
while
(
++
i
<
this
.
props
.
vmTrace
.
length
)
{
if
(
this
.
isCallInstruction
(
i
))
{
this
.
selectState
(
i
+
1
)
break
}
}
},
stepIntoBack
:
function
()
{
this
.
moveSelection
(
-
1
)
},
stepIntoForward
:
function
()
{
this
.
moveSelection
(
1
)
},
stepOverBack
:
function
()
{
this
.
context
.
traceManager
.
getStorageAt
(
nextProps
.
currentStepIndex
,
function
(
storage
)
{
if
(
this
.
isReturnInstruction
(
this
.
state
.
currentSelected
-
1
))
{
self
.
setState
({
this
.
stepOutBack
()
currentStorage
:
storage
}
else
{
})
this
.
moveSelection
(
-
1
)
})
}
},
stepOverForward
:
function
()
{
if
(
this
.
isCallInstruction
(
this
.
state
.
currentSelected
))
{
this
.
stepOutForward
()
}
else
{
this
.
moveSelection
(
1
)
}
},
isCallInstruction
:
function
(
index
)
{
var
state
=
this
.
props
.
vmTrace
[
index
]
return
state
.
instname
===
'CALL'
||
state
.
instname
===
'CALLCODE'
||
state
.
instname
===
'CREATE'
||
state
.
instname
===
'DELEGATECALL'
},
isReturnInstruction
:
function
(
index
)
{
var
state
=
this
.
props
.
vmTrace
[
index
]
return
state
.
instname
===
'RETURN'
},
stepOutBack
:
function
()
{
var
i
=
this
.
state
.
currentSelected
-
1
var
depth
=
0
while
(
--
i
>=
0
)
{
if
(
this
.
isCallInstruction
(
i
))
{
if
(
depth
===
0
)
{
break
}
else
{
depth
--
}
}
else
if
(
this
.
isReturnInstruction
(
i
))
{
depth
++
}
}
this
.
selectState
(
i
)
},
stepOutForward
:
function
()
{
var
i
=
this
.
state
.
currentSelected
var
depth
=
0
while
(
++
i
<
this
.
props
.
vmTrace
.
length
)
{
if
(
this
.
isReturnInstruction
(
i
))
{
if
(
depth
===
0
)
{
break
}
else
{
depth
--
}
}
else
if
(
this
.
isCallInstruction
(
i
))
{
depth
++
}
}
this
.
selectState
(
i
+
1
)
},
moveSelection
:
function
(
incr
)
{
this
.
context
.
traceManager
.
getStackAt
(
nextProps
.
currentStepIndex
,
function
(
stack
)
{
this
.
selectState
(
this
.
state
.
currentSelected
+
incr
)
self
.
setState
({
},
currentStack
:
stack
})
})
selectState
:
function
(
index
)
{
this
.
context
.
traceManager
.
getCurrentCalledAddressAt
(
nextProps
.
currentStepIndex
,
function
(
address
)
{
this
.
updateState
(
this
.
props
,
index
)
self
.
setState
({
currentAddress
:
address
})
})
},
},
formatMemory
:
function
(
mem
,
width
)
{
formatMemory
:
function
(
mem
,
width
)
{
...
...
src/
vmTraceB
uttonNavigator.js
→
src/
b
uttonNavigator.js
View file @
79ae4bf9
...
@@ -2,6 +2,10 @@
...
@@ -2,6 +2,10 @@
var
React
=
require
(
'react'
)
var
React
=
require
(
'react'
)
module
.
exports
=
React
.
createClass
({
module
.
exports
=
React
.
createClass
({
contextTypes
:
{
traceManager
:
React
.
PropTypes
.
object
},
propTypes
:
{
propTypes
:
{
stepIntoBack
:
React
.
PropTypes
.
func
.
isRequired
,
stepIntoBack
:
React
.
PropTypes
.
func
.
isRequired
,
stepIntoForward
:
React
.
PropTypes
.
func
.
isRequired
,
stepIntoForward
:
React
.
PropTypes
.
func
.
isRequired
,
...
@@ -32,7 +36,7 @@ module.exports = React.createClass({
...
@@ -32,7 +36,7 @@ module.exports = React.createClass({
if
(
incr
===
-
1
)
{
if
(
incr
===
-
1
)
{
return
this
.
props
.
step
===
0
?
'disabled'
:
''
return
this
.
props
.
step
===
0
?
'disabled'
:
''
}
else
if
(
incr
===
1
)
{
}
else
if
(
incr
===
1
)
{
return
this
.
props
.
step
>=
this
.
props
.
vmTraceLength
-
1
?
'disabled'
:
''
return
this
.
props
.
step
>=
this
.
props
.
max
-
1
?
'disabled'
:
''
}
}
}
}
})
})
src/codeResolver.js
0 → 100644
View file @
79ae4bf9
'use strict'
var
codeUtils
=
require
(
'./codeUtils'
)
module
.
exports
=
{
web3
:
null
,
codes
:
{},
// assembly items instructions list by contract addesses
instructionsIndexByBytesOffset
:
{},
// mapping between bytes offset and instructions index.
setWeb3
:
function
(
web3
)
{
this
.
web3
=
web3
},
resolveCode
:
function
(
address
,
vmTraceIndex
,
transaction
,
callBack
)
{
var
cache
=
this
.
getExecutingCodeFromCache
(
address
)
if
(
cache
)
{
callBack
(
address
,
cache
.
code
)
return
}
if
(
vmTraceIndex
===
0
&&
transaction
.
to
===
null
)
{
// start of the trace
callBack
(
address
,
this
.
cacheExecutingCode
(
address
,
transaction
.
input
).
code
)
return
}
var
self
=
this
this
.
loadCode
(
address
,
function
(
code
)
{
callBack
(
address
,
self
.
cacheExecutingCode
(
address
,
code
).
code
)
})
},
loadCode
:
function
(
address
,
callback
)
{
console
.
log
(
'loading new code from web3 '
+
address
)
this
.
web3
.
eth
.
getCode
(
address
,
function
(
error
,
result
)
{
if
(
error
)
{
console
.
log
(
error
)
}
else
{
callback
(
result
)
}
})
},
cacheExecutingCode
:
function
(
address
,
hexCode
)
{
var
code
=
codeUtils
.
nameOpCodes
(
new
Buffer
(
hexCode
.
substring
(
2
),
'hex'
))
this
.
codes
[
address
]
=
code
[
0
]
this
.
instructionsIndexByBytesOffset
[
address
]
=
code
[
1
]
return
{
code
:
code
[
0
],
instructionsIndexByBytesOffset
:
code
[
1
]
}
},
getExecutingCodeFromCache
:
function
(
address
)
{
if
(
this
.
codes
[
address
])
{
return
{
code
:
this
.
codes
[
address
],
instructionsIndexByBytesOffset
:
this
.
instructionsIndexByBytesOffset
[
address
]
}
}
else
{
return
null
}
},
getInstructionIndex
:
function
(
address
,
pc
)
{
return
this
.
getExecutingCodeFromCache
(
address
).
instructionsIndexByBytesOffset
[
pc
]
}
}
src/debugger.js
View file @
79ae4bf9
'use strict'
'use strict'
var
React
=
require
(
'react'
)
var
React
=
require
(
'react'
)
var
TxBrowser
=
require
(
'./txBrowser'
)
var
TxBrowser
=
require
(
'./txBrowser'
)
var
StepManager
=
require
(
'./stepManager'
)
var
AssemblyItemsBrowser
=
require
(
'./assemblyItemsBrowser'
)
var
AssemblyItemsBrowser
=
require
(
'./assemblyItemsBrowser'
)
var
traceManager
=
require
(
'./traceManager'
)
var
style
=
require
(
'./basicStyles'
)
var
style
=
require
(
'./basicStyles'
)
module
.
exports
=
React
.
createClass
({
module
.
exports
=
React
.
createClass
({
getInitialState
:
function
()
{
getInitialState
:
function
()
{
return
{
return
{
vmTrace
:
null
,
tx
:
null
,
state
:
''
,
currentStepIndex
:
-
1
// index of the selected item in the vmtrace
currentStep
:
-
1
}
}
},
},
childContextTypes
:
{
childContextTypes
:
{
web3
:
React
.
PropTypes
.
object
web3
:
React
.
PropTypes
.
object
,
traceManager
:
React
.
PropTypes
.
object
,
tx
:
React
.
PropTypes
.
object
},
},
getChildContext
:
function
()
{
getChildContext
:
function
()
{
return
{
web3
:
this
.
props
.
web3
}
return
{
web3
:
this
.
props
.
web3
,
traceManager
:
traceManager
,
tx
:
this
.
state
.
tx
}
},
componentDidMount
:
function
()
{
traceManager
.
setWeb3
(
this
.
props
.
web3
)
},
},
render
:
function
()
{
render
:
function
()
{
return
(
return
(
<
div
style
=
{
style
.
wrapper
}
>
<
div
style
=
{
style
.
wrapper
}
>
<
h1
style
=
{
style
.
container
}
>
Eth
Debugger
<
/h1
>
<
h1
style
=
{
style
.
container
}
>
Eth
Debugger
<
/h1
>
<
TxBrowser
onNewTxRequested
=
{
this
.
retrieveVmTrace
}
/
>
<
TxBrowser
onNewTxRequested
=
{
this
.
startDebugging
}
/
>
<
div
style
=
{
style
.
container
}
>
<
StepManager
ref
=
'stepManager'
onStepChanged
=
{
this
.
stepChanged
}
/
>
{
this
.
state
.
state
}
<
AssemblyItemsBrowser
currentStepIndex
=
{
this
.
state
.
currentStepIndex
}
/
>
<
/div
>
<
AssemblyItemsBrowser
vmTrace
=
{
this
.
state
.
vmTrace
}
transaction
=
{
this
.
state
.
transaction
}
/
>
<
/div
>
<
/div
>
)
)
},
},
retrieveVmTrace
:
function
(
blockNumber
,
txNumber
,
tx
)
{
stepChanged
:
function
(
stepIndex
)
{
if
(
this
.
state
.
state
!==
''
)
return
this
.
setState
({
currentStepIndex
:
stepIndex
})
},
startDebugging
:
function
(
blockNumber
,
txIndex
,
tx
)
{
if
(
traceManager
.
isLoading
)
{
return
}
console
.
log
(
'loading trace...'
)
this
.
setState
({
tx
:
tx
})
traceManager
.
setTransaction
(
tx
)
var
self
=
this
var
self
=
this
this
.
setState
({
state
:
'loading...'
})
traceManager
.
resolveTrace
(
blockNumber
,
txIndex
,
function
(
success
)
{
console
.
log
(
'trace loaded '
+
success
)
this
.
props
.
web3
.
debug
.
trace
(
blockNumber
,
parseInt
(
txNumber
),
function
(
error
,
result
)
{
self
.
setState
({
if
(
error
)
{
currentStepIndex
:
0
console
.
log
(
error
)
})
}
else
{
self
.
refs
.
stepManager
.
newTraceAvailable
()
self
.
setState
({
vmTrace
:
result
,
transaction
:
tx
,
state
:
''
})
}
})
})
}
}
})
})
src/slider.js
View file @
79ae4bf9
...
@@ -3,6 +3,10 @@ var React = require('react')
...
@@ -3,6 +3,10 @@ var React = require('react')
var
style
=
require
(
'./sliderStyles'
)
var
style
=
require
(
'./sliderStyles'
)
module
.
exports
=
React
.
createClass
({
module
.
exports
=
React
.
createClass
({
contextTypes
:
{
traceManager
:
React
.
PropTypes
.
object
},
propTypes
:
{
propTypes
:
{
onChange
:
React
.
PropTypes
.
func
.
isRequired
onChange
:
React
.
PropTypes
.
func
.
isRequired
},
},
...
@@ -10,7 +14,7 @@ module.exports = React.createClass({
...
@@ -10,7 +14,7 @@ module.exports = React.createClass({
getDefaultProps
:
function
()
{
getDefaultProps
:
function
()
{
return
{
return
{
min
:
0
,
min
:
0
,
max
:
500
max
:
1
}
}
},
},
...
@@ -28,6 +32,10 @@ module.exports = React.createClass({
...
@@ -28,6 +32,10 @@ module.exports = React.createClass({
)
)
},
},
componentDidMount
:
function
()
{
this
.
setValue
(
0
)
},
onMouseUp
:
function
(
event
)
{
onMouseUp
:
function
(
event
)
{
this
.
props
.
onChange
(
parseInt
(
this
.
refs
.
rule
.
value
))
this
.
props
.
onChange
(
parseInt
(
this
.
refs
.
rule
.
value
))
},
},
...
...
src/stepManager.js
0 → 100644
View file @
79ae4bf9
'use strict'
var
React
=
require
(
'react'
)
var
ButtonNavigator
=
require
(
'./buttonNavigator'
)
var
Slider
=
require
(
'./slider'
)
var
style
=
require
(
'./basicStyles'
)
module
.
exports
=
React
.
createClass
({
propTypes
:
{
onStepChanged
:
React
.
PropTypes
.
func
.
isRequired
},
contextTypes
:
{
traceManager
:
React
.
PropTypes
.
object
},
getInitialState
:
function
()
{
return
{
currentStepIndex
:
0
,
traceLength
:
0
}
},
render
:
function
()
{
return
(
<
div
style
=
{
style
.
container
}
>
<
Slider
ref
=
'slider'
onChange
=
{
this
.
sliderMoved
}
min
=
'0'
max
=
{
this
.
state
.
traceLength
}
/
>
<
ButtonNavigator
stepIntoBack
=
{
this
.
stepIntoBack
}
stepIntoForward
=
{
this
.
stepIntoForward
}
stepOverBack
=
{
this
.
stepOverBack
}
stepOverForward
=
{
this
.
stepOverForward
}
jumpToNextCall
=
{
this
.
jumpToNextCall
}
max
=
{
this
.
state
.
traceLength
}
/
>
<
/div
>
)
},
init
:
function
()
{
this
.
refs
.
slider
.
setValue
(
0
)
},
newTraceAvailable
:
function
()
{
this
.
init
()
var
self
=
this
this
.
context
.
traceManager
.
getLength
(
function
(
length
)
{
self
.
setState
({
traceLength
:
length
})
})
},
sliderMoved
:
function
(
step
)
{
this
.
props
.
onStepChanged
(
step
)
this
.
changeState
(
step
)
},
stepIntoForward
:
function
()
{
var
step
=
this
.
state
.
currentStepIndex
+
1
this
.
props
.
onStepChanged
(
step
)
this
.
changeState
(
step
)
},
stepIntoBack
:
function
()
{
var
step
=
this
.
state
.
currentStepIndex
-
1
this
.
props
.
onStepChanged
(
step
)
this
.
refs
.
slider
.
setValue
(
step
)
this
.
changeState
(
step
)
},
stepOverForward
:
function
()
{
var
step
=
this
.
context
.
traceManager
.
findStepOverForward
(
this
.
state
.
currentStepIndex
)
this
.
props
.
onStepChanged
(
step
)
this
.
refs
.
slider
.
setValue
(
step
)
this
.
changeState
(
step
)
},
stepOverBack
:
function
()
{
var
step
=
this
.
context
.
traceManager
.
findStepOverBack
(
this
.
state
.
currentStepIndex
)
this
.
props
.
onStepChanged
(
step
)
this
.
refs
.
slider
.
setValue
(
step
)
this
.
changeState
(
step
)
},
jumpToNextCall
:
function
()
{
var
step
=
this
.
context
.
traceManager
.
findNextCall
(
this
.
state
.
currentStepIndex
)
this
.
props
.
onStepChanged
(
step
)
this
.
refs
.
slider
.
setValue
(
step
)
this
.
changeState
(
step
)
},
changeState
:
function
(
step
)
{
this
.
setState
({
currentStepIndex
:
step
})
}
})
src/sticker.js
View file @
79ae4bf9
...
@@ -2,9 +2,22 @@
...
@@ -2,9 +2,22 @@
var
React
=
require
(
'react'
)
var
React
=
require
(
'react'
)
module
.
exports
=
React
.
createClass
({
module
.
exports
=
React
.
createClass
({
contextTypes
:
{
traceManager
:
React
.
PropTypes
.
object
},
getDefaultProps
:
function
()
{
getDefaultProps
:
function
()
{
return
{
return
{
data
:
null
currentStepIndex
:
-
1
}
},
getInitialState
:
function
()
{
return
{
step
:
''
,
addmemory
:
''
,
gas
:
''
,
remainingGas
:
''
}
}
},
},
...
@@ -13,7 +26,38 @@ module.exports = React.createClass({
...
@@ -13,7 +26,38 @@ module.exports = React.createClass({
<
div
>
<
div
>
<
table
>
<
table
>
<
tbody
>
<
tbody
>
{
this
.
renderItems
()}
<
tr
key
=
'step'
>
<
td
>
step
<
/td
>
<
td
>
{
this
.
state
.
step
}
<
/td
>
<
/tr
>
<
tr
key
=
'addmemory'
>
<
td
>
add
memory
<
/td
>
<
td
>
{
this
.
state
.
addmemory
}
<
/td
>
<
/tr
>
<
tr
key
=
'gas'
>
<
td
>
gas
<
/td
>
<
td
>
{
this
.
state
.
gas
}
<
/td
>
<
/tr
>
<
tr
key
=
'remaininggas'
>
<
td
>
remaining
gas
<
/td
>
<
td
>
{
this
.
state
.
remaingas
}
<
/td
>
<
/tr
>
<
/tbody
>
<
/tbody
>
<
/table
>
<
/table
>
<
/div
>
<
/div
>
...
@@ -21,9 +65,9 @@ module.exports = React.createClass({
...
@@ -21,9 +65,9 @@ module.exports = React.createClass({
},
},
renderItems
:
function
()
{
renderItems
:
function
()
{
if
(
this
.
props
.
data
)
{
if
(
this
.
state
.
data
)
{
var
ret
=
[]
var
ret
=
[]
for
(
var
key
in
this
.
props
.
data
)
{
for
(
var
key
in
this
.
state
.
data
)
{
ret
.
push
(
ret
.
push
(
<
tr
key
=
{
key
}
>
<
tr
key
=
{
key
}
>
<
td
>
<
td
>
...
@@ -34,5 +78,34 @@ module.exports = React.createClass({
...
@@ -34,5 +78,34 @@ module.exports = React.createClass({
return
ret
return
ret
}
}
return
null
return
null
},
componentWillReceiveProps
:
function
(
nextProps
)
{
if
(
nextProps
.
currentStepIndex
<
0
)
return
var
self
=
this
this
.
context
.
traceManager
.
getCurrentStep
(
nextProps
.
currentStepIndex
,
function
(
step
)
{
self
.
setState
({
step
:
step
})
})
this
.
context
.
traceManager
.
getMemExpand
(
nextProps
.
currentStepIndex
,
function
(
addmem
)
{
self
.
setState
({
addmemory
:
addmem
})
})
this
.
context
.
traceManager
.
getStepCost
(
nextProps
.
currentStepIndex
,
function
(
gas
)
{
self
.
setState
({
gas
:
gas
})
})
this
.
context
.
traceManager
.
getRemainingGas
(
nextProps
.
currentStepIndex
,
function
(
remaingas
)
{
self
.
setState
({
remaininGas
:
remaingas
})
})
}
}
})
})
src/storageResolver.js
deleted
100644 → 0
View file @
cfe1903a
'use strict'
var
React
=
require
(
'react'
)
module
.
exports
=
React
.
createClass
({
contextTypes
:
{
web3
:
React
.
PropTypes
.
object
},
getInitialState
:
function
()
{
return
{
storage
:
{},
storageChanges
:
[],
vmTraceIndexByStorageChange
:
{},
vmTraceChangesRef
:
[]
}
},
init
:
function
()
{
var
defaultState
=
this
.
getInitialState
()
this
.
state
.
storage
=
defaultState
.
storage
this
.
state
.
storageChanges
=
defaultState
.
storageChanges
this
.
state
.
vmTraceIndexByStorageChange
=
defaultState
.
vmTraceIndexByStorageChange
this
.
state
.
vmTraceChangesRef
=
defaultState
.
vmTraceChangesRef
},
render
:
function
()
{
return
null
},
// retrieve the storage of an account just after the execution of txHash
retrieveStorage
:
function
(
address
,
transaction
,
callBack
)
{
if
(
this
.
state
.
storage
[
address
])
{
callBack
(
this
.
state
.
storage
[
address
])
}
var
self
=
this
if
(
transaction
)
{
this
.
context
.
web3
.
debug
.
storageAt
(
transaction
.
blockNumber
.
toString
(),
transaction
.
transactionIndex
,
address
,
function
(
error
,
result
)
{
if
(
error
)
{
console
.
log
(
error
)
}
else
{
self
.
state
.
storage
[
address
]
=
result
callBack
(
result
)
}
})
}
else
{
console
.
log
(
'transaction is not defined'
)
}
},
trackStorageChange
:
function
(
vmTraceIndex
,
trace
)
{
var
change
=
false
if
(
trace
.
address
)
{
// new context
this
.
state
.
storageChanges
.
push
({
address
:
trace
.
address
,
changes
:
[]
})
change
=
true
}
else
if
(
trace
.
depth
&&
!
trace
.
address
)
{
// returned from context
this
.
state
.
storageChanges
.
push
({
address
:
this
.
state
.
storageChanges
[
this
.
state
.
storageChanges
.
length
-
1
].
address
,
changes
:
[]
})
change
=
true
}
else
if
(
trace
.
inst
===
'SSTORE'
)
{
this
.
state
.
storageChanges
[
this
.
state
.
storageChanges
.
length
-
1
].
changes
.
push
(
{
'key'
:
trace
.
stack
[
trace
.
stack
.
length
-
1
],
'value'
:
trace
.
stack
[
trace
.
stack
.
length
-
2
]
})
change
=
true
}
if
(
change
)
{
this
.
state
.
vmTraceIndexByStorageChange
[
vmTraceIndex
]
=
{
context
:
this
.
state
.
storageChanges
.
length
-
1
,
changes
:
this
.
state
.
storageChanges
[
this
.
state
.
storageChanges
.
length
-
1
].
changes
.
length
-
1
}
this
.
state
.
vmTraceChangesRef
.
push
(
vmTraceIndex
)
}
},
rebuildStorageAt
:
function
(
vmTraceIndex
,
transaction
,
callBack
)
{
var
changesLocation
=
this
.
retrieveLastChange
(
vmTraceIndex
)
if
(
!
changesLocation
)
{
console
.
log
(
'unable to build storage'
)
callBack
({})
}
else
{
var
address
=
this
.
state
.
storageChanges
[
changesLocation
.
context
].
address
this
.
retrieveStorage
(
address
,
transaction
,
function
(
storage
)
{
for
(
var
k
=
0
;
k
<
changesLocation
.
context
;
k
++
)
{
var
context
=
this
.
state
.
storageChanges
[
k
]
if
(
context
.
address
===
address
)
{
for
(
var
i
=
0
;
i
<
context
.
changes
.
length
;
i
++
)
{
if
(
i
>
changesLocation
.
changes
)
break
var
change
=
context
.
changes
[
i
]
storage
[
change
.
key
]
=
change
.
value
}
}
}
callBack
(
storage
)
})
}
},
retrieveLastChange
:
function
(
vmTraceIndex
)
{
var
change
=
this
.
state
.
vmTraceIndexByStorageChange
[
vmTraceIndex
]
if
(
change
)
{
return
change
}
else
{
for
(
var
k
in
this
.
state
.
vmTraceChangesRef
)
{
if
(
this
.
state
.
vmTraceChangesRef
[
k
]
>
vmTraceIndex
)
{
return
this
.
state
.
vmTraceIndexByStorageChange
[
k
-
1
]
}
}
}
}
})
src/traceManager.js
0 → 100644
View file @
79ae4bf9
'use strict'
module
.
exports
=
{
isLoading
:
false
,
web3
:
null
,
transaction
:
null
,
trace
:
null
,
// vmtrace changes section
depthChanges
:
[],
callStack
:
{},
memoryChanges
:
[],
callDataChanges
:
[],
// storage section
storageChanges
:
[],
vmTraceIndexByStorageChange
:
{},
vmTraceChangesRef
:
[],
storages
:
{},
// init section
setWeb3
:
function
(
web3
)
{
this
.
web3
=
web3
},
setTransaction
:
function
(
tx
)
{
this
.
transaction
=
tx
},
resolveTrace
:
function
(
blockNumber
,
txNumber
,
callback
)
{
this
.
isLoading
=
true
this
.
init
()
if
(
!
this
.
web3
)
callback
(
false
)
var
self
=
this
this
.
web3
.
debug
.
trace
(
blockNumber
,
parseInt
(
txNumber
),
function
(
error
,
result
)
{
if
(
!
error
)
{
self
.
computeTrace
(
result
)
callback
(
true
)
}
else
{
console
.
log
(
error
)
callback
(
false
)
}
this
.
isLoading
=
false
})
},
init
:
function
()
{
this
.
trace
=
null
this
.
depthChanges
=
[]
this
.
memoryChanges
=
[]
this
.
callDataChanges
=
[]
this
.
storageChanges
=
[]
this
.
vmTraceIndexByStorageChange
=
{}
this
.
vmTraceChangesRef
=
[]
this
.
callStack
=
{}
},
computeTrace
:
function
(
trace
)
{
this
.
trace
=
trace
var
currentDepth
=
0
var
currentStorageAddress
var
callStack
=
[]
for
(
var
k
in
this
.
trace
)
{
var
step
=
this
.
trace
[
k
]
this
.
calldata
(
k
,
step
)
this
.
memory
(
k
,
step
)
currentStorageAddress
=
this
.
storage
(
k
,
step
,
currentStorageAddress
)
var
depth
=
this
.
depth
(
k
,
step
,
currentDepth
,
callStack
)
if
(
depth
)
{
currentDepth
=
depth
}
}
},
// compute trace section
calldata
:
function
(
index
,
step
)
{
if
(
step
.
calldata
)
{
this
.
callDataChanges
.
push
(
index
)
}
},
memory
:
function
(
index
,
step
)
{
if
(
step
.
memory
)
{
this
.
memoryChanges
.
push
(
index
)
}
},
storage
:
function
(
index
,
step
,
currentAddress
)
{
var
change
=
false
if
(
step
.
address
)
{
// new context
this
.
storageChanges
.
push
({
address
:
step
.
address
,
changes
:
[]
})
change
=
true
}
else
if
(
step
.
inst
===
'SSTORE'
)
{
this
.
storageChanges
[
this
.
storageChanges
.
length
-
1
].
changes
.
push
(
{
'key'
:
step
.
stack
[
step
.
stack
.
length
-
1
],
'value'
:
step
.
stack
[
step
.
stack
.
length
-
2
]
})
change
=
true
}
else
if
(
!
step
.
address
&&
step
.
depth
)
{
// returned from context
var
address
=
this
.
storageChanges
[
this
.
storageChanges
.
length
-
2
].
address
this
.
storageChanges
.
push
({
address
:
address
,
changes
:
[]
})
change
=
true
}
if
(
change
)
{
this
.
vmTraceIndexByStorageChange
[
index
]
=
{
context
:
this
.
storageChanges
.
length
-
1
,
changes
:
this
.
storageChanges
[
this
.
storageChanges
.
length
-
1
].
changes
.
length
-
1
}
this
.
vmTraceChangesRef
.
push
(
index
)
}
return
currentAddress
},
depth
:
function
(
index
,
step
,
currentDepth
,
callStack
)
{
if
(
step
.
depth
===
undefined
)
return
if
(
step
.
depth
>
currentDepth
)
{
if
(
index
===
0
)
{
callStack
.
push
(
'0x'
+
step
.
address
)
// new context
}
else
{
// getting the address from the stack
var
callTrace
=
this
.
trace
[
index
-
1
]
var
address
=
callTrace
.
stack
[
callTrace
.
stack
.
length
-
2
]
callStack
.
push
(
address
)
// new context
}
}
else
if
(
step
.
depth
<
currentDepth
)
{
callStack
.
pop
()
// returning from context
}
this
.
callStack
[
index
]
=
{
stack
:
callStack
.
slice
(
0
),
depth
:
step
.
depth
,
address
:
step
.
address
}
this
.
depthChanges
.
push
(
index
)
return
step
.
depth
},
// API section
getLength
:
function
(
callback
)
{
if
(
!
this
.
trace
)
callback
(
0
)
callback
(
this
.
trace
.
length
)
},
getStorageAt
:
function
(
stepIndex
,
callback
)
{
var
stoChange
=
this
.
lastPropertyChange
(
stepIndex
,
this
.
vmTraceChangesRef
)
if
(
!
stoChange
)
{
return
{}
}
var
changeRefs
=
this
.
vmTraceIndexByStorageChange
[
stoChange
]
var
address
=
this
.
storageChanges
[
changeRefs
.
context
].
address
var
self
=
this
this
.
retrieveStorage
(
address
,
function
(
storage
)
{
for
(
var
k
=
0
;
k
<
changeRefs
.
context
;
k
++
)
{
var
context
=
self
.
storageChanges
[
k
]
if
(
context
.
address
===
address
)
{
for
(
var
i
=
0
;
i
<
context
.
changes
.
length
;
i
++
)
{
if
(
i
>
changeRefs
.
changes
)
break
var
change
=
context
.
changes
[
i
]
storage
[
change
.
key
]
=
change
.
value
}
}
}
callback
(
storage
)
})
},
getCallDataAt
:
function
(
stepIndex
,
callback
)
{
var
callDataChange
=
this
.
lastPropertyChange
(
stepIndex
,
this
.
callDataChanges
)
if
(
!
callDataChange
)
return
[
''
]
callback
([
this
.
trace
[
callDataChange
].
calldata
])
},
getCallStackAt
:
function
(
stepIndex
,
callback
)
{
var
callStackChange
=
this
.
lastPropertyChange
(
stepIndex
,
this
.
depthChanges
)
if
(
!
callStackChange
)
return
''
callback
(
this
.
callStack
[
callStackChange
].
stack
)
},
getStackAt
:
function
(
stepIndex
,
callback
)
{
var
stack
if
(
this
.
trace
[
stepIndex
].
stack
)
{
// there's always a stack
stack
=
this
.
trace
[
stepIndex
].
stack
.
slice
(
0
)
stack
.
reverse
()
callback
(
stack
)
}
},
getLastDepthIndexChangeSince
:
function
(
stepIndex
,
callback
)
{
var
depthIndex
=
this
.
lastPropertyChange
(
stepIndex
,
this
.
depthChanges
)
callback
(
depthIndex
)
},
getCurrentCalledAddressAt
:
function
(
stepIndex
,
callback
)
{
var
self
=
this
this
.
getLastDepthIndexChangeSince
(
stepIndex
,
function
(
addressIndex
)
{
callback
(
self
.
resolveAddress
(
addressIndex
))
})
},
getMemoryAt
:
function
(
stepIndex
,
callback
)
{
var
lastChanges
=
this
.
lastPropertyChange
(
stepIndex
,
this
.
memoryChanges
)
if
(
!
lastChanges
)
return
''
callback
(
this
.
trace
[
lastChanges
].
memory
)
},
getCurrentPC
:
function
(
stepIndex
,
callback
)
{
callback
(
this
.
trace
[
stepIndex
].
pc
)
},
getCurrentStep
:
function
(
stepIndex
,
callback
)
{
callback
(
this
.
trace
[
stepIndex
].
steps
)
},
getMemExpand
:
function
(
stepIndex
,
callback
)
{
callback
(
this
.
trace
[
stepIndex
].
memexpand
?
this
.
trace
[
stepIndex
].
memexpand
:
''
)
},
getStepCost
:
function
(
stepIndex
,
callback
)
{
callback
(
this
.
trace
[
stepIndex
].
gascost
)
},
getRemainingGas
:
function
(
stepIndex
,
callback
)
{
callback
(
this
.
trace
[
stepIndex
].
gas
)
},
// step section
isCallInstruction
:
function
(
index
)
{
var
state
=
this
.
trace
[
index
]
return
state
.
instname
===
'CALL'
||
state
.
instname
===
'CALLCODE'
||
state
.
instname
===
'CREATE'
||
state
.
instname
===
'DELEGATECALL'
},
isReturnInstruction
:
function
(
index
)
{
var
state
=
this
.
trace
[
index
]
return
state
.
instname
===
'RETURN'
},
findStepOverBack
:
function
(
currentStep
)
{
if
(
this
.
isReturnInstruction
(
currentStep
-
1
))
{
return
this
.
findStepOutBack
(
currentStep
)
}
else
{
return
currentStep
-
1
}
},
findStepOverForward
:
function
(
currentStep
)
{
if
(
this
.
isCallInstruction
(
currentStep
))
{
return
this
.
findStepOutForward
(
currentStep
)
}
else
{
return
currentStep
+
1
}
},
findStepOutBack
:
function
(
currentStep
)
{
var
i
=
currentStep
-
1
var
depth
=
0
while
(
--
i
>=
0
)
{
if
(
this
.
isCallInstruction
(
i
))
{
if
(
depth
===
0
)
{
break
}
else
{
depth
--
}
}
else
if
(
this
.
isReturnInstruction
(
i
))
{
depth
++
}
}
return
i
},
findStepOutForward
:
function
(
currentStep
)
{
var
i
=
currentStep
var
depth
=
0
while
(
++
i
<
this
.
trace
.
length
)
{
if
(
this
.
isReturnInstruction
(
i
))
{
if
(
depth
===
0
)
{
break
}
else
{
depth
--
}
}
else
if
(
this
.
isCallInstruction
(
i
))
{
depth
++
}
}
return
i
+
1
},
// util section
lastPropertyChange
:
function
(
target
,
changes
)
{
if
(
changes
.
length
===
1
)
{
if
(
changes
[
0
]
>
target
)
{
// we only a closest maximum, returning 0
return
null
}
else
{
return
changes
[
0
]
}
}
var
middle
=
Math
.
floor
(
changes
.
length
/
2
)
if
(
changes
[
middle
]
>
target
)
{
return
this
.
lastPropertyChange
(
target
,
changes
.
slice
(
0
,
middle
))
}
else
if
(
changes
[
middle
]
<
target
)
{
return
this
.
lastPropertyChange
(
target
,
changes
.
slice
(
middle
,
changes
.
length
))
}
else
{
return
changes
[
middle
]
}
},
resolveAddress
:
function
(
vmTraceIndex
)
{
var
address
=
this
.
trace
[
vmTraceIndex
].
address
if
(
vmTraceIndex
>
0
)
{
var
stack
=
this
.
trace
[
vmTraceIndex
-
1
].
stack
// callcode, delegatecall, ...
address
=
stack
[
stack
.
length
-
2
]
}
return
address
},
// retrieve the storage of an account just after the execution of tx
retrieveStorage
:
function
(
address
,
callBack
)
{
if
(
this
.
storages
[
address
])
{
callBack
(
this
.
storages
[
address
])
}
var
self
=
this
if
(
this
.
transaction
)
{
this
.
web3
.
debug
.
storageAt
(
this
.
transaction
.
blockNumber
.
toString
(),
this
.
transaction
.
transactionIndex
,
address
,
function
(
error
,
result
)
{
if
(
error
)
{
console
.
log
(
error
)
}
else
{
self
.
storages
[
address
]
=
result
callBack
(
result
)
}
})
}
else
{
console
.
log
(
'transaction is not defined'
)
}
}
}
src/txBrowser.js
View file @
79ae4bf9
...
@@ -42,18 +42,22 @@ module.exports = React.createClass({
...
@@ -42,18 +42,22 @@ module.exports = React.createClass({
Get
Get
<
/button
>
<
/button
>
<
div
style
=
{
style
.
transactionInfo
}
>
<
div
style
=
{
style
.
transactionInfo
}
>
<
div
>
<
table
>
Hash
:
<
tbody
>
{
this
.
state
.
hash
}
<
tr
>
<
/div
>
<
td
>
Hash
:
<
/td
>
<
div
>
<
td
>
{
this
.
state
.
hash
}
<
/td
>
From
:
<
/tr
>
{
this
.
state
.
from
}
<
tr
>
<
/div
>
<
td
>
From
:
<
/td
>
<
div
>
<
td
>
{
this
.
state
.
from
}
<
/td
>
To
:
<
/tr
>
{
this
.
state
.
to
}
<
tr
>
<
/div
>
<
td
>
To
:
<
/td
>
<
td
>
{
this
.
state
.
to
}
<
/td
>
<
/tr
>
<
/tbody
>
<
/table
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
)
)
...
...
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