Francesco Canessa
@makevoid
Lead Software Developer
Applied Blockchain
Rise London - Blockchain Week '18 - Development Workshop
Generate a Private Key
Derive an Ethereum address
Get the address balance
Sign transansaction
Broadcast transaction
Requirement:
Upgrade or use github:yortus/asyncawait
Alternative: Runkit (https://runkit.com)
$ node -vv7.6+ (at least)v8 is good (aim for v8.9.x)
9 should be ok as well
Check Async-Await support
if you don't have native support, you can use github:yortus/asyncawait
console.log("hello world")
npm init -fynpm install --save bitcore-lib
const bitcore = require('bitcore-lib')const PrivateKey = bitcore.PrivateKeyconst privateKey = new PrivateKey()console.log(privateKey.toString())
const bitcore = require('bitcore-lib')const PrivateKey = bitcore.PrivateKeyconst privateKey = new PrivateKey("711fd1eeecec8bb8c912129466504de109a17e764060c7e5e5b56d3ea0a8aa3b")const publicKey = privateKey.toPublicKey()console.log(publicKey.toString())
const bitcore = require('bitcore-lib')const PrivateKey = bitcore.PrivateKeyconst privateKey = new PrivateKey()const publicKey = privateKey.toPublicKey()console.log(publicKey.toString())const address = publicKey.toAddress().toString()console.log(address)

const Web3 = require('web3')const web3 = new Web3("https://mainnet.infura.io")
npm init -fynpm i --save web3-eth-accountsnpm i --save isomorphic-fetchnpm i --save isomorphic-form-data
Optional:
npm i --save-dev lernanpm i --save ethereum/web3.js#1.0
const Web3 = require('web3')const web3 = new Web3("https://kovan.infura.io")
const Web3 = require('web3')const provUrl = "https://mainnet.infura.io"const provider = new Web3.providers.HttpProvider(provUrl)const web3 = new Web3(provider)
const Accounts = require('web3-eth-accounts')const accounts = new Accounts()
const bitcore = require('bitcore-lib')const PrivateKey = bitcore.PrivateKeyconst Accounts = require('web3-eth-accounts')const accounts = new Accounts()const privateKey = new PrivateKey()const key = `0x${privateKey.toString()}`const account = accounts.privateKeyToAccount(key)console.log(account.address)
const Accounts = require('web3-eth-accounts')const accounts = new Accounts()const account = accounts.create()console.log(account.address)
const Accounts = require('web3-eth-accounts')const accounts = new Accounts()const account = accounts.create()console.log(account.privateKey)
Extra step: save key into private-key.txt
const fs = require('fs')const readFileSync = fs.readFileSyncconst Accounts = require('web3-eth-accounts')const accounts = new Accounts()const key = readFileSync("private-key.txt")const account = accounts.privateKeyToAccount(key)console.log(account.address)
const fs = require('fs')const readFileSync = fs.readFileSyncconst Accounts = require('web3-eth-accounts')const accounts = new Accounts()const key = readFileSync("private-key.txt")const account = accounts.privateKeyToAccount(key)console.log(account.address)
run this again - notice that it will return the same address! :D
https://duckduckgo.com
!qr 0x1234...
tip for future UI - handy QR npm package:
(for testnet)
require('isomorphic-fetch')const getBalance = async (address) => { const balanceUrl = `https://api.etherscan.io/api?module=account&action=balance&address=${address}&tag=latest` let resp = await fetch(balanceUrl) resp = await resp.json() return Number(resp['result'] || 0)}(async () => { const balance = await getBalance("0x738d145faabb1e00cf5a017588a9c0f998318012") console.log(balance)})()
Etherscan API: https://etherscan.io/apis#accounts
const createTx = async ({recipient, account, value}) => { const txData = { value: value, to: recipient, gas: 21000, gasPrice: 5000000000, // 5 gwei from: account.address, // nonce: 1, } const tx = await account.signTransaction(txData) const txRaw = tx.rawTransaction console.log("TX RAW", txRaw) return txRaw}(async () => { const fs = require('fs') const readFileSync = fs.readFileSync const Accounts = require('web3-eth-accounts') const accounts = new Accounts() const key = readFileSync("private-key.txt") const account = accounts.privateKeyToAccount(key) createTx({ account: account, recipient: "0xD9dDF72Ef671261Cb2266B9D924c5980C5186699", value: 100000000000000, // 100 szabo })})()
https://ethgasstation.info - https://converter.murkin.me
For reference:
const createTx = async ({recipient, account, value}) => { const txData = { value: value, to: recipient, gas: 21000, gasPrice: 5000000000, // 5 gwei from: account.address, // nonce: 1, } const tx = await account.signTransaction(txData) const txRaw = tx.rawTransaction console.log("TX RAW", txRaw) return txRaw}(async () => { const fs = require('fs') const readFileSync = fs.readFileSync const Accounts = require('web3-eth-accounts') const accounts = new Accounts() const key = readFileSync("private-key.txt") const account = accounts.privateKeyToAccount(key) createTx({ account: account, recipient: "0xD9dDF72Ef671261Cb2266B9D924c5980C5186699", value: 100000000000000, // 100 szabo })})()
(manual)
programmatically
require('isomorphic-fetch')require('isomorphic-form-data')const broadcastTransaction = async (rawTx) => { const broadcastUrl = "https://api.etherscan.io/api" // ...}const broadcastTransaction = async (rawTx) => { const broadcastUrl = "https://api.etherscan.io/api" const data = new FormData() data.append('module', 'proxy') data.append('action', 'eth_sendRawTransaction') data.append('hex', rawTx) data.append('apikey', '3DQFQQZ51G4M18SW8RDKHIMERD79GYTVEA') // please use your own api key let resp = await fetch(broadcastUrl, { method: "post", body: data, }) resp = await resp.json() c.log("broadcast Tx:", resp) return resp}// ...(async () => { const rawTx = "0xf86a0285012a05f20082520894d9ddf72ef671261cb2266b9d924c5980c5186699865af3107a40008026a0824d7b8b937437feff4ab206a556d599a70ce150ecc6ceeee7174bb5c679e0cea0643e49ae4bb8aae422245b6837997cff4a03714088043afc83deabf03043f253" await broadcastTransaction(rawTx)})()For reference:
require('isomorphic-fetch')require('isomorphic-form-data')const broadcastTransaction = async (rawTx) => { const broadcastUrl = "https://api.etherscan.io/api" const data = new FormData() data.append('module', 'proxy') data.append('action', 'eth_sendRawTransaction') data.append('hex', rawTx) data.append('apikey', '3DQFQQZ51G4M18SW8RDKHIMERD79GYTVEA') // please use your own api key let resp = await fetch(broadcastUrl, { method: "post", body: data, }) resp = await resp.json() c.log("broadcast Tx:", resp) return resp}(async () => { const rawTx = "0xf86a0285012a05f20082520894d9ddf72ef671261cb2266b9d924c5980c5186699865af3107a40008026a0824d7b8b937437feff4ab206a556d599a70ce150ecc6ceeee7174bb5c679e0cea0643e49ae4bb8aae422245b6837997cff4a03714088043afc83deabf03043f253" await broadcastTransaction(rawTx)})()
npm i -g browserify babelify
RUN:
browserify js/index.js > js/dist/bundle.js
ADD:
<script src="js/dist/bundle.js" charset="utf-8"></script>
npm i -g watchify
RUN:
watchify js/index.js -o js/dist/bundle.js
.babelrc
{ "presets": ["env"]}
@makevoid
Applied Blockchain
@makevoid
Applied Blockchain
Generate a Private Key
Derive an Ethereum address
Get the address balance
Sign transansaction
Broadcast transaction
Keyboard shortcuts
| ↑, ←, Pg Up, k | Go to previous slide |
| ↓, →, Pg Dn, Space, j | Go to next slide |
| Home | Go to first slide |
| End | Go to last slide |
| Number + Return | Go to specific slide |
| b / m / f | Toggle blackout / mirrored / fullscreen mode |
| c | Clone slideshow |
| p | Toggle presenter mode |
| t | Restart the presentation timer |
| ?, h | Toggle this help |
| Esc | Back to slideshow |