10 KiB
What is embark
Embark is a framework that allows you to easily develop and deploy DApps.
With Embark you can:
- 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.
- Use any build pipeline or tool you wish, including grunt and meteor. (for 1.x, plugins coming soon for 2.x series)
- Do Test Driven Development with Contracts using Javascript.
- Easily deploy to & use decentralized systems such as IPFS.
- Keep track of deployed contracts, deploy only when truly needed.
- Manage different chains (e.g testnet, private net, livenet)
- Quickly create advanced DApps using multiple contracts that can interact with decentralized infrastructure for storage and comunication.
Installation
Requirements: geth (1.4.4 or higher), node (5.0.0) and npm Optional: serpent (develop) if using contracts with Serpent, testrpc or ethersim if using the simulator or the test functionality. Further: depending on the dapp stack you choose: IPFS
$ npm -g install embark
# If you plan to use the simulator instead of a real ethereum node.
$ npm -g install testrpc
See Complete Installation Instructions.
Usage - Demo
You can easily create a sample working DApp with the following:
$ embark demo
$ cd embark_demo
To run a ethereum rpc simulator simply run:
$ embark simulator
Or Alternatively, you can run a REAL ethereum node for development purposes:
$ embark blockchain
By default embark blockchain will mine a minimum amount of ether and will only mine when new transactions come in. This is quite usefull to keep a low CPU. The option can be configured at config/blockchain.json
Then, in another command line:
$ embark run
This will automatically deploy the contracts, update their JS bindings and deploy your DApp to a local server at http://localhost:8000
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.
Dashboard
Embark 2 comes with a terminal dashboard.
The dashboard will tell you the state of your contracts, the enviroment you are using, and what embark is doing at the moment.
available services
Available Services will display the services available to your dapp in green, if one of these is down then it will be displayed in red.
logs and console
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.
Creating a new DApp
If you want to create a blank new app.
$ embark new AppName
$ cd AppName
DApp Structure
app/
|___ contracts/ #solidity or serpent contracts
|___ html/
|___ css/
|___ js/
config/
|___ blockchain.json #environments configuration
|___ contracts.json #contracts configuration
test/
|___ #contracts tests
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
Using Contracts
Embark will automatically take care of deployment for you and set all needed JS bindings. For example, the contract below:
# app/contracts/simple_storage.sol
contract SimpleStorage {
uint public storedData;
function SimpleStorage(uint initialValue) {
storedData = initialValue;
}
function set(uint x) {
storedData = x;
}
function get() constant returns (uint retVal) {
return storedData;
}
}
Will automatically be available in Javascript as:
# app/js/index.js
SimpleStorage.set(100);
SimpleStorage.get();
SimpleStorage.storedData();
You can specify for each contract and environment its gas costs and arguments:
# config/contracts.json
{
"development": {
"gas": "auto",
"contracts": {
"SimpleStorage": {
"args": [
100
]
}
}
}
}
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.
# config/contracts.json
{
...
"development": {
"contracts": {
"SimpleStorage": {
"args": [
100,
$MyStorage
]
},
"MyStorage": {
"args": [
"initial string"
]
},
"MyMainContract": {
"args": [
$SimpleStorage
]
}
}
}
...
}
You can now deploy many instances of the same contract. e.g
# config/contracts.json
{
"development": {
"contracts": {
"Currency": {
"deploy": false,
"args": [
100
]
},
"Usd": {
"instanceOf": "Currency",
"args": [
200
]
},
"MyCoin": {
"instanceOf": "Currency",
"args": [
200
]
}
}
}
}
...
Contracts addresses can be defined, If an address is defined the contract wouldn't be deployed but its defined address will be used instead.
# config/contracts.json
{
...
"development": {
"contracts": {
"UserStorage": {
"address": "0x123456"
},
"UserManagement": {
"args": [
"$UserStorage"
]
}
}
}
...
}
EmbarkJS
EmbarkJS is a javascript library meant to abstract and facilitate the development of DApps.
promises
methods in EmbarkJS contracts will be converted to promises.
var myContract = new EmbarkJS.Contract({abi: abiObject, address: "0x123"});
myContract.get().then(function(value) { console.log("value is " + value.toNumber) });
deployment
Client side deployment will be automatically available in Embark for existing contracts:
var myContract = new EmbarkJS.Contract({abi: abiObject, code: code});
myContract.deploy().then(function(address) {});
or it can be manually definied as
var myContract = new EmbarkJS.Contract({abi: abiObject, code: code});
myContract.deploy().then(function(address) {});
EmbarkJS - Storage
initialization
The current available storage is IPFS. it can be initialized as
EmbarkJS.Storage.setProvider('ipfs',{server: 'localhost', port: '5001'})
Saving Text
EmbarkJS.Storage.saveText("hello world").then(function(hash) {});
Retrieving Data/Text
EmbarkJS.Storage.get(hash).then(function(content) {});
Uploading a file
<input type="file">
var input = $("input[type=file"]);
EmbarkJS.Storage.uploadFile(input).then(function(hash) {});
Generate URL to file
EmbarkJS.Storage.getUrl(hash);
EmbarkJS - Communication
initialization
The current available communication is Whisper.
listening to messages
EmbarkJS.Messages.listenTo({topic: ["achannel", "anotherchannel"]}).then(function(message) { console.log("received: " + message); })
sending messages
you can send plain text
EmbarkJS.Messages.sendMessage({topic: "achannel", data: 'hello world'})
or an object
EmbarkJS.Messages.sendMessage({topic: "achannel", data: {msg: 'hello world'}})
Tests
You can run specs with embark test
, it will run any test files under test/
.
Embark includes a testing lib to fastly run & test your contracts in a EVM.
# test/simple_storage_spec.js
var assert = require('assert');
var Embark = require('embark-framework');
var EmbarkSpec = Embark.initTests();
var web3 = EmbarkSpec.web3;
describe("SimpleStorage", function() {
before(function(done) {
var contractsConfig = {
"SimpleStorage": {
args: [100]
}
};
EmbarkSpec.deployAll(contractsConfig, done);
});
it("should set constructor value", function(done) {
SimpleStorage.storedData(function(err, result) {
assert.equal(result.toNumber(), 100);
done();
});
});
it("set storage value", function(done) {
SimpleStorage.set(150, function() {
SimpleStorage.get(function(err, result) {
assert.equal(result.toNumber(), 150);
done();
});
});
});
});
Embark uses Mocha by default, but you can use any testing framework you want.
Working with different chains
You can specify which environment to deploy to:
$ embark blockchain production
$ embark run production
The environment is a specific blockchain configuration that can be managed at config/blockchain.json
# config/blockchain.json
...
"livenet": {
"networkType": "livenet",
"rpcHost": "localhost",
"rpcPort": 8545,
"rpcCorsDomain": "http://localhost:8000",
"account": {
"password": "config/production/password"
}
},
...
Structuring Application
Embark is quite flexible and you can configure you're own directory structure using embark.json
# embark.json
{
"contracts": ["app/contracts/**"],
"app": {
"css/app.css": ["app/css/**"],
"js/app.js": ["embark.js", "app/js/**"],
"index.html": "app/index.html"
},
"buildDir": "dist/",
"config": "config/"
}
Deploying to IPFS
To deploy a dapp to IPFS, all you need to do is run a local IPFS node and then run embark ipfs
.
If you want to deploy to the livenet then after configuring you account on config/blockchain.json
on the production
environment then you can deploy to that chain by specifying the environment embark ipfs production
.
LiveReload Plugin
Embark works quite well with the LiveReload Plugin
Donations
If you like Embark please consider donating to 0x8811FdF0F988f0CD1B7E9DE252ABfA5b18c1cDb1