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
6884d6dc
Unverified
Commit
6884d6dc
authored
Dec 11, 2017
by
yann300
Committed by
GitHub
Dec 11, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #802 from ethereum/recordTxs
Record Transactions
parents
1bd5cc6e
48da81b7
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
800 additions
and
166 deletions
+800
-166
.travis.yml
.travis.yml
+1
-1
makeMockCompiler.js
ci/makeMockCompiler.js
+9
-20
app.js
src/app.js
+10
-0
debugger.js
src/app/debugger/debugger.js
+4
-1
contextView.js
src/app/editor/contextView.js
+2
-2
txFormat.js
src/app/execution/txFormat.js
+43
-12
txLogger.js
src/app/execution/txLogger.js
+2
-2
txRunner.js
src/app/execution/txRunner.js
+2
-2
fileManager.js
src/app/files/fileManager.js
+7
-0
run-tab.js
src/app/tabs/run-tab.js
+123
-27
modal-dialog-custom.js
src/app/ui/modal-dialog-custom.js
+14
-2
recorder.js
src/recorder.js
+256
-0
universal-dapp.js
src/universal-dapp.js
+68
-76
contracts.js
test-browser/helpers/contracts.js
+56
-5
ballot.js
test-browser/tests/ballot.js
+25
-15
compiling.js
test-browser/tests/compiling.js
+4
-1
simpleContract.js
test-browser/tests/simpleContract.js
+1
-0
staticanalysis.js
test-browser/tests/staticanalysis.js
+1
-0
testRecorder.js
test-browser/tests/units/testRecorder.js
+172
-0
No files found.
.travis.yml
View file @
6884d6dc
...
@@ -2,7 +2,7 @@ language: node_js
...
@@ -2,7 +2,7 @@ language: node_js
node_js
:
node_js
:
-
"
7"
-
"
7"
script
:
script
:
-
npm run lint && npm run test && npm run downloadsolc && npm run make-mock-compiler && npm run
pullremix && npm run linkremix && npm run
build
-
npm run lint && npm run test && npm run downloadsolc && npm run make-mock-compiler && npm run build
-
./ci/browser_tests.sh
-
./ci/browser_tests.sh
deploy
:
deploy
:
-
provider
:
script
-
provider
:
script
...
...
ci/makeMockCompiler.js
View file @
6884d6dc
...
@@ -6,25 +6,16 @@ var soljson = require('../soljson')
...
@@ -6,25 +6,16 @@ var soljson = require('../soljson')
var
compiler
=
solc
(
soljson
)
var
compiler
=
solc
(
soljson
)
var
compilerInput
=
require
(
'../src/app/compiler/compiler-input'
)
var
compilerInput
=
require
(
'../src/app/compiler/compiler-input'
)
var
compilationResult
=
{}
gatherCompilationResults
(
'./test-browser/tests/'
,
compilationResult
)
gatherCompilationResults
(
'./test-browser/tests/units/'
,
compilationResult
)
replaceSolCompiler
(
compilationResult
)
gatherCompilationResults
(
function
(
error
,
data
)
{
function
gatherCompilationResults
(
dir
,
compilationResult
,
callback
)
{
if
(
error
)
{
var
filenames
=
fs
.
readdirSync
(
dir
,
'utf8'
)
console
.
log
(
error
)
process
.
exit
(
1
)
}
else
{
replaceSolCompiler
(
data
)
}
})
function
gatherCompilationResults
(
callback
)
{
var
compilationResult
=
{}
fs
.
readdir
(
'./test-browser/tests'
,
'utf8'
,
function
(
error
,
filenames
)
{
if
(
error
)
{
console
.
log
(
error
)
process
.
exit
(
1
)
}
else
{
filenames
.
map
(
function
(
item
,
i
)
{
filenames
.
map
(
function
(
item
,
i
)
{
var
testDef
=
require
(
'../test-browser/tests/'
+
item
)
if
(
item
.
endsWith
(
'.js'
))
{
var
testDef
=
require
(
'.'
+
dir
+
item
)
if
(
'@sources'
in
testDef
)
{
if
(
'@sources'
in
testDef
)
{
var
sources
=
testDef
[
'@sources'
]()
var
sources
=
testDef
[
'@sources'
]()
for
(
var
files
in
sources
)
{
for
(
var
files
in
sources
)
{
...
@@ -36,11 +27,9 @@ function gatherCompilationResults (callback) {
...
@@ -36,11 +27,9 @@ function gatherCompilationResults (callback) {
})
})
}
}
}
}
})
callback
(
null
,
compilationResult
)
}
}
})
})
return
compilationResult
}
}
function
compile
(
source
,
optimization
,
addCompilationResult
)
{
function
compile
(
source
,
optimization
,
addCompilationResult
)
{
...
...
src/app.js
View file @
6884d6dc
...
@@ -537,6 +537,9 @@ function run () {
...
@@ -537,6 +537,9 @@ function run () {
document
.
querySelector
(
`.
${
css
.
dragbar2
}
`
).
style
.
right
=
delta
+
'px'
document
.
querySelector
(
`.
${
css
.
dragbar2
}
`
).
style
.
right
=
delta
+
'px'
onResize
()
onResize
()
},
},
getAccounts
:
(
cb
)
=>
{
udapp
.
getAccounts
(
cb
)
},
getSource
:
(
fileName
)
=>
{
getSource
:
(
fileName
)
=>
{
return
compiler
.
getSource
(
fileName
)
return
compiler
.
getSource
(
fileName
)
},
},
...
@@ -558,12 +561,19 @@ function run () {
...
@@ -558,12 +561,19 @@ function run () {
udapp
:
()
=>
{
udapp
:
()
=>
{
return
udapp
return
udapp
},
},
switchFile
:
function
(
path
)
{
fileManager
.
switchFile
(
path
)
},
filesProviders
:
filesProviders
,
fileProviderOf
:
(
path
)
=>
{
fileProviderOf
:
(
path
)
=>
{
return
fileManager
.
fileProviderOf
(
path
)
return
fileManager
.
fileProviderOf
(
path
)
},
},
fileProvider
:
(
name
)
=>
{
fileProvider
:
(
name
)
=>
{
return
self
.
_api
.
filesProviders
[
name
]
return
self
.
_api
.
filesProviders
[
name
]
},
},
currentPath
:
function
()
{
return
fileManager
.
currentPath
()
},
getBalance
:
(
address
,
callback
)
=>
{
getBalance
:
(
address
,
callback
)
=>
{
udapp
.
getBalance
(
address
,
(
error
,
balance
)
=>
{
udapp
.
getBalance
(
address
,
(
error
,
balance
)
=>
{
if
(
error
)
{
if
(
error
)
{
...
...
src/app/debugger/debugger.js
View file @
6884d6dc
...
@@ -75,7 +75,10 @@ Debugger.prototype.debug = function (txHash) {
...
@@ -75,7 +75,10 @@ Debugger.prototype.debug = function (txHash) {
var
self
=
this
var
self
=
this
this
.
debugger
.
web3
().
eth
.
getTransaction
(
txHash
,
function
(
error
,
tx
)
{
this
.
debugger
.
web3
().
eth
.
getTransaction
(
txHash
,
function
(
error
,
tx
)
{
if
(
!
error
)
{
if
(
!
error
)
{
self
.
debugger
.
setCompilationResult
(
self
.
appAPI
.
lastCompilationResult
().
data
)
var
compilationResult
=
self
.
appAPI
.
lastCompilationResult
()
if
(
compilationResult
)
{
self
.
debugger
.
setCompilationResult
(
compilationResult
.
data
)
}
self
.
debugger
.
debug
(
tx
)
self
.
debugger
.
debug
(
tx
)
}
}
})
})
...
...
src/app/editor/contextView.js
View file @
6884d6dc
...
@@ -109,7 +109,7 @@ class ContextView {
...
@@ -109,7 +109,7 @@ class ContextView {
if
(
target
)
{
if
(
target
)
{
this
.
_current
=
target
this
.
_current
=
target
}
else
{
}
else
{
this
.
_current
=
last
this
.
_current
=
null
}
}
}
}
}
}
...
@@ -123,7 +123,7 @@ class ContextView {
...
@@ -123,7 +123,7 @@ class ContextView {
if
(
!
node
)
return
yo
`<div></div>`
if
(
!
node
)
return
yo
`<div></div>`
var
self
=
this
var
self
=
this
var
references
=
this
.
_api
.
contextualListener
.
referencesOf
(
node
)
var
references
=
this
.
_api
.
contextualListener
.
referencesOf
(
node
)
var
type
=
node
.
attributes
.
type
?
node
.
attributes
.
type
:
node
.
name
var
type
=
(
node
.
attributes
&&
node
.
attributes
.
type
)
?
node
.
attributes
.
type
:
node
.
name
references
=
`
${
references
?
references
.
length
:
'0'
}
reference(s)`
references
=
`
${
references
?
references
.
length
:
'0'
}
reference(s)`
var
ref
=
0
var
ref
=
0
...
...
src/app/execution/txFormat.js
View file @
6884d6dc
...
@@ -8,9 +8,34 @@ var TreeView = require('remix-debugger').ui.TreeView
...
@@ -8,9 +8,34 @@ var TreeView = require('remix-debugger').ui.TreeView
var
executionContext
=
require
(
'../../execution-context'
)
var
executionContext
=
require
(
'../../execution-context'
)
module
.
exports
=
{
module
.
exports
=
{
/**
* build the transaction data
*
* @param {Object} function abi
* @param {Object} values to encode
* @param {String} contractbyteCode
*/
encodeData
:
function
(
funABI
,
values
,
contractbyteCode
)
{
var
encoded
var
encodedHex
try
{
encoded
=
helper
.
encodeParams
(
funABI
,
values
)
encodedHex
=
encoded
.
toString
(
'hex'
)
}
catch
(
e
)
{
return
{
error
:
'cannot encode arguments'
}
}
if
(
contractbyteCode
)
{
return
{
data
:
contractbyteCode
+
encodedHex
}
}
else
{
return
{
data
:
Buffer
.
concat
([
helper
.
encodeFunctionId
(
funABI
),
encoded
]).
toString
(
'hex'
)
}
}
},
/**
/**
* build the transaction data
* build the transaction data
*
*
* @param {String} contractName
* @param {Object} contract - abi definition of the current contract.
* @param {Object} contract - abi definition of the current contract.
* @param {Object} contracts - map of all compiled contracts.
* @param {Object} contracts - map of all compiled contracts.
* @param {Bool} isConstructor - isConstructor.
* @param {Bool} isConstructor - isConstructor.
...
@@ -20,7 +45,7 @@ module.exports = {
...
@@ -20,7 +45,7 @@ module.exports = {
* @param {Function} callback - callback
* @param {Function} callback - callback
* @param {Function} callbackStep - callbackStep
* @param {Function} callbackStep - callbackStep
*/
*/
buildData
:
function
(
contract
,
contracts
,
isConstructor
,
funAbi
,
params
,
udapp
,
callback
,
callbackStep
)
{
buildData
:
function
(
contract
Name
,
contract
,
contracts
,
isConstructor
,
funAbi
,
params
,
udapp
,
callback
,
callbackStep
)
{
var
funArgs
=
''
var
funArgs
=
''
try
{
try
{
funArgs
=
$
.
parseJSON
(
'['
+
params
+
']'
)
funArgs
=
$
.
parseJSON
(
'['
+
params
+
']'
)
...
@@ -45,7 +70,9 @@ module.exports = {
...
@@ -45,7 +70,9 @@ module.exports = {
if
(
data
.
slice
(
0
,
2
)
===
'0x'
)
{
if
(
data
.
slice
(
0
,
2
)
===
'0x'
)
{
dataHex
=
data
.
slice
(
2
)
dataHex
=
data
.
slice
(
2
)
}
}
var
contractBytecode
if
(
isConstructor
)
{
if
(
isConstructor
)
{
contractBytecode
=
contract
.
evm
.
bytecode
.
object
var
bytecodeToDeploy
=
contract
.
evm
.
bytecode
.
object
var
bytecodeToDeploy
=
contract
.
evm
.
bytecode
.
object
if
(
bytecodeToDeploy
.
indexOf
(
'_'
)
>=
0
)
{
if
(
bytecodeToDeploy
.
indexOf
(
'_'
)
>=
0
)
{
this
.
linkBytecode
(
contract
,
contracts
,
udapp
,
(
err
,
bytecode
)
=>
{
this
.
linkBytecode
(
contract
,
contracts
,
udapp
,
(
err
,
bytecode
)
=>
{
...
@@ -53,7 +80,7 @@ module.exports = {
...
@@ -53,7 +80,7 @@ module.exports = {
callback
(
'Error deploying required libraries: '
+
err
)
callback
(
'Error deploying required libraries: '
+
err
)
}
else
{
}
else
{
bytecodeToDeploy
=
bytecode
+
dataHex
bytecodeToDeploy
=
bytecode
+
dataHex
return
callback
(
null
,
bytecodeToDeploy
)
return
callback
(
null
,
{
dataHex
:
bytecodeToDeploy
,
funAbi
,
funArgs
,
contractBytecode
,
contractName
:
contractName
}
)
}
}
},
callbackStep
)
},
callbackStep
)
return
return
...
@@ -63,7 +90,7 @@ module.exports = {
...
@@ -63,7 +90,7 @@ module.exports = {
}
else
{
}
else
{
dataHex
=
Buffer
.
concat
([
helper
.
encodeFunctionId
(
funAbi
),
data
]).
toString
(
'hex'
)
dataHex
=
Buffer
.
concat
([
helper
.
encodeFunctionId
(
funAbi
),
data
]).
toString
(
'hex'
)
}
}
callback
(
null
,
dataHex
)
callback
(
null
,
{
dataHex
,
funAbi
,
funArgs
,
contractBytecode
,
contractName
:
contractName
}
)
},
},
atAddress
:
function
()
{},
atAddress
:
function
()
{},
...
@@ -90,7 +117,7 @@ module.exports = {
...
@@ -90,7 +117,7 @@ module.exports = {
if
(
!
library
)
{
if
(
!
library
)
{
return
callback
(
'Library '
+
libraryName
+
' not found.'
)
return
callback
(
'Library '
+
libraryName
+
' not found.'
)
}
}
this
.
deployLibrary
(
libraryName
,
library
,
contracts
,
udapp
,
(
err
,
address
)
=>
{
this
.
deployLibrary
(
libraryName
,
library
ShortName
,
library
,
contracts
,
udapp
,
(
err
,
address
)
=>
{
if
(
err
)
{
if
(
err
)
{
return
callback
(
err
)
return
callback
(
err
)
}
}
...
@@ -104,7 +131,7 @@ module.exports = {
...
@@ -104,7 +131,7 @@ module.exports = {
},
callbackStep
)
},
callbackStep
)
},
},
deployLibrary
:
function
(
libraryName
,
library
,
contracts
,
udapp
,
callback
,
callbackStep
)
{
deployLibrary
:
function
(
libraryName
,
library
ShortName
,
library
,
contracts
,
udapp
,
callback
,
callbackStep
)
{
var
address
=
library
.
address
var
address
=
library
.
address
if
(
address
)
{
if
(
address
)
{
return
callback
(
null
,
address
)
return
callback
(
null
,
address
)
...
@@ -113,11 +140,12 @@ module.exports = {
...
@@ -113,11 +140,12 @@ module.exports = {
if
(
bytecode
.
indexOf
(
'_'
)
>=
0
)
{
if
(
bytecode
.
indexOf
(
'_'
)
>=
0
)
{
this
.
linkBytecode
(
libraryName
,
contracts
,
udapp
,
(
err
,
bytecode
)
=>
{
this
.
linkBytecode
(
libraryName
,
contracts
,
udapp
,
(
err
,
bytecode
)
=>
{
if
(
err
)
callback
(
err
)
if
(
err
)
callback
(
err
)
else
this
.
deployLibrary
(
libraryName
,
library
,
contracts
,
udapp
,
callback
,
callbackStep
)
else
this
.
deployLibrary
(
libraryName
,
library
ShortName
,
library
,
contracts
,
udapp
,
callback
,
callbackStep
)
},
callbackStep
)
},
callbackStep
)
}
else
{
}
else
{
callbackStep
(
`creation of library
${
libraryName
}
pending...`
)
callbackStep
(
`creation of library
${
libraryName
}
pending...`
)
udapp
.
runTx
({
data
:
bytecode
,
useCall
:
false
},
(
err
,
txResult
)
=>
{
var
data
=
{
dataHex
:
bytecode
,
funAbi
:
{
type
:
'constructor'
},
funArgs
:
[],
contractBytecode
:
bytecode
,
contractName
:
libraryShortName
}
udapp
.
runTx
({
data
:
data
,
useCall
:
false
},
(
err
,
txResult
)
=>
{
if
(
err
)
{
if
(
err
)
{
return
callback
(
err
)
return
callback
(
err
)
}
}
...
@@ -128,18 +156,21 @@ module.exports = {
...
@@ -128,18 +156,21 @@ module.exports = {
}
}
},
},
linkLibraryStandard
:
function
(
libraryName
,
address
,
contract
)
{
linkLibraryStandardFromlinkReferences
:
function
(
libraryName
,
address
,
bytecode
,
linkReferences
)
{
var
bytecode
=
contract
.
evm
.
bytecode
.
object
for
(
var
file
in
linkReferences
)
{
for
(
var
file
in
contract
.
evm
.
bytecode
.
linkReferences
)
{
for
(
var
libName
in
linkReferences
[
file
])
{
for
(
var
libName
in
contract
.
evm
.
bytecode
.
linkReferences
[
file
])
{
if
(
libraryName
===
libName
)
{
if
(
libraryName
===
libName
)
{
bytecode
=
this
.
setLibraryAddress
(
address
,
bytecode
,
contract
.
evm
.
bytecode
.
linkReferences
[
file
][
libName
])
bytecode
=
this
.
setLibraryAddress
(
address
,
bytecode
,
linkReferences
[
file
][
libName
])
}
}
}
}
}
}
return
bytecode
return
bytecode
},
},
linkLibraryStandard
:
function
(
libraryName
,
address
,
contract
)
{
return
this
.
linkLibraryStandardFromlinkReferences
(
libraryName
,
address
,
contract
.
evm
.
bytecode
.
object
,
contract
.
evm
.
bytecode
.
linkReferences
)
},
setLibraryAddress
:
function
(
address
,
bytecodeToLink
,
positions
)
{
setLibraryAddress
:
function
(
address
,
bytecodeToLink
,
positions
)
{
if
(
positions
)
{
if
(
positions
)
{
for
(
var
pos
of
positions
)
{
for
(
var
pos
of
positions
)
{
...
...
src/app/execution/txLogger.js
View file @
6884d6dc
...
@@ -269,7 +269,7 @@ function renderUnknownTransaction (self, data) {
...
@@ -269,7 +269,7 @@ function renderUnknownTransaction (self, data) {
input
:
data
.
tx
.
input
,
input
:
data
.
tx
.
input
,
hash
:
data
.
tx
.
hash
,
hash
:
data
.
tx
.
hash
,
gas
:
data
.
tx
.
gas
,
gas
:
data
.
tx
.
gas
,
logs
:
data
.
logs
,
logs
:
data
.
tx
.
logs
,
transactionCost
:
data
.
tx
.
transactionCost
,
transactionCost
:
data
.
tx
.
transactionCost
,
executionCost
:
data
.
tx
.
executionCost
,
executionCost
:
data
.
tx
.
executionCost
,
status
:
data
.
tx
.
status
status
:
data
.
tx
.
status
...
@@ -440,7 +440,7 @@ function createTable (opts) {
...
@@ -440,7 +440,7 @@ function createTable (opts) {
}
}
var
stringified
=
' - '
var
stringified
=
' - '
if
(
opts
.
logs
.
decoded
)
{
if
(
opts
.
logs
&&
opts
.
logs
.
decoded
)
{
stringified
=
typeConversion
.
stringify
(
opts
.
logs
.
decoded
)
stringified
=
typeConversion
.
stringify
(
opts
.
logs
.
decoded
)
}
}
var
logs
=
yo
`
var
logs
=
yo
`
...
...
src/app/execution/txRunner.js
View file @
6884d6dc
...
@@ -156,8 +156,8 @@ function run (self, tx, stamp, callback) {
...
@@ -156,8 +156,8 @@ function run (self, tx, stamp, callback) {
self
.
execute
(
tx
,
(
error
,
result
)
=>
{
self
.
execute
(
tx
,
(
error
,
result
)
=>
{
delete
self
.
pendingTxs
[
stamp
]
delete
self
.
pendingTxs
[
stamp
]
callback
(
error
,
result
)
callback
(
error
,
result
)
if
(
Object
.
keys
(
self
.
pendingTxs
)
.
length
)
{
if
(
self
.
queusTxs
.
length
)
{
var
next
=
self
.
pending
Txs
.
pop
()
var
next
=
self
.
queus
Txs
.
pop
()
run
(
self
,
next
.
tx
,
next
.
stamp
,
next
.
callback
)
run
(
self
,
next
.
tx
,
next
.
stamp
,
next
.
callback
)
}
}
})
})
...
...
src/app/files/fileManager.js
View file @
6884d6dc
...
@@ -79,6 +79,13 @@ class FileManager {
...
@@ -79,6 +79,13 @@ class FileManager {
this
.
refreshTabs
()
this
.
refreshTabs
()
}
}
currentPath
()
{
var
currentFile
=
this
.
opt
.
config
.
get
(
'currentFile'
)
var
reg
=
/
(
.*
\/)
.*/
var
path
=
reg
.
exec
(
currentFile
)
return
path
?
path
[
1
]
:
null
}
fileRemovedEvent
(
path
)
{
fileRemovedEvent
(
path
)
{
if
(
path
===
this
.
opt
.
config
.
get
(
'currentFile'
))
{
if
(
path
===
this
.
opt
.
config
.
get
(
'currentFile'
))
{
this
.
opt
.
config
.
set
(
'currentFile'
,
''
)
this
.
opt
.
config
.
set
(
'currentFile'
,
''
)
...
...
src/app/tabs/run-tab.js
View file @
6884d6dc
This diff is collapsed.
Click to expand it.
src/app/ui/modal-dialog-custom.js
View file @
6884d6dc
...
@@ -13,8 +13,20 @@ module.exports = {
...
@@ -13,8 +13,20 @@ module.exports = {
},
},
prompt
:
function
(
title
,
text
,
inputValue
,
ok
,
cancel
)
{
prompt
:
function
(
title
,
text
,
inputValue
,
ok
,
cancel
)
{
if
(
!
inputValue
)
inputValue
=
''
if
(
!
inputValue
)
inputValue
=
''
modal
(
title
,
var
input
=
yo
`<input type='text' name='prompt_text' id='prompt_text' class="
${
css
[
'prompt_text'
]}
" value='
${
inputValue
}
' >`
yo
`<div>
${
text
}
<div><input type='text' name='prompt_text' id='prompt_text' class="
${
css
[
'prompt_text'
]}
" value='
${
inputValue
}
' ></div></div>`
,
modal
(
title
,
yo
`<div>
${
text
}
<div>
${
input
}
</div></div>`
,
{
fn
:
()
=>
{
if
(
typeof
ok
===
'function'
)
ok
(
document
.
getElementById
(
'prompt_text'
).
value
)
}
},
{
fn
:
()
=>
{
if
(
typeof
cancel
===
'function'
)
cancel
()
}
}
)
},
promptMulti
:
function
({
title
,
text
,
inputValue
},
ok
,
cancel
)
{
if
(
!
inputValue
)
inputValue
=
''
var
input
=
yo
`<textarea id="prompt_text" class=
${
css
.
prompt_text
}
rows="4" cols="50"></textarea>`
modal
(
title
,
yo
`<div>
${
text
}
<div>
${
input
}
</div></div>`
,
{
{
fn
:
()
=>
{
if
(
typeof
ok
===
'function'
)
ok
(
document
.
getElementById
(
'prompt_text'
).
value
)
}
fn
:
()
=>
{
if
(
typeof
ok
===
'function'
)
ok
(
document
.
getElementById
(
'prompt_text'
).
value
)
}
},
},
...
...
src/recorder.js
0 → 100644
View file @
6884d6dc
var
remixLib
=
require
(
'remix-lib'
)
var
EventManager
=
remixLib
.
EventManager
var
ethutil
=
require
(
'ethereumjs-util'
)
var
executionContext
=
require
(
'./execution-context'
)
var
format
=
require
(
'./app/execution/txFormat'
)
var
txHelper
=
require
(
'./app/execution/txHelper'
)
var
async
=
require
(
'async'
)
var
modal
=
require
(
'./app/ui/modal-dialog-custom'
)
/**
* Record transaction as long as the user create them.
*
*
*/
class
Recorder
{
constructor
(
opts
=
{})
{
var
self
=
this
self
.
_api
=
opts
.
api
self
.
event
=
new
EventManager
()
self
.
data
=
{
_listen
:
true
,
_replay
:
false
,
journal
:
[],
_createdContracts
:
{},
_createdContractsReverse
:
{},
_usedAccounts
:
{},
_abis
:
{},
_contractABIReferences
:
{},
_linkReferences
:
{}
}
opts
.
events
.
executioncontext
.
register
(
'contextChanged'
,
()
=>
{
self
.
clearAll
()
})
opts
.
events
.
runtab
.
register
(
'clearInstances'
,
()
=>
{
self
.
clearAll
()
})
opts
.
events
.
udapp
.
register
(
'initiatingTransaction'
,
(
timestamp
,
tx
,
payLoad
)
=>
{
if
(
tx
.
useCall
)
return
var
{
from
,
to
,
value
}
=
tx
// convert to and from to tokens
if
(
this
.
data
.
_listen
)
{
var
record
=
{
value
,
parameters
:
payLoad
.
funArgs
}
if
(
!
to
)
{
var
selectedContract
=
self
.
_api
.
getContract
(
payLoad
.
contractName
)
if
(
selectedContract
)
{
var
abi
=
selectedContract
.
object
.
abi
var
sha3
=
ethutil
.
bufferToHex
(
ethutil
.
sha3
(
abi
))
record
.
abi
=
sha3
record
.
contractName
=
payLoad
.
contractName
record
.
bytecode
=
payLoad
.
contractBytecode
record
.
linkReferences
=
selectedContract
.
object
.
evm
.
bytecode
.
linkReferences
if
(
Object
.
keys
(
record
.
linkReferences
).
length
)
{
for
(
var
file
in
record
.
linkReferences
)
{
for
(
var
lib
in
record
.
linkReferences
[
file
])
{
self
.
data
.
_linkReferences
[
lib
]
=
'<address>'
}
}
}
self
.
data
.
_abis
[
sha3
]
=
abi
this
.
data
.
_contractABIReferences
[
timestamp
]
=
sha3
}
}
else
{
var
creationTimestamp
=
this
.
data
.
_createdContracts
[
to
]
record
.
to
=
`created{
${
creationTimestamp
}
}`
record
.
abi
=
this
.
data
.
_contractABIReferences
[
creationTimestamp
]
}
record
.
name
=
payLoad
.
funAbi
.
name
record
.
type
=
payLoad
.
funAbi
.
type
self
.
_api
.
getAccounts
((
error
,
accounts
)
=>
{
if
(
error
)
return
console
.
log
(
error
)
record
.
from
=
`account{
${
accounts
.
indexOf
(
from
)}
}`
self
.
data
.
_usedAccounts
[
record
.
from
]
=
from
self
.
append
(
timestamp
,
record
)
})
}
})
opts
.
events
.
udapp
.
register
(
'transactionExecuted'
,
(
error
,
from
,
to
,
data
,
call
,
txResult
,
timestamp
)
=>
{
if
(
error
)
return
console
.
log
(
error
)
if
(
call
)
return
var
address
=
executionContext
.
isVM
()
?
txResult
.
result
.
createdAddress
:
txResult
.
result
.
contractAddress
if
(
!
address
)
return
// not a contract creation
address
=
addressToString
(
address
)
// save back created addresses for the convertion from tokens to real adresses
this
.
data
.
_createdContracts
[
address
]
=
timestamp
this
.
data
.
_createdContractsReverse
[
timestamp
]
=
address
})
}
/**
* stop/start saving txs. If not listenning, is basically in replay mode
*
* @param {Bool} listen
*/
setListen
(
listen
)
{
this
.
data
.
_listen
=
listen
this
.
data
.
_replay
=
!
listen
}
extractTimestamp
(
value
)
{
var
stamp
=
/created{
(
.*
)
}/g
.
exec
(
value
)
if
(
stamp
)
{
return
stamp
[
1
]
}
return
null
}
/**
* convert back from/to from tokens to real addresses
*
* @param {Object} record
* @param {Object} accounts
* @param {Object} options
*
*/
resolveAddress
(
record
,
accounts
,
options
)
{
if
(
record
.
to
)
{
var
stamp
=
this
.
extractTimestamp
(
record
.
to
)
if
(
stamp
)
{
record
.
to
=
this
.
data
.
_createdContractsReverse
[
stamp
]
}
}
record
.
from
=
accounts
[
record
.
from
]
// @TODO: writing browser test
return
record
}
/**
* save the given @arg record
*
* @param {Number/String} timestamp
* @param {Object} record
*
*/
append
(
timestamp
,
record
)
{
var
self
=
this
self
.
data
.
journal
.
push
({
timestamp
,
record
})
}
/**
* basically return the records + associate values (like abis / accounts)
*
*/
getAll
()
{
var
self
=
this
var
records
=
[].
concat
(
self
.
data
.
journal
)
return
{
accounts
:
self
.
data
.
_usedAccounts
,
linkReferences
:
self
.
data
.
_linkReferences
,
transactions
:
records
.
sort
((
A
,
B
)
=>
{
var
stampA
=
A
.
timestamp
var
stampB
=
B
.
timestamp
return
stampA
-
stampB
}),
abis
:
self
.
data
.
_abis
}
}
/**
* delete the seen transactions
*
*/
clearAll
()
{
var
self
=
this
self
.
data
.
_listen
=
true
self
.
data
.
_replay
=
false
self
.
data
.
journal
=
[]
self
.
data
.
_createdContracts
=
{}
self
.
data
.
_createdContractsReverse
=
{}
self
.
data
.
_usedAccounts
=
{}
self
.
data
.
_abis
=
{}
self
.
data
.
_contractABIReferences
=
{}
self
.
data
.
_linkReferences
=
{}
}
/**
* run the list of records
*
* @param {Object} accounts
* @param {Object} options
* @param {Object} abis
* @param {Function} newContractFn
*
*/
run
(
records
,
accounts
,
options
,
abis
,
linkReferences
,
newContractFn
)
{
var
self
=
this
self
.
setListen
(
false
)
self
.
_api
.
logMessage
(
`Running
${
records
.
length
}
transaction(s) ...`
)
async
.
eachOfSeries
(
records
,
function
(
tx
,
index
,
cb
)
{
var
record
=
self
.
resolveAddress
(
tx
.
record
,
accounts
,
options
)
var
abi
=
abis
[
tx
.
record
.
abi
]
if
(
!
abi
)
{
modal
.
alert
(
'cannot find ABI for '
+
tx
.
record
.
abi
+
'. Execution stopped at '
+
index
)
return
}
/* Resolve Library */
if
(
record
.
linkReferences
&&
Object
.
keys
(
record
.
linkReferences
).
length
)
{
for
(
var
k
in
linkReferences
)
{
var
link
=
linkReferences
[
k
]
var
timestamp
=
self
.
extractTimestamp
(
link
)
if
(
timestamp
&&
self
.
data
.
_createdContractsReverse
[
timestamp
])
{
link
=
self
.
data
.
_createdContractsReverse
[
timestamp
]
}
tx
.
record
.
bytecode
=
format
.
linkLibraryStandardFromlinkReferences
(
k
,
link
.
replace
(
'0x'
,
''
),
tx
.
record
.
bytecode
,
tx
.
record
.
linkReferences
)
}
}
/* Encode params */
var
fnABI
if
(
tx
.
record
.
type
===
'constructor'
)
{
fnABI
=
txHelper
.
getConstructorInterface
(
abi
)
}
else
{
fnABI
=
txHelper
.
getFunction
(
abi
,
record
.
name
)
}
if
(
!
fnABI
)
{
modal
.
alert
(
'cannot resolve abi of '
+
JSON
.
stringify
(
record
,
null
,
'
\
t'
)
+
'. Execution stopped at '
+
index
)
cb
(
'cannot resolve abi'
)
return
}
var
data
=
format
.
encodeData
(
fnABI
,
tx
.
record
.
parameters
,
tx
.
record
.
bytecode
)
if
(
data
.
error
)
{
modal
.
alert
(
data
.
error
+
'. Record:'
+
JSON
.
stringify
(
record
,
null
,
'
\
t'
)
+
'. Execution stopped at '
+
index
)
cb
(
data
.
error
)
return
}
else
{
self
.
_api
.
logMessage
(
`(
${
index
}
)
${
JSON
.
stringify
(
record
,
null
,
'
\
t'
)}
`
)
self
.
_api
.
logMessage
(
`(
${
index
}
) data:
${
data
.
data
}
`
)
record
.
data
=
{
dataHex
:
data
.
data
,
funArgs
:
tx
.
record
.
parameters
,
funAbi
:
fnABI
,
contractBytecode
:
tx
.
record
.
bytecode
,
contractName
:
tx
.
record
.
contractName
}
}
self
.
_api
.
udapp
().
runTx
(
record
,
function
(
err
,
txResult
)
{
if
(
err
)
{
console
.
error
(
err
)
self
.
_api
.
logMessage
(
err
+
'. Execution failed at '
+
index
)
}
else
{
var
address
=
executionContext
.
isVM
()
?
txResult
.
result
.
createdAddress
:
txResult
.
result
.
contractAddress
if
(
address
)
{
address
=
addressToString
(
address
)
// save back created addresses for the convertion from tokens to real adresses
self
.
data
.
_createdContracts
[
address
]
=
tx
.
timestamp
self
.
data
.
_createdContractsReverse
[
tx
.
timestamp
]
=
address
newContractFn
(
abi
,
address
,
record
.
contractName
)
}
}
cb
(
err
)
})
},
()
=>
{
self
.
setListen
(
true
);
self
.
clearAll
()
})
}
}
function
addressToString
(
address
)
{
if
(
!
address
)
return
null
if
(
typeof
address
!==
'string'
)
{
address
=
address
.
toString
(
'hex'
)
}
if
(
address
.
indexOf
(
'0x'
)
===
-
1
)
{
address
=
'0x'
+
address
}
return
address
}
module
.
exports
=
Recorder
src/universal-dapp.js
View file @
6884d6dc
...
@@ -7,7 +7,6 @@ var BN = ethJSUtil.BN
...
@@ -7,7 +7,6 @@ var BN = ethJSUtil.BN
var
remixLib
=
require
(
'remix-lib'
)
var
remixLib
=
require
(
'remix-lib'
)
var
EventManager
=
remixLib
.
EventManager
var
EventManager
=
remixLib
.
EventManager
var
crypto
=
require
(
'crypto'
)
var
crypto
=
require
(
'crypto'
)
var
async
=
require
(
'async'
)
var
TxRunner
=
require
(
'./app/execution/txRunner'
)
var
TxRunner
=
require
(
'./app/execution/txRunner'
)
var
yo
=
require
(
'yo-yo'
)
var
yo
=
require
(
'yo-yo'
)
var
txFormat
=
require
(
'./app/execution/txFormat'
)
var
txFormat
=
require
(
'./app/execution/txFormat'
)
...
@@ -291,10 +290,10 @@ UniversalDApp.prototype.renderInstanceFromABI = function (contractABI, address,
...
@@ -291,10 +290,10 @@ UniversalDApp.prototype.renderInstanceFromABI = function (contractABI, address,
function
remove
()
{
instance
.
remove
()
}
function
remove
()
{
instance
.
remove
()
}
var
instance
=
yo
`<div class="instance
${
css
.
instance
}
"></div>`
address
=
(
address
.
slice
(
0
,
2
)
===
'0x'
?
''
:
'0x'
)
+
address
.
toString
(
'hex'
)
var
instance
=
yo
`<div class="instance
${
css
.
instance
}
" id="instance
${
address
}
"></div>`
var
context
=
executionContext
.
isVM
()
?
'memory'
:
'blockchain'
var
context
=
executionContext
.
isVM
()
?
'memory'
:
'blockchain'
address
=
(
address
.
slice
(
0
,
2
)
===
'0x'
?
''
:
'0x'
)
+
address
.
toString
(
'hex'
)
var
shortAddress
=
helper
.
shortenAddress
(
address
)
var
shortAddress
=
helper
.
shortenAddress
(
address
)
var
title
=
yo
`<div class="
${
css
.
title
}
" onclick=
${
toggleClass
}
>
var
title
=
yo
`<div class="
${
css
.
title
}
" onclick=
${
toggleClass
}
>
<div class="
${
css
.
titleText
}
">
${
contractName
}
at
${
shortAddress
}
(
${
context
}
) </div>
<div class="
${
css
.
titleText
}
">
${
contractName
}
at
${
shortAddress
}
(
${
context
}
) </div>
...
@@ -310,22 +309,20 @@ UniversalDApp.prototype.renderInstanceFromABI = function (contractABI, address,
...
@@ -310,22 +309,20 @@ UniversalDApp.prototype.renderInstanceFromABI = function (contractABI, address,
$
(
instance
).
toggleClass
(
`
${
css
.
hidesub
}
`
)
$
(
instance
).
toggleClass
(
`
${
css
.
hidesub
}
`
)
}
}
var
abi
=
txHelper
.
sortAbiFunction
(
contractABI
)
instance
.
appendChild
(
title
)
instance
.
appendChild
(
title
)
// Add the fallback function
// Add the fallback function
var
fallback
=
txHelper
.
getFallbackInterface
(
abi
)
var
fallback
=
txHelper
.
getFallbackInterface
(
contractABI
)
if
(
fallback
)
{
if
(
fallback
)
{
instance
.
appendChild
(
this
.
getCallButton
({
instance
.
appendChild
(
this
.
getCallButton
({
funABI
:
fallback
,
funABI
:
fallback
,
address
:
address
,
address
:
address
,
contractAbi
:
abi
,
contractAbi
:
contractABI
,
contractName
:
contractName
contractName
:
contractName
}))
}))
}
}
$
.
each
(
abi
,
(
i
,
funABI
)
=>
{
$
.
each
(
contractABI
,
(
i
,
funABI
)
=>
{
if
(
funABI
.
type
!==
'function'
)
{
if
(
funABI
.
type
!==
'function'
)
{
return
return
}
}
...
@@ -333,7 +330,7 @@ UniversalDApp.prototype.renderInstanceFromABI = function (contractABI, address,
...
@@ -333,7 +330,7 @@ UniversalDApp.prototype.renderInstanceFromABI = function (contractABI, address,
instance
.
appendChild
(
this
.
getCallButton
({
instance
.
appendChild
(
this
.
getCallButton
({
funABI
:
funABI
,
funABI
:
funABI
,
address
:
address
,
address
:
address
,
contractAbi
:
abi
,
contractAbi
:
contractABI
,
contractName
:
contractName
contractName
:
contractName
}))
}))
})
})
...
@@ -384,7 +381,7 @@ UniversalDApp.prototype.getCallButton = function (args) {
...
@@ -384,7 +381,7 @@ UniversalDApp.prototype.getCallButton = function (args) {
logMsg
=
`call to
${
args
.
contractName
}
.
${(
args
.
funABI
.
name
)
?
args
.
funABI
.
name
:
'(fallback)'
}
`
logMsg
=
`call to
${
args
.
contractName
}
.
${(
args
.
funABI
.
name
)
?
args
.
funABI
.
name
:
'(fallback)'
}
`
}
}
}
}
txFormat
.
buildData
(
args
.
contractAbi
,
self
.
contracts
,
false
,
args
.
funABI
,
inputField
.
value
,
self
,
(
error
,
data
)
=>
{
txFormat
.
buildData
(
args
.
contract
Name
,
args
.
contract
Abi
,
self
.
contracts
,
false
,
args
.
funABI
,
inputField
.
value
,
self
,
(
error
,
data
)
=>
{
if
(
!
error
)
{
if
(
!
error
)
{
if
(
isUserAction
)
{
if
(
isUserAction
)
{
if
(
!
args
.
funABI
.
constant
)
{
if
(
!
args
.
funABI
.
constant
)
{
...
@@ -435,7 +432,6 @@ UniversalDApp.prototype.getCallButton = function (args) {
...
@@ -435,7 +432,6 @@ UniversalDApp.prototype.getCallButton = function (args) {
if
(
lookupOnly
)
{
if
(
lookupOnly
)
{
contractProperty
.
classList
.
add
(
css
.
constant
)
contractProperty
.
classList
.
add
(
css
.
constant
)
button
.
setAttribute
(
'title'
,
(
title
+
' - call'
))
button
.
setAttribute
(
'title'
,
(
title
+
' - call'
))
call
(
false
)
}
}
if
(
args
.
funABI
.
inputs
&&
args
.
funABI
.
inputs
.
length
>
0
)
{
if
(
args
.
funABI
.
inputs
&&
args
.
funABI
.
inputs
.
length
>
0
)
{
...
@@ -458,103 +454,99 @@ UniversalDApp.prototype.pendingTransactions = function () {
...
@@ -458,103 +454,99 @@ UniversalDApp.prototype.pendingTransactions = function () {
return
this
.
txRunner
.
pendingTxs
return
this
.
txRunner
.
pendingTxs
}
}
function
execute
(
pipeline
,
env
,
callback
)
{
function
next
(
err
,
env
)
{
if
(
err
)
return
callback
(
err
)
var
step
=
pipeline
.
shift
()
if
(
step
)
step
(
env
,
next
)
else
callback
(
null
,
env
.
result
)
}
next
(
null
,
env
)
}
UniversalDApp
.
prototype
.
runTx
=
function
(
args
,
cb
)
{
UniversalDApp
.
prototype
.
runTx
=
function
(
args
,
cb
)
{
var
self
=
this
var
self
=
this
var
tx
=
{
var
tx
=
{
to
:
args
.
to
,
data
:
args
.
data
.
dataHex
,
useCall
:
args
.
useCall
,
from
:
args
.
from
,
value
:
args
.
value
}
to
:
args
.
to
,
var
payLoad
=
{
funAbi
:
args
.
data
.
funAbi
,
funArgs
:
args
.
data
.
funArgs
,
contractBytecode
:
args
.
data
.
contractBytecode
,
contractName
:
args
.
data
.
contractName
}
// contains decoded parameters
data
:
args
.
data
,
var
pipeline
=
[
queryGasLimit
]
useCall
:
args
.
useCall
if
(
!
args
.
value
)
{
}
pipeline
.
push
(
queryValue
)
async
.
waterfall
([
}
// query gas limit
if
(
!
args
.
from
)
{
function
(
callback
)
{
pipeline
.
push
(
queryAddress
)
tx
.
gasLimit
=
3000000
}
pipeline
.
push
(
runTransaction
)
var
env
=
{
self
,
tx
,
payLoad
}
execute
(
pipeline
,
env
,
cb
)
}
function
queryGasLimit
(
env
,
next
)
{
var
{
self
,
tx
}
=
env
tx
.
gasLimit
=
3000000
if
(
self
.
transactionContextAPI
.
getGasLimit
)
{
if
(
self
.
transactionContextAPI
.
getGasLimit
)
{
self
.
transactionContextAPI
.
getGasLimit
(
function
(
err
,
ret
)
{
self
.
transactionContextAPI
.
getGasLimit
(
function
(
err
,
ret
)
{
if
(
err
)
{
if
(
err
)
return
next
(
err
)
return
callback
(
err
)
}
tx
.
gasLimit
=
ret
tx
.
gasLimit
=
ret
callback
(
)
next
(
null
,
env
)
})
})
}
else
{
}
else
next
(
null
,
env
)
callback
()
}
}
},
function
queryValue
(
env
,
next
)
{
// query value
var
{
self
,
tx
}
=
env
function
(
callback
)
{
tx
.
value
=
0
tx
.
value
=
0
if
(
tx
.
useCall
)
return
callback
(
)
if
(
tx
.
useCall
)
return
next
(
null
,
env
)
if
(
self
.
transactionContextAPI
.
getValue
)
{
if
(
self
.
transactionContextAPI
.
getValue
)
{
self
.
transactionContextAPI
.
getValue
(
function
(
err
,
ret
)
{
self
.
transactionContextAPI
.
getValue
(
function
(
err
,
ret
)
{
if
(
err
)
{
if
(
err
)
return
next
(
err
)
return
callback
(
err
)
}
tx
.
value
=
ret
tx
.
value
=
ret
callback
(
)
next
(
null
,
env
)
})
})
}
else
{
}
else
next
(
null
,
env
)
callback
()
}
}
},
function
queryAddress
(
env
,
next
)
{
// query address
var
{
self
,
tx
}
=
env
function
(
callback
)
{
if
(
self
.
transactionContextAPI
.
getAddress
)
{
if
(
self
.
transactionContextAPI
.
getAddress
)
{
self
.
transactionContextAPI
.
getAddress
(
function
(
err
,
ret
)
{
self
.
transactionContextAPI
.
getAddress
(
function
(
err
,
ret
)
{
if
(
err
)
{
if
(
err
)
return
next
(
err
)
return
callback
(
err
)
}
tx
.
from
=
ret
tx
.
from
=
ret
next
(
null
,
env
)
callback
()
})
})
}
else
{
}
else
{
self
.
getAccounts
(
function
(
err
,
ret
)
{
self
.
getAccounts
(
function
(
err
,
ret
)
{
if
(
err
)
{
if
(
err
)
return
next
(
err
)
return
callback
(
err
)
if
(
ret
.
length
===
0
)
return
next
(
'No accounts available'
)
}
if
(
ret
.
length
===
0
)
{
return
callback
(
'No accounts available'
)
}
if
(
executionContext
.
isVM
()
&&
!
self
.
accounts
[
ret
[
0
]])
{
if
(
executionContext
.
isVM
()
&&
!
self
.
accounts
[
ret
[
0
]])
{
return
callback
(
'Invalid account selected'
)
return
next
(
'Invalid account selected'
)
}
}
tx
.
from
=
ret
[
0
]
tx
.
from
=
ret
[
0
]
next
(
null
,
env
)
callback
()
})
})
}
}
},
}
// run transaction
function
(
callback
)
{
function
runTransaction
(
env
,
next
)
{
var
{
self
,
tx
,
payLoad
}
=
env
var
timestamp
=
Date
.
now
()
self
.
event
.
trigger
(
'initiatingTransaction'
,
[
timestamp
,
tx
,
payLoad
])
self
.
txRunner
.
rawRun
(
tx
,
function
(
error
,
result
)
{
self
.
txRunner
.
rawRun
(
tx
,
function
(
error
,
result
)
{
if
(
!
args
.
useCall
)
{
if
(
!
tx
.
useCall
)
{
self
.
event
.
trigger
(
'transactionExecuted'
,
[
error
,
args
.
from
,
args
.
to
,
args
.
data
,
false
,
result
])
self
.
event
.
trigger
(
'transactionExecuted'
,
[
error
,
tx
.
from
,
tx
.
to
,
tx
.
data
,
false
,
result
,
timestamp
,
payLoad
])
}
else
{
}
else
{
self
.
event
.
trigger
(
'callExecuted'
,
[
error
,
args
.
from
,
args
.
to
,
args
.
data
,
true
,
result
])
self
.
event
.
trigger
(
'callExecuted'
,
[
error
,
tx
.
from
,
tx
.
to
,
tx
.
data
,
true
,
result
,
timestamp
,
payLoad
])
}
}
if
(
error
)
{
if
(
error
)
{
if
(
typeof
(
error
)
!==
'string'
)
{
if
(
typeof
(
error
)
!==
'string'
)
{
if
(
error
.
message
)
{
if
(
error
.
message
)
error
=
error
.
message
error
=
error
.
message
else
{
}
else
{
try
{
error
=
'error: '
+
JSON
.
stringify
(
error
)
}
catch
(
e
)
{}
try
{
error
=
'error: '
+
JSON
.
stringify
(
error
)
}
catch
(
e
)
{}
}
}
}
}
}
}
callback
(
error
,
result
)
env
.
result
=
result
next
(
error
,
env
)
})
})
}
],
cb
)
}
}
module
.
exports
=
UniversalDApp
module
.
exports
=
UniversalDApp
test-browser/helpers/contracts.js
View file @
6884d6dc
...
@@ -11,7 +11,10 @@ module.exports = {
...
@@ -11,7 +11,10 @@ module.exports = {
checkDebug
,
checkDebug
,
goToVMtraceStep
,
goToVMtraceStep
,
useFilter
,
useFilter
,
addInstance
addInstance
,
clickFunction
,
verifyCallReturnValue
,
setEditorValue
}
}
function
getCompiledContracts
(
browser
,
compiled
,
callback
)
{
function
getCompiledContracts
(
browser
,
compiled
,
callback
)
{
...
@@ -65,7 +68,41 @@ function testContracts (browser, fileName, contractCode, compiledContractNames,
...
@@ -65,7 +68,41 @@ function testContracts (browser, fileName, contractCode, compiledContractNames,
})
})
}
}
function
testFunction
(
fnFullName
,
txHash
,
log
,
expectedInput
,
expectedReturn
,
expectedEvent
)
{
function
clickFunction
(
fnFullName
,
expectedInput
)
{
this
.
waitForElementPresent
(
'.instance button[title="'
+
fnFullName
+
'"]'
)
.
perform
(
function
(
client
,
done
)
{
client
.
execute
(
function
()
{
document
.
querySelector
(
'#optionViews'
).
scrollTop
=
document
.
querySelector
(
'#optionViews'
).
scrollHeight
},
[],
function
()
{
if
(
expectedInput
)
{
client
.
setValue
(
'#runTabView input[title="'
+
expectedInput
.
types
+
'"]'
,
expectedInput
.
values
,
function
()
{})
}
done
()
})
})
.
click
(
'.instance button[title="'
+
fnFullName
+
'"]'
)
.
pause
(
500
)
return
this
}
function
verifyCallReturnValue
(
browser
,
address
,
checks
,
done
)
{
browser
.
execute
(
function
(
address
)
{
var
nodes
=
document
.
querySelectorAll
(
'#instance'
+
address
+
' div[class^="contractProperty"] div[class^="value"]'
)
var
ret
=
[]
for
(
var
k
=
0
;
k
<
nodes
.
length
;
k
++
)
{
var
text
=
nodes
[
k
].
innerText
?
nodes
[
k
].
innerText
:
nodes
[
k
].
textContent
ret
.
push
(
text
.
replace
(
'
\
n'
,
''
))
}
return
ret
},
[
address
],
function
(
result
)
{
for
(
var
k
in
checks
)
{
browser
.
assert
.
equal
(
checks
[
k
],
result
.
value
[
k
])
}
done
()
})
}
function
testFunction
(
fnFullName
,
txHash
,
log
,
expectedInput
,
expectedReturn
,
expectedEvent
,
callback
)
{
// this => browser
// this => browser
this
.
waitForElementPresent
(
'.instance button[title="'
+
fnFullName
+
'"]'
)
this
.
waitForElementPresent
(
'.instance button[title="'
+
fnFullName
+
'"]'
)
.
perform
(
function
(
client
,
done
)
{
.
perform
(
function
(
client
,
done
)
{
...
@@ -94,19 +131,33 @@ function testFunction (fnFullName, txHash, log, expectedInput, expectedReturn, e
...
@@ -94,19 +131,33 @@ function testFunction (fnFullName, txHash, log, expectedInput, expectedReturn, e
client
.
assert
.
containsText
(
'#editor-container div[class^="terminal"] span[id="tx'
+
txHash
+
'"] table[class^="txTable"] #logs'
,
expectedEvent
)
client
.
assert
.
containsText
(
'#editor-container div[class^="terminal"] span[id="tx'
+
txHash
+
'"] table[class^="txTable"] #logs'
,
expectedEvent
)
}
}
done
()
done
()
if
(
callback
)
callback
()
})
})
return
this
return
this
}
}
function
addInstance
(
browser
,
address
,
done
)
{
function
setEditorValue
(
value
)
{
this
.
perform
((
client
,
done
)
=>
{
this
.
execute
(
function
(
value
)
{
document
.
getElementById
(
'input'
).
editor
.
session
.
setValue
(
value
)
},
[
value
],
function
(
result
)
{
done
()
})
})
return
this
}
function
addInstance
(
browser
,
address
,
callback
)
{
browser
.
setValue
(
'.ataddressinput'
,
address
,
function
()
{
browser
.
setValue
(
'.ataddressinput'
,
address
,
function
()
{
browser
.
click
(
'div[class^="atAddress"]'
)
browser
.
click
(
'div[class^="atAddress"]'
)
.
perform
((
client
)
=>
{
.
perform
((
client
,
done
)
=>
{
browser
.
execute
(
function
()
{
browser
.
execute
(
function
()
{
document
.
querySelector
(
'#modal-footer-ok'
).
click
()
document
.
querySelector
(
'#modal-footer-ok'
).
click
()
},
[],
function
(
result
)
{
},
[],
function
(
result
)
{
done
()
done
()
})
})
}).
perform
(()
=>
{
callback
()
})
})
})
})
}
}
...
@@ -124,7 +175,7 @@ function addFile (browser, name, content, done) {
...
@@ -124,7 +175,7 @@ function addFile (browser, name, content, done) {
done
()
done
()
})
})
})
})
.
set
Value
(
'#input textarea'
,
content
.
content
,
function
()
{}
)
.
set
EditorValue
(
content
.
content
)
.
pause
(
1000
)
.
pause
(
1000
)
.
perform
(
function
()
{
.
perform
(
function
()
{
done
()
done
()
...
...
test-browser/tests/ballot.js
View file @
6884d6dc
...
@@ -23,29 +23,34 @@ module.exports = {
...
@@ -23,29 +23,34 @@ module.exports = {
function
runTests
(
browser
,
testData
)
{
function
runTests
(
browser
,
testData
)
{
browser
.
testFunction
=
contractHelper
.
testFunction
browser
.
testFunction
=
contractHelper
.
testFunction
browser
.
setEditorValue
=
contractHelper
.
setEditorValue
browser
browser
.
waitForElementVisible
(
'.newFile'
,
10000
)
.
waitForElementVisible
(
'.newFile'
,
10000
)
.
click
(
'.compileView'
)
.
click
(
'.compileView'
)
.
perform
((
client
,
done
)
=>
{
contractHelper
.
testContracts
(
browser
,
'Untitled.sol'
,
sources
[
0
][
'browser/Untitled.sol'
],
[
'Ballot'
],
function
()
{
contractHelper
.
testContracts
(
browser
,
'Untitled.sol'
,
sources
[
0
][
'browser/Untitled.sol'
],
[
'Ballot'
],
function
()
{
browser
done
()
.
click
(
'.runView'
)
})
.
setValue
(
'input[placeholder="uint8 _numProposals"]'
,
'1'
,
()
=>
{})
}).
click
(
'.runView'
)
.
setValue
(
'input[placeholder="uint8 _numProposals"]'
,
'1'
)
.
click
(
'#runTabView div[class^="create"]'
)
.
click
(
'#runTabView div[class^="create"]'
)
.
testFunction
(
'delegate - transact (not payable)'
,
'0x
d3cd54e2f76f3993078ecf9e1b54a148def4520afc141a182293b3610bddf10f
'
,
.
testFunction
(
'delegate - transact (not payable)'
,
'0x
0571a2439ea58bd349dd130afb8aff62a33af14c06de0dbc3928519bdf13ce2e
'
,
'[vm] from:0xca3...a733c, to:Ballot.delegate(address) 0x692...77b3a, value:0 wei, data:0x5c1...4d2db, 0 logs, hash:0x
d3c...df10f
'
,
'[vm] from:0xca3...a733c, to:Ballot.delegate(address) 0x692...77b3a, value:0 wei, data:0x5c1...4d2db, 0 logs, hash:0x
057...3ce2e
'
,
{
types
:
'address to'
,
values
:
'"0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db"'
},
null
,
null
)
{
types
:
'address to'
,
values
:
'"0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db"'
},
null
,
null
)
.
click
(
'span#tx0xd3cd54e2f76f3993078ecf9e1b54a148def4520afc141a182293b3610bddf10f button[class^="debug"]'
)
.
pause
(
500
)
.
click
(
'span#tx0x0571a2439ea58bd349dd130afb8aff62a33af14c06de0dbc3928519bdf13ce2e button[class^="debug"]'
)
.
pause
(
1000
)
.
pause
(
1000
)
.
click
(
'#jumppreviousbreakpoint'
)
.
click
(
'#jumppreviousbreakpoint'
)
.
click
(
'#stepdetail .title'
)
.
click
(
'#stepdetail .title'
)
.
click
(
'#asmcodes .title'
)
.
click
(
'#asmcodes .title'
)
.
pause
(
500
)
.
pause
(
500
)
.
perform
(
function
(
client
,
done
)
{
.
perform
(
function
(
client
,
done
)
{
console
.
log
(
'goToVMtraceStep'
)
contractHelper
.
goToVMtraceStep
(
browser
,
39
,
()
=>
{
contractHelper
.
goToVMtraceStep
(
browser
,
39
,
()
=>
{
done
()
done
()
})
})
})
})
.
pause
(
5
000
)
.
pause
(
1
000
)
.
perform
(
function
(
client
,
done
)
{
.
perform
(
function
(
client
,
done
)
{
contractHelper
.
checkDebug
(
browser
,
'soliditystate'
,
stateCheck
,
()
=>
{
contractHelper
.
checkDebug
(
browser
,
'soliditystate'
,
stateCheck
,
()
=>
{
done
()
done
()
...
@@ -58,19 +63,24 @@ function runTests (browser, testData) {
...
@@ -58,19 +63,24 @@ function runTests (browser, testData) {
})
})
.
click
(
'.runView'
)
.
click
(
'.runView'
)
.
click
(
'div[class^="udappClose"]'
)
.
click
(
'div[class^="udappClose"]'
)
.
perform
(
function
(
client
,
done
)
{
.
perform
((
client
,
done
)
=>
{
contractHelper
.
addFile
(
client
,
'ballot.abi'
,
{
content
:
ballotABI
},
()
=>
{
console
.
log
(
'ballot.abi'
)
contractHelper
.
addInstance
(
client
,
'0x692a70d2e424a56d2c6c27aa97d1a86395877b3a'
,
()
=>
{
contractHelper
.
addFile
(
browser
,
'ballot.abi'
,
{
content
:
ballotABI
},
()
=>
{
browser
.
testFunction
(
'delegate - transact (not payable)'
,
'0x7a9ebc90614274b7eb6b072f9bba7825e588cf88ae00598cfdbc4c215b88433e'
,
'[vm] from:0xca3...a733c, to:Ballot.delegate(address) 0x692...77b3a, value:0 wei, data:0x5c1...4d2db, 0 logs, hash:0x7a9...8433e'
,
{
types
:
'address to'
,
values
:
'"0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db"'
},
null
,
null
).
perform
(()
=>
{
done
()
done
()
browser
.
end
()
})
})
})
})
})
.
perform
((
client
,
done
)
=>
{
console
.
log
(
'addInstance 0x692a70d2e424a56d2c6c27aa97d1a86395877b3a'
)
contractHelper
.
addInstance
(
browser
,
'0x692a70d2e424a56d2c6c27aa97d1a86395877b3a'
,
()
=>
{
done
()
})
})
})
})
.
perform
((
client
,
done
)
=>
{
console
.
log
(
'delegate - transact (not payable)'
)
browser
.
testFunction
(
'delegate - transact (not payable)'
,
'0xd3cd54e2f76f3993078ecf9e1b54a148def4520afc141a182293b3610bddf10f'
,
'[vm] from:0xca3...a733c, to:Ballot.delegate(address) 0x692...77b3a, value:0 wei, data:0x5c1...4d2db, 0 logs, hash:0xd3c...df10f'
,
{
types
:
'address to'
,
values
:
'"0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db"'
},
null
,
null
,
()
=>
{
done
()
})
}).
end
()
}
}
var
localsCheck
=
{
var
localsCheck
=
{
...
...
test-browser/tests/compiling.js
View file @
6884d6dc
...
@@ -3,6 +3,7 @@ var contractHelper = require('../helpers/contracts')
...
@@ -3,6 +3,7 @@ var contractHelper = require('../helpers/contracts')
var
init
=
require
(
'../helpers/init'
)
var
init
=
require
(
'../helpers/init'
)
var
sauce
=
require
(
'./sauce'
)
var
sauce
=
require
(
'./sauce'
)
var
async
=
require
(
'async'
)
var
async
=
require
(
'async'
)
var
testRecorder
=
require
(
'./units/testRecorder'
)
module
.
exports
=
{
module
.
exports
=
{
before
:
function
(
browser
,
done
)
{
before
:
function
(
browser
,
done
)
{
...
@@ -19,12 +20,14 @@ module.exports = {
...
@@ -19,12 +20,14 @@ module.exports = {
function
runTests
(
browser
)
{
function
runTests
(
browser
)
{
browser
.
testFunction
=
contractHelper
.
testFunction
browser
.
testFunction
=
contractHelper
.
testFunction
browser
.
clickFunction
=
contractHelper
.
clickFunction
browser
.
setEditorValue
=
contractHelper
.
setEditorValue
browser
browser
.
waitForElementVisible
(
'.newFile'
,
10000
)
.
waitForElementVisible
(
'.newFile'
,
10000
)
.
click
(
'.compileView'
)
.
click
(
'.compileView'
)
.
perform
(()
=>
{
.
perform
(()
=>
{
// the first fn is used to pass browser to the other ones.
// the first fn is used to pass browser to the other ones.
async
.
waterfall
([
function
(
callback
)
{
callback
(
null
,
browser
)
},
testSimpleContract
,
testReturnValues
,
testInputValues
],
function
()
{
async
.
waterfall
([
function
(
callback
)
{
callback
(
null
,
browser
)
},
testSimpleContract
,
testReturnValues
,
testInputValues
,
testRecorder
],
function
()
{
browser
.
end
()
browser
.
end
()
})
})
})
})
...
...
test-browser/tests/simpleContract.js
View file @
6884d6dc
...
@@ -18,6 +18,7 @@ module.exports = {
...
@@ -18,6 +18,7 @@ module.exports = {
}
}
function
runTests
(
browser
)
{
function
runTests
(
browser
)
{
browser
.
setEditorValue
=
contractHelper
.
setEditorValue
browser
browser
.
waitForElementVisible
(
'.newFile'
,
10000
)
.
waitForElementVisible
(
'.newFile'
,
10000
)
.
click
(
'.compileView'
)
.
click
(
'.compileView'
)
...
...
test-browser/tests/staticanalysis.js
View file @
6884d6dc
...
@@ -33,6 +33,7 @@ module.exports = {
...
@@ -33,6 +33,7 @@ module.exports = {
}
}
function
runTests
(
browser
)
{
function
runTests
(
browser
)
{
browser
.
setEditorValue
=
contractHelper
.
setEditorValue
browser
browser
.
waitForElementVisible
(
'.newFile'
,
10000
)
.
waitForElementVisible
(
'.newFile'
,
10000
)
.
click
(
'.compileView'
)
.
click
(
'.compileView'
)
...
...
test-browser/tests/units/testRecorder.js
0 → 100644
View file @
6884d6dc
'use strict'
var
contractHelper
=
require
(
'../../helpers/contracts'
)
module
.
exports
=
function
(
browser
,
callback
)
{
contractHelper
.
addFile
(
browser
,
'scenario.json'
,
{
content
:
records
},
()
=>
{
browser
.
click
(
'.runView'
)
.
click
(
'#runTabView .runtransaction'
)
.
clickFunction
(
'getInt - call'
)
.
clickFunction
(
'getAddress - call'
)
.
clickFunction
(
'getFromLib - call'
)
.
waitForElementPresent
(
'div[class^="contractProperty"] div[class^="value"]'
)
.
perform
(()
=>
{
contractHelper
.
verifyCallReturnValue
(
browser
,
'0x35ef07393b57464e93deb59175ff72e6499450cf'
,
[
'0: uint256: 1'
,
'0: uint256: 3456'
,
'0: address: 0xca35b7d915458ef540ade6068dfe2f44e8fa733c'
],
()
=>
{
callback
()
})
})
})
}
var
records
=
`{
"accounts": {
"account{0}": "0xca35b7d915458ef540ade6068dfe2f44e8fa733c"
},
"linkReferences": {
"testLib": "created{1512830014773}"
},
"transactions": [
{
"timestamp": 1512830014773,
"record": {
"value": "0",
"parameters": [],
"abi": "0xbc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a",
"contractName": "testLib",
"bytecode": "60606040523415600e57600080fd5b60968061001c6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680636d4ce63c146044575b600080fd5b604a6060565b6040518082815260200191505060405180910390f35b6000610d809050905600a165627a7a7230582022d123b15248b8176151f8d45c2dc132063bcc9bb8d5cd652aea7efae362c8050029",
"linkReferences": {},
"type": "constructor",
"from": "account{0}"
}
},
{
"timestamp": 1512830015080,
"record": {
"value": "100",
"parameters": [
11
],
"abi": "0xc41589e7559804ea4a2080dad19d876a024ccb05117835447d72ce08c1d020ec",
"contractName": "test",
"bytecode": "60606040526040516020806102b183398101604052808051906020019091905050806000819055505061027a806100376000396000f300606060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680632f30c6f61461006757806338cc48311461009e57806362738998146100f357806387cc10e11461011c575b600080fd5b61009c600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610145565b005b34156100a957600080fd5b6100b1610191565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156100fe57600080fd5b6101066101bb565b6040518082815260200191505060405180910390f35b341561012757600080fd5b61012f6101c4565b6040518082815260200191505060405180910390f35b8160008190555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008054905090565b600073__browser/ballot.sol:testLib____________636d4ce63c6000604051602001526040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b151561022e57600080fd5b6102c65a03f4151561023f57600080fd5b505050604051805190509050905600a165627a7a72305820e0b2510bb2890a0334bfe5613d96db3e72442e63b514cdeaee8fc2c6bbd19d3a0029",
"linkReferences": {
"browser/ballot.sol": {
"testLib": [
{
"length": 20,
"start": 511
}
]
}
},
"name": "",
"type": "constructor",
"from": "account{0}"
}
},
{
"timestamp": 1512830034180,
"record": {
"value": "1000000000000000000",
"parameters": [
1,
"0xca35b7d915458ef540ade6068dfe2f44e8fa733c"
],
"to": "created{1512830015080}",
"abi": "0xc41589e7559804ea4a2080dad19d876a024ccb05117835447d72ce08c1d020ec",
"name": "set",
"type": "function",
"from": "account{0}"
}
}
],
"abis": {
"0xbc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a": [
{
"constant": true,
"inputs": [],
"name": "get",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
],
"0xc41589e7559804ea4a2080dad19d876a024ccb05117835447d72ce08c1d020ec": [
{
"constant": true,
"inputs": [],
"name": "getInt",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getFromLib",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getAddress",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_t",
"type": "uint256"
},
{
"name": "_add",
"type": "address"
}
],
"name": "set",
"outputs": [],
"payable": true,
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"name": "_r",
"type": "uint256"
}
],
"payable": true,
"stateMutability": "payable",
"type": "constructor"
}
]
}
}`
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