Parity Dev Tools

ETHWaterloo, 14 Oct 2017

Tomasz Drwięga, @tomusdrw

Agenda

  • Parity Features For Users

  • Parity For Developers
  • JSON-RPC
  • Unique Parity APIs
  • JS tooling
    • parity.js (promise-based and subscriptions ready)
    • oo7 - The Bond API (reactive streams)
    • parity-reactive-ui
  • Dapps tutorial

For Users

Loads directly in your browser

$ parity ui --chain=foundation

ERC20 Token Support

Seamless integration with tokens

Certifications

SMS, E-mail, PICOPS (KYC)

Dapps Integration

Let users discover your dapps easily

Browser Extension

Let's you open web3-enabled websites
with Trusted Signer

Mobile Signer

Air-Gapped Cold Wallet

For Devs

Development & Chain

$ parity ui --chain=dev
  • Instant sealing

every transaction creates a block

  • Development account

preconfigured with plenty of ETH

If you need more control start a Proof of Authority chain:

https://github.com/paritytech/parity/wiki/Proof-of-Authority-Chains

Contract development

In-browser development IDE

API compatibility

web3.js-compatible APIs

  • Supports all JSON-RPC methods
    over HTTP, IPC and WebSockets

     
  • Supports PubSub JSON-RPC
    over IPC and WebSockets

Unique Parity APIs

  • Asynchronous signing
    parity_postTransaction/parity_checkRequest
  • Encryption / decryption
    parity_encryptMessage / parity_decryptMessage
  • Account naming / default account
    parity_accountsInfo / parity_defaultAccount
  • Generic PubSub
    parity_subscribe("eth_accounts", [])

Certification Interface

  • SMS-verified accounts
  • E-mail-verified accounts
  • PICOPS-verified accounts (KYC)

Certification Interface

contract Certifier {
	event Confirmed(address indexed who);
	event Revoked(address indexed who);

	function certified(address _who) 
            constant returns (bool);
	function get(address _who, string _field)
            constant returns (bytes32);
	function getAddress(address _who, string _field)
            constant returns (address);
	function getUint(address _who, string _field)
            constant returns (uint);
}

SMS / Email Cert. API

Secret Store

On-chain ACL to encrypted documents without a need to trust a 3rd party.

Secret Store

 

Blockchain

 

 

IPFS*

 

 

Key

Server 1

 

 

Key

Server 2

 

 

Key

Server 3

 

Owner requests a document  encryption key

(AES)

Secret Store

 

Blockchain

 

 

IPFS*

 

 

Key

Server 1

 

 

Key

Server 2

 

 

Key

Server 3

 

KeyServers store the encrypted (EcElGamal)

document key shares.
m-of-n is required to recover the doc key.

Secret Store

 

Blockchain

 

 

IPFS*

 

 

Key

Server 1

 

 

Key

Server 2

 

 

Key

Server 3

 

Owner encrypts (AES) the document and stores it in IPFS 

Secret Store

 

Blockchain

 

 

IPFS*

 

 

Key

Server 1

 

 

Key

Server 2

 

 

Key

Server 3

 

Owner authorizes the User to access the file 

Secret Store

 

Blockchain

 

 

IPFS*

 

 

Key

Server 1

 

 

Key

Server 2

 

 

Key

Server 3

 

The User requests access to the document

Secret Store

 

Blockchain

 

 

IPFS*

 

 

Key

Server 1

 

 

Key

Server 2

 

 

Key

Server 3

 

Key Servers check permissons on the blockchain

Secret Store

 

Blockchain

 

 

IPFS*

 

 

Key

Server 1

 

 

Key

Server 2

 

 

Key

Server 3

 

Encrypted Key parts are returned to the user

Secret Store

 

Blockchain

 

 

IPFS*

 

 

Key

Server 1

 

 

Key

Server 2

 

 

Key

Server 3

 

The User recovers
the key

(decrypt and some EC some math)

Secret Store

 

Blockchain

 

 

IPFS*

 

 

Key

Server 1

 

 

Key

Server 2

 

 

Key

Server 3

 

The Users requests encrypted document and decrypts it with recovered key.

JS Toolkit

@parity/parity.js

A web3.js replacement

import {Api} from '@parity/parity.js'

// Initialization
let api = (typeof(window.parity) !== 'undefined') ? parity.api : null
if (!api) {
    const transport = new Api.Transport.Http('http://localhost:8545')
    api = new Api(transport)
}

// Promise based API
api.eth.coinbase()
  .then(coinbase => console.log(`The coinbase is ${coinbase}`))

Use @parity/api for node.js

Promise-based

import {Api} from '@parity/parity.js'

let api = (typeof(window.parity) !== 'undefined') ? parity.api : null
if (!api) {
    const transport = new Api.Transport.Http('http://localhost:8545')
    api = new Api(transport)
}

// Contracts support
const abi = [
    { name: 'callMe', inputs: [
        { type: 'bool', ...}, { type: 'string', ...}
    ]}, ...
]
const address = '0x123456...9abc'
const contract = new api.newContract(abi, address)

// Calling a constant method
contract.instance
  .callMe
  .call({ gas: 21000 }, [true, 'someString'])
  // ^^ or estimateGas or postTransaction 
  .then(result => console.log(`the result was ${result}`))

Contract support

import {Api} from '@parity/parity.js'

let api = (typeof(window.parity) !== 'undefined') ? parity.api : null
if (!api) {
    // Make sure to use WebSockets transport
    const transport = new Api.Transport.Ws('ws://localhost:8546')
    api = new Api(transport)
}


// Subscriptions API
api.pubsub.eth
  .coinbase((err, coinbase) => {
    console.log(`The coinbase is ${coinbase}`)
  })
  .then(subscriptionId => {
    console.log(`Subscription id: ${subscriptionId}`)
  })

Pub-Sub

oo7

The Bond API

// npm i oo7
import {TimeBond} from 'oo7'


// Initialize the bond
const bond = new TimeBond()
bond
    .map(t => new Date(t))
    .tie(date => console.log(`${date}`))
    // Wed Oct 11 2017 12:14:56 GMT+0200 (CEST)

Time Bond

// npm i oo7
import {Bond} from 'oo7'


// Initialize the bond
const bond = new Bond()
bond
    .map(t => new Date(t))
    .tie(date => console.log(`${date}`))
    // Wed Oct 11 2017 12:14:56 GMT+0200 (CEST)


// Trigger changes
setInterval(() => {
  bond.changed(Date.now())
}, 2000)


Time Bond

// npm i oo7
import {Bond, TimeBond} from 'oo7'


const bond = new Bond()
bond
    .map(t => new Date(t))
    .tie(date => console.log(`${date}`))
setInterval(() => {
  bond.changed(Date.now())
}, 2000)

const timeBond = new TimeBond()
timeBond
    .map(t => new Date(t))
    .tie(date => console.log(`${date}`))

// Triggered when any bond has a new value.
Bond.all([bond, timeBond])
    .tie(data => console.log('Result: ', data))
    // Result: [1507716953099, 1507716953000]

Bond.all

oo7-parity

Bonds for Ethereum

// npm i oo7-parity
import {Bonds} from 'oo7-parity'

const bonds = Bonds(/* Optional Transport */)

// Process a stream of latest block numbers
bonds.blockNumber
    .map(b => `Current block: ${b}`)
    .tie(console.log) // Current block: 4512345

Bonds for Ethereum

// npm i oo7-parity
import {Bonds, hexToAscii} from 'oo7-parity'

const bonds = Bonds()

// A bond for latest block extra data
bonds.blocks[bonds.blockNumber]
    .extraData
    .map(hexToAscii)
    .tie(console.log) // Parity.1.7

Bonds for Ethereum

Auto dereferencing

You can compose and dereference bonds

// npm i oo7-parity
import {Bonds, formatBalance} from 'oo7-parity'

const bonds = Bonds()

bonds.balance(bonds.me)
    .map(formatBalance)
    .tie(console.log) // 4.45 ETH

Bonds for Ethereum

Getting balance of current default account

// npm i oo7-parity
import {Bonds, formatBalance} from 'oo7-parity'

const bonds = Bonds()

// take a transaction
const tx = bonds.transaction('0x907902e933378e0063400845d2361481785354546d977b0b27bba5825415c551')
const contractAddress = tx.to

// create an instance of contract
bonds.makeContract(contractAddress, [
    {"constant": true,"inputs": [{"name": "_owner","type": "address"}],
      "name": "balanceOf",
      "outputs": [{"name": "balance","type": "uint256"}],"payable": false,"type": "function"
    }
])
// call balanceOf
  .balanceOf(tx.from)
  .map(formatBalance)
  .tie(b => console.log(`Balance: ${b}`)) // 23.51 Mether

Bonds for Ethereum

Querying a contract

// npm i oo7-parity
import {Bonds, formatBalance} from 'oo7-parity'

const bonds = Bonds()

const contractAddress = '0xff..ff'
const recipient = '0x00..00'
bonds.makeContract(contractAddress, [/* abi */])
  .transfer(recipient, 5, bonds.me)
  .tie(b => {
    if (s.failed) { 
        console.log(`transfer failed: ${s.failed}`)
    } else if (s.confirmed) {
        console.log(`transfer completed at #${s.confirmed.blockNumber}`)
    } else {
        return
    }
    b.untie()
  })

Bonds for Ethereum

Sending a transaction

oo7-react

React support for Bonds

import ReactDOM from 'react-dom'
import React, { Component } from 'react'

// Import reactive element
import {Rspan} from 'oo7-react'
import {Bonds, formatBalance} from 'oo7-parity'

const bond = new Bond()

class App extends Component {
  render() {
    // Simply render bonds
    return (
      <div>
          <Rspan>
            {bonds.me} has 
            {bonds.balance(bonds.me).map(formatBalance)}
          </Rspan>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.querySelector('body'))

oo7-react

import ReactDOM from 'react-dom'
import React, { Component } from 'react'

import {Hash} from 'oo7-react'
import {Bonds} from 'oo7-parity'

const bonds = Bonds();

class App extends React.Component {
  render () {
    const background = bonds.me
        .map(x => x.startsWith('0x00') ? 'red': 'blue')

    return (
        <Hash
          style={{ background }}
          value={bonds.me}
        />
    )
  }
}

ReactDOM.render(<App />, document.body)

oo7-react

Reactive attributes

import {ReactiveComponent} from 'oo7-react'
import {Bonds} from 'oo7-parity'

class DateFormatter extends ReactiveComponent {
    constructor() {
        // Tell the object to look out for 'date' prop
        // and keep the 'date' state up to date.
        super(['date'])
    }
    render() {
        return this.state.date === null
            ? <div>Date unknown</div>
            : <div>The date is {this.state.date}</div>
    }
}

const bonds = Bonds();
ReactDOM.render(
    <DateFormatter date={bonds.head.timestamp} />,
    document.body
)

oo7-react

Build your own reactive components

parity-reactive-ui

React components

import ReactDOM from 'react-dom'
import React, { Component } from 'react'
import {Bonds} from 'oo7-parity'
import {Hash} from 'oo7-react'
import {AccountIcon} from 'parity-reactive-ui'

const bonds = Bonds();

class App extends React.Component {
  render () {
    const background = bonds.me
        .map(x => x.startsWith('0x00') ? 'red': 'blue')

    return (
        <AccountIcon address={bonds.me} />
        <Hash
          style={{ background }}
          value={bonds.me}
        />
    )
  }
}
ReactDOM.render(<App />, document.body)

Account Icon

Other components

  • HashBond, UrlBond, BalanceBond, AddressInputBond
    Ethereum-specific input components
  • SigningButton, TransactButton
    Buttons for signing and sending transactions with progress status

* Still work in progress

Parity Dapp Tutorial

Complete guide to dapps

Questions?

jobs@parity.io
or leave your e-mail:

http://bit.ly/parity-ethwaterloo

Parity Dev Tools

By Tomasz Drwięga

Parity Dev Tools

  • 2,431