Dapps Development Intro
Tomasz Drwięga
@tomusdrw
http://tomusdrw.github.io/parity-dapp-example
http://localhost:8080/d39f5f496d13282fe84d95299c4a00b929eb49183e773840b857c1167c094599/
How to get Parity?
- https://github.com/ethcore/parity/releases
 - https://ethcore.io
 - git clone https://github.com/ethcore/parity.git
 
Let's start!
# Check parity version
$ parity --version
2016-11-26 20:09:42  main INFO parity  Parity
  version Parity/v1.5.0-unstable-6d6a2a8-20161124/x86_64-linux-gnu/rustc1.13.0
# Run Parity and connect to new Testnet
$ parity ui --chain ropsten
# `ui` command should open the browser for youTypes of applications
- Builtins - shiped with Parity
 - Local - on your file system
 - Network - fetched from the network
 
How to create a local dapp?
# Go to Dapps location
$ cd ~/.parity/dapps/
# Create a new directory...
$ mkdir my-dapp
# ... and index.html file
$ echo "<h1>Hello World!</h1>" > my-dapp/index.html
# (restart Parity)
$ open http://localhost:8080/my-dapp/Let's do some RPC calls
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>My First Dapp</title>
    <!-- Import parity.js -->
    <script src="/parity-utils/parity.js"></script>
    <!-- Import web3.js -->
    <script src="/parity-utils/web3.js"></script>
    <!-- or fire RPC calls to `/rpc/` with your favourite library -->
  </head>
  <body>
    <h1>Hello World</h1>
    <script>
        window.web3.eth.getAccounts((err, accounts) => {
            console.log(accounts);
        });
        window.parity.api.eth.accounts()
            .then(accounts => {
                console.log(accounts);
            });
    </script>
  </body>
</html>Why did we make parity.js?
- Promise-based
 - No sync requests
 - More modular
 - Less "magic" (no conversions)
 - Easier to maintain/extend
 
React
# Install create-react-app
$ npm install create-react-app -g # sudo?
# Start React app
$ create-react-app react-app
# Start a development server
$ cd react-app
$ npm startAdd the proxy
{
  "name": "react-dapp",
  "version": "0.1.0",
  "private": true,
  "devDependencies": {
    "react-scripts": "0.7.0"
  },
  "proxy": "http://localhost:8080",
  "dependencies": {
    "react": "^15.4.1",
    "react-dom": "^15.4.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}Icon?
# Create icon.png file
$ curl \
    https://raw.githubusercontent.com/tomusdrw/eth.wallet/master/icon.png \
    -O ~/.parity/my-dapp/icon.pngName and description?
# ~/.parity/dapps/my-dapp/manifest.json
{
  "id": "my-dapp",
  "name": "My Dapp",
  "description": "My First Parity Dapp",
  "version": "0.0.1",
  "author": "todr <tomasz@ethcore.io>",
  "iconUrl": "icon.png"
}Making the dapp public.
- Push to Github
 - Register Content
 - Add to DappReg
 
Get some Ropsten eth from:
http://icarus.parity.io/make_it_rain/<address>
Parity fetchable content

http://localhost:8080/99506fde795f7faeb5706a16742813ed7ee0d17f7ae67bf1c210023475d8969e/
Registration
- Register your Dapp as "Content Bundle"
	
- Use your Github slug
 - Use specific commit hash
 
 - Register your icon as "File Link"
 - Register your manifest as "File Link"
 
You can now access the dapp using hash of content bundle!
Make your dapp discoverable
# DappRegistry dapp is currently in development
# and was not released yet.
# We need to get the bleeding edge UI for this:)
# Start Parity in UI-development mode
$ parity --chain ropsten --ui-no-validation
# Clone Parity repo
$ git clone https://github.com/ethcore/parity.git
# Run UI
$ cd parity/js
$ npm i
$ npm startLook for "Dapp Registration"
(click "Edit" if it's not visible)
Make your dapp discoverable
Manual approach
// Watch contract (Ropsten)
0x724A8602fc0C2b346f8eC56Df2913710742d3fD0
// ABI
[{"constant":true,"inputs":[{"name":"_id","type":"bytes32"},{"name":"_key","type":"bytes32"}],"name":"meta","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"count","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_new","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"bytes32"}],"name":"unregister","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"bytes32"}],"name":"get","outputs":[{"name":"id","type":"bytes32"},{"name":"owner","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"bytes32"},{"name":"_key","type":"bytes32"},{"name":"_value","type":"bytes32"}],"name":"setMeta","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"drain","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"bytes32"},{"name":"_owner","type":"address"}],"name":"setDappOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"fee","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_index","type":"uint256"}],"name":"at","outputs":[{"name":"id","type":"bytes32"},{"name":"owner","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"bytes32"}],"name":"register","outputs":[],"payable":true,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"bytes32"},{"indexed":true,"name":"key","type":"bytes32"},{"indexed":false,"name":"value","type":"bytes32"}],"name":"MetaChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"bytes32"},{"indexed":true,"name":"owner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"bytes32"},{"indexed":true,"name":"owner","type":"address"}],"name":"Registered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"bytes32"}],"name":"Unregistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"old","type":"address"},{"indexed":true,"name":"current","type":"address"}],"name":"NewOwner","type":"event"}]
// Register new ID
register(sha3("App name"))
// Register manifest and icon
setMeta(sha3("App name"), asHex("MANIFEST"), <manifest hash>)
setMeta(sha3("App name"), asHex("IMG"), <icon hash>)
// Register content
setMeta(sha3("App name"), asHex("CONTENT"), <content bundle hash>)
Now your turn!
- Task 1: Create Local Dapp
	
- Basic
		
- Display latest block number
 - Display number of transactions in last 5 blocks
 - Display sum and avg of value transfered (last 5 blocks)
 
 - Advanced
		
- Display transactions from local queue
(see api.parity.pendingTransactions()) - Display data from DappRegistry
(interact with contract) 
 - Display transactions from local queue
 - Extra
		
- Use React (create-react-app)
 
 
 - Basic
		
 - Task 2: Icon and Manifest
	
- Add Icon and Manifest and register as "File Link"
 
 - Task 3: Publish Dapp
	
- Publish to Github and register as "Content Bundle"
 
 - Task 4: Add to the Reg
	
- Make your dapp visible on Parity's home screen
 
 
Useful links
- Dapp Example
https://github.com/tomusdrw/parity-dapp-example - Writing Dapps
https://github.com/ethcore/parity/wiki/Writing-Dapps-for-Parity - Dapps Registry
https://github.com/ethcore/parity/wiki/Parity-dapp-registry 
Parity Dapps
By Tomasz Drwięga
Parity Dapps
- 926