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
0611230d
Commit
0611230d
authored
Aug 17, 2016
by
chriseth
Committed by
GitHub
Aug 17, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #167 from yann300/refactoring_event
Refactoring:: add events
parents
3448ce4b
afa87c96
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
510 additions
and
355 deletions
+510
-355
app.js
src/app.js
+47
-18
compiler.js
src/app/compiler.js
+26
-24
debugger.js
src/app/debugger.js
+9
-1
execution-context.js
src/app/execution-context.js
+23
-12
formalVerification.js
src/app/formalVerification.js
+22
-15
renderer.js
src/app/renderer.js
+104
-246
ui-helper.js
src/app/ui-helper.js
+161
-0
eventManager.js
src/lib/eventManager.js
+64
-0
universal-dapp.js
src/universal-dapp.js
+52
-37
compiler-test.js
test/compiler-test.js
+2
-2
No files found.
src/app.js
View file @
0611230d
...
...
@@ -13,9 +13,10 @@ var Editor = require('./app/editor');
var
Renderer
=
require
(
'./app/renderer'
);
var
Compiler
=
require
(
'./app/compiler'
);
var
ExecutionContext
=
require
(
'./app/execution-context'
);
var
UniversalDApp
=
require
(
'./universal-dapp.js'
);
var
Debugger
=
require
(
'./app/debugger'
);
var
FormalVerification
=
require
(
'./app/formalVerification'
);
var
E
thJSVM
=
require
(
'ethereumjs-vm
'
);
var
E
ventManager
=
require
(
'./lib/eventManager
'
);
// The event listener needs to be registered as early as possible, because the
// parent will send the message upon the "load" event.
...
...
@@ -26,8 +27,12 @@ window.addEventListener('message', function (ev) {
loadFilesCallback
(
ev
.
data
[
1
]);
}
},
false
);
/*
trigger tabChanged
*/
var
run
=
function
()
{
var
self
=
this
;
this
.
event
=
new
EventManager
();
var
storage
=
new
Storage
(
updateFiles
);
function
loadFiles
(
files
)
{
...
...
@@ -108,6 +113,7 @@ var run = function () {
el
.
removeClass
(
'active'
);
$
(
'#optionViews'
).
removeClass
(
cls
);
}
self
.
event
.
trigger
(
'tabChanged'
,
[
cls
]);
};
// ------------------ gist publish --------------
...
...
@@ -199,7 +205,7 @@ var run = function () {
$fileNameInputEl
.
off
(
'keyup'
);
if
(
newName
!==
originalName
&&
confirm
(
storage
.
exists
(
utils
.
fileKey
(
newName
))
storage
.
exists
(
utils
.
fileKey
(
newName
))
?
'Are you sure you want to overwrite: '
+
newName
+
' with '
+
originalName
+
'?'
:
'Are you sure you want to rename: '
+
originalName
+
' to '
+
newName
+
'?'
))
{
storage
.
rename
(
utils
.
fileKey
(
originalName
),
utils
.
fileKey
(
newName
));
...
...
@@ -279,7 +285,7 @@ var run = function () {
}
// function widthOfHidden () {
// return ($filesWrapper.outerWidth() - widthOfList() - getLeftPosi())
;
// return ($filesWrapper.outerWidth() - widthOfList() - getLeftPosi())
// }
function
widthOfVisible
()
{
...
...
@@ -405,11 +411,8 @@ var run = function () {
setEditorSize
(
hidingRHP
?
0
:
storage
.
getEditorSize
());
$
(
'.toggleRHP i'
).
toggleClass
(
'fa-angle-double-right'
,
!
hidingRHP
);
$
(
'.toggleRHP i'
).
toggleClass
(
'fa-angle-double-left'
,
hidingRHP
);
if
(
!
hidingRHP
)
compiler
.
compile
();
});
function
getHidingRHP
()
{
return
hidingRHP
;
}
// ----------------- editor resize ---------------
function
onResize
()
{
...
...
@@ -432,20 +435,46 @@ var run = function () {
$
(
'#output'
).
append
(
$
(
'<div/>'
).
append
(
$
(
'<pre/>'
).
text
(
'Loading github.com/'
+
root
+
'/'
+
path
+
' ...'
)));
return
$
.
getJSON
(
'https://api.github.com/repos/'
+
root
+
'/contents/'
+
path
,
cb
);
}
var
transactionDebugger
=
new
Debugger
(
'#debugger'
);
var
vm
=
new
EthJSVM
(
null
,
null
,
{
activatePrecompiles
:
true
,
enableHomestead
:
true
}
);
v
m
.
stateManager
.
checkpoint
(
);
transactionDebugger
.
addProvider
(
'VM'
,
vm
);
var
executionContext
=
new
ExecutionContext
(
);
v
ar
transactionDebugger
=
new
Debugger
(
'#debugger'
,
executionContext
.
event
);
transactionDebugger
.
addProvider
(
'VM'
,
executionContext
.
vm
()
);
transactionDebugger
.
switchProvider
(
'VM'
);
var
executionContext
=
new
ExecutionContext
(
transactionDebugger
);
transactionDebugger
.
addProvider
(
'INTERNAL'
,
executionContext
.
web3
()
);
transactionDebugger
.
addProvider
(
'EXTERNAL'
,
executionContext
.
web3
());
transactionDebugger
.
onDebugRequested
=
function
()
{
selectTab
(
$
(
'ul#options li.debugView'
));
};
var
renderer
=
new
Renderer
(
editor
,
executionContext
,
updateFiles
,
transactionDebugger
,
vm
);
var
formalVerification
=
new
FormalVerification
(
$
(
'#verificationView'
),
renderer
);
var
compiler
=
new
Compiler
(
editor
,
renderer
,
queryParams
,
handleGithubCall
,
$
(
'#output'
),
getHidingRHP
,
formalVerification
,
updateFiles
);
executionContext
.
setCompiler
(
compiler
);
var
udapp
=
new
UniversalDApp
(
executionContext
,
{
removable
:
false
,
removable_instances
:
true
},
transactionDebugger
);
udapp
.
event
.
register
(
'debugRequested'
,
this
,
function
(
data
)
{
transactionDebugger
.
debug
(
data
);
});
var
compiler
=
new
Compiler
(
editor
,
queryParams
,
handleGithubCall
,
updateFiles
);
var
formalVerification
=
new
FormalVerification
(
$
(
'#verificationView'
),
compiler
.
event
);
var
renderer
=
new
Renderer
(
editor
,
executionContext
.
web3
(),
updateFiles
,
udapp
,
executionContext
,
formalVerification
.
event
,
compiler
.
event
);
// eslint-disable-line
executionContext
.
event
.
register
(
'contextChanged'
,
this
,
function
(
context
)
{
compiler
.
compile
();
});
executionContext
.
event
.
register
(
'web3EndpointChanged'
,
this
,
function
(
context
)
{
compiler
.
compile
();
});
executionContext
.
event
.
register
(
'compilerLoaded'
,
this
,
function
(
context
)
{
compiler
.
compile
();
});
compiler
.
event
.
register
(
'compilerLoaded'
,
this
,
function
(
version
)
{
setVersionText
(
version
);
compiler
.
compile
();
});
function
setVersionText
(
text
)
{
$
(
'#version'
).
text
(
text
);
...
...
@@ -462,9 +491,9 @@ var run = function () {
// Workers cannot load js on "file:"-URLs and we get a
// "Uncaught RangeError: Maximum call stack size exceeded" error on Chromium,
// resort to non-worker version in that case.
compiler
.
loadVersion
(
true
,
version
,
setVersionText
);
compiler
.
loadVersion
(
true
,
version
);
}
else
{
compiler
.
loadVersion
(
false
,
version
,
setVersionText
);
compiler
.
loadVersion
(
false
,
version
);
}
};
...
...
src/app/compiler.js
View file @
0611230d
...
...
@@ -5,7 +5,15 @@ var utils = require('./utils');
var
Base64
=
require
(
'js-base64'
).
Base64
;
function
Compiler
(
editor
,
renderer
,
queryParams
,
handleGithubCall
,
outputField
,
hidingRHP
,
formalVerification
,
updateFiles
)
{
var
EventManager
=
require
(
'../lib/eventManager'
);
/*
trigger compilationFinished, compilerLoaded, compilationStarted
*/
function
Compiler
(
editor
,
queryParams
,
handleGithubCall
,
updateFiles
)
{
var
self
=
this
;
this
.
event
=
new
EventManager
();
var
compileJSON
;
var
compilerAcceptsMultipleFiles
;
...
...
@@ -36,19 +44,15 @@ function Compiler (editor, renderer, queryParams, handleGithubCall, outputField,
var
compile
=
function
(
missingInputs
)
{
editor
.
clearAnnotations
();
outputField
.
empty
();
if
(
formalVerification
)
{
formalVerification
.
compiling
();
}
self
.
event
.
trigger
(
'compilationStarted'
,
[]);
var
input
=
editor
.
getValue
();
editor
.
setCacheFileContent
(
input
);
var
files
=
{};
files
[
utils
.
fileNameFromKey
(
editor
.
getCacheFile
())]
=
input
;
gatherImports
(
files
,
missingInputs
,
function
(
input
,
error
)
{
outputField
.
empty
();
if
(
input
===
null
)
{
renderer
.
error
(
error
);
this
.
event
.
trigger
(
'compilationFinished'
,
[
false
,
error
,
editor
.
getValue
()]
);
}
else
{
var
optimize
=
queryParams
.
get
().
optimize
;
compileJSON
(
input
,
optimize
?
1
:
0
);
...
...
@@ -62,13 +66,12 @@ function Compiler (editor, renderer, queryParams, handleGithubCall, outputField,
}
this
.
setCompileJSON
=
setCompileJSON
;
// this is exposed for testing
function
onCompilerLoaded
(
setVersionText
,
version
)
{
setVersionText
(
version
);
function
onCompilerLoaded
(
version
)
{
previousInput
=
''
;
onChange
(
);
self
.
event
.
trigger
(
'compilerLoaded'
,
[
version
]
);
}
function
onInternalCompilerLoaded
(
setVersionText
)
{
function
onInternalCompilerLoaded
()
{
if
(
worker
===
null
)
{
var
compiler
=
solc
(
window
.
Module
);
...
...
@@ -91,7 +94,7 @@ function Compiler (editor, renderer, queryParams, handleGithubCall, outputField,
compilationFinished
(
result
,
missingInputs
);
};
onCompilerLoaded
(
setVersionText
,
compiler
.
version
());
onCompilerLoaded
(
compiler
.
version
());
}
}
...
...
@@ -99,14 +102,14 @@ function Compiler (editor, renderer, queryParams, handleGithubCall, outputField,
var
noFatalErrors
=
true
;
// ie warnings are ok
if
(
data
[
'error'
]
!==
undefined
)
{
renderer
.
error
(
data
[
'error'
]);
self
.
event
.
trigger
(
'compilationFinished'
,
[
false
,
[
data
[
'error'
]],
editor
.
getValue
()
]);
if
(
utils
.
errortype
(
data
[
'error'
])
!==
'warning'
)
{
noFatalErrors
=
false
;
}
}
if
(
data
[
'errors'
]
!==
undefined
)
{
self
.
event
.
trigger
(
'compilationFinished'
,
[
false
,
data
[
'errors'
],
editor
.
getValue
()]);
data
[
'errors'
].
forEach
(
function
(
err
)
{
renderer
.
error
(
err
);
if
(
utils
.
errortype
(
err
)
!==
'warning'
)
{
noFatalErrors
=
false
;
}
...
...
@@ -115,13 +118,12 @@ function Compiler (editor, renderer, queryParams, handleGithubCall, outputField,
if
(
missingInputs
!==
undefined
&&
missingInputs
.
length
>
0
)
{
compile
(
missingInputs
);
}
else
if
(
noFatalErrors
&&
!
hidingRHP
())
{
renderer
.
contracts
(
data
,
editor
.
getValue
());
formalVerification
.
compilationFinished
(
data
);
}
else
if
(
noFatalErrors
)
{
self
.
event
.
trigger
(
'compilationFinished'
,
[
true
,
data
,
editor
.
getValue
()]);
}
}
this
.
loadVersion
=
function
(
usingWorker
,
version
,
setVersionText
)
{
this
.
loadVersion
=
function
(
usingWorker
,
version
)
{
var
url
;
if
(
version
!==
'soljson.js'
)
{
url
=
'https://ethereum.github.io/solc-bin/bin/'
+
version
;
...
...
@@ -131,13 +133,13 @@ function Compiler (editor, renderer, queryParams, handleGithubCall, outputField,
console
.
log
(
'Loading '
+
url
+
' '
+
(
usingWorker
?
'with worker'
:
'without worker'
));
if
(
usingWorker
)
{
loadWorker
(
url
,
setVersionText
);
loadWorker
(
url
);
}
else
{
loadInternal
(
url
,
setVersionText
);
loadInternal
(
url
);
}
};
function
loadInternal
(
url
,
setVersionText
)
{
function
loadInternal
(
url
)
{
delete
window
.
Module
;
// Set a safe fallback until the new one is loaded
setCompileJSON
(
function
(
source
,
optimize
)
{
compilationFinished
(
'{}'
);
});
...
...
@@ -151,11 +153,11 @@ function Compiler (editor, renderer, queryParams, handleGithubCall, outputField,
return
;
}
window
.
clearInterval
(
check
);
onInternalCompilerLoaded
(
setVersionText
);
onInternalCompilerLoaded
();
},
200
);
}
function
loadWorker
(
url
,
setVersionText
)
{
function
loadWorker
(
url
)
{
if
(
worker
!==
null
)
{
worker
.
terminate
();
}
...
...
@@ -165,7 +167,7 @@ function Compiler (editor, renderer, queryParams, handleGithubCall, outputField,
switch
(
data
.
cmd
)
{
case
'versionLoaded'
:
compilerAcceptsMultipleFiles
=
!!
data
.
acceptsMultipleFiles
;
onCompilerLoaded
(
setVersionText
,
data
.
data
);
onCompilerLoaded
(
data
.
data
);
break
;
case
'compiled'
:
var
result
;
...
...
src/app/debugger.js
View file @
0611230d
var
remix
=
require
(
'ethereum-remix'
);
function
Debugger
(
id
)
{
function
Debugger
(
id
,
executionContextEvent
)
{
this
.
el
=
document
.
querySelector
(
id
);
this
.
debugger
=
new
remix
.
ui
.
Debugger
();
this
.
el
.
appendChild
(
this
.
debugger
.
render
());
var
self
=
this
;
executionContextEvent
.
register
(
'contextChanged'
,
this
,
function
(
context
)
{
context
=
context
===
'vm'
?
'VM'
:
context
;
context
=
context
===
'injected'
?
'EXTERNAL'
:
context
;
context
=
context
===
'web3'
?
'INTERNAL'
:
context
;
self
.
switchProvider
(
context
);
});
}
Debugger
.
prototype
.
debug
=
function
(
receipt
)
{
...
...
src/app/execution-context.js
View file @
0611230d
...
...
@@ -2,6 +2,8 @@
var
$
=
require
(
'jquery'
);
var
Web3
=
require
(
'web3'
);
var
EventManager
=
require
(
'../lib/eventManager'
);
var
EthJSVM
=
require
(
'ethereumjs-vm'
);
var
injectedProvider
;
...
...
@@ -13,14 +15,17 @@ if (typeof window.web3 !== 'undefined') {
web3
=
new
Web3
(
new
Web3
.
providers
.
HttpProvider
(
'http://localhost:8545'
));
}
function
ExecutionContext
(
_txDebugger
)
{
var
txDebugger
=
_txDebugger
;
var
compiler
;
var
executionContext
=
injectedProvider
?
'injected'
:
'vm'
;
var
vm
=
new
EthJSVM
(
null
,
null
,
{
activatePrecompiles
:
true
,
enableHomestead
:
true
});
vm
.
stateManager
.
checkpoint
();
this
.
setCompiler
=
function
(
_compiler
)
{
compiler
=
_compiler
;
};
/*
trigger contextChanged, web3EndpointChanged
*/
function
ExecutionContext
()
{
var
self
=
this
;
this
.
event
=
new
EventManager
();
var
executionContext
=
injectedProvider
?
'injected'
:
'vm'
;
this
.
isVM
=
function
()
{
return
executionContext
===
'vm'
;
...
...
@@ -30,6 +35,10 @@ function ExecutionContext (_txDebugger) {
return
web3
;
};
this
.
vm
=
function
()
{
return
vm
;
};
var
$injectedToggle
=
$
(
'#injected-mode'
);
var
$vmToggle
=
$
(
'#vm-mode'
);
var
$web3Toggle
=
$
(
'#web3-mode'
);
...
...
@@ -47,7 +56,7 @@ function ExecutionContext (_txDebugger) {
$web3endpoint
.
on
(
'change'
,
function
()
{
setProviderFromEndpoint
();
if
(
executionContext
===
'web3'
)
{
compiler
.
compile
(
);
self
.
event
.
trigger
(
'web3EndpointChanged'
);
}
});
...
...
@@ -60,15 +69,17 @@ function ExecutionContext (_txDebugger) {
executionContext
=
ev
.
target
.
value
;
if
(
executionContext
===
'web3'
)
{
setProviderFromEndpoint
();
txDebugger
.
switchProvider
(
'EXTERNAL'
);
self
.
event
.
trigger
(
'contextChanged'
,
[
'web3'
]
);
}
else
if
(
executionContext
===
'injected'
)
{
web3
.
setProvider
(
injectedProvider
);
txDebugger
.
switchProvider
(
'EXTERNAL'
);
self
.
event
.
trigger
(
'contextChanged'
,
[
'injected'
]
);
}
else
if
(
executionContext
===
'vm'
)
{
txDebugger
.
switchProvider
(
'VM'
);
vm
.
stateManager
.
revert
(
function
()
{
vm
.
stateManager
.
checkpoint
();
});
self
.
event
.
trigger
(
'contextChanged'
,
[
'vm'
]);
}
}
compiler
.
compile
();
}
function
setProviderFromEndpoint
()
{
...
...
src/app/formalVerification.js
View file @
0611230d
var
$
=
require
(
'jquery'
);
var
EventManager
=
require
(
'../lib/eventManager'
);
function
FormalVerification
(
outputElement
,
renderer
)
{
/*
trigger compilationFinished
*/
function
FormalVerification
(
outputElement
,
compilerEvent
)
{
this
.
event
=
new
EventManager
();
this
.
outputElement
=
outputElement
;
this
.
renderer
=
renderer
;
}
FormalVerification
.
prototype
.
compiling
=
function
()
{
$
(
'#formalVerificationInput'
,
this
.
outputElement
)
var
self
=
this
;
compilerEvent
.
register
(
'compilationFinished'
,
this
,
function
(
success
,
data
,
source
)
{
if
(
success
)
{
self
.
compilationFinished
(
data
);
}
});
compilerEvent
.
register
(
'compilationStarted'
,
this
,
function
()
{
$
(
'#formalVerificationInput'
,
self
.
outputElement
)
.
val
(
''
)
.
hide
();
$
(
'#formalVerificationErrors'
).
empty
();
};
$
(
'#formalVerificationErrors'
).
empty
();
});
}
FormalVerification
.
prototype
.
compilationFinished
=
function
(
compilationResult
)
{
if
(
compilationResult
.
formal
===
undefined
)
{
this
.
renderer
.
error
(
'Formal verification not supported by this compiler version.'
,
$
(
'#formalVerificationErrors'
),
true
);
this
.
event
.
trigger
(
'compilationFinished'
,
[
false
,
'Formal verification not supported by this compiler version.'
,
$
(
'#formalVerificationErrors'
),
true
]);
}
else
{
if
(
compilationResult
.
formal
[
'why3'
]
!==
undefined
)
{
$
(
'#formalVerificationInput'
,
this
.
outputElement
).
val
(
'(* copy this to http://why3.lri.fr/try/ *)'
+
compilationResult
.
formal
[
'why3'
]
)
.
show
();
.
show
();
}
if
(
compilationResult
.
formal
.
errors
!==
undefined
)
{
var
errors
=
compilationResult
.
formal
.
errors
;
for
(
var
i
=
0
;
i
<
errors
.
length
;
i
++
)
{
this
.
renderer
.
error
(
errors
[
i
],
$
(
'#formalVerificationErrors'
),
true
);
this
.
event
.
trigger
(
'compilationFinished'
,
[
false
,
errors
[
i
],
$
(
'#formalVerificationErrors'
),
true
]
);
}
}
else
{
this
.
event
.
trigger
(
'compilationFinished'
,
[
true
,
null
,
null
,
true
]);
}
}
};
...
...
src/app/renderer.js
View file @
0611230d
var
$
=
require
(
'jquery'
);
var
UniversalDApp
=
require
(
'../universal-dapp.js'
);
var
utils
=
require
(
'./utils'
);
function
Renderer
(
editor
,
executionContext
,
updateFiles
,
transactionDebugger
,
vm
)
{
var
detailsOpen
=
{};
function
renderError
(
message
,
container
,
noAnnotations
)
{
var
type
=
utils
.
errortype
(
message
);
var
$pre
=
$
(
'<pre />'
).
text
(
message
);
var
$error
=
$
(
'<div class="sol '
+
type
+
'"><div class="close"><i class="fa fa-close"></i></div></div>'
).
prepend
(
$pre
);
if
(
container
===
undefined
)
{
container
=
$
(
'#output'
);
}
container
.
append
(
$error
);
var
err
=
message
.
match
(
/^
([^
:
]
*
)
:
([
0-9
]
*
)
:
(([
0-9
]
*
)
:
)?
/
);
if
(
err
)
{
var
errFile
=
err
[
1
];
var
errLine
=
parseInt
(
err
[
2
],
10
)
-
1
;
var
errCol
=
err
[
4
]
?
parseInt
(
err
[
4
],
10
)
:
0
;
if
(
!
noAnnotations
&&
(
errFile
===
''
||
errFile
===
utils
.
fileNameFromKey
(
editor
.
getCacheFile
())))
{
editor
.
addAnnotation
({
row
:
errLine
,
column
:
errCol
,
text
:
message
,
type
:
type
});
}
$error
.
click
(
function
(
ev
)
{
if
(
errFile
!==
''
&&
errFile
!==
utils
.
fileNameFromKey
(
editor
.
getCacheFile
())
&&
editor
.
hasFile
(
errFile
))
{
// Switch to file
editor
.
setCacheFile
(
utils
.
fileKey
(
errFile
));
updateFiles
();
// @TODO could show some error icon in files with errors
}
editor
.
handleErrorClick
(
errLine
,
errCol
);
});
$error
.
find
(
'.close'
).
click
(
function
(
ev
)
{
ev
.
preventDefault
();
$error
.
remove
();
return
false
;
var
uiHelper
=
require
(
'./ui-helper'
);
function
Renderer
(
editor
,
web3
,
updateFiles
,
udapp
,
executionContext
,
formalVerificationEvent
,
compilerEvent
)
{
this
.
editor
=
editor
;
this
.
web3
=
web3
;
this
.
updateFiles
=
updateFiles
;
this
.
udapp
=
udapp
;
this
.
executionContext
=
executionContext
;
var
self
=
this
;
formalVerificationEvent
.
register
(
'compilationFinished'
,
this
,
function
(
success
,
message
,
container
,
noAnnotations
)
{
if
(
!
success
)
{
self
.
error
(
message
,
container
,
noAnnotations
);
}
});
compilerEvent
.
register
(
'compilationFinished'
,
this
,
function
(
success
,
data
,
source
)
{
$
(
'#output'
).
empty
();
if
(
success
)
{
self
.
contracts
(
data
,
source
);
}
else
{
data
.
forEach
(
function
(
err
)
{
self
.
error
(
err
);
});
}
}
this
.
error
=
renderError
;
var
combined
=
function
(
contractName
,
jsonInterface
,
bytecode
)
{
return
JSON
.
stringify
([{
name
:
contractName
,
interface
:
jsonInterface
,
bytecode
:
bytecode
}]);
};
});
}
function
renderContracts
(
data
,
source
)
{
var
udappContracts
=
[];
for
(
var
contractName
in
data
.
contracts
)
{
var
contract
=
data
.
contracts
[
contractName
];
udappContracts
.
push
({
name
:
contractName
,
interface
:
contract
[
'interface'
],
bytecode
:
contract
.
bytecode
Renderer
.
prototype
.
error
=
function
(
message
,
container
,
noAnnotations
)
{
var
type
=
utils
.
errortype
(
message
);
var
$pre
=
$
(
'<pre />'
).
text
(
message
);
var
$error
=
$
(
'<div class="sol '
+
type
+
'"><div class="close"><i class="fa fa-close"></i></div></div>'
).
prepend
(
$pre
);
if
(
container
===
undefined
)
{
container
=
$
(
'#output'
);
}
container
.
append
(
$error
);
var
err
=
message
.
match
(
/^
([^
:
]
*
)
:
([
0-9
]
*
)
:
(([
0-9
]
*
)
:
)?
/
);
if
(
err
)
{
var
errFile
=
err
[
1
];
var
errLine
=
parseInt
(
err
[
2
],
10
)
-
1
;
var
errCol
=
err
[
4
]
?
parseInt
(
err
[
4
],
10
)
:
0
;
if
(
!
noAnnotations
&&
(
errFile
===
''
||
errFile
===
utils
.
fileNameFromKey
(
this
.
editor
.
getCacheFile
())))
{
this
.
editor
.
addAnnotation
({
row
:
errLine
,
column
:
errCol
,
text
:
message
,
type
:
type
});
}
vm
.
stateManager
.
revert
(
function
()
{
vm
.
stateManager
.
checkpoint
();
});
var
dapp
=
new
UniversalDApp
(
udappContracts
,
{
mode
:
executionContext
.
isVM
()
?
'vm'
:
'web3'
,
web3
:
executionContext
.
web3
(),
removable
:
false
,
getAddress
:
function
()
{
return
$
(
'#txorigin'
).
val
();
},
getValue
:
function
()
{
var
comp
=
$
(
'#value'
).
val
().
split
(
' '
);
return
executionContext
.
web3
().
toWei
(
comp
[
0
],
comp
.
slice
(
1
).
join
(
' '
));
},
getGasLimit
:
function
()
{
return
$
(
'#gasLimit'
).
val
();
},
removable_instances
:
true
,
renderOutputModifier
:
function
(
contractName
,
$contractOutput
)
{
var
contract
=
data
.
contracts
[
contractName
];
if
(
contract
.
bytecode
)
{
$contractOutput
.
append
(
textRow
(
'Bytecode'
,
contract
.
bytecode
));
}
$contractOutput
.
append
(
textRow
(
'Interface'
,
contract
[
'interface'
]));
if
(
contract
.
bytecode
)
{
$contractOutput
.
append
(
textRow
(
'Web3 deploy'
,
gethDeploy
(
contractName
.
toLowerCase
(),
contract
[
'interface'
],
contract
.
bytecode
),
'deploy'
));
$contractOutput
.
append
(
textRow
(
'uDApp'
,
combined
(
contractName
,
contract
[
'interface'
],
contract
.
bytecode
),
'deploy'
));
}
return
$contractOutput
.
append
(
getDetails
(
contract
,
source
,
contractName
));
$error
.
click
(
function
(
ev
)
{
if
(
errFile
!==
''
&&
errFile
!==
utils
.
fileNameFromKey
(
this
.
editor
.
getCacheFile
())
&&
this
.
editor
.
hasFile
(
errFile
))
{
// Switch to file
this
.
editor
.
setCacheFile
(
utils
.
fileKey
(
errFile
));
this
.
updateFiles
();
// @TODO could show some error icon in files with errors
}
},
transactionDebugger
,
vm
);
var
$contractOutput
=
dapp
.
render
();
var
$txOrigin
=
$
(
'#txorigin'
);
function
renderAccounts
(
err
,
accounts
)
{
if
(
err
)
{
renderError
(
err
.
message
);
}
if
(
accounts
&&
accounts
[
0
])
{
$txOrigin
.
empty
();
for
(
var
a
in
accounts
)
{
$txOrigin
.
append
(
$
(
'<option />'
).
val
(
accounts
[
a
]).
text
(
accounts
[
a
]));
}
$txOrigin
.
val
(
accounts
[
0
]);
}
else
{
$txOrigin
.
val
(
'unknown'
);
}
}
dapp
.
getAccounts
(
renderAccounts
);
$contractOutput
.
find
(
'.title'
).
click
(
function
(
ev
)
{
$
(
this
).
closest
(
'.contract'
).
toggleClass
(
'hide'
);
});
$
(
'#output'
).
append
(
$contractOutput
);
$
(
'.col2 input,textarea'
).
click
(
function
()
{
this
.
select
();
});
this
.
editor
.
handleErrorClick
(
errLine
,
errCol
);
});
$error
.
find
(
'.close'
).
click
(
function
(
ev
)
{
ev
.
preventDefault
();
$error
.
remove
();
return
false
;
});
}
};
Renderer
.
prototype
.
contracts
=
function
(
data
,
source
)
{
var
udappContracts
=
[];
for
(
var
contractName
in
data
.
contracts
)
{
var
contract
=
data
.
contracts
[
contractName
];
udappContracts
.
push
({
name
:
contractName
,
interface
:
contract
[
'interface'
],
bytecode
:
contract
.
bytecode
});
}
this
.
contracts
=
renderContracts
;
var
tableRowItems
=
function
(
first
,
second
,
cls
)
{
return
$
(
'<div class="crow"/>'
)
.
addClass
(
cls
)
.
append
(
$
(
'<div class="col1">'
).
append
(
first
))
.
append
(
$
(
'<div class="col2">'
).
append
(
second
));
};
var
tableRow
=
function
(
description
,
data
)
{
return
tableRowItems
(
$
(
'<span/>'
).
text
(
description
),
$
(
'<input readonly="readonly"/>'
).
val
(
data
));
};
var
textRow
=
function
(
description
,
data
,
cls
)
{
return
tableRowItems
(
$
(
'<strong/>'
).
text
(
description
),
$
(
'<textarea readonly="readonly" class="gethDeployText"/>'
).
val
(
data
),
cls
);
// rendering function used by udapp. they need data and source
var
combined
=
function
(
contractName
,
jsonInterface
,
bytecode
)
{
return
JSON
.
stringify
([{
name
:
contractName
,
interface
:
jsonInterface
,
bytecode
:
bytecode
}]);
};
var
getDetails
=
function
(
contract
,
source
,
contractName
)
{
var
button
=
$
(
'<button>Toggle Details</button>'
);
var
details
=
$
(
'<div style="display: none;"/>'
)
.
append
(
tableRow
(
'Solidity Interface'
,
contract
.
solidity_interface
));
if
(
contract
.
opcodes
!==
''
)
{
details
.
append
(
tableRow
(
'Opcodes'
,
contract
.
opcodes
));
var
renderOutputModifier
=
function
(
contractName
,
$contractOutput
)
{
var
contract
=
data
.
contracts
[
contractName
];
if
(
contract
.
bytecode
)
{
$contractOutput
.
append
(
uiHelper
.
textRow
(
'Bytecode'
,
contract
.
bytecode
));
}
var
funHashes
=
''
;
for
(
var
fun
in
contract
.
functionHashes
)
{
funHashes
+=
contract
.
functionHashes
[
fun
]
+
' '
+
fun
+
'
\
n'
;
}
details
.
append
(
$
(
'<span class="col1">Functions</span>'
));
details
.
append
(
$
(
'<pre/>'
).
text
(
funHashes
));
var
gasEstimates
=
formatGasEstimates
(
contract
.
gasEstimates
);
if
(
gasEstimates
)
{
details
.
append
(
$
(
'<span class="col1">Gas Estimates</span>'
));
details
.
append
(
$
(
'<pre/>'
).
text
(
gasEstimates
));
}
$contractOutput
.
append
(
uiHelper
.
textRow
(
'Interface'
,
contract
[
'interface'
]));
if
(
contract
.
runtimeBytecode
&&
contract
.
runtimeBytecode
.
length
>
0
)
{
details
.
append
(
tableRow
(
'Runtime Bytecode'
,
contract
.
runtimeBytecode
));
if
(
contract
.
bytecode
)
{
$contractOutput
.
append
(
uiHelper
.
textRow
(
'Web3 deploy'
,
uiHelper
.
gethDeploy
(
contractName
.
toLowerCase
(),
contract
[
'interface'
],
contract
.
bytecode
),
'deploy'
));
$contractOutput
.
append
(
uiHelper
.
textRow
(
'uDApp'
,
combined
(
contractName
,
contract
[
'interface'
],
contract
.
bytecode
),
'deploy'
));
}
return
$contractOutput
.
append
(
uiHelper
.
getDetails
(
contract
,
source
,
contractName
));
};
// //
var
self
=
this
;
if
(
contract
.
assembly
!==
null
)
{
details
.
append
(
$
(
'<span class="col1">Assembly</span>'
));
var
assembly
=
$
(
'<pre/>'
).
text
(
formatAssemblyText
(
contract
.
assembly
,
''
,
source
));
details
.
append
(
assembly
);
}
var
getAddress
=
function
()
{
return
$
(
'#txorigin'
).
val
();
};
button
.
click
(
function
()
{
detailsOpen
[
contractName
]
=
!
detailsOpen
[
contractName
];
details
.
toggle
();
});
if
(
detailsOpen
[
contractName
])
{
details
.
show
();
}
return
$
(
'<div class="contractDetails"/>'
).
append
(
button
).
append
(
details
);
var
getValue
=
function
()
{
var
comp
=
$
(
'#value'
).
val
().
split
(
' '
);
return
self
.
executionContext
.
web3
().
toWei
(
comp
[
0
],
comp
.
slice
(
1
).
join
(
' '
));
};
var
formatGasEstimates
=
function
(
data
)
{
// FIXME: the whole gasEstimates object should be nil instead
if
(
data
.
creation
===
undefined
&&
data
.
external
===
undefined
&&
data
.
internal
===
undefined
)
{
return
;
}
var
gasToText
=
function
(
g
)
{
return
g
===
null
?
'unknown'
:
g
;
};
var
text
=
''
;
var
fun
;
if
(
'creation'
in
data
)
{
text
+=
'Creation: '
+
gasToText
(
data
.
creation
[
0
])
+
' + '
+
gasToText
(
data
.
creation
[
1
])
+
'
\
n'
;
}
var
getGasLimit
=
function
()
{
return
$
(
'#gasLimit'
).
val
();
};
if
(
'external'
in
data
)
{
text
+=
'External:
\
n'
;
for
(
fun
in
data
.
external
)
{
text
+=
' '
+
fun
+
': '
+
gasToText
(
data
.
external
[
fun
])
+
'
\
n'
;
}
}
this
.
udapp
.
reset
(
udappContracts
,
getAddress
,
getValue
,
getGasLimit
,
renderOutputModifier
);
if
(
'internal'
in
data
)
{
text
+=
'Internal:
\
n'
;
for
(
fun
in
data
.
internal
)
{
text
+=
' '
+
fun
+
': '
+
gasToText
(
data
.
internal
[
fun
])
+
'
\
n'
;
}
}
var
$contractOutput
=
this
.
udapp
.
render
();
return
text
;
};
var
$txOrigin
=
$
(
'#txorigin'
);
var
formatAssemblyText
=
function
(
asm
,
prefix
,
source
)
{
if
(
typeof
asm
===
typeof
''
||
asm
===
null
||
asm
===
undefined
)
{
return
prefix
+
asm
+
'
\
n'
;
this
.
udapp
.
getAccounts
(
function
(
err
,
accounts
)
{
if
(
err
)
{
self
.
error
(
err
.
message
)
;
}
var
text
=
prefix
+
'.code
\
n'
;
$
.
each
(
asm
[
'.code'
],
function
(
i
,
item
)
{
var
v
=
item
.
value
===
undefined
?
''
:
item
.
value
;
var
src
=
''
;
if
(
item
.
begin
!==
undefined
&&
item
.
end
!==
undefined
)
{
src
=
source
.
slice
(
item
.
begin
,
item
.
end
).
replace
(
'
\
n'
,
'
\\
n'
,
'g'
);
}
if
(
src
.
length
>
30
)
{
src
=
src
.
slice
(
0
,
30
)
+
'...'
;
}
if
(
item
.
name
!==
'tag'
)
{
text
+=
' '
;
}
text
+=
prefix
+
item
.
name
+
' '
+
v
+
'
\
t
\
t
\
t'
+
src
+
'
\
n'
;
});
text
+=
prefix
+
'.data
\
n'
;
if
(
asm
[
'.data'
])
{
$
.
each
(
asm
[
'.data'
],
function
(
i
,
item
)
{
text
+=
' '
+
prefix
+
''
+
i
+
':
\
n'
;
text
+=
formatAssemblyText
(
item
,
prefix
+
' '
,
source
);
});
if
(
accounts
&&
accounts
[
0
])
{
$txOrigin
.
empty
();
for
(
var
a
in
accounts
)
{
$txOrigin
.
append
(
$
(
'<option />'
).
val
(
accounts
[
a
]).
text
(
accounts
[
a
]));
}
$txOrigin
.
val
(
accounts
[
0
]);
}
else
{
$txOrigin
.
val
(
'unknown'
);
}
});
return
text
;
};
function
gethDeploy
(
contractName
,
jsonInterface
,
bytecode
)
{
var
code
=
''
;
var
funABI
=
getConstructorInterface
(
JSON
.
parse
(
jsonInterface
));
funABI
.
inputs
.
forEach
(
function
(
inp
)
{
code
+=
'var '
+
inp
.
name
+
' = /* var of type '
+
inp
.
type
+
' here */ ;
\
n'
;
});
code
+=
'var '
+
contractName
+
'Contract = web3.eth.contract('
+
jsonInterface
.
replace
(
'
\
n'
,
''
)
+
');'
+
'
\
nvar '
+
contractName
+
' = '
+
contractName
+
'Contract.new('
;
funABI
.
inputs
.
forEach
(
function
(
inp
)
{
code
+=
'
\
n '
+
inp
.
name
+
','
;
});
code
+=
'
\
n {'
+
'
\
n from: web3.eth.accounts[0], '
+
'
\
n data:
\'
'
+
bytecode
+
'
\'
, '
+
'
\
n gas: 4700000'
+
'
\
n }, function (e, contract){'
+
'
\
n console.log(e, contract);'
+
'
\
n if (typeof contract.address !==
\'
undefined
\'
) {'
+
'
\
n console.log(
\'
Contract mined! address:
\'
+ contract.address +
\'
transactionHash:
\'
+ contract.transactionHash);'
+
'
\
n }'
+
'
\
n })'
;
return
code
;
}
function
getConstructorInterface
(
abi
)
{
var
funABI
=
{
'name'
:
''
,
'inputs'
:
[],
'type'
:
'constructor'
,
'outputs'
:
[]
};
for
(
var
i
=
0
;
i
<
abi
.
length
;
i
++
)
{
if
(
abi
[
i
].
type
===
'constructor'
)
{
funABI
.
inputs
=
abi
[
i
].
inputs
||
[];
break
;
}
}
return
funABI
;
}
}
$contractOutput
.
find
(
'.title'
).
click
(
function
(
ev
)
{
$
(
this
).
closest
(
'.contract'
).
toggleClass
(
'hide'
);
});
$
(
'#output'
).
append
(
$contractOutput
);
$
(
'.col2 input,textarea'
).
click
(
function
()
{
this
.
select
();
});
};
module
.
exports
=
Renderer
;
src/app/ui-helper.js
0 → 100644
View file @
0611230d
var
$
=
require
(
'jquery'
);
module
.
exports
=
{
tableRowItems
:
function
(
first
,
second
,
cls
)
{
return
$
(
'<div class="crow"/>'
)
.
addClass
(
cls
)
.
append
(
$
(
'<div class="col1">'
).
append
(
first
))
.
append
(
$
(
'<div class="col2">'
).
append
(
second
));
},
tableRow
:
function
(
description
,
data
)
{
return
this
.
tableRowItems
(
$
(
'<span/>'
).
text
(
description
),
$
(
'<input readonly="readonly"/>'
).
val
(
data
));
},
textRow
:
function
(
description
,
data
,
cls
)
{
return
this
.
tableRowItems
(
$
(
'<strong/>'
).
text
(
description
),
$
(
'<textarea readonly="readonly" class="gethDeployText"/>'
).
val
(
data
),
cls
);
},
formatAssemblyText
:
function
(
asm
,
prefix
,
source
)
{
var
self
=
this
;
if
(
typeof
asm
===
typeof
''
||
asm
===
null
||
asm
===
undefined
)
{
return
prefix
+
asm
+
'
\
n'
;
}
var
text
=
prefix
+
'.code
\
n'
;
$
.
each
(
asm
[
'.code'
],
function
(
i
,
item
)
{
var
v
=
item
.
value
===
undefined
?
''
:
item
.
value
;
var
src
=
''
;
if
(
item
.
begin
!==
undefined
&&
item
.
end
!==
undefined
)
{
src
=
source
.
slice
(
item
.
begin
,
item
.
end
).
replace
(
'
\
n'
,
'
\\
n'
,
'g'
);
}
if
(
src
.
length
>
30
)
{
src
=
src
.
slice
(
0
,
30
)
+
'...'
;
}
if
(
item
.
name
!==
'tag'
)
{
text
+=
' '
;
}
text
+=
prefix
+
item
.
name
+
' '
+
v
+
'
\
t
\
t
\
t'
+
src
+
'
\
n'
;
});
text
+=
prefix
+
'.data
\
n'
;
if
(
asm
[
'.data'
])
{
$
.
each
(
asm
[
'.data'
],
function
(
i
,
item
)
{
text
+=
' '
+
prefix
+
''
+
i
+
':
\
n'
;
text
+=
self
.
formatAssemblyText
(
item
,
prefix
+
' '
,
source
);
});
}
return
text
;
},
gethDeploy
:
function
(
contractName
,
jsonInterface
,
bytecode
)
{
var
code
=
''
;
var
funABI
=
this
.
getConstructorInterface
(
JSON
.
parse
(
jsonInterface
));
funABI
.
inputs
.
forEach
(
function
(
inp
)
{
code
+=
'var '
+
inp
.
name
+
' = /* var of type '
+
inp
.
type
+
' here */ ;
\
n'
;
});
code
+=
'var '
+
contractName
+
'Contract = web3.eth.contract('
+
jsonInterface
.
replace
(
'
\
n'
,
''
)
+
');'
+
'
\
nvar '
+
contractName
+
' = '
+
contractName
+
'Contract.new('
;
funABI
.
inputs
.
forEach
(
function
(
inp
)
{
code
+=
'
\
n '
+
inp
.
name
+
','
;
});
code
+=
'
\
n {'
+
'
\
n from: web3.eth.accounts[0], '
+
"
\
n data: '"
+
bytecode
+
"', "
+
'
\
n gas: 4700000'
+
'
\
n }, function (e, contract){'
+
'
\
n console.log(e, contract);'
+
"
\
n if (typeof contract.address !== 'undefined') {"
+
"
\
n console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);"
+
'
\
n }'
+
'
\
n })'
;
return
code
;
},
getConstructorInterface
:
function
(
abi
)
{
var
funABI
=
{
'name'
:
''
,
'inputs'
:
[],
'type'
:
'constructor'
,
'outputs'
:
[]
};
for
(
var
i
=
0
;
i
<
abi
.
length
;
i
++
)
{
if
(
abi
[
i
].
type
===
'constructor'
)
{
funABI
.
inputs
=
abi
[
i
].
inputs
||
[];
break
;
}
}
return
funABI
;
},
formatGasEstimates
:
function
(
data
)
{
// FIXME: the whole gasEstimates object should be nil instead
if
(
data
.
creation
===
undefined
&&
data
.
external
===
undefined
&&
data
.
internal
===
undefined
)
{
return
;
}
var
gasToText
=
function
(
g
)
{
return
g
===
null
?
'unknown'
:
g
;
};
var
text
=
''
;
var
fun
;
if
(
'creation'
in
data
)
{
text
+=
'Creation: '
+
gasToText
(
data
.
creation
[
0
])
+
' + '
+
gasToText
(
data
.
creation
[
1
])
+
'
\
n'
;
}
if
(
'external'
in
data
)
{
text
+=
'External:
\
n'
;
for
(
fun
in
data
.
external
)
{
text
+=
' '
+
fun
+
': '
+
gasToText
(
data
.
external
[
fun
])
+
'
\
n'
;
}
}
if
(
'internal'
in
data
)
{
text
+=
'Internal:
\
n'
;
for
(
fun
in
data
.
internal
)
{
text
+=
' '
+
fun
+
': '
+
gasToText
(
data
.
internal
[
fun
])
+
'
\
n'
;
}
}
return
text
;
},
detailsOpen
:
{},
getDetails
:
function
(
contract
,
source
,
contractName
)
{
var
button
=
$
(
'<button>Toggle Details</button>'
);
var
details
=
$
(
'<div style="display: none;"/>'
)
.
append
(
this
.
tableRow
(
'Solidity Interface'
,
contract
.
solidity_interface
));
if
(
contract
.
opcodes
!==
''
)
{
details
.
append
(
this
.
tableRow
(
'Opcodes'
,
contract
.
opcodes
));
}
var
funHashes
=
''
;
for
(
var
fun
in
contract
.
functionHashes
)
{
funHashes
+=
contract
.
functionHashes
[
fun
]
+
' '
+
fun
+
'
\
n'
;
}
details
.
append
(
$
(
'<span class="col1">Functions</span>'
));
details
.
append
(
$
(
'<pre/>'
).
text
(
funHashes
));
var
gasEstimates
=
this
.
formatGasEstimates
(
contract
.
gasEstimates
);
if
(
gasEstimates
)
{
details
.
append
(
$
(
'<span class="col1">Gas Estimates</span>'
));
details
.
append
(
$
(
'<pre/>'
).
text
(
gasEstimates
));
}
if
(
contract
.
runtimeBytecode
&&
contract
.
runtimeBytecode
.
length
>
0
)
{
details
.
append
(
this
.
tableRow
(
'Runtime Bytecode'
,
contract
.
runtimeBytecode
));
}
if
(
contract
.
assembly
!==
null
)
{
details
.
append
(
$
(
'<span class="col1">Assembly</span>'
));
var
assembly
=
$
(
'<pre/>'
).
text
(
this
.
formatAssemblyText
(
contract
.
assembly
,
''
,
source
));
details
.
append
(
assembly
);
}
button
.
click
(
function
()
{
this
.
detailsOpen
[
contractName
]
=
!
this
.
detailsOpen
[
contractName
];
details
.
toggle
();
});
if
(
this
.
detailsOpen
[
contractName
])
{
details
.
show
();
}
return
$
(
'<div class="contractDetails"/>'
).
append
(
button
).
append
(
details
);
}
};
src/lib/eventManager.js
0 → 100644
View file @
0611230d
'use strict'
;
function
eventManager
()
{
this
.
registered
=
{};
}
/*
* Unregister a listenner.
* Note that if obj is a function. the unregistration will be applied to the dummy obj {}.
*
* @param {String} eventName - the event name
* @param {Object or Func} obj - object that will listen on this event
* @param {Func} func - function of the listenners that will be executed
*/
eventManager
.
prototype
.
unregister
=
function
(
eventName
,
obj
,
func
)
{
if
(
obj
instanceof
Function
)
{
func
=
obj
;
obj
=
{};
}
for
(
var
reg
in
this
.
registered
[
eventName
])
{
if
(
this
.
registered
[
eventName
][
reg
]
&&
this
.
registered
[
eventName
][
reg
].
obj
===
obj
&&
(
!
func
||
this
.
registered
[
eventName
][
reg
].
func
===
func
))
{
this
.
registered
[
eventName
].
splice
(
reg
,
1
);
return
;
}
}
};
/*
* Register a new listenner.
* Note that if obj is a function, the function registration will be associated with the dummy object {}
*
* @param {String} eventName - the event name
* @param {Object or Func} obj - object that will listen on this event
* @param {Func} func - function of the listenners that will be executed
*/
eventManager
.
prototype
.
register
=
function
(
eventName
,
obj
,
func
)
{
if
(
!
this
.
registered
[
eventName
])
{
this
.
registered
[
eventName
]
=
[];
}
if
(
obj
instanceof
Function
)
{
func
=
obj
;
obj
=
{};
}
this
.
registered
[
eventName
].
push
({
obj
:
obj
,
func
:
func
});
};
/*
* trigger event.
* Every listenner have their associated function executed
*
* @param {String} eventName - the event name
* @param {Array}j - argument that will be passed to the exectued function.
*/
eventManager
.
prototype
.
trigger
=
function
(
eventName
,
args
)
{
for
(
var
listener
in
this
.
registered
[
eventName
])
{
var
l
=
this
.
registered
[
eventName
][
listener
];
l
.
func
.
apply
(
l
.
obj
,
args
);
}
};
module
.
exports
=
eventManager
;
src/universal-dapp.js
View file @
0611230d
...
...
@@ -6,31 +6,46 @@ var EthJSTX = require('ethereumjs-tx');
var
ethJSABI
=
require
(
'ethereumjs-abi'
);
var
EthJSBlock
=
require
(
'ethereumjs-block'
);
var
BN
=
ethJSUtil
.
BN
;
var
EventManager
=
require
(
'./lib/eventManager'
);
function
UniversalDApp
(
contracts
,
options
,
transactionDebugger
,
vm
)
{
/*
trigger debugRequested
*/
function
UniversalDApp
(
executionContext
,
options
,
txdebugger
)
{
this
.
event
=
new
EventManager
();
var
self
=
this
;
self
.
options
=
options
||
{};
self
.
$el
=
$
(
'<div class="udapp" />'
);
self
.
contracts
=
contracts
;
self
.
renderOutputModifier
=
options
.
renderOutputModifier
||
function
(
name
,
content
)
{
return
content
;
};
self
.
web3
=
options
.
web3
;
self
.
transactionDebugger
=
transactionDebugger
;
if
(
options
.
mode
===
'vm'
)
{
// FIXME: use `options.vm` or `self.vm` consistently
options
.
vm
=
true
;
self
.
accounts
=
{};
self
.
vm
=
vm
;
self
.
addAccount
(
'3cd7232cd6f3fc66a57a6bedc1a8ed6c228fff0a327e169c2bcc5e869ed49511'
);
self
.
addAccount
(
'2ac6c190b09897cd8987869cc7b918cfea07ee82038d492abce033c75c1b1d0c'
);
}
else
if
(
options
.
mode
!==
'web3'
)
{
throw
new
Error
(
'Either VM or Web3 mode must be selected'
);
}
self
.
contracts
;
self
.
getAddress
;
self
.
getValue
;
self
.
getGasLimit
;
self
.
txdebugger
=
txdebugger
;
// temporary: will not be needed anymore when we'll add memory support to the VM
var
defaultRenderOutputModifier
=
function
(
name
,
content
)
{
return
content
;
};
self
.
renderOutputModifier
=
defaultRenderOutputModifier
;
self
.
web3
=
executionContext
.
web3
();
self
.
vm
=
executionContext
.
vm
();
self
.
executionContext
=
executionContext
;
self
.
executionContext
.
event
.
register
(
'contextChanged'
,
this
,
function
(
context
)
{
self
.
reset
(
self
.
contracts
);
});
}
UniversalDApp
.
prototype
.
reset
=
function
(
contracts
,
getAddress
,
getValue
,
getGasLimit
,
renderer
)
{
this
.
$el
.
empty
();
this
.
contracts
=
contracts
;
this
.
getAddress
=
getAddress
;
this
.
getValue
=
getValue
;
this
.
getGasLimit
=
getGasLimit
;
this
.
renderOutputModifier
=
renderer
;
this
.
accounts
=
{};
if
(
this
.
executionContext
.
isVM
())
{
this
.
addAccount
(
'3cd7232cd6f3fc66a57a6bedc1a8ed6c228fff0a327e169c2bcc5e869ed49511'
);
this
.
addAccount
(
'2ac6c190b09897cd8987869cc7b918cfea07ee82038d492abce033c75c1b1d0c'
);
}
};
UniversalDApp
.
prototype
.
addAccount
=
function
(
privateKey
,
balance
)
{
var
self
=
this
;
...
...
@@ -48,7 +63,7 @@ UniversalDApp.prototype.addAccount = function (privateKey, balance) {
UniversalDApp
.
prototype
.
getAccounts
=
function
(
cb
)
{
var
self
=
this
;
if
(
!
self
.
vm
)
{
if
(
!
self
.
executionContext
.
isVM
()
)
{
self
.
web3
.
eth
.
getAccounts
(
cb
);
}
else
{
if
(
!
self
.
accounts
)
{
...
...
@@ -64,7 +79,7 @@ UniversalDApp.prototype.getBalance = function (address, cb) {
address
=
ethJSUtil
.
stripHexPrefix
(
address
);
if
(
!
self
.
vm
)
{
if
(
!
self
.
executionContext
.
isVM
()
)
{
self
.
web3
.
eth
.
getBalance
(
address
,
function
(
err
,
res
)
{
if
(
err
)
{
cb
(
err
);
...
...
@@ -194,7 +209,7 @@ UniversalDApp.prototype.getInstanceInterface = function (contract, address, $tar
$close
.
click
(
function
()
{
$instance
.
remove
();
});
$instance
.
append
(
$close
);
}
var
context
=
self
.
options
.
vm
?
'memory'
:
'blockchain'
;
var
context
=
self
.
executionContext
.
isVM
()
?
'memory'
:
'blockchain'
;
address
=
(
address
.
slice
(
0
,
2
)
===
'0x'
?
''
:
'0x'
)
+
address
.
toString
(
'hex'
);
var
$title
=
$
(
'<span class="title"/>'
).
text
(
contract
.
name
+
' at '
+
address
+
' ('
+
context
+
')'
);
...
...
@@ -221,7 +236,7 @@ UniversalDApp.prototype.getInstanceInterface = function (contract, address, $tar
$events
.
append
(
$event
);
};
if
(
self
.
options
.
vm
)
{
if
(
self
.
executionContext
.
isVM
()
)
{
// FIXME: support indexed events
var
eventABI
=
{};
...
...
@@ -354,7 +369,7 @@ UniversalDApp.prototype.getCallButton = function (args) {
var
$debugTx
=
$
(
'<div class="debugTx">'
);
var
$button
=
$
(
'<button title="Launch Debugger" class="debug"><i class="fa fa-bug"></i></button>'
);
$button
.
click
(
function
()
{
self
.
transactionDebugger
.
debug
(
result
);
self
.
event
.
trigger
(
'debugRequested'
,
[
result
]
);
});
$debugTx
.
append
(
$button
);
return
$debugTx
;
...
...
@@ -364,7 +379,7 @@ UniversalDApp.prototype.getCallButton = function (args) {
var
$debugTx
=
$
(
'<div class="debugCall">'
);
var
$button
=
$
(
'<button title="Launch Debugger" class="debug"><i class="fa fa-bug"></i></button>'
);
$button
.
click
(
function
()
{
self
.
transactionDebugger
.
debug
(
result
);
self
.
event
.
trigger
(
'debugRequested'
,
[
result
]
);
});
$debugTx
.
append
(
$button
);
return
$debugTx
;
...
...
@@ -504,16 +519,16 @@ UniversalDApp.prototype.getCallButton = function (args) {
if
(
err
)
{
replaceOutput
(
$result
,
$
(
'<span/>'
).
text
(
err
).
addClass
(
'error'
));
// VM only
}
else
if
(
self
.
options
.
vm
&&
result
.
vm
.
exception
===
0
&&
result
.
vm
.
exceptionError
)
{
}
else
if
(
self
.
executionContext
.
isVM
()
&&
result
.
vm
.
exception
===
0
&&
result
.
vm
.
exceptionError
)
{
replaceOutput
(
$result
,
$
(
'<span/>'
).
text
(
'VM Exception: '
+
result
.
vm
.
exceptionError
).
addClass
(
'error'
));
// VM only
}
else
if
(
self
.
options
.
vm
&&
result
.
vm
.
return
===
undefined
)
{
}
else
if
(
self
.
executionContext
.
isVM
()
&&
result
.
vm
.
return
===
undefined
)
{
replaceOutput
(
$result
,
$
(
'<span/>'
).
text
(
'Exception during execution.'
).
addClass
(
'error'
));
}
else
if
(
isConstructor
)
{
replaceOutput
(
$result
,
getGasUsedOutput
(
result
,
result
.
vm
));
$result
.
append
(
getDebugTransaction
(
result
));
args
.
appendFunctions
(
self
.
options
.
vm
?
result
.
createdAddress
:
result
.
contractAddress
);
}
else
if
(
self
.
options
.
vm
)
{
args
.
appendFunctions
(
self
.
executionContext
.
isVM
()
?
result
.
createdAddress
:
result
.
contractAddress
);
}
else
if
(
self
.
executionContext
.
isVM
()
)
{
var
outputObj
=
'0x'
+
result
.
vm
.
return
.
toString
(
'hex'
);
clearOutput
(
$result
);
$result
.
append
(
getReturnOutput
(
outputObj
)).
append
(
getGasUsedOutput
(
result
,
result
.
vm
));
...
...
@@ -611,7 +626,7 @@ UniversalDApp.prototype.deployLibrary = function (contractName, cb) {
if
(
err
)
{
return
cb
(
err
);
}
var
address
=
self
.
options
.
vm
?
result
.
createdAddress
:
result
.
contractAddress
;
var
address
=
self
.
executionContext
.
isVM
()
?
result
.
createdAddress
:
result
.
contractAddress
;
self
.
getContractByName
(
contractName
).
address
=
address
;
cb
(
err
,
address
);
});
...
...
@@ -644,27 +659,27 @@ UniversalDApp.prototype.runTx = function (data, args, cb) {
}
var
gasLimit
=
3000000
;
if
(
self
.
options
.
getGasLimit
)
{
if
(
self
.
getGasLimit
)
{
try
{
gasLimit
=
self
.
options
.
getGasLimit
();
gasLimit
=
self
.
getGasLimit
();
}
catch
(
e
)
{
return
cb
(
e
);
}
}
var
value
=
0
;
if
(
self
.
options
.
getValue
)
{
if
(
self
.
getValue
)
{
try
{
value
=
self
.
options
.
getValue
();
value
=
self
.
getValue
();
}
catch
(
e
)
{
return
cb
(
e
);
}
}
var
tx
;
if
(
!
self
.
vm
)
{
if
(
!
self
.
executionContext
.
isVM
()
)
{
tx
=
{
from
:
self
.
options
.
getAddress
?
self
.
options
.
getAddress
()
:
self
.
web3
.
eth
.
accounts
[
0
],
from
:
self
.
getAddress
?
self
.
getAddress
()
:
self
.
web3
.
eth
.
accounts
[
0
],
to
:
to
,
data
:
data
,
value
:
value
...
...
@@ -695,7 +710,7 @@ UniversalDApp.prototype.runTx = function (data, args, cb) {
}
}
else
{
try
{
var
address
=
self
.
options
.
getAddress
?
self
.
options
.
getAddress
()
:
self
.
getAccounts
(
)[
0
];
var
address
=
self
.
getAddress
?
self
.
getAddress
()
:
Object
.
keys
(
self
.
accounts
)[
0
];
var
account
=
self
.
accounts
[
address
];
tx
=
new
EthJSTX
({
nonce
:
new
BN
(
account
.
nonce
++
),
...
...
@@ -715,7 +730,7 @@ UniversalDApp.prototype.runTx = function (data, args, cb) {
uncleHeaders
:
[]
});
self
.
vm
.
runTx
({
block
:
block
,
tx
:
tx
,
skipBalance
:
true
,
skipNonce
:
true
},
function
(
err
,
result
)
{
result
.
transactionHash
=
self
.
t
ransactionD
ebugger
.
web3
().
releaseCurrentHash
();
// used to keep track of the transaction
result
.
transactionHash
=
self
.
t
xd
ebugger
.
web3
().
releaseCurrentHash
();
// used to keep track of the transaction
cb
(
err
,
result
);
});
}
catch
(
e
)
{
...
...
test/compiler-test.js
View file @
0611230d
var
test
=
require
(
'tape'
);
var
Compiler
=
require
(
'../src/app/compiler'
);
var
EventManager
=
require
(
'../src/lib/eventManager'
);
test
(
'compiler.compile smoke'
,
function
(
t
)
{
t
.
plan
(
1
);
...
...
@@ -8,9 +9,8 @@ test('compiler.compile smoke', function (t) {
var
noop
=
function
()
{};
var
getCacheFile
=
function
()
{
return
'fakeCacheFile'
;
};
var
fakeEditor
=
{
onChangeSetup
:
noop
,
clearAnnotations
:
noop
,
getValue
:
noop
,
setCacheFileContent
:
noop
,
getCacheFile
:
getCacheFile
};
var
fakeOutputField
=
{
empty
:
noop
};
var
fakeQueryParams
=
{
get
:
function
()
{
return
{};
}};
var
compiler
=
new
Compiler
(
fakeEditor
,
null
,
fakeQueryParams
,
null
,
fakeOutputField
);
var
compiler
=
new
Compiler
(
fakeEditor
,
fakeQueryParams
,
null
,
null
,
new
EventManager
()
);
compiler
.
setCompileJSON
(
noop
);
compiler
.
compile
();
t
.
ok
(
compiler
);
...
...
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