diff --git a/ballot.sol.js b/ballot.sol.js new file mode 100644 index 0000000000..b25609a681 --- /dev/null +++ b/ballot.sol.js @@ -0,0 +1,68 @@ +var multi = function(func) { return func.toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]; } + +var BALLOT_EXAMPLE = multi(function(){/*contract Ballot { + struct Voter { + uint weight; + bool voted; + uint8 vote; + address delegate; + } + struct Proposal { + uint voteCount; + } + + address chairperson; + mapping(address => Voter) voters; + Proposal[] proposals; + + // Create a new ballot with $(_numProposals) different proposals. + function Ballot(uint8 _numProposals) { + chairperson = msg.sender; + voters[chairperson].weight = 1; + proposals.length = _numProposals; + } + + // Give $(voter) the right to vote on this ballot. + // May only be called by $(chairperson). + function giveRightToVote(address voter) { + if (msg.sender != chairperson || voters[voter].voted) return; + voters[voter].weight = 1; + } + + // Delegate your vote to the voter $(to). + function delegate(address to) { + Voter sender = voters[msg.sender]; // assigns reference + if (sender.voted) return; + while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender) + to = voters[to].delegate; + if (to == msg.sender) return; + sender.voted = true; + sender.delegate = to; + Voter delegate = voters[to]; + if (delegate.voted) + proposals[delegate.vote].voteCount += sender.weight; + else + delegate.weight += sender.weight; + } + + // Give a single vote to proposal $(proposal). + function vote(uint8 proposal) { + Voter sender = voters[msg.sender]; + if (sender.voted || proposal >= proposals.length) return; + sender.voted = true; + sender.vote = proposal; + proposals[proposal].voteCount += sender.weight; + } + + function winningProposal() constant returns (uint8 winningProposal) { + uint256 winningVoteCount = 0; + for (uint8 proposal = 0; proposal < proposals.length; proposal++) { + if (proposals[proposal].voteCount > winningVoteCount) { + winningVoteCount = proposals[proposal].voteCount; + winningProposal = proposal; + } + ++proposal; + } + } +} +*/}); \ No newline at end of file diff --git a/index.html b/index.html index 5c334f02f4..dfba3c99ee 100644 --- a/index.html +++ b/index.html @@ -12,67 +12,206 @@ body { font-size: 12px; color: #111111; } -#solIcon { - right: 10px; - top: 10px; +#editor { position: absolute; - height: 100px; - width: 100px; - overflow: hidden; -} -#solIcon img { - top: -20px; - right: -10px; - position: absolute; - height: 100px; -} -#optimizeBox { - position: absolute; - top: 30px; - left: 720px; - font-size: 14px; -} -#input { - position: absolute; - top: 120px; + top: 0; left: 0px; - width: 700px; + width: auto; bottom: 0px; + right: 37em; + +} +#input { font-size: 15px; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + min-width: 20vw; } -#output { + +#righthand-panel { position: absolute; - top: 120px; - left: 720px; - right: 10px; + top: 0; + width: 37em; + max-width: 80vw; + right: 0; bottom: 0px; - font-size: 14px; overflow: auto; + border-left: 1px dotted black; + box-sizing: border-box; } + +#output { + border-top: 1px dotted black; + display: block; +} + #header { - margin-bottom: 4px; + font-size: 14px; + padding: 1em; + font-size: 12px; } + +#header h1 { + margin-top: 0; +} + +#header .info { clear: left; } + +#header #solIcon { + float: left; + height: 5em; +} + .col1 { - width: 18ex; - display: inline-block; + width: 30%; + float: left; } .col2 { - width: 60ex; - display: inline-block; + width: 70%; + float: left; +} + +.row { + overflow: auto; } .gethDeployText { border-color: #bebebe; - height: 2.5ex; + height: 2.5em; + width: 100%; + display: block; +} + +.contractInstance { + background-color: #ccc; + margin-bottom: 1em; + padding: 0.6em; } -.runButton { - width: 30ex; + +.contractInstance.hide > *:not(.title) { + display: none; +} + + +.contractInstance .contractProperty input, +.contractInstance .contractProperty button { text-align: left; - overflow: hidden; + padding: 0.3em; + width: 50%; + margin: 0; } -.contractInstance { - margin-left: 2ex; - margin-bottom: 20px; +.contractOutput .contractInstance .contractProperty { + margin-bottom: 0; +} +.contractOutput .contractInstance .contractProperty .output { + padding: 0.4em; + background-color: #333; + color: white; + margin-bottom: 1em; + display: block; +} +.contractInstance .contractProperty .output:empty { display: none; } + +.contractOutput { + border-bottom: 1px dotted black; + padding: 0.6em; + box-sizing: border-box; +} +.contractOutput .contractProperty { + margin-bottom: 0.6em; +} +.contractOutput .contractProperty .output { + display: inline; +} + + +.contractOutput .body { + margin-top: 10px; +} + +.contractOutput.hide { + background-color: #4C4C67; + color: white; +} + +.contractOutput.hide > *:not(.title) { + display: none; +} + +.title { + margin: 0; + cursor: pointer; + font-family: monospace; + font-weight: bold; +} + +.title:before { + content: "\25BC"; + opacity: 0.5; + margin-right: 0.4em; + font-size: 10px; +} + +.hide > .title:before { + content: "\25B6"; +} + +.contractOutput > .title { + border-bottom: #4C4C67; +} + + +.title .size { + font-weight: normal; + float: right; +} + +.solError { + position: absolute; + background-color: rgba(255, 0, 0, 0.2); + z-index:40; +} + +.error { + background-color: rgba(255, 0, 0, 0.5); + border-radius: 0; + word-wrap: break-word; + border: 1px solid #D00909; +} + +#ghostbar { + width: 1px; + background-color: red; + opacity: 0.5; + position: absolute; + cursor: col-resize; + z-index: 9999; + top: 0; + bottom: 0; +} + +#dragbar{ + background-color: transparent; + position: absolute; + width: 5px; + left: 0; + top: 0; + bottom: 0; + cursor: col-resize; + z-index: 999; +} + + +input[readonly] { + padding: .4em; + border: 1px solid #ccc; + box-sizing: border-box; + display: block; + width: 100%; } + @@ -80,369 +219,432 @@ body { + + + -
-

Solidity realtime compiler and runtime

-Version: (loading)
-Execution environment does not connect to any node, everyhing is in-memory only.
-Note: If Chrome/Chromium reports "Uncaught JavaScript Exception", -enable the debug console (Ctrl+Shift+i) and reload. -
- -
-
contract Ballot { - struct Voter { - uint weight; - bool voted; - uint8 vote; - address delegate; - } - struct Proposal { - uint voteCount; - } - - address chairperson; - mapping(address => Voter) voters; - Proposal[] proposals; - - // Create a new ballot with $(_numProposals) different proposals. - function Ballot(uint8 _numProposals) { - chairperson = msg.sender; - voters[chairperson].weight = 1; - proposals.length = _numProposals; - } - - // Give $(voter) the right to vote on this ballot. - // May only be called by $(chairperson). - function giveRightToVote(address voter) { - if (msg.sender != chairperson || voters[voter].voted) return; - voters[voter].weight = 1; - } - - // Delegate your vote to the voter $(to). - function delegate(address to) { - Voter sender = voters[msg.sender]; // assigns reference - if (sender.voted) return; - while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender) - to = voters[to].delegate; - if (to == msg.sender) return; - sender.voted = true; - sender.delegate = to; - Voter delegate = voters[to]; - if (delegate.voted) - proposals[delegate.vote].voteCount += sender.weight; - else - delegate.weight += sender.weight; - } - - // Give a single vote to proposal $(proposal). - function vote(uint8 proposal) { - Voter sender = voters[msg.sender]; - if (sender.voted || proposal >= proposals.length) return; - sender.voted = true; - sender.vote = proposal; - proposals[proposal].voteCount += sender.weight; - } - - function winningProposal() constant returns (uint8 winningProposal) { - uint256 winningVoteCount = 0; - for (uint8 proposal = 0; proposal < proposals.length; proposal++) { - if (proposals[proposal].voteCount > winningVoteCount) { - winningVoteCount = proposals[proposal].voteCount; - winningProposal = proposal; - } - ++proposal; - } - } -} -
-
- -
-

Theme by orderedlist

- - + + // 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 = Module.cwrap("compileJSON", "string", ["string", "number"]); + $('#version').text(Module.cwrap("version", "string", [])()); + + var previousInput = ''; + var compile = function() { + editor.getSession().clearAnnotations(); + editor.getSession().removeMarker(errMarkerId); + 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']); + 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); + }; + onChange(); + + editor.getSession().on('change', onChange); + + document.querySelector('#optimize').addEventListener('change', compile); + + // ----------------- compiler output renderer ---------------------- + var detailsOpen = {}; + + var renderError = function(message) { + var $output = $('#output').empty() + 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; + $output.append($('
').text(message));
+                editor.getSession().setAnnotations([{
+                    row: errLine,
+                    column: errCol,
+                    text: message,
+                    type: "error"
+                }]);
+            }
+        };
+
+        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: 1000000"+
+            "\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 = $('

').text(contractName); + var contractOutput = $('
') + .append(title); + var body = $('
') + contractOutput.append( body ); + if (contract.bytecode.length > 0) + title.append($('
').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 $('
') + .addClass(cls) + .append($('
').append(first)) + .append($('
').append(second)); + }; + var tableRow = function(description, data) { + return tableRowItems( + $('').text(description), + $('').val(data)); + }; + var textRow = function(description, data, cls) { + return tableRowItems( + $('').text(description), + $('