Merge pull request #1 from ethereum/npmify

Use npm and browserify to build website.
pull/1/head
yann300 9 years ago
commit 1d404ea0d6
  1. 2
      .gitignore
  2. 52
      README.md
  3. 4
      assets/js/jquery-2.1.3.min.js
  4. 8
      index.html
  5. 62
      index.js
  6. 30
      package.json
  7. 27
      src/app.js
  8. 4
      src/index.js
  9. 56
      src/mode-solidity.js
  10. 33
      src/universal-dapp.js
  11. 11
      src/web3-adapter.js

2
.gitignore vendored

@ -0,0 +1,2 @@
.vscode
node_modules

@ -1,51 +1,27 @@
# Browser-Solidity
#Browser-solidity
Browser solidity is a browser based solidity compiler and IDE.
Browser solidity is a browser based solidity compiler. To use either visit [https://chriseth.github.io/browser-solidity](https://chriseth.github.io/browser-solidity) or clone/download this repo and open `index.html` in your browser.
Visit [https://ethereum.github.io/browser-solidity](https://ethereum.github.io/browser-solidity) to use,
it will always deliver the latest version.
#Nodejs usage
# Offline Usage
To use the solidity compiler via nodejs you can install it via npm
Full offline usage is currently not supported because the compiler is always
loaded via http. If you clone or download the repository, you still have to
build it before you can use it.
npm install solc
# Building
And then use it like so:
Many dependencies are only provided via npm:
var solc = require('solc');
var input = "contract x { function g() {} }";
var output = solc.compile(input, 1); // 1 activates the optimiser
for (var contractName in output.contracts) {
// code and ABI that are needed by web3
console.log(contractName + ': ' + output.contracts[contractName].bytecode);
console.log(contractName + '; ' + JSON.parse( output.contracts[contractName].interface));
}
npm install # fetch dependencies
npm run build # build application into build/app.js
Starting from version 0.1.6, multiple files are supported with automatic import resolution by the compiler as follows:
Now point your browser to `index.html` to open the application.
var solc = require('solc');
var input = {
'lib.sol': 'library L { function f() returns (uint) { return 7; } }',
'cont.sol': 'import "lib.sol"; contract x { function g() { L.f(); } }'
};
var output = solc.compile({sources: input}, 1);
for (var contractName in output.contracts)
console.log(contractName + ': ' + output.contracts[contractName].bytecode);
# To use it as a chrome extension
Note that all input files that are imported have to be supplied, the compiler will not load any additional files on its own.
###Using a legacy version
In order to allow compiling contracts using a specific version of solidity, the `solc.useVersion` method is available. This returns a new solc object using the version provided. **Note**: version strings must match the version substring of the files availble in `/bin/soljson-*.js`. See below for an example.
var solc = require('solc');
// by default the latest version is used
// ie: solc.useVersion('latest')
// getting a legacy version
var solcV011 = solc.useVersion( 'v0.1.1-2015-08-04-6ff4cd6' );
var output = solcV011.compile( "contract t { function g() {} }", 1 );
#To use it as a chrome extension:
Browse to chrome://extensions/
Make sure 'Developer mode' has been checked. Then click 'Load unpacked extension...' to pop up a file-selection dialog.

File diff suppressed because one or more lines are too long

@ -37,12 +37,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<script src="https://ethereum.github.io/solc-bin/bin/list.js"></script>
<script src="assets/js/jquery-2.1.3.min.js"></script>
<script src="assets/js/ace.js"></script>
<script src="assets/js/mode-solidity.js"></script>
<script src="assets/js/ethereumjs-vm.js"></script>
<script src="assets/js/universal-dapp.js"></script>
<script src="assets/js/web3.min.js"></script>
<script src="assets/js/ballot.sol.js"></script>
</head>
@ -124,6 +118,6 @@
<div id="output"></div>
</div>
<script src="assets/js/app.js"></script>
<script src="build/app.js"></script>
</body>
</html>

@ -1,62 +0,0 @@
function setupMethods (soljson){
var compileJSON = soljson.cwrap("compileJSON", "string", ["string", "number"]);
var compileJSONMulti =
'_compileJSONMulti' in soljson ?
soljson.cwrap("compileJSONMulti", "string", ["string", "number"]) :
null;
var compileJSONCallback = null;
if ('_compileJSONCallback' in soljson)
{
/// TODO: Allocating memory and copying the strings over
/// to the emscripten runtime does not seem to work.
var copyString = function(str, ptr) {
var buffer = soljson._malloc(str.length + 1);
soljson.writeStringToMemory(str, buffer);
soljson.setValue(ptr, buffer, '*');
};
var wrapCallback = function(callback) {
return soljson.Runtime.addFunction(function(path, contents, error) {
// path is char*, contents is char**, error is char**
// TODO copying the results does not seem to work.
// This is not too bad, because most of the requests
// cannot be answered synchronously anyway.
var result = callback(soljson.Pointer_stringify(path));
if (typeof(result.contents) === typeof(''))
copyString(result.contents, contents);
if (typeof(result.error) === typeof(''))
copyString(result.error, error);
});
};
var compileInternal = soljson.cwrap("compileJSONCallback", "string", ["string", "number", "number"]);
compileJSONCallback = function(input, optimize, readCallback) {
var cb = wrapCallback(readCallback);
var output = compileInternal(input, optimize, cb);
soljson.Runtime.removeFunction(cb);
return output;
};
}
var compile = function(input, optimise, readCallback) {
var result = '';
if (readCallback !== undefined && compileJSONCallback !== null)
result = compileJSONCallback(JSON.stringify(input), optimise, readCallback);
if (typeof(input) != typeof('') && compileJSONMulti !== null)
result = compileJSONMulti(JSON.stringify(input), optimise);
else
result = compileJSON(input, optimise);
return JSON.parse(result);
}
var version = soljson.cwrap("version", "string", []);
return {
version: version,
compile: compile,
useVersion: function( versionString ){
return setupMethods( require('./bin/soljson-' + versionString + '.js' ) );
}
}
}
module.exports = setupMethods( require('./bin/soljson-latest.js') );

@ -1,14 +1,27 @@
{
"name": "solc",
"version": "0.3.1-1",
"description": "Solidity compiler",
"main": "index.js",
"name": "browser-solidity",
"version": "1.0.0",
"description": "Minimalistic browser-based Solidity IDE",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"build": "mkdir -p build; browserify src/index.js -o build/app.js"
},
"devDependencies": {
"ethereumjs-vm": "^1.3.0",
"merkle-patricia-tree": "^2.1.2",
"ethereumjs-util": "^4.4.0",
"ethereumjs-tx": "^1.1.1",
"ethereumjs-account": "^2.0.2",
"ethereumjs-abi": "^0.6.0",
"web3": "^0.15.3",
"jquery": "^2.2.0",
"brace": "^0.8.0",
"browserify": "^13.0.0",
"js-base64": "^2.1.9"
},
"repository": {
"type": "git",
"url": "git+https://github.com/chriseth/browser-solidity.git"
"url": "git+https://github.com/ethereum/browser-solidity.git"
},
"keywords": [
"ethereum",
@ -18,7 +31,8 @@
"author": "chriseth",
"license": "MIT",
"bugs": {
"url": "https://github.com/chriseth/browser-solidity/issues"
"url": "https://github.com/ethereum/browser-solidity/issues"
},
"homepage": "https://github.com/chriseth/browser-solidity#readme"
"homepage": "https://github.com/ethereum/browser-solidity#readme",
"private": true
}

@ -1,8 +1,12 @@
var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}};
$(document).ready(function() {
var $ = require('jquery');
var UniversalDApp = require('./universal-dapp.js');
var web3 = require('./web3-adapter.js');
var ace = require('brace');
require('./mode-solidity.js');
var Base64 = require('js-base64').Base64;
var run = function() {
// ------------------ query params (hash) ----------------
@ -153,7 +157,7 @@ $(document).ready(function() {
var editor = ace.edit("input");
var sessions = {};
var Range = ace.require('ace/range').Range;
var Range = ace.acequire('ace/range').Range;
var errMarkerId = null;
var untitledCount = '';
@ -211,13 +215,8 @@ $(document).ready(function() {
var $web3Toggle = $('#web3');
var $web3endpoint = $('#web3Endpoint');
if (typeof web3 !== 'undefined')
{
if (web3.providers && web3.currentProvider instanceof web3.providers.IpcProvider)
$web3endpoint.val('ipc');
web3 = new Web3(web3.currentProvider);
} else
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
var executionContext = 'vm';
$vmToggle.get(0).checked = true;
@ -227,9 +226,9 @@ $(document).ready(function() {
$web3endpoint.on('change', function() {
var endpoint = $web3endpoint.val();
if (endpoint == 'ipc')
web3.setProvider(new Web3.providers.IpcProvider());
web3.setProvider(new web3.providers.IpcProvider());
else
web3.setProvider(new Web3.providers.HttpProvider(endpoint));
web3.setProvider(new web3.providers.HttpProvider(endpoint));
compile();
});
@ -990,4 +989,8 @@ $(document).ready(function() {
syncStorage()
});
};
module.exports = {
'run': run
};

@ -0,0 +1,4 @@
var app = require("./app.js");
var $ = require("jquery");
$(document).ready(function() { app.run(); });

@ -1,8 +1,10 @@
ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) {
var ace = window.ace;
ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(acequire, exports, module) {
"use strict";
var oop = require("../lib/oop");
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
var oop = acequire("../lib/oop");
var TextHighlightRules = acequire("./text_highlight_rules").TextHighlightRules;
var DocCommentHighlightRules = function() {
this.$rules = {
@ -48,12 +50,12 @@ exports.DocCommentHighlightRules = DocCommentHighlightRules;
});
ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"], function(require, exports, module) {
ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"], function(acequire, exports, module) {
"use strict";
var oop = require("../lib/oop");
var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules;
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
var oop = acequire("../lib/oop");
var DocCommentHighlightRules = acequire("./doc_comment_highlight_rules").DocCommentHighlightRules;
var TextHighlightRules = acequire("./text_highlight_rules").TextHighlightRules;
var JavaScriptHighlightRules = function(options) {
var intTypes = 'bytes|int|uint';
@ -389,10 +391,10 @@ oop.inherits(JavaScriptHighlightRules, TextHighlightRules);
exports.JavaScriptHighlightRules = JavaScriptHighlightRules;
});
ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(require, exports, module) {
ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(acequire, exports, module) {
"use strict";
var Range = require("../range").Range;
var Range = acequire("../range").Range;
var MatchingBraceOutdent = function() {};
@ -429,13 +431,13 @@ var MatchingBraceOutdent = function() {};
exports.MatchingBraceOutdent = MatchingBraceOutdent;
});
ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"], function(require, exports, module) {
ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"], function(acequire, exports, module) {
"use strict";
var oop = require("../../lib/oop");
var Behaviour = require("../behaviour").Behaviour;
var TokenIterator = require("../../token_iterator").TokenIterator;
var lang = require("../../lib/lang");
var oop = acequire("../../lib/oop");
var Behaviour = acequire("../behaviour").Behaviour;
var TokenIterator = acequire("../../token_iterator").TokenIterator;
var lang = acequire("../../lib/lang");
var SAFE_INSERT_IN_TOKENS =
["text", "paren.rparen", "punctuation.operator"];
@ -787,12 +789,12 @@ oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
});
ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) {
ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(acequire, exports, module) {
"use strict";
var oop = require("../../lib/oop");
var Range = require("../../range").Range;
var BaseFoldMode = require("./fold_mode").FoldMode;
var oop = acequire("../../lib/oop");
var Range = acequire("../../range").Range;
var BaseFoldMode = acequire("./fold_mode").FoldMode;
var FoldMode = exports.FoldMode = function(commentRegex) {
if (commentRegex) {
@ -882,17 +884,17 @@ oop.inherits(FoldMode, BaseFoldMode);
});
ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"], function(require, exports, module) {
ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"], function(acequire, exports, module) {
"use strict";
var oop = require("../lib/oop");
var TextMode = require("./text").Mode;
var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules;
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var Range = require("../range").Range;
var WorkerClient = require("../worker/worker_client").WorkerClient;
var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
var CStyleFoldMode = require("./folding/cstyle").FoldMode;
var oop = acequire("../lib/oop");
var TextMode = acequire("./text").Mode;
var JavaScriptHighlightRules = acequire("./javascript_highlight_rules").JavaScriptHighlightRules;
var MatchingBraceOutdent = acequire("./matching_brace_outdent").MatchingBraceOutdent;
var Range = acequire("../range").Range;
var WorkerClient = acequire("../worker/worker_client").WorkerClient;
var CstyleBehaviour = acequire("./behaviour/cstyle").CstyleBehaviour;
var CStyleFoldMode = acequire("./folding/cstyle").FoldMode;
var Mode = function() {
this.HighlightRules = JavaScriptHighlightRules;

@ -1,3 +1,12 @@
var $ = require('jquery');
var EthJSVM = require('ethereumjs-vm');
var Trie = require('merkle-patricia-tree');
var ethJSUtil = require('ethereumjs-util');
var EthJSTX = require('ethereumjs-tx');
var EthJSAccount = require('ethereumjs-account');
var ethABI = require('ethereumjs-abi');
var web3 = require('./web3-adapter.js');
function UniversalDApp (contracts, options) {
this.options = options || {};
this.$el = $('<div class="udapp" />');
@ -9,9 +18,9 @@ function UniversalDApp (contracts, options) {
} else if (options.vm) {
this.accounts = {}
this.BN = EthJS.BN;
this.stateTrie = new EthJS.Trie();
this.vm = new EthJS.VM(this.stateTrie);
this.BN = ethJSUtil.BN;
this.stateTrie = new Trie();
this.vm = new EthJSVM(this.stateTrie);
this.addAccount('3cd7232cd6f3fc66a57a6bedc1a8ed6c228fff0a327e169c2bcc5e869ed49511')
this.addAccount('2ac6c190b09897cd8987869cc7b918cfea07ee82038d492abce033c75c1b1d0c')
@ -27,9 +36,9 @@ function UniversalDApp (contracts, options) {
UniversalDApp.prototype.addAccount = function (privateKey, balance) {
if (this.accounts) {
privateKey = new Buffer(privateKey, 'hex')
var address = EthJS.Util.privateToAddress(privateKey);
var address = ethJSUtil.privateToAddress(privateKey);
var account = new EthJS.Account();
var account = new EthJSAccount();
account.balance = balance || 'f00000000000000001';
this.vm.stateManager.trie.put(address, account.serialize());
@ -175,7 +184,7 @@ UniversalDApp.prototype.getInstanceInterface = function (contract, address, $tar
$.each(abi, function(i, funABI) {
if (funABI.type !== 'event') return;
var hash = EthJS.ABI.eventID(funABI.name, funABI.inputs.map(function(item) { return item.type }))
var hash = ethABI.eventID(funABI.name, funABI.inputs.map(function(item) { return item.type }))
eventABI[hash.toString('hex')] = { event: funABI.name, inputs: funABI.inputs };
});
@ -191,8 +200,8 @@ UniversalDApp.prototype.getInstanceInterface = function (contract, address, $tar
var types = abi.inputs.map(function (item) {
return item.type;
});
decoded = EthJS.ABI.rawDecode(types, log[2]);
decoded = EthJS.ABI.stringify(types, decoded)
decoded = ethABI.rawDecode(types, log[2]);
decoded = ethABI.stringify(types, decoded)
} catch (e) {
decoded = '0x' + log[2].toString('hex');
}
@ -392,10 +401,10 @@ UniversalDApp.prototype.getCallButton = function(args) {
}
// decode data
var decodedObj = EthJS.ABI.rawDecode(outputTypes, result.vm.return);
var decodedObj = ethABI.rawDecode(outputTypes, result.vm.return);
// format decoded data
decodedObj = EthJS.ABI.stringify(outputTypes, decodedObj);
decodedObj = ethABI.stringify(outputTypes, decodedObj);
for (var i = 0; i < outputTypes.length; i++) {
var name = args.abi.outputs[i].name;
if (name.length > 0) {
@ -551,7 +560,7 @@ UniversalDApp.prototype.runTx = function( data, args, cb) {
try {
var address = this.options.getAddress ? this.options.getAddress() : this.getAccounts()[0];
var account = this.accounts[address];
var tx = new EthJS.Tx({
var tx = new EthJSTX({
nonce: new Buffer([account.nonce++]), //@todo count beyond 255
gasPrice: 1,
gasLimit: 3000000000, //plenty
@ -566,3 +575,5 @@ UniversalDApp.prototype.runTx = function( data, args, cb) {
}
}
}
module.exports = UniversalDApp;

@ -0,0 +1,11 @@
// This mainly extracts the provider that might be
// supplied through mist.
var Web3 = require("web3");
if (typeof web3 !== 'undefined')
web3 = new Web3(web3.currentProvider);
else
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
module.exports = web3;
Loading…
Cancel
Save