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
676068b1
Commit
676068b1
authored
Nov 30, 2017
by
yann300
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
store ABI & simplify address resolver
parent
652307e8
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
146 additions
and
87 deletions
+146
-87
remix
remix
+1
-0
run-tab.js
src/app/tabs/run-tab.js
+11
-26
recorder.js
src/recorder.js
+134
-61
No files found.
remix
@
4fe13da1
Subproject commit 4fe13da1c8c51dc7bb728df14c30fbb274e0bc80
src/app/tabs/run-tab.js
View file @
676068b1
'use strict'
'use strict'
var
async
=
require
(
'async'
)
var
$
=
require
(
'jquery'
)
var
$
=
require
(
'jquery'
)
var
yo
=
require
(
'yo-yo'
)
var
yo
=
require
(
'yo-yo'
)
var
helper
=
require
(
'../../lib/helper.js'
)
var
helper
=
require
(
'../../lib/helper.js'
)
...
@@ -246,7 +245,6 @@ function updateAccountBalances (container, appAPI) {
...
@@ -246,7 +245,6 @@ function updateAccountBalances (container, appAPI) {
RECORDER
RECORDER
------------------------------------------------ */
------------------------------------------------ */
function
makeRecorder
(
appAPI
,
appEvents
)
{
function
makeRecorder
(
appAPI
,
appEvents
)
{
var
udapp
=
appAPI
.
udapp
()
var
recorder
=
new
Recorder
({
var
recorder
=
new
Recorder
({
events
:
{
events
:
{
udapp
:
appEvents
.
udapp
,
udapp
:
appEvents
.
udapp
,
...
@@ -291,10 +289,9 @@ function makeRecorder (appAPI, appEvents) {
...
@@ -291,10 +289,9 @@ function makeRecorder (appAPI, appEvents) {
})
})
}
}
runButton
.
onclick
=
()
=>
{
runButton
.
onclick
=
()
=>
{
modalDialogCustom
.
prompt
(
null
,
'load from file (e.g. `scenarios/transactions1.json`)'
,
''
,
filepath
=>
{
var
currentFile
=
appAPI
.
config
.
get
(
'currentFile'
)
var
filename
=
appAPI
.
filesProviders
[
'browser'
].
type
+
'/'
+
filepath
var
json
=
appAPI
.
filesProviders
[
'browser'
].
get
(
currentFile
)
var
json
=
appAPI
.
filesProviders
[
'browser'
].
get
(
filename
)
if
(
currentFile
.
match
(
'.json$'
))
{
if
(
!
json
)
return
modalDialogCustom
.
alert
(
'Could not find file with transactions, please try again'
)
try
{
try
{
var
obj
=
JSON
.
parse
(
json
)
var
obj
=
JSON
.
parse
(
json
)
var
txArray
=
obj
.
transactions
||
[]
var
txArray
=
obj
.
transactions
||
[]
...
@@ -302,28 +299,16 @@ function makeRecorder (appAPI, appEvents) {
...
@@ -302,28 +299,16 @@ function makeRecorder (appAPI, appEvents) {
var
options
=
obj
.
options
var
options
=
obj
.
options
var
abis
=
obj
.
abis
var
abis
=
obj
.
abis
}
catch
(
e
)
{
}
catch
(
e
)
{
modalDialogCustom
.
alert
(
'Invalid JSON
, please try again'
)
return
modalDialogCustom
.
alert
(
'Invalid Scenario File
, please try again'
)
}
}
if
(
txArray
.
length
)
{
if
(
txArray
.
length
)
{
recorder
.
setListen
(
false
)
recorder
.
run
(
txArray
,
accounts
,
options
,
abis
,
(
abi
,
address
,
contractName
)
=>
{
async
.
eachSeries
(
txArray
,
function
(
tx
,
cb
)
{
instanceContainer
.
appendChild
(
appAPI
.
udapp
().
renderInstanceFromABI
(
abi
,
address
,
contractName
))
var
record
=
recorder
.
resolveAddress
(
tx
.
record
,
accounts
,
options
)
})
udapp
.
rerunTx
(
record
,
function
(
err
,
txResult
)
{
if
(
err
)
{
console
.
error
(
err
)
}
else
{
var
address
=
executionContext
.
isVM
()
?
txResult
.
result
.
createdAddress
:
tx
.
result
.
contractAddress
if
(
!
address
)
return
// not a contract creation
var
abi
=
abis
[
tx
.
record
.
abi
]
if
(
abi
)
{
instanceContainer
.
appendChild
(
appAPI
.
udapp
().
renderInstanceFromABI
(
abi
,
address
,
record
.
contractName
))
}
}
cb
()
})
},
()
=>
{
recorder
.
setListen
(
true
)
})
}
}
})
}
else
{
modalDialogCustom
.
alert
(
'Scenario File require JSON type'
)
}
}
}
return
el
return
el
}
}
...
@@ -395,7 +380,7 @@ function contractDropdown (appAPI, appEvents, instanceContainer) {
...
@@ -395,7 +380,7 @@ function contractDropdown (appAPI, appEvents, instanceContainer) {
// ADD BUTTONS AT ADDRESS AND CREATE
// ADD BUTTONS AT ADDRESS AND CREATE
function
createInstance
()
{
function
createInstance
()
{
var
selectedContract
=
getSelectedContract
()
var
selectedContract
=
getSelectedContract
()
if
(
selectedContract
.
contract
.
object
.
evm
.
bytecode
.
object
.
length
===
0
)
{
if
(
selectedContract
.
contract
.
object
.
evm
.
bytecode
.
object
.
length
===
0
)
{
modalDialogCustom
.
alert
(
'This contract does not implement all functions and thus cannot be created.'
)
modalDialogCustom
.
alert
(
'This contract does not implement all functions and thus cannot be created.'
)
...
...
src/recorder.js
View file @
676068b1
var
remixLib
=
require
(
'remix-lib'
)
var
remixLib
=
require
(
'remix-lib'
)
var
EventManager
=
remixLib
.
EventManager
var
EventManager
=
remixLib
.
EventManager
var
util
=
remixLib
.
util
var
executionContext
=
require
(
'./execution-context'
)
var
async
=
require
(
'async'
)
/**
* Record transaction as long as the user create them.
*
*
*/
class
Recorder
{
class
Recorder
{
constructor
(
opts
=
{})
{
constructor
(
opts
=
{})
{
var
self
=
this
var
self
=
this
self
.
_api
=
opts
.
api
self
.
_api
=
opts
.
api
self
.
event
=
new
EventManager
()
self
.
event
=
new
EventManager
()
self
.
data
=
{
journal
:
[],
_pendingCreation
:
{}
}
self
.
data
=
{
_listen
:
true
,
_replay
:
false
,
journal
:
[],
_pendingTxs
:
{},
_createdContracts
:
{},
_createdContractsReverse
:
{},
_usedAccounts
:
{},
_abis
:
{}
}
opts
.
events
.
executioncontext
.
register
(
'contextChanged'
,
()
=>
self
.
clearAll
())
opts
.
events
.
executioncontext
.
register
(
'contextChanged'
,
()
=>
{
var
counter
=
0
self
.
clearAll
()
self
.
_addressCache
=
{}
})
function
getAddresses
(
cb
)
{
self
.
_api
.
getAccounts
(
function
(
err
,
accounts
=
[])
{
if
(
err
)
console
.
error
(
err
)
var
addresses
=
accounts
.
reduce
((
addr
,
account
)
=>
{
if
(
!
addr
[
account
])
addr
[
account
]
=
`account{
${
++
counter
}
}`
return
addr
},
self
.
_addressCache
)
cb
(
addresses
)
})
}
function
getCurrentContractName
()
{
var
contractNames
=
document
.
querySelector
(
`[class^="contractNames"]`
)
var
contractName
=
contractNames
.
children
[
contractNames
.
selectedIndex
].
innerHTML
return
contractName
}
opts
.
events
.
udapp
.
register
(
'initiatingTransaction'
,
(
timestamp
,
tx
)
=>
{
opts
.
events
.
udapp
.
register
(
'initiatingTransaction'
,
(
timestamp
,
tx
)
=>
{
var
{
from
,
to
,
value
,
gas
,
data
}
=
tx
var
{
from
,
to
,
value
,
data
,
useCall
}
=
tx
var
record
=
{
value
,
gas
,
data
}
var
record
=
{
value
,
data
,
useCall
}
getAddresses
(
addresses
=>
{
if
(
to
)
record
.
to
=
addresses
[
to
]
||
(
addresses
[
to
]
=
self
.
_addressCache
[
to
]
=
`contract{
${
++
counter
}
}`
)
this
.
data
.
_pendingTxs
[
timestamp
]
=
tx
else
{
record
.
src
=
getCurrentContractName
()
// convert to and from to tokens
self
.
data
.
_pendingCreation
[
timestamp
]
=
record
if
(
this
.
data
.
_listen
)
{
if
(
!
to
)
{
var
selectedContract
=
self
.
_api
.
getSelectedContract
()
if
(
selectedContract
)
{
var
abi
=
selectedContract
.
contract
.
object
.
abi
var
sha3
=
util
.
sha3_256
(
JSON
.
stringify
(
abi
))
record
.
abi
=
sha3
self
.
data
.
_abis
[
sha3
]
=
abi
}
}
else
{
record
.
to
=
`created-contract{
${
this
.
data
.
_createdContracts
[
to
]}
}`
}
}
record
.
from
=
addresses
[
from
]
||
(
addresses
[
from
]
=
self
.
_addressCache
[
from
]
=
`account{
${
++
counter
}
}`
)
self
.
append
(
timestamp
,
record
)
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'
,
(...
args
)
=>
{
var
err
=
args
[
0
]
opts
.
events
.
udapp
.
register
(
'transactionExecuted'
,
(
error
,
from
,
to
,
data
,
call
,
txResult
,
timestamp
)
=>
{
if
(
err
)
console
.
error
(
err
)
if
(
error
)
return
console
.
log
(
error
)
var
timestamp
=
args
[
6
]
var
tx
=
this
.
data
.
_pendingTxs
[
timestamp
]
// update transaction which was pending with correct `to` address
var
record
=
self
.
data
.
_pendingCreation
[
timestamp
]
var
address
=
executionContext
.
isVM
()
?
txResult
.
result
.
createdAddress
:
tx
.
result
.
contractAddress
delete
self
.
data
.
_pendingCreation
[
timestamp
]
if
(
!
address
)
return
// not a contract creation
if
(
!
record
)
return
address
=
'0x'
+
address
.
toString
(
'hex'
)
var
to
=
args
[
2
]
// save back created addresses for the convertion from tokens to real adresses
getAddresses
(
addresses
=>
{
this
.
data
.
_createdContracts
[
address
]
=
timestamp
if
(
to
)
{
this
.
data
.
_createdContractsReverse
[
timestamp
]
=
address
delete
record
.
src
record
.
to
=
addresses
[
to
]
||
(
addresses
[
to
]
=
self
.
_addressCache
[
to
]
=
`account{
${
++
counter
}
}`
)
}
else
record
.
src
=
getCurrentContractName
()
})
})
})
}
}
resolveAddress
(
record
,
addresses
)
{
// var getPseudoAddress = placeholder => placeholder.split(' ')[0]//.split('-')[1].slice(1)
var
pseudos
=
Object
.
keys
(
addresses
).
reduce
((
pseudos
,
address
)
=>
{
// var p = addresses[address]//getPseudoAddress()//.split('>')[0].split('-')[1].slice(1)
pseudos
[
addresses
[
address
]]
=
address
return
pseudos
},
{})
if
(
record
.
to
&&
record
.
to
[
0
]
!==
'0'
)
record
.
to
=
pseudos
[
record
.
to
]
if
(
record
.
from
&&
record
.
from
[
0
]
!==
'0'
)
record
.
from
=
pseudos
[
record
.
from
]
// @TODO: fix load transactions and execute !
/**
// @TODO: add 'clean' button to clear all recorded transactions
* stop/start saving txs. If not listenning, is basically in replay mode
// @TODO: prefix path with `browser/` or `localhost/` if user provides
*
// @TODO: offer users by default a "save path" prefixed with the currently open file in the editor
* @param {Bool} listen
// @TODO: offer users by default a "load path" prefixed with the currently open file in the editor (show first one that comes)
*/
setListen
(
listen
)
{
this
.
data
.
_listen
=
listen
this
.
data
.
_replay
=
!
listen
}
/**
* 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
timestamp
=
/created-contract{
(
.*
)
}/g
.
exec
(
record
.
to
)
record
.
to
=
this
.
data
.
_createdContractsReverse
[
timestamp
[
1
]]
}
record
.
from
=
accounts
[
record
.
from
]
// @TODO: writing browser test
// @TODO: writing browser test
return
record
return
record
}
}
/**
* save the given @arg record
*
* @param {Number/String} timestamp
* @param {Object} record
*
*/
append
(
timestamp
,
record
)
{
append
(
timestamp
,
record
)
{
var
self
=
this
var
self
=
this
self
.
data
.
journal
.
push
({
timestamp
,
record
})
self
.
data
.
journal
.
push
({
timestamp
,
record
})
}
}
/**
* basically return the records + associate values (like abis / accounts)
*
*/
getAll
()
{
getAll
()
{
var
self
=
this
var
self
=
this
var
records
=
[].
concat
(
self
.
data
.
journal
)
var
records
=
[].
concat
(
self
.
data
.
journal
)
return
{
return
{
addresses
:
self
.
_addressCache
,
accounts
:
self
.
data
.
_usedAccounts
,
options
:
{
useAccountList
:
true
},
transactions
:
records
.
sort
((
A
,
B
)
=>
{
transactions
:
records
.
sort
((
A
,
B
)
=>
{
var
stampA
=
A
.
timestamp
var
stampA
=
A
.
timestamp
var
stampB
=
B
.
timestamp
var
stampB
=
B
.
timestamp
return
stampA
-
stampB
return
stampA
-
stampB
})
}),
abis
:
self
.
data
.
_abis
}
}
}
}
/**
* delete the seen transactions
*
*/
clearAll
()
{
clearAll
()
{
var
self
=
this
var
self
=
this
self
.
data
.
journal
=
[]
self
.
data
.
journal
=
[]
self
.
data
.
_pendingTxs
=
{}
self
.
data
.
_createdContracts
=
{}
self
.
data
.
_createdContractsReverse
=
{}
self
.
data
.
_usedAccounts
=
{}
self
.
data
.
_abis
=
{}
}
/**
* run the list of records
*
* @param {Object} accounts
* @param {Object} options
* @param {Object} abis
* @param {Function} newContractFn
*
*/
run
(
records
,
accounts
,
options
,
abis
,
newContractFn
)
{
var
self
=
this
self
.
setListen
(
false
)
async
.
eachSeries
(
records
,
function
(
tx
,
cb
)
{
var
record
=
self
.
resolveAddress
(
tx
.
record
,
accounts
,
options
)
self
.
_api
.
udapp
().
rerunTx
(
record
,
function
(
err
,
txResult
)
{
if
(
err
)
{
console
.
error
(
err
)
}
else
{
var
address
=
executionContext
.
isVM
()
?
txResult
.
result
.
createdAddress
:
tx
.
result
.
contractAddress
if
(
!
address
)
return
// not a contract creation
address
=
'0x'
+
address
.
toString
(
'hex'
)
// save back created addresses for the convertion from tokens to real adresses
self
.
data
.
_createdContracts
[
address
]
=
tx
.
timestamp
self
.
data
.
_createdContractsReverse
[
tx
.
timestamp
]
=
address
var
abi
=
abis
[
tx
.
record
.
abi
]
if
(
abi
)
{
newContractFn
(
abi
,
address
,
record
.
contractName
)
}
}
cb
()
})
},
()
=>
{
self
.
setListen
(
true
)
})
}
}
}
}
...
...
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