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:
Parity Dev Tools
By Tomasz Drwięga
Parity Dev Tools
- 2,431