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
9e7fe56e
Commit
9e7fe56e
authored
Oct 04, 2015
by
chriseth
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'd11e9-gh-pages' into preservePreviousContent
Conflicts: index.html
parents
ec718645
ad567503
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
642 additions
and
460 deletions
+642
-460
ballot.sol.js
ballot.sol.js
+1
-0
index.html
index.html
+585
-458
browser-solidity.css
stylesheets/browser-solidity.css
+56
-2
No files found.
ballot.sol.js
View file @
9e7fe56e
...
...
@@ -25,6 +25,7 @@
var
multi
=
function
(
func
)
{
return
func
.
toString
().
match
(
/
[^]
*
\/\*([^]
*
)\*\/\}
$/
)[
1
];
}
var
BALLOT_EXAMPLE
=
multi
(
function
(){
/*contract Ballot {
struct Voter {
uint weight;
bool voted;
...
...
index.html
View file @
9e7fe56e
...
...
@@ -47,463 +47,590 @@ THE SOFTWARE.
</head>
<body>
<div
id=
"editor"
>
<div
id=
"input"
></div>
</div>
<div
id=
"righthand-panel"
>
<div
id=
"dragbar"
></div>
<div
id=
"header"
>
<img
id=
"solIcon"
src=
"solidity.svg"
>
<h1>
Solidity realtime
<br/>
compiler and runtime
</h1>
<div
class=
"info"
>
<p>
Version:
<span
id=
"version"
>
(loading)
</span><br/>
Change to:
<select
id=
"versionSelector"
></select><br/>
Execution environment does not connect to any node, everyhing is local and in memory only.
<br/>
<code>
tx.origin =
<span
id=
"txorigin"
/></code></p>
</div>
<div
id=
"optimizeBox"
>
<input
id=
"editorWrap"
type=
"checkbox"
><label
for=
"editorWrap"
>
Text Wrap
</label>
<input
id=
"optimize"
type=
"checkbox"
><label
for=
"optimize"
>
Enable Optimization
</label>
</div>
</div>
<div
id=
"output"
></div>
</div>
<script>
// ----------------- editor ----------------------
var
SOL_CACHE_KEY
=
"sol-cache"
;
var
editor
=
ace
.
edit
(
"input"
);
var
session
=
editor
.
getSession
();
var
Range
=
ace
.
require
(
'ace/range'
).
Range
;
var
errMarkerId
=
null
;
var
solCache
=
window
.
localStorage
.
getItem
(
SOL_CACHE_KEY
);
editor
.
setValue
(
solCache
||
BALLOT_EXAMPLE
,
1
);
session
.
setMode
(
"ace/mode/javascript"
);
session
.
setTabSize
(
4
);
session
.
setUseSoftTabs
(
true
);
// ----------------- version selector-------------
// var soljsonSources is provided by bin/list.js
$
(
'option'
,
'#versionSelector'
).
remove
();
$
.
each
(
soljsonSources
,
function
(
i
,
file
)
{
if
(
file
)
{
var
version
=
file
.
replace
(
/soljson-
(
.*
)
.js/
,
"$1"
);
$
(
'#versionSelector'
).
append
(
new
Option
(
version
,
file
));
}
});
$
(
'#versionSelector'
).
change
(
function
()
{
Module
=
null
;
compileJSON
=
null
;
var
script
=
document
.
createElement
(
'script'
);
script
.
type
=
'text/javascript'
;
script
.
src
=
'bin/'
+
$
(
'#versionSelector'
).
val
();
$
(
'head'
).
append
(
script
);
onCompilerLoaded
();
});
// ----------------- resizeable ui ---------------
var
EDITOR_SIZE_CACHE_KEY
=
"editor-size-cache"
;
var
dragging
=
false
;
$
(
'#dragbar'
).
mousedown
(
function
(
e
){
e
.
preventDefault
();
dragging
=
true
;
var
main
=
$
(
'#righthand-panel'
);
var
ghostbar
=
$
(
'<div id="ghostbar">'
,
{
css
:
{
top
:
main
.
offset
().
top
,
left
:
main
.
offset
().
left
}
}).
prependTo
(
'body'
);
$
(
document
).
mousemove
(
function
(
e
){
ghostbar
.
css
(
"left"
,
e
.
pageX
+
2
);
});
});
var
$body
=
$
(
'body'
);
function
setEditorSize
(
delta
)
{
$
(
'#righthand-panel'
).
css
(
"width"
,
delta
);
$
(
'#editor'
).
css
(
"right"
,
delta
);
onResize
();
}
$
(
document
).
mouseup
(
function
(
e
){
if
(
dragging
)
{
var
delta
=
$body
.
width
()
-
e
.
pageX
+
2
;
$
(
'#ghostbar'
).
remove
();
$
(
document
).
unbind
(
'mousemove'
);
dragging
=
false
;
setEditorSize
(
delta
)
window
.
localStorage
.
setItem
(
EDITOR_SIZE_CACHE_KEY
,
delta
);
}
});
// set cached defaults
var
cachedSize
=
window
.
localStorage
.
getItem
(
EDITOR_SIZE_CACHE_KEY
);
if
(
cachedSize
)
setEditorSize
(
cachedSize
);
// ----------------- editor resize ---------------
function
onResize
()
{
editor
.
resize
();
session
.
setUseWrapMode
(
document
.
querySelector
(
'#editorWrap'
).
checked
);
if
(
session
.
getUseWrapMode
())
{
var
characterWidth
=
editor
.
renderer
.
characterWidth
;
var
contentWidth
=
editor
.
container
.
ownerDocument
.
getElementsByClassName
(
"ace_scroller"
)[
0
].
clientWidth
;
if
(
contentWidth
>
0
)
{
session
.
setWrapLimit
(
parseInt
(
contentWidth
/
characterWidth
,
10
));
}
}
}
window
.
onresize
=
onResize
;
onResize
();
document
.
querySelector
(
'#editor'
).
addEventListener
(
'change'
,
onResize
);
// ----------------- compiler ----------------------
var
compileJSON
;
var
previousInput
=
''
;
var
sourceAnnotations
=
[];
var
compile
=
function
()
{
editor
.
getSession
().
clearAnnotations
();
sourceAnnotations
=
[];
editor
.
getSession
().
removeMarker
(
errMarkerId
);
$
(
'#output'
).
empty
();
var
input
=
editor
.
getValue
();
var
optimize
=
document
.
querySelector
(
'#optimize'
).
checked
;
try
{
var
data
=
$
.
parseJSON
(
compileJSON
(
input
,
optimize
?
1
:
0
));
}
catch
(
exception
)
{
renderError
(
"Uncaught JavaScript Exception:
\
n"
+
exception
);
return
;
}
if
(
data
[
'error'
]
!==
undefined
)
renderError
(
data
[
'error'
]);
if
(
data
[
'errors'
]
!=
undefined
)
$
.
each
(
data
[
'errors'
],
function
(
i
,
err
)
{
renderError
(
err
);
});
else
renderContracts
(
data
,
input
);
}
var
compileTimeout
=
null
;
var
onChange
=
function
()
{
var
input
=
editor
.
getValue
();
if
(
input
===
""
)
{
window
.
localStorage
.
setItem
(
SOL_CACHE_KEY
,
''
)
return
;
}
if
(
input
===
previousInput
)
return
;
previousInput
=
input
;
if
(
compileTimeout
)
window
.
clearTimeout
(
compileTimeout
);
compileTimeout
=
window
.
setTimeout
(
compile
,
300
);
};
var
onCompilerLoaded
=
function
()
{
compileJSON
=
Module
.
cwrap
(
"compileJSON"
,
"string"
,
[
"string"
,
"number"
]);
$
(
'#version'
).
text
(
Module
.
cwrap
(
"version"
,
"string"
,
[])());
previousInput
=
''
;
onChange
();
};
if
(
Module
)
onCompilerLoaded
();
editor
.
getSession
().
on
(
'change'
,
onChange
);
document
.
querySelector
(
'#optimize'
).
addEventListener
(
'change'
,
compile
);
// ----------------- compiler output renderer ----------------------
var
detailsOpen
=
{};
var
renderError
=
function
(
message
)
{
$
(
'#output'
)
.
append
(
$
(
'<pre class="error"></pre>'
).
text
(
message
));
var
err
=
message
.
match
(
/^:
([
0-9
]
*
)
:
([
0-9
]
*
)
/
)
if
(
err
&&
err
.
length
)
{
var
errLine
=
parseInt
(
err
[
1
],
10
)
-
1
;
var
errCol
=
err
[
2
]
?
parseInt
(
err
[
2
],
10
)
:
0
;
sourceAnnotations
[
sourceAnnotations
.
length
]
=
{
row
:
errLine
,
column
:
errCol
,
text
:
message
,
type
:
"error"
};
editor
.
getSession
().
setAnnotations
(
sourceAnnotations
);
}
};
var
gethDeploy
=
function
(
contractName
,
interface
,
bytecode
){
var
code
=
""
;
var
funABI
=
getConstructorInterface
(
$
.
parseJSON
(
interface
));
$
.
each
(
funABI
.
inputs
,
function
(
i
,
inp
)
{
code
+=
"var "
+
inp
.
name
+
" = /* var of type "
+
inp
.
type
+
" here */ ;
\
n"
;
});
code
+=
"
\
nvar "
+
contractName
+
"Contract = web3.eth.contract("
+
interface
.
replace
(
"
\
n"
,
""
)
+
");"
+
"
\
nvar "
+
contractName
+
" = "
+
contractName
+
"Contract.new("
;
$
.
each
(
funABI
.
inputs
,
function
(
i
,
inp
)
{
code
+=
"
\
n "
+
inp
.
name
+
","
;
});
code
+=
"
\
n {"
+
"
\
n from: web3.eth.accounts[0], "
+
"
\
n data: '"
+
bytecode
+
"', "
+
"
\
n gas: 3000000"
+
"
\
n }, function(e, contract){"
+
"
\
n if (typeof contract.address != 'undefined') {"
+
"
\
n console.log(e, contract);"
+
"
\
n console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);"
+
"
\
n }"
+
"
\
n })"
;
return
code
;
};
var
combined
=
function
(
contractName
,
interface
,
bytecode
){
return
JSON
.
stringify
(
[{
name
:
contractName
,
interface
:
interface
,
bytecode
:
bytecode
}]);
};
var
renderContracts
=
function
(
data
,
source
)
{
window
.
localStorage
.
setItem
(
SOL_CACHE_KEY
,
source
);
$
(
'#output'
).
empty
();
for
(
var
contractName
in
data
.
contracts
)
{
var
contract
=
data
.
contracts
[
contractName
];
var
title
=
$
(
'<h3 class="title"/>'
).
text
(
contractName
);
var
contractOutput
=
$
(
'<div class="contractOutput"/>'
)
.
append
(
title
);
var
body
=
$
(
'<div class="body" />'
)
contractOutput
.
append
(
body
);
if
(
contract
.
bytecode
.
length
>
0
)
title
.
append
(
$
(
'<div class="size"/>'
).
text
((
contract
.
bytecode
.
length
/
2
)
+
' bytes'
))
body
.
append
(
getExecuteInterface
(
contract
,
contractName
))
.
append
(
tableRow
(
'Bytecode'
,
contract
.
bytecode
));
body
.
append
(
tableRow
(
'Interface'
,
contract
[
'interface'
]))
.
append
(
textRow
(
'Web3 deploy'
,
gethDeploy
(
contractName
.
toLowerCase
(),
contract
[
'interface'
],
contract
.
bytecode
),
'deploy'
))
.
append
(
textRow
(
'uDApp'
,
combined
(
contractName
,
contract
[
'interface'
],
contract
.
bytecode
),
'deploy'
))
.
append
(
getDetails
(
contract
,
source
,
contractName
));
$
(
'#output'
).
append
(
contractOutput
);
title
.
click
(
function
(
ev
){
$
(
this
).
parent
().
toggleClass
(
'hide'
)
});
}
$
(
'.col2 input,textarea'
).
click
(
function
()
{
this
.
select
();
}
);
};
var
tableRowItems
=
function
(
first
,
second
,
cls
)
{
return
$
(
'<div class="row"/>'
)
.
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
);
};
var
getDetails
=
function
(
contract
,
source
,
contractName
)
{
var
button
=
$
(
'<button>Details</button>'
);
var
details
=
$
(
'<div style="display: none;"/>'
)
.
append
(
tableRow
(
'Solidity Interface'
,
contract
.
solidity_interface
))
.
append
(
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
));
details
.
append
(
$
(
'<span class="col1">Gas Estimates</span>'
));
details
.
append
(
$
(
'<pre/>'
).
text
(
formatGasEstimates
(
contract
.
gasEstimates
)));
if
(
contract
.
runtimeBytecode
&&
contract
.
runtimeBytecode
.
length
>
0
)
details
.
append
(
tableRow
(
'Runtime Bytecode'
,
contract
.
runtimeBytecode
));
if
(
contract
.
assembly
!==
null
)
{
details
.
append
(
$
(
'<span class="col1">Assembly</span>'
));
var
assembly
=
$
(
'<pre/>'
).
text
(
formatAssemblyText
(
contract
.
assembly
,
''
,
source
));
details
.
append
(
assembly
);
}
button
.
click
(
function
()
{
detailsOpen
[
contractName
]
=
!
detailsOpen
[
contractName
];
details
.
toggle
();
});
if
(
detailsOpen
[
contractName
])
details
.
show
();
return
$
(
'<div/>'
).
append
(
button
).
append
(
details
);
};
var
formatGasEstimates
=
function
(
data
)
{
var
gasToText
=
function
(
g
)
{
return
g
===
null
?
'unknown'
:
g
;
}
var
text
=
''
;
if
(
'creation'
in
data
)
text
+=
'Creation: '
+
gasToText
(
data
.
creation
[
0
])
+
' + '
+
gasToText
(
data
.
creation
[
1
])
+
'
\
n'
;
text
+=
'External:
\
n'
;
for
(
var
fun
in
data
.
external
)
text
+=
' '
+
fun
+
': '
+
gasToText
(
data
.
external
[
fun
])
+
'
\
n'
;
text
+=
'Internal:
\
n'
;
for
(
var
fun
in
data
.
internal
)
text
+=
' '
+
fun
+
': '
+
gasToText
(
data
.
internal
[
fun
])
+
'
\
n'
;
return
text
;
};
var
formatAssemblyText
=
function
(
asm
,
prefix
,
source
)
{
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
+=
formatAssemblyText
(
item
,
prefix
+
' '
,
source
);
});
return
text
;
};
$
(
'.asmOutput button'
).
click
(
function
()
{
$
(
this
).
parent
().
find
(
'pre'
).
toggle
();
}
)
// ----------------- VM ----------------------
var
stateTrie
=
new
EthVm
.
Trie
();
var
vm
=
new
EthVm
.
VM
(
stateTrie
);
//@todo this does not calculate the gas costs correctly but gets the job done.
var
identityCode
=
'return { gasUsed: 1, return: opts.data, exception: 1 };'
;
var
identityAddr
=
ethUtil
.
pad
(
new
Buffer
(
'04'
,
'hex'
),
20
)
vm
.
loadPrecompiled
(
identityAddr
,
identityCode
);
var
secretKey
=
'3cd7232cd6f3fc66a57a6bedc1a8ed6c228fff0a327e169c2bcc5e869ed49511'
var
publicKey
=
'0406cc661590d48ee972944b35ad13ff03c7876eae3fd191e8a2f77311b0a3c6613407b5005e63d7d8d76b89d5f900cde691497688bb281e07a5052ff61edebdc0'
var
address
=
ethUtil
.
pubToAddress
(
new
Buffer
(
publicKey
,
'hex'
));
$
(
'#txorigin'
).
text
(
'0x'
+
address
.
toString
(
'hex'
));
var
account
=
new
EthVm
.
Account
();
account
.
balance
=
'f00000000000000001'
;
var
nonce
=
0
;
stateTrie
.
put
(
address
,
account
.
serialize
());
var
runTx
=
function
(
data
,
to
,
cb
)
{
var
tx
=
new
EthVm
.
Transaction
({
nonce
:
new
Buffer
([
nonce
++
]),
//@todo count beyond 255
gasPrice
:
'01'
,
gasLimit
:
'3000000000'
,
// plenty
to
:
to
,
data
:
data
});
tx
.
sign
(
new
Buffer
(
secretKey
,
'hex'
));
vm
.
runTx
({
tx
:
tx
},
cb
);
};
var
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
;
};
var
getCallButton
=
function
(
args
)
{
// args.abi, args.bytecode [constr only], args.address [fun only]
// args.appendFunctions [constr only]
var
isConstructor
=
args
.
bytecode
!==
undefined
;
var
fun
=
new
web3
.
eth
.
function
(
args
.
abi
);
var
inputs
=
''
;
$
.
each
(
args
.
abi
.
inputs
,
function
(
i
,
inp
)
{
if
(
inputs
!=
''
)
inputs
+=
', '
;
inputs
+=
inp
.
type
+
' '
+
inp
.
name
;
});
var
inputField
=
$
(
'<input/>'
).
attr
(
'placeholder'
,
inputs
);
var
outputSpan
=
$
(
'<div class="output"/>'
);
var
button
=
$
(
'<button/>'
)
.
text
(
args
.
bytecode
?
'Create'
:
fun
.
displayName
())
.
click
(
function
()
{
var
funArgs
=
$
.
parseJSON
(
'['
+
inputField
.
val
()
+
']'
);
var
data
=
fun
.
toPayload
(
funArgs
).
data
;
if
(
data
.
slice
(
0
,
2
)
==
'0x'
)
data
=
data
.
slice
(
2
);
if
(
isConstructor
)
data
=
args
.
bytecode
+
data
.
slice
(
8
);
outputSpan
.
text
(
'...'
);
runTx
(
data
,
args
.
address
,
function
(
err
,
result
)
{
if
(
err
)
outputSpan
.
text
(
err
);
else
if
(
isConstructor
)
{
outputSpan
.
text
(
' Creation used '
+
result
.
vm
.
gasUsed
.
toString
(
10
)
+
' gas.'
);
args
.
appendFunctions
(
result
.
createdAddress
);
}
else
{
var
outputObj
=
fun
.
unpackOutput
(
'0x'
+
result
.
vm
.
return
.
toString
(
'hex'
));
outputSpan
.
text
(
' Returned: '
+
JSON
.
stringify
(
outputObj
));
}
});
});
if
(
!
isConstructor
)
button
.
addClass
(
'runButton'
);
var
c
=
$
(
'<div class="contractProperty"/>'
)
.
append
(
button
);
if
(
args
.
abi
.
inputs
.
length
>
0
)
c
.
append
(
inputField
);
return
c
.
append
(
outputSpan
);
};
var
getExecuteInterface
=
function
(
contract
,
name
)
{
var
abi
=
$
.
parseJSON
(
contract
.
interface
);
var
execInter
=
$
(
'<div/>'
);
var
funABI
=
getConstructorInterface
(
abi
);
var
appendFunctions
=
function
(
address
)
{
var
instance
=
$
(
'<div class="contractInstance"/>'
);
var
title
=
$
(
'<span class="title"/>'
).
text
(
'Contract at '
+
address
.
toString
(
'hex'
)
);
instance
.
append
(
title
);
$
.
each
(
abi
,
function
(
i
,
funABI
)
{
if
(
funABI
.
type
!=
'function'
)
return
;
instance
.
append
(
getCallButton
({
abi
:
funABI
,
address
:
address
}));
});
execInter
.
append
(
instance
);
title
.
click
(
function
(
ev
){
$
(
this
).
parent
().
toggleClass
(
'hide'
)
});
};
if
(
contract
.
bytecode
.
length
>
0
)
execInter
.
append
(
getCallButton
({
abi
:
funABI
,
bytecode
:
contract
.
bytecode
,
appendFunctions
:
appendFunctions
}));
return
execInter
;
};
</script>
<div
id=
"editor"
>
<div
id=
"files"
>
<span
class=
"newFile"
title=
"New File"
>
+
</span>
</div>
<div
id=
"input"
></div>
</div>
<div
id=
"righthand-panel"
>
<div
id=
"dragbar"
></div>
<div
id=
"header"
>
<img
id=
"solIcon"
src=
"solidity.svg"
>
<h1>
Solidity realtime
<br/>
compiler and runtime
</h1>
<div
class=
"info"
>
<p>
Version:
<span
id=
"version"
>
(loading)
</span><br/>
Change to:
<select
id=
"versionSelector"
></select><br/>
Execution environment does not connect to any node, everyhing is local and in memory only.
<br/>
<code>
tx.origin =
<span
id=
"txorigin"
/></code></p>
</div>
<div
id=
"optimizeBox"
>
<input
id=
"editorWrap"
type=
"checkbox"
><label
for=
"editorWrap"
>
Text Wrap
</label>
<input
id=
"optimize"
type=
"checkbox"
><label
for=
"optimize"
>
Enable Optimization
</label>
</div>
</div>
<div
id=
"output"
></div>
</div>
<script>
// ----------------- editor ----------------------
var
SOL_CACHE_FILE
=
"Untitled"
var
SOL_CACHE_FILES_KEY
=
"sol-cache-files"
;
var
editor
=
ace
.
edit
(
"input"
);
var
session
=
editor
.
getSession
();
var
Range
=
ace
.
require
(
'ace/range'
).
Range
;
var
errMarkerId
=
null
;
var
solFiles
=
JSON
.
parse
(
window
.
localStorage
.
getItem
(
SOL_CACHE_FILES_KEY
)
)
||
[
SOL_CACHE_FILE
];
if
(
solFiles
.
length
===
0
)
solFiles
=
[
SOL_CACHE_FILE
];
window
.
localStorage
.
setItem
(
SOL_CACHE_FILES_KEY
,
JSON
.
stringify
(
solFiles
)
);
var
solCache
=
window
.
localStorage
.
getItem
(
SOL_CACHE_FILE
)
||
BALLOT_EXAMPLE
;
window
.
localStorage
.
setItem
(
SOL_CACHE_FILE
,
solCache
)
editor
.
setValue
(
solCache
,
1
);
session
.
setMode
(
"ace/mode/javascript"
);
session
.
setTabSize
(
4
);
session
.
setUseSoftTabs
(
true
);
// ----------------- file selector-------------
var
count
=
0
;
var
$filesEl
=
$
(
'#files'
);
$filesEl
.
on
(
'click'
,
'.newFile'
,
function
(){
count
++
;
var
name
=
'Unititled'
+
count
;
solFiles
.
push
(
name
)
SOL_CACHE_FILE
=
name
;
window
.
localStorage
.
setItem
(
SOL_CACHE_FILES_KEY
,
JSON
.
stringify
(
solFiles
)
);
window
.
localStorage
.
setItem
(
SOL_CACHE_FILE
,
''
);
updateFiles
();
})
$filesEl
.
on
(
'click'
,
'.file:not(.active)'
,
showFileHandler
)
$filesEl
.
on
(
'click'
,
'.file.active'
,
function
(
ev
){
var
$fileTabEl
=
$
(
this
)
var
originalName
=
$fileTabEl
.
find
(
'.name'
).
text
()
ev
.
preventDefault
()
if
(
$
(
this
).
find
(
'input'
).
length
>
0
)
return
false
;
var
$fileNameInputEl
=
$
(
'<input value="'
+
originalName
+
'"/>'
);
$fileTabEl
.
html
(
$fileNameInputEl
)
$fileNameInputEl
.
focus
()
$fileNameInputEl
.
select
()
$fileNameInputEl
.
on
(
'blur'
,
handleRename
)
$fileNameInputEl
.
keyup
(
handleRename
);
function
handleRename
(
ev
)
{
ev
.
preventDefault
()
if
(
ev
.
which
&&
ev
.
which
!==
13
)
return
false
;
var
newName
=
ev
.
target
.
value
;
var
$new
=
null
if
(
newName
!==
originalName
&&
confirm
(
"Are you sure you want to rename: "
+
originalName
+
" to "
+
newName
+
'?'
))
{
solFiles
.
splice
(
solFiles
.
indexOf
(
originalName
),
1
,
newName
);
window
.
localStorage
.
setItem
(
newName
,
window
.
localStorage
.
getItem
(
originalName
)
);
window
.
localStorage
.
setItem
(
SOL_CACHE_FILES_KEY
,
JSON
.
stringify
(
solFiles
)
);
window
.
localStorage
.
removeItem
(
originalName
)
SOL_CACHE_FILE
=
newName
;
}
updateFiles
()
return
false
;
}
return
false
;
})
$filesEl
.
on
(
'click'
,
'.file .remove'
,
function
(
ev
){
ev
.
preventDefault
();
var
name
=
$
(
this
).
parent
().
find
(
'.name'
).
text
()
if
(
confirm
(
"Are you sure you want to remove: "
+
name
+
" from local storage?"
))
{
var
index
=
solFiles
.
indexOf
(
name
);
solFiles
.
splice
(
index
,
1
);
window
.
localStorage
.
setItem
(
SOL_CACHE_FILES_KEY
,
JSON
.
stringify
(
solFiles
)
);
SOL_CACHE_FILE
=
solFiles
[
Math
.
max
(
0
,
index
-
1
)]
window
.
localStorage
.
removeItem
(
name
)
updateFiles
()
}
return
false
;
});
function
showFileHandler
(
ev
)
{
ev
.
preventDefault
()
SOL_CACHE_FILE
=
$
(
this
).
find
(
'.name'
).
text
();
updateFiles
()
return
false
;
}
function
fileTabFromName
(
name
)
{
return
$
(
'#files .file'
).
filter
(
function
(){
return
$
(
this
).
find
(
'.name'
).
text
()
==
name
;
})
}
function
updateFiles
()
{
$filesEl
.
find
(
'.file'
).
remove
()
for
(
var
f
in
solFiles
)
{
if
(
solFiles
[
f
])
$filesEl
.
append
(
fileTabTemplate
(
solFiles
[
f
])
);
}
var
active
=
fileTabFromName
(
SOL_CACHE_FILE
);
active
.
addClass
(
'active'
)
editor
.
setValue
(
window
.
localStorage
.
getItem
(
SOL_CACHE_FILE
)
||
''
,
1
);
$
(
'#input'
).
toggle
(
typeof
SOL_CACHE_FILE
===
'string'
)
}
function
fileTabTemplate
(
name
){
return
$
(
'<span class="file"><span class="name">'
+
name
+
'</span><span class="remove">x</span></span>'
);
}
SOL_CACHE_FILE
=
solFiles
[
0
]
updateFiles
();
// ----------------- version selector-------------
// var soljsonSources is provided by bin/list.js
$
(
'option'
,
'#versionSelector'
).
remove
();
$
.
each
(
soljsonSources
,
function
(
i
,
file
)
{
if
(
file
)
{
var
version
=
file
.
replace
(
/soljson-
(
.*
)
.js/
,
"$1"
);
$
(
'#versionSelector'
).
append
(
new
Option
(
version
,
file
));
}
});
$
(
'#versionSelector'
).
change
(
function
()
{
Module
=
null
;
compileJSON
=
null
;
var
script
=
document
.
createElement
(
'script'
);
script
.
type
=
'text/javascript'
;
script
.
src
=
'bin/'
+
$
(
'#versionSelector'
).
val
();
$
(
'head'
).
append
(
script
);
onCompilerLoaded
();
});
// ----------------- resizeable ui ---------------
var
EDITOR_SIZE_CACHE_KEY
=
"editor-size-cache"
;
var
dragging
=
false
;
$
(
'#dragbar'
).
mousedown
(
function
(
e
){
e
.
preventDefault
();
dragging
=
true
;
var
main
=
$
(
'#righthand-panel'
);
var
ghostbar
=
$
(
'<div id="ghostbar">'
,
{
css
:
{
top
:
main
.
offset
().
top
,
left
:
main
.
offset
().
left
}
}).
prependTo
(
'body'
);
$
(
document
).
mousemove
(
function
(
e
){
ghostbar
.
css
(
"left"
,
e
.
pageX
+
2
);
});
});
var
$body
=
$
(
'body'
);
function
setEditorSize
(
delta
)
{
$
(
'#righthand-panel'
).
css
(
"width"
,
delta
);
$
(
'#editor'
).
css
(
"right"
,
delta
);
onResize
();
}
$
(
document
).
mouseup
(
function
(
e
){
if
(
dragging
)
{
var
delta
=
$body
.
width
()
-
e
.
pageX
+
2
;
$
(
'#ghostbar'
).
remove
();
$
(
document
).
unbind
(
'mousemove'
);
dragging
=
false
;
setEditorSize
(
delta
)
window
.
localStorage
.
setItem
(
EDITOR_SIZE_CACHE_KEY
,
delta
);
}
});
// set cached defaults
var
cachedSize
=
window
.
localStorage
.
getItem
(
EDITOR_SIZE_CACHE_KEY
);
if
(
cachedSize
)
setEditorSize
(
cachedSize
);
// ----------------- editor resize ---------------
function
onResize
()
{
editor
.
resize
();
session
.
setUseWrapMode
(
document
.
querySelector
(
'#editorWrap'
).
checked
);
if
(
session
.
getUseWrapMode
())
{
var
characterWidth
=
editor
.
renderer
.
characterWidth
;
var
contentWidth
=
editor
.
container
.
ownerDocument
.
getElementsByClassName
(
"ace_scroller"
)[
0
].
clientWidth
;
if
(
contentWidth
>
0
)
{
session
.
setWrapLimit
(
parseInt
(
contentWidth
/
characterWidth
,
10
));
}
}
}
window
.
onresize
=
onResize
;
onResize
();
document
.
querySelector
(
'#editor'
).
addEventListener
(
'change'
,
onResize
);
// ----------------- compiler ----------------------
var
compileJSON
;
var
previousInput
=
''
;
var
sourceAnnotations
=
[];
var
compile
=
function
()
{
editor
.
getSession
().
clearAnnotations
();
sourceAnnotations
=
[];
editor
.
getSession
().
removeMarker
(
errMarkerId
);
$
(
'#output'
).
empty
();
var
input
=
editor
.
getValue
();
window
.
localStorage
.
setItem
(
SOL_CACHE_FILE
,
input
);
var
inputIncludingImports
=
includeLocalImports
(
input
);
var
optimize
=
document
.
querySelector
(
'#optimize'
).
checked
;
try
{
var
data
=
$
.
parseJSON
(
compileJSON
(
inputIncludingImports
,
optimize
?
1
:
0
));
}
catch
(
exception
)
{
renderError
(
"Uncaught JavaScript Exception:
\
n"
+
exception
);
return
;
}
if
(
data
[
'error'
]
!==
undefined
)
renderError
(
data
[
'error'
]);
if
(
data
[
'errors'
]
!=
undefined
)
$
.
each
(
data
[
'errors'
],
function
(
i
,
err
)
{
renderError
(
err
);
});
else
renderContracts
(
data
,
input
);
}
var
compileTimeout
=
null
;
var
onChange
=
function
()
{
var
input
=
editor
.
getValue
();
if
(
input
===
""
)
{
window
.
localStorage
.
setItem
(
SOL_CACHE_FILE
,
''
)
return
;
}
if
(
input
===
previousInput
)
return
;
previousInput
=
input
;
if
(
compileTimeout
)
window
.
clearTimeout
(
compileTimeout
);
compileTimeout
=
window
.
setTimeout
(
compile
,
300
);
};
var
onCompilerLoaded
=
function
()
{
compileJSON
=
Module
.
cwrap
(
"compileJSON"
,
"string"
,
[
"string"
,
"number"
]);
$
(
'#version'
).
text
(
Module
.
cwrap
(
"version"
,
"string"
,
[])());
previousInput
=
''
;
onChange
();
};
function
includeLocalImports
(
input
)
{
var
importRegex
=
/import
\s[\'\"]([^\'\"]
+
)[\'\"]
;/g
var
imports
=
[];
var
matches
=
[];
var
match
;
while
((
match
=
importRegex
.
exec
(
input
))
!==
null
)
{
if
(
match
[
1
]
&&
solFiles
.
indexOf
(
match
[
1
])
!==
-
1
)
{
imports
.
push
(
match
[
1
]
)
matches
.
push
(
match
[
0
]
)
}
}
for
(
var
i
in
imports
)
{
imported
=
includeLocalImports
(
window
.
localStorage
.
getItem
(
imports
[
i
]
)
)
input
=
input
.
replace
(
matches
[
i
],
imported
);
}
return
input
;
}
if
(
Module
)
onCompilerLoaded
();
editor
.
getSession
().
on
(
'change'
,
onChange
);
document
.
querySelector
(
'#optimize'
).
addEventListener
(
'change'
,
compile
);
// ----------------- compiler output renderer ----------------------
var
detailsOpen
=
{};
var
renderError
=
function
(
message
)
{
$
(
'#output'
)
.
append
(
$
(
'<pre class="error"></pre>'
).
text
(
message
));
var
err
=
message
.
match
(
/^:
([
0-9
]
*
)
:
([
0-9
]
*
)
/
)
if
(
err
&&
err
.
length
)
{
var
errLine
=
parseInt
(
err
[
1
],
10
)
-
1
;
var
errCol
=
err
[
2
]
?
parseInt
(
err
[
2
],
10
)
:
0
;
sourceAnnotations
[
sourceAnnotations
.
length
]
=
{
row
:
errLine
,
column
:
errCol
,
text
:
message
,
type
:
"error"
};
editor
.
getSession
().
setAnnotations
(
sourceAnnotations
);
}
};
var
gethDeploy
=
function
(
contractName
,
interface
,
bytecode
){
var
code
=
""
;
var
funABI
=
getConstructorInterface
(
$
.
parseJSON
(
interface
));
$
.
each
(
funABI
.
inputs
,
function
(
i
,
inp
)
{
code
+=
"var "
+
inp
.
name
+
" = /* var of type "
+
inp
.
type
+
" here */ ;
\
n"
;
});
code
+=
"
\
nvar "
+
contractName
+
"Contract = web3.eth.contract("
+
interface
.
replace
(
"
\
n"
,
""
)
+
");"
+
"
\
nvar "
+
contractName
+
" = "
+
contractName
+
"Contract.new("
;
$
.
each
(
funABI
.
inputs
,
function
(
i
,
inp
)
{
code
+=
"
\
n "
+
inp
.
name
+
","
;
});
code
+=
"
\
n {"
+
"
\
n from: web3.eth.accounts[0], "
+
"
\
n data: '"
+
bytecode
+
"', "
+
"
\
n gas: 3000000"
+
"
\
n }, function(e, contract){"
+
"
\
n if (typeof contract.address != 'undefined') {"
+
"
\
n console.log(e, contract);"
+
"
\
n console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);"
+
"
\
n }"
+
"
\
n })"
;
return
code
;
};
var
combined
=
function
(
contractName
,
interface
,
bytecode
){
return
JSON
.
stringify
(
[{
name
:
contractName
,
interface
:
interface
,
bytecode
:
bytecode
}]);
};
var
renderContracts
=
function
(
data
,
source
)
{
$
(
'#output'
).
empty
();
for
(
var
contractName
in
data
.
contracts
)
{
var
contract
=
data
.
contracts
[
contractName
];
var
title
=
$
(
'<h3 class="title"/>'
).
text
(
contractName
);
var
contractOutput
=
$
(
'<div class="contractOutput"/>'
)
.
append
(
title
);
var
body
=
$
(
'<div class="body" />'
)
contractOutput
.
append
(
body
);
if
(
contract
.
bytecode
.
length
>
0
)
title
.
append
(
$
(
'<div class="size"/>'
).
text
((
contract
.
bytecode
.
length
/
2
)
+
' bytes'
))
body
.
append
(
getExecuteInterface
(
contract
,
contractName
))
.
append
(
tableRow
(
'Bytecode'
,
contract
.
bytecode
));
body
.
append
(
tableRow
(
'Interface'
,
contract
[
'interface'
]))
.
append
(
textRow
(
'Web3 deploy'
,
gethDeploy
(
contractName
.
toLowerCase
(),
contract
[
'interface'
],
contract
.
bytecode
),
'deploy'
))
.
append
(
textRow
(
'uDApp'
,
combined
(
contractName
,
contract
[
'interface'
],
contract
.
bytecode
),
'deploy'
))
.
append
(
getDetails
(
contract
,
source
,
contractName
));
$
(
'#output'
).
append
(
contractOutput
);
title
.
click
(
function
(
ev
){
$
(
this
).
parent
().
toggleClass
(
'hide'
)
});
}
$
(
'.col2 input,textarea'
).
click
(
function
()
{
this
.
select
();
}
);
};
var
tableRowItems
=
function
(
first
,
second
,
cls
)
{
return
$
(
'<div class="row"/>'
)
.
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
);
};
var
getDetails
=
function
(
contract
,
source
,
contractName
)
{
var
button
=
$
(
'<button>Details</button>'
);
var
details
=
$
(
'<div style="display: none;"/>'
)
.
append
(
tableRow
(
'Solidity Interface'
,
contract
.
solidity_interface
))
.
append
(
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
));
details
.
append
(
$
(
'<span class="col1">Gas Estimates</span>'
));
details
.
append
(
$
(
'<pre/>'
).
text
(
formatGasEstimates
(
contract
.
gasEstimates
)));
if
(
contract
.
runtimeBytecode
&&
contract
.
runtimeBytecode
.
length
>
0
)
details
.
append
(
tableRow
(
'Runtime Bytecode'
,
contract
.
runtimeBytecode
));
if
(
contract
.
assembly
!==
null
)
{
details
.
append
(
$
(
'<span class="col1">Assembly</span>'
));
var
assembly
=
$
(
'<pre/>'
).
text
(
formatAssemblyText
(
contract
.
assembly
,
''
,
source
));
details
.
append
(
assembly
);
}
button
.
click
(
function
()
{
detailsOpen
[
contractName
]
=
!
detailsOpen
[
contractName
];
details
.
toggle
();
});
if
(
detailsOpen
[
contractName
])
details
.
show
();
return
$
(
'<div/>'
).
append
(
button
).
append
(
details
);
};
var
formatGasEstimates
=
function
(
data
)
{
var
gasToText
=
function
(
g
)
{
return
g
===
null
?
'unknown'
:
g
;
}
var
text
=
''
;
if
(
'creation'
in
data
)
text
+=
'Creation: '
+
gasToText
(
data
.
creation
[
0
])
+
' + '
+
gasToText
(
data
.
creation
[
1
])
+
'
\
n'
;
text
+=
'External:
\
n'
;
for
(
var
fun
in
data
.
external
)
text
+=
' '
+
fun
+
': '
+
gasToText
(
data
.
external
[
fun
])
+
'
\
n'
;
text
+=
'Internal:
\
n'
;
for
(
var
fun
in
data
.
internal
)
text
+=
' '
+
fun
+
': '
+
gasToText
(
data
.
internal
[
fun
])
+
'
\
n'
;
return
text
;
};
var
formatAssemblyText
=
function
(
asm
,
prefix
,
source
)
{
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
+=
formatAssemblyText
(
item
,
prefix
+
' '
,
source
);
});
return
text
;
};
$
(
'.asmOutput button'
).
click
(
function
()
{
$
(
this
).
parent
().
find
(
'pre'
).
toggle
();
}
)
// ----------------- VM ----------------------
var
stateTrie
=
new
EthVm
.
Trie
();
var
vm
=
new
EthVm
.
VM
(
stateTrie
);
//@todo this does not calculate the gas costs correctly but gets the job done.
var
identityCode
=
'return { gasUsed: 1, return: opts.data, exception: 1 };'
;
var
identityAddr
=
ethUtil
.
pad
(
new
Buffer
(
'04'
,
'hex'
),
20
)
vm
.
loadPrecompiled
(
identityAddr
,
identityCode
);
var
secretKey
=
'3cd7232cd6f3fc66a57a6bedc1a8ed6c228fff0a327e169c2bcc5e869ed49511'
var
publicKey
=
'0406cc661590d48ee972944b35ad13ff03c7876eae3fd191e8a2f77311b0a3c6613407b5005e63d7d8d76b89d5f900cde691497688bb281e07a5052ff61edebdc0'
var
address
=
ethUtil
.
pubToAddress
(
new
Buffer
(
publicKey
,
'hex'
));
$
(
'#txorigin'
).
text
(
'0x'
+
address
.
toString
(
'hex'
));
var
account
=
new
EthVm
.
Account
();
account
.
balance
=
'f00000000000000001'
;
var
nonce
=
0
;
stateTrie
.
put
(
address
,
account
.
serialize
());
var
runTx
=
function
(
data
,
to
,
cb
)
{
var
tx
=
new
EthVm
.
Transaction
({
nonce
:
new
Buffer
([
nonce
++
]),
//@todo count beyond 255
gasPrice
:
'01'
,
gasLimit
:
'3000000000'
,
// plenty
to
:
to
,
data
:
data
});
tx
.
sign
(
new
Buffer
(
secretKey
,
'hex'
));
vm
.
runTx
({
tx
:
tx
},
cb
);
};
var
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
;
};
var
getCallButton
=
function
(
args
)
{
// args.abi, args.bytecode [constr only], args.address [fun only]
// args.appendFunctions [constr only]
var
isConstructor
=
args
.
bytecode
!==
undefined
;
var
fun
=
new
web3
.
eth
.
function
(
args
.
abi
);
var
inputs
=
''
;
$
.
each
(
args
.
abi
.
inputs
,
function
(
i
,
inp
)
{
if
(
inputs
!=
''
)
inputs
+=
', '
;
inputs
+=
inp
.
type
+
' '
+
inp
.
name
;
});
var
inputField
=
$
(
'<input/>'
).
attr
(
'placeholder'
,
inputs
);
var
outputSpan
=
$
(
'<div class="output"/>'
);
var
button
=
$
(
'<button/>'
)
.
text
(
args
.
bytecode
?
'Create'
:
fun
.
displayName
())
.
click
(
function
()
{
var
funArgs
=
$
.
parseJSON
(
'['
+
inputField
.
val
()
+
']'
);
var
data
=
fun
.
toPayload
(
funArgs
).
data
;
if
(
data
.
slice
(
0
,
2
)
==
'0x'
)
data
=
data
.
slice
(
2
);
if
(
isConstructor
)
data
=
args
.
bytecode
+
data
.
slice
(
8
);
outputSpan
.
text
(
'...'
);
runTx
(
data
,
args
.
address
,
function
(
err
,
result
)
{
if
(
err
)
outputSpan
.
text
(
err
);
else
if
(
isConstructor
)
{
outputSpan
.
text
(
' Creation used '
+
result
.
vm
.
gasUsed
.
toString
(
10
)
+
' gas.'
);
args
.
appendFunctions
(
result
.
createdAddress
);
}
else
{
var
outputObj
=
fun
.
unpackOutput
(
'0x'
+
result
.
vm
.
return
.
toString
(
'hex'
));
outputSpan
.
text
(
' Returned: '
+
JSON
.
stringify
(
outputObj
));
}
});
});
if
(
!
isConstructor
)
button
.
addClass
(
'runButton'
);
var
c
=
$
(
'<div class="contractProperty"/>'
)
.
append
(
button
);
if
(
args
.
abi
.
inputs
.
length
>
0
)
c
.
append
(
inputField
);
return
c
.
append
(
outputSpan
);
};
var
getExecuteInterface
=
function
(
contract
,
name
)
{
var
abi
=
$
.
parseJSON
(
contract
.
interface
);
var
execInter
=
$
(
'<div/>'
);
var
funABI
=
getConstructorInterface
(
abi
);
var
appendFunctions
=
function
(
address
)
{
var
instance
=
$
(
'<div class="contractInstance"/>'
);
var
title
=
$
(
'<span class="title"/>'
).
text
(
'Contract at '
+
address
.
toString
(
'hex'
)
);
instance
.
append
(
title
);
$
.
each
(
abi
,
function
(
i
,
funABI
)
{
if
(
funABI
.
type
!=
'function'
)
return
;
instance
.
append
(
getCallButton
({
abi
:
funABI
,
address
:
address
}));
});
execInter
.
append
(
instance
);
title
.
click
(
function
(
ev
){
$
(
this
).
parent
().
toggleClass
(
'hide'
)
});
};
if
(
contract
.
bytecode
.
length
>
0
)
execInter
.
append
(
getCallButton
({
abi
:
funABI
,
bytecode
:
contract
.
bytecode
,
appendFunctions
:
appendFunctions
}));
return
execInter
;
};
</script>
</body>
</html>
stylesheets/browser-solidity.css
View file @
9e7fe56e
...
...
@@ -10,12 +10,66 @@ body {
width
:
auto
;
bottom
:
0px
;
right
:
37em
;
}
#input
{
#files
{
font-size
:
15px
;
height
:
2.5em
;
box-sizing
:
border-box
;
line-height
:
2em
;
padding
:
0.5em
0.5em
0
;
}
#files
.file
,
#files
.newFile
{
display
:
inline-block
;
padding
:
0
0.6em
;
box-sizing
:
border-box
;
background-color
:
#f0f0f0
;
cursor
:
pointer
;
margin-right
:
0.5em
;
position
:
relative
;
}
#files
.newFile
{
background-color
:
#B1EAC5
;
font-weight
:
bold
;
color
:
#4E775D
;
}
#files
.file.active
{
font-weight
:
bold
;
border-bottom
:
0
none
;
padding-right
:
2.5em
;
}
#files
.file
.remove
{
position
:
absolute
;
right
:
0
;
top
:
0
;
height
:
1.25em
;
width
:
1.25em
;
line-height
:
1em
;
border-radius
:
1em
;
color
:
#FF8080
;
display
:
none
;
margin
:
0.4em
;
text-align
:
center
;
}
#files
.file
input
{
background-color
:
transparent
;
border
:
0
none
;
border-bottom
:
1px
dotted
black
;
line-height
:
1em
;
margin
:
0.5em
0
;
}
#files
.file.active
.remove
{
display
:
inline-block
;
}
#input
{
font-size
:
15px
;
position
:
absolute
;
top
:
2.5em
;
left
:
0
;
right
:
0
;
bottom
:
0
;
...
...
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