1 | ![Embark](https://github.com/iurimatias/embark-framework/raw/develop/logo.png)
|
2 |
|
3 | [![npm](https://img.shields.io/npm/dm/embark.svg)](https://npmjs.com/package/embark)
|
4 | [![Gitter](https://img.shields.io/gitter/room/iurimatias/embark-framework.svg)](https://gitter.im/iurimatias/embark-framework)
|
5 | [![Build
|
6 | Status](https://travis-ci.org/iurimatias/embark-framework.svg?branch=develop)](https://travis-ci.org/iurimatias/embark-framework)
|
7 | [![Code Climate](https://codeclimate.com/github/iurimatias/embark-framework/badges/gpa.svg)](https://codeclimate.com/github/iurimatias/embark-framework)
|
8 |
|
9 | What is Embark
|
10 | ======
|
11 |
|
12 | Embark is a framework that allows you to easily develop and deploy Decentralized Applications (DApps).
|
13 |
|
14 | A Decentralized Application is a serverless html5 application that uses one or more decentralized technologies.
|
15 |
|
16 | Embark currently integrates with EVM blockchains (Ethereum), Decentralized Storages (IPFS), and Decentralized communication platforms (Whisper and Orbit). Swarm is supported for deployment.
|
17 |
|
18 | With Embark you can:
|
19 |
|
20 | **Blockchain (Ethereum)**
|
21 | * Automatically deploy contracts and make them available in your JS code. Embark watches for changes, and if you update a contract, Embark will automatically redeploy the contracts (if needed) and the dapp.
|
22 | * Contracts are available in JS with Promises.
|
23 | * Do Test Driven Development with Contracts using Javascript.
|
24 | * Keep track of deployed contracts; deploy only when truly needed.
|
25 | * Manage different chains (e.g testnet, private net, livenet)
|
26 | * Easily manage complex systems of interdependent contracts.
|
27 |
|
28 | **Decentralized Storage (IPFS)**
|
29 | * Easily Store & Retrieve Data on the DApp through EmbarkJS. Including uploading and retrieving files.
|
30 | * Deploy the full application to IPFS or Swarm.
|
31 |
|
32 |
|
33 | **Decentralized Communication (Whisper, Orbit)**
|
34 | * Easily send/receive messages through channels in P2P through Whisper or Orbit.
|
35 |
|
36 | **Web Technologies**
|
37 | * Integrate with any web technology including React, Foundation, etc..
|
38 | * Use any build pipeline or tool you wish, including grunt, gulp and webpack.
|
39 |
|
40 | Table of Contents
|
41 | ======
|
42 | * [Installation](#installation)
|
43 | * [Usage Demo](#usage---demo)
|
44 | * [Dashboard](#dashboard)
|
45 | * [Creating a new DApp](#creating-a-new-dapp)
|
46 | * [Libraries and APIs available](#libraries-and-languages-available)
|
47 | * [Using and Configuring Contracts](#using-contracts)
|
48 | * [EmbarkJS](#embarkjs)
|
49 | * [EmbarkJS - Storage (IPFS)](#embarkjs---storage)
|
50 | * [EmbarkJS - Communication (Whisper/Orbit)](#embarkjs---communication)
|
51 | * [Testing Contracts](#tests)
|
52 | * [Working with different chains](#working-with-different-chains)
|
53 | * [Custom Application Structure](#structuring-application)
|
54 | * [Deploying to IPFS](#deploying-to-ipfs-and-swarm)
|
55 | * [Extending Functionality with Plugins](#plugins)
|
56 | * [Donations](#donations)
|
57 |
|
58 | Installation
|
59 | ======
|
60 | Requirements: geth (1.6.7 or higher recommended), node (6.9.1 or higher is recommended) and npm
|
61 | Optional: testrpc (3.0 or higher) if using the simulator
|
62 | Further: depending on the dapp stack you choose: [IPFS](https://ipfs.io/)
|
63 |
|
64 | ```Bash
|
65 | $ npm -g install embark
|
66 |
|
67 | # If you plan to use the simulator instead of a real ethereum node.
|
68 | $ npm -g install ethereumjs-testrpc
|
69 | ```
|
70 |
|
71 | See [Complete Installation Instructions](https://github.com/iurimatias/embark-framework/wiki/Installation).
|
72 |
|
73 |
|
74 | **updating from Embark 1**
|
75 |
|
76 | Embark's npm package has changed from ```embark-framework``` to ```embark```, this sometimes can create conflicts. To update first uninstall embark-framework 1 to avoid any conflicts. ```npm uninstall -g embark-framework``` then ```npm install -g embark```
|
77 |
|
78 | Usage - Demo
|
79 | ======
|
80 |
|
81 | ![Embark Demo screenshot](http://i.imgur.com/a9ddSjn.png)
|
82 |
|
83 | You can easily create a sample working DApp with the following:
|
84 |
|
85 | ```Bash
|
86 | $ embark demo
|
87 | $ cd embark_demo
|
88 | ```
|
89 |
|
90 | You can run a REAL ethereum node for development purposes:
|
91 |
|
92 | ```Bash
|
93 | $ embark blockchain
|
94 | ```
|
95 |
|
96 | Alternatively, to use an ethereum rpc simulator simply run:
|
97 |
|
98 | ```Bash
|
99 | $ embark simulator
|
100 | ```
|
101 |
|
102 | By default Embark blockchain will mine a minimum amount of ether and will only mine when new transactions come in. This is quite useful to keep a low CPU. The option can be configured at ```config/blockchain.json```. Note that running a real node requires at least 2GB of free ram, please take this into account if running it in a VM.
|
103 |
|
104 | Then, in another command line:
|
105 |
|
106 | ```Bash
|
107 | $ embark run
|
108 | ```
|
109 | This will automatically deploy the contracts, update their JS bindings and deploy your DApp to a local server at http://localhost:8000
|
110 |
|
111 | Note that if you update your code, it will automatically be re-deployed, contracts included. There is no need to restart embark, refreshing the page on the browser will do.
|
112 |
|
113 | Dashboard
|
114 | =====
|
115 |
|
116 | Embark 2 comes with a terminal dashboard.
|
117 |
|
118 | ![Dashboard](http://i.imgur.com/s4OQZpu.jpg)
|
119 |
|
120 | The dashboard will tell you the state of your contracts, the environment you are using, and what Embark is doing at the moment.
|
121 |
|
122 | **available services**
|
123 |
|
124 | Available Services will display the services available to your dapp in green. If a service is down, then it will be displayed in red.
|
125 |
|
126 | **logs and console**
|
127 |
|
128 | There is a console at the bottom which can be used to interact with contracts or with Embark itself. Type ```help``` to see a list of available commands. More commands will be added with each version of Embark.
|
129 |
|
130 | Creating a new DApp
|
131 | ======
|
132 |
|
133 | If you want to create a blank new app:
|
134 |
|
135 | ```Bash
|
136 | $ embark new AppName
|
137 | $ cd AppName
|
138 | ```
|
139 |
|
140 | DApp Structure
|
141 | ======
|
142 |
|
143 | ```Bash
|
144 | app/
|
145 | |___ contracts/ #solidity or serpent contracts
|
146 | |___ html/
|
147 | |___ css/
|
148 | |___ js/
|
149 | config/
|
150 | |___ blockchain.json #rpc and blockchain configuration
|
151 | |___ contracts.json #ethereum contracts configuration
|
152 | |___ storage.json #ipfs configuration
|
153 | |___ communication.json #whisper/orbit configuration
|
154 | |___ webserver.json #dev webserver configuration
|
155 | test/
|
156 | |___ #contracts tests
|
157 | ```
|
158 |
|
159 | Solidity/Serpent files in the contracts directory will automatically be deployed with Embark run. Changes in any files will automatically be reflected in app, changes to contracts will result in a redeployment and update of their JS Bindings
|
160 |
|
161 | Libraries and languages available
|
162 | ======
|
163 |
|
164 | Embark can build and deploy contracts coded in Solidity. It will make them available on the client side using EmbarkJS and Web3.js.
|
165 |
|
166 | Further documentation for these can be found below:
|
167 |
|
168 | * Smart Contracts: [Solidity](https://solidity.readthedocs.io/en/develop/) and [Serpent](https://github.com/ethereum/wiki/wiki/Serpent)
|
169 | * Client Side: [Web3.js](https://github.com/ethereum/wiki/wiki/JavaScript-API) and [EmbarkJS](#embarkjs)
|
170 |
|
171 | Using Contracts
|
172 | ======
|
173 | Embark will automatically take care of deployment for you and set all needed JS bindings. For example, the contract below:
|
174 |
|
175 | ```Javascript
|
176 | # app/contracts/simple_storage.sol
|
177 | pragma solidity ^0.4.17;
|
178 | contract SimpleStorage {
|
179 | uint public storedData;
|
180 |
|
181 | function SimpleStorage(uint initialValue) public {
|
182 | storedData = initialValue;
|
183 | }
|
184 |
|
185 | function set(uint x) public {
|
186 | storedData = x;
|
187 | }
|
188 | function get() view returns (uint retVal) {
|
189 | return storedData;
|
190 | }
|
191 | }
|
192 | ```
|
193 | Will automatically be available in Javascript as:
|
194 |
|
195 | ```Javascript
|
196 | # app/js/index.js
|
197 | SimpleStorage.methods.set(100).send({from: web3.eth.defaultAccount});
|
198 | SimpleStorage.methods.get().call().then(function(value) { console.log(value.toNumber()) });
|
199 | SimpleStorage.methods.storedData().then(function(value) { console.log(value.toNumber()) });
|
200 | ```
|
201 |
|
202 | You can specify for each contract and environment its gas costs and arguments:
|
203 |
|
204 | ```Json
|
205 | # config/contracts.json
|
206 | {
|
207 | "development": {
|
208 | "gas": "auto",
|
209 | "contracts": {
|
210 | "SimpleStorage": {
|
211 | "args": [
|
212 | 100
|
213 | ]
|
214 | }
|
215 | }
|
216 | }
|
217 | }
|
218 | ```
|
219 |
|
220 | If you are using multiple contracts, you can pass a reference to another contract as ```$ContractName```, Embark will automatically replace this with the correct address for the contract.
|
221 |
|
222 |
|
223 | ```Json
|
224 | # config/contracts.json
|
225 | {
|
226 | ...
|
227 | "development": {
|
228 | "contracts": {
|
229 | "SimpleStorage": {
|
230 | "args": [
|
231 | 100,
|
232 | "$MyStorage"
|
233 | ]
|
234 | },
|
235 | "MyStorage": {
|
236 | "args": [
|
237 | "initial string"
|
238 | ]
|
239 | },
|
240 | "MyMainContract": {
|
241 | "args": [
|
242 | "$SimpleStorage"
|
243 | ]
|
244 | }
|
245 | }
|
246 | }
|
247 | ...
|
248 | }
|
249 | ```
|
250 |
|
251 | You can now deploy many instances of the same contract. e.g
|
252 |
|
253 |
|
254 | ```Json
|
255 | # config/contracts.json
|
256 | {
|
257 | "development": {
|
258 | "contracts": {
|
259 | "Currency": {
|
260 | "deploy": false,
|
261 | "args": [
|
262 | 100
|
263 | ]
|
264 | },
|
265 | "Usd": {
|
266 | "instanceOf": "Currency",
|
267 | "args": [
|
268 | 200
|
269 | ]
|
270 | },
|
271 | "MyCoin": {
|
272 | "instanceOf": "Currency",
|
273 | "args": [
|
274 | 200
|
275 | ]
|
276 | }
|
277 | }
|
278 | }
|
279 | }
|
280 | ...
|
281 | ```
|
282 |
|
283 | Contracts addresses can be defined. If an address is defined, Embark uses the defined address instead of deploying the contract.
|
284 |
|
285 |
|
286 | ```Json
|
287 | # config/contracts.json
|
288 | {
|
289 | ...
|
290 | "development": {
|
291 | "contracts": {
|
292 | "UserStorage": {
|
293 | "address": "0x123456"
|
294 | },
|
295 | "UserManagement": {
|
296 | "args": [
|
297 | "$UserStorage"
|
298 | ]
|
299 | }
|
300 | }
|
301 | }
|
302 | ...
|
303 | }
|
304 | ```
|
305 |
|
306 | You can Also specify which versions of solc and web3.js to use:
|
307 |
|
308 | ```Json
|
309 | # config/contracts.json
|
310 | {
|
311 | ...
|
312 | "development": {
|
313 | "versions": {
|
314 | "web3.js": "1.0.0-beta",
|
315 | "solc": "0.4.17"
|
316 | }
|
317 | }
|
318 | ...
|
319 | }
|
320 | ```
|
321 |
|
322 | You specify which node the contracts should be deploy to and the order of nodes
|
323 | the dapp should connect to. $WEB3 means the dapp will try to use an existing
|
324 | web3 object first if available.
|
325 |
|
326 | ```Json
|
327 | # config/contracts.json
|
328 | {
|
329 | ...
|
330 | "development": {
|
331 | "deployment": {
|
332 | "host": "localhost",
|
333 | "port": 8545,
|
334 | "type": "rpc"
|
335 | },
|
336 | "dappConnection": [
|
337 | "$WEB3",
|
338 | "http://localhost:8545"
|
339 | ]
|
340 | }
|
341 | ...
|
342 | }
|
343 | ```
|
344 |
|
345 | EmbarkJS
|
346 | ======
|
347 |
|
348 | EmbarkJS is a javascript library meant to abstract and facilitate the development of DApps.
|
349 |
|
350 | **promises**
|
351 |
|
352 | ```Javascript
|
353 | var myContract = new EmbarkJS.Contract({abi: abiObject, address: "0x123"});
|
354 | myContract.methods.get().call().then(function(value) { console.log("value is " + value.toNumber) });
|
355 | ```
|
356 |
|
357 | events:
|
358 |
|
359 | ```Javascript
|
360 | myContract.events.eventName({from: web3.eth.accounts}, 'latest').then(function(event) { console.log(event) });
|
361 | ```
|
362 |
|
363 | **deployment**
|
364 |
|
365 | Client side deployment will be automatically available in Embark for existing contracts:
|
366 |
|
367 | ```Javascript
|
368 | SimpleStorage.deploy([args], {options}).then(function(anotherSimpleStorage) {});
|
369 | ```
|
370 |
|
371 | or it can be manually definied as
|
372 |
|
373 | ```Javascript
|
374 | var myContract = new EmbarkJS.Contract({abi: abiObject, code: code});
|
375 | myContract.deploy([args], {options}).then(function(anotherMyContractObject) {});
|
376 | ```
|
377 |
|
378 | so you can define your gas as
|
379 |
|
380 | ```Javascript
|
381 | myContract.deploy([100, "seconde argument"], {gas: 800000}).then(function(anotherMyContractObject) {});
|
382 | ```
|
383 |
|
384 | EmbarkJS - Storage
|
385 | ======
|
386 |
|
387 | **initialization**
|
388 |
|
389 | The current available storage is IPFS. It can be initialized as
|
390 |
|
391 | ```Javascript
|
392 | EmbarkJS.Storage.setProvider('ipfs',{server: 'localhost', port: '5001'})
|
393 | ```
|
394 |
|
395 | **Saving Text**
|
396 |
|
397 | ```Javascript
|
398 | EmbarkJS.Storage.saveText("hello world").then(function(hash) {});
|
399 | ```
|
400 |
|
401 | **Retrieving Data/Text**
|
402 |
|
403 | ```Javascript
|
404 | EmbarkJS.Storage.get(hash).then(function(content) {});
|
405 | ```
|
406 |
|
407 | **Uploading a file**
|
408 |
|
409 | ```HTML
|
410 | <input type="file">
|
411 | ```
|
412 |
|
413 | ```Javascript
|
414 | var input = $("input[type=file"]);
|
415 | EmbarkJS.Storage.uploadFile(input).then(function(hash) {});
|
416 | ```
|
417 |
|
418 | **Generate URL to file**
|
419 |
|
420 | ```Javascript
|
421 | EmbarkJS.Storage.getUrl(hash);
|
422 | ```
|
423 |
|
424 | note: if not using localhost, the cors needs to be set as ```ipfs --json API.HTTPHeaders.Access-Control-Allow-Origin '["your-host-name-port"]```
|
425 |
|
426 | EmbarkJS - Communication
|
427 | ======
|
428 |
|
429 | **initialization**
|
430 |
|
431 | For Whisper (note: currently requires geth 1.6.0 or higher):
|
432 |
|
433 | ```Javascript
|
434 | EmbarkJS.Messages.setProvider('whisper')
|
435 | ```
|
436 |
|
437 | For Orbit:
|
438 |
|
439 | You'll need to use IPFS from master and run it as: ```ipfs daemon --enable-pubsub-experiment```
|
440 |
|
441 | then set the provider:
|
442 |
|
443 | ```Javascript
|
444 | EmbarkJS.Messages.setProvider('orbit', {server: 'localhost', port: 5001})
|
445 | ```
|
446 |
|
447 | **listening to messages**
|
448 |
|
449 | ```Javascript
|
450 | EmbarkJS.Messages.listenTo({topic: ["topic1", "topic2"]}).then(function(message) { console.log("received: " + message); })
|
451 | ```
|
452 |
|
453 | **sending messages**
|
454 |
|
455 | you can send plain text
|
456 |
|
457 | ```Javascript
|
458 | EmbarkJS.Messages.sendMessage({topic: "sometopic", data: 'hello world'})
|
459 | ```
|
460 |
|
461 | or an object
|
462 |
|
463 | ```Javascript
|
464 | EmbarkJS.Messages.sendMessage({topic: "sometopic", data: {msg: 'hello world'}})
|
465 | ```
|
466 |
|
467 | note: array of topics are considered an AND. In Whisper you can use another array for OR combinations of several topics e.g ```["topic1", ["topic2", "topic3"]]``` => ```topic1 AND (topic2 OR topic 3)```
|
468 |
|
469 | Tests
|
470 | ======
|
471 |
|
472 | You can run specs with ```embark test```, it will run any test files under ```test/```.
|
473 |
|
474 | Embark includes a testing lib to rapidly run & test your contracts in a EVM.
|
475 |
|
476 | ```Javascript
|
477 | # test/simple_storage_spec.js
|
478 | describe("SimpleStorage", function() {
|
479 | before(function(done) {
|
480 | this.timeout(0);
|
481 | var contractsConfig = {
|
482 | "SimpleStorage": {
|
483 | args: [100]
|
484 | }
|
485 | };
|
486 | EmbarkSpec.deployAll(contractsConfig, done);
|
487 | });
|
488 |
|
489 | it("should set constructor value", function(done) {
|
490 | SimpleStorage.storedData(function(err, result) {
|
491 | assert.equal(result.toNumber(), 100);
|
492 | done();
|
493 | });
|
494 | });
|
495 |
|
496 | it("set storage value", function(done) {
|
497 | SimpleStorage.set(150, function() {
|
498 | SimpleStorage.get(function(err, result) {
|
499 | assert.equal(result.toNumber(), 150);
|
500 | done();
|
501 | });
|
502 | });
|
503 | });
|
504 |
|
505 | });
|
506 |
|
507 | ```
|
508 |
|
509 | Embark uses [Mocha](http://mochajs.org/) by default, but you can use any testing framework you want.
|
510 |
|
511 | Working with different chains
|
512 | ======
|
513 | You can specify which environment to deploy to:
|
514 |
|
515 |
|
516 | ```$ embark blockchain livenet```
|
517 |
|
518 | ```$ embark run livenet```
|
519 |
|
520 | The environment is a specific blockchain configuration that can be managed at config/blockchain.json
|
521 |
|
522 | ```Json
|
523 | # config/blockchain.json
|
524 | ...
|
525 | "livenet": {
|
526 | "networkType": "livenet",
|
527 | "rpcHost": "localhost",
|
528 | "rpcPort": 8545,
|
529 | "rpcCorsDomain": "http://localhost:8000",
|
530 | "account": {
|
531 | "password": "config/livenet/password"
|
532 | }
|
533 | },
|
534 | ...
|
535 | ```
|
536 |
|
537 | Structuring Application
|
538 | ======
|
539 |
|
540 | Embark is quite flexible and you can configure your own directory structure using ```embark.json```
|
541 |
|
542 | ```Json
|
543 | # embark.json
|
544 | {
|
545 | "contracts": ["app/contracts/**"],
|
546 | "app": {
|
547 | "css/app.css": ["app/css/**"],
|
548 | "images/": ["app/images/**"],
|
549 | "js/app.js": ["embark.js", "app/js/**"],
|
550 | "index.html": "app/index.html"
|
551 | },
|
552 | "buildDir": "dist/",
|
553 | "config": "config/",
|
554 | "plugins": {}
|
555 | }
|
556 | ```
|
557 |
|
558 | Deploying to IPFS and Swarm
|
559 | ======
|
560 |
|
561 | To deploy a dapp to IPFS, all you need to do is run a local IPFS node and then run ```embark upload ipfs```.
|
562 | If you want to deploy to the livenet then after configuring you account on ```config/blockchain.json``` on the ```livenet``` environment then you can deploy to that chain by specifying the environment ```embark ipfs livenet```.
|
563 |
|
564 | To deploy a dapp to SWARM, all you need to do is run a local SWARM node and then run ```embark upload swarm```.
|
565 |
|
566 | Plugins
|
567 | ======
|
568 |
|
569 | It's possible to extend Embark's functionality with plugins. For example, the following is possible:
|
570 |
|
571 | * plugin to add support for es6, jsx, coffescript, etc (``embark.registerPipeline``)
|
572 | * plugin to add standard contracts or a contract framework (``embark.registerContractConfiguration`` and ``embark.addContractFile``)
|
573 | * plugin to make some contracts available in all environments for use by other contracts or the dapp itself e.g a Token, a DAO, ENS, etc.. (``embark.registerContractConfiguration`` and ``embark.addContractFile``)
|
574 | * plugin to add a libraries such as react or bootstrap (``embark.addFileToPipeline``)
|
575 | * plugin to specify a particular web3 initialization for special provider uses (``embark.registerClientWeb3Provider``)
|
576 | * plugin to create a different contract wrapper (``embark.registerContractsGeneration``)
|
577 | * plugin to add new console commands (``embark.registerConsoleCommand``)
|
578 | * plugin to add support for another contract language such as viper, LLL, etc (``embark.registerCompiler``)
|
579 |
|
580 | For more information on how to develop your own plugin, please see the [plugin documentation](http://embark.readthedocs.io/en/latest/plugins.html)
|
581 |
|
582 | Donations
|
583 | ======
|
584 |
|
585 | If you like Embark, please consider donating to 0xFA239D14c7117C3D2370B2a4c4238534391fadd9
|
586 |
|
\ | No newline at end of file |