@stadolf @coding_earth
Hack it like it’s hot 😅
a 1 year hackathon wrap up
2
Stefan Adolf
Developer Ambassador
#javascript #mongodb #serverless
#blockchain #codingberlin #elastic
#aws #php #symfony #react
#digitalization #agile #b2b #marketplaces
#spryker #php #k8s #largescale
#turbinejetzt #iot #ux #vuejs
@stadolf
elmariachi111
@stadolf @coding_earth
Hackathons. They’re all the same.
1. You pitch an idea
2. you find friendly team mates
3. you hack 40 hours
4. you present what you’ve done.
5. you do a team selfie
@stadolf @coding_earth
Buy By ID
Self sovereign identity meets eCommerce
T-Labs Blockchain Group - “Decentralizing the Enterprise” - Jan 2019
@stadolf @coding_earth
Challenge: Self Sovereign Identity
•authenticate / SSO by using an
identity under your control
•enabled by self signed DID
documents on Ethereum
•support verifiable claims
• “my government claims that
I’m Stefan and over 21”
1. You pitch an idea
@stadolf @coding_earth
Buy By ID: Idea
•add a “login with your identity” button to an headless shop system
•integrate with Vue Storefront (headless adapter for Magento e.a.)
•use Jolocom’s Smart Wallet for claim exchange
2. you find friendly team mates
3. you hack 24 hours
@stadolf @coding_earth
Tools / APIs
•Jolocom: Typescript
•Vue Storefront: ECMAScript / Vue
•node / express, Redis & socket.io
@stadolf @coding_earth
Brainkillers / pitfalls
•Both projects rely on Redis (VSF: cache, Jolocom: wallet storage)
•Jolo’s samples rely on socket.io to detect phone activities (QR scanned)
•socket.io can’t be bound to express apps (only to a http.Server inst)
• socket.io relies on https
•had to activate body parser on VSF
•conflicting build setup (Jolocom / VSF) - had to align start scripts / ts-node
•asynchronous calls conflicts with express route wiring
@stadolf @coding_earth
bind Jolocom backend to VSF
const { getAsync, setAsync, delAsync } = configureRedisClient()
const registry = JolocomLib.registries.jolocom.create()
const vaultedKeyProvider = new JolocomLib.KeyProvider(seed, password)
module.exports = async (expressApp: Express, server: http.Server) => {
const identityWallet = await registry.authenticate(vaultedKeyProvider, {derivationPath:
JolocomLib.KeyTypes.jolocomIdentityKey, encryptionPass: password})
configureRoutes(expressApp, {setAsync, getAsync, delAsync}, identityWallet, password)
configureSockets(server, identityWallet, password, new DbWatcher(getAsync), {getAsync, setAsync, delAsync})
return identityWallet
}
const configureRoutes = (app: Express, redisApi: RedisApi, iw: IdentityWallet, password: string) => {
/**
* An authentication endpoint route for deep linking for demo-sso-mobile;
*/
app.get('/mobile/credentialRequest', async (req, res, next) => {
…
@stadolf @coding_earth
listen to smart wallet events in Vue
continueWithJolo () {


const randomId = randomString(8);
this.getQrCode(randomId).then(image => {
this.$bus.$emit('modal-show', 'modal-jolo-user', null, 

{image: image})
this.awaitUserData(randomId).then(data => {
const parsed = JSON.parse(data)
const userData = parsed.data
this.personalDetails = {
firstName: userData.givenName,
lastName: userData.familyName,
}
this.$bus.$emit('modal-hide', 'modal-jolo-user')
this.sendDataToCheckout()
})
}).catch(err => {
console.log(err)
})
},
awaitUserData(randomId: string): Promise<string> {
const socket = io(`/sso-status`, {
query: { userId: randomId }
})
return new Promise<string>(resolve => {
socket.on(randomId, (data: string) => resolve(data))
})
}
/* server: http.Server */
const baseSocket = io(server).origins('*:*')


baseSocket.of('/sso-status').on('connection', async socket => {
const { userId } = socket.handshake.query
console.log(`sockets.ts: waiting until ${userId} logs in`)
dbWatcher.addSubscription(userId)
dbWatcher.on(userId, async () => {
const userData = await getAsync(userId)
await delAsync(userId)
socket.emit(userId, userData)
})
})
getQrCode (randomId: string) {
const socket = io('/qr-code', {query: { userId: randomId } })
return new Promise<string>(resolve => {
socket.on(randomId, (qrCode: string) => resolve(qrCode))
})
},
Wait for auth Redis
Checkout form
4. you present what you’ve done.
@stadolf @coding_earth
Demo
5. you do a team selfie
@stadolf @coding_earth
💡team building
•find your team ahead of the event if possible
•be very careful of people who
• consider themselves “very senior” (they’re not pragmatic)
• are “designers” without knowing CSS (“Photoshoppers”)
• talk about everything but the hackathon (just want to hire you)
•first thing you do: agree on a messenger protocol (Slack) / channel
@stadolf @coding_earth
Tech Tinder
Customize your Tech radar
Schwarz Group - “CodeCamp Heilbronn” - Nov 2018
@stadolf @coding_earth
Challenge
•“Schwarz group”: 2nd largest grocery / supermarket in Germany / LIDL
• ~500 developers over the world
• no one knows all requirements
•Build a tool that helps their dev teams to keep track of their tech stack
1. You pitch an idea
@stadolf @coding_earth
Idea: Tech-Tinder
•a tech radar controlled by employees
•everyone can add new technologies
•vote on technologies using a “tinder” interface
2. you find friendly team mates
3. you hack 36 hours
@stadolf @coding_earth
Tools / APIs
•Backend: MongoDB Atlas / Stitch (FaaS)
•Frontend: Vue.js / Bueify
•integrate “swing” swiping library (vue-swing2)
•copy / paste and adjust Zalando’s TechRadar project
@stadolf @coding_earth
stitch FaaS editor
@stadolf @coding_earth
technology_aggregate.js (stitch)
exports = function(technologyId){
const colTech = context.services.get("mongodb-atlas").db("tech-
tinder").collection("technology");
const colVotes = context.services.get("mongodb-atlas").db("tech-
tinder").collection("votes");
const aggregationPipeline = [
{"$group": {
"_id": { tech: "$ref", opinion: "$op" },
"total": { "$sum": 1 }
}
},
{"$group": {
"_id": "$_id.tech",
"count": {"$sum": "$total"},
"stats": {
"$push": {
op: "$_id.opinion",
total: "$total"
}
}
}
}
];
var pipeline;
if (technologyId) {
pipeline = [{$match:{ref: BSON.ObjectId(technologyId)} }]
.concat(aggregationPipeline);
} else {
pipeline = aggregationPipeline;
}
return new Promise( (resolve, reject) => {
//let technology = colTech.findOne({_id: techId});
colVotes.aggregate(pipeline).toArray().then(ag => {
const techIds = ag.map(agg => agg._id); //stitch doesnt
support $lookup
colTech.find({_id: {"$in":
techIds} }).toArray().then(technologies => {
const combined = ag.map(agg => {
let base = technologies.filter(tt => {
return tt._id.toString() == agg._id.toString();
})[0];
if (!base) {
return null;
}
base.votes = {
total: agg.count,
results: {}
};
agg.stats.forEach(s => base.votes.results[s.op] =
s.total );
return base;
});
resolve(combined.filter(c => c != null));
});
});
});
};
@stadolf @coding_earth
vote.js (“tinder”)
<div class="container" v-if="technologies.length > 0">
<span class="tag is-info is-large tag-hint tag-top" :style="{ opacity: opacity.top }">interested</span>
<span class="tag is-info is-large tag-hint tag-left" :style="{ opacity: opacity.left }">discouraged</span>
<span class="tag is-info is-large tag-hint tag-right" :style="{ opacity: opacity.right }">using</span>
<span class="tag is-info is-large tag-hint tag-bottom" :style="{ opacity: opacity.bottom }">evaluating</span>
<div class="card-viewport">
<div class="card-stack">
<vue-swing
v-for="technology in technologies"
:key="technology._id"
:config="cardConfig"
@throwout="throwout"
@throwin="throwin"
>
<div class="card card-item" :data-key="technology._id" >
<div class="card-image">
<figure class="image">
<h1 class="title is-3">{{ technology.name }}</h1>
</figure>
</div>
<div class="card-content">
<p class="is-5" v-html="technology.description"/>
</div>
</div>
</vue-swing>
</div>
</div>
</div>
4. you present what you’ve done.
@stadolf @coding_earth
Demo
5. you do a team selfie
@stadolf @coding_earth
👍 hackers’ rules of thumb
•you can’t learn a new language during a hackathon
•use as much SaaS and PaaS services as possible
• Contentful, Heroku, AWS Lambda / RDS, Firebase, now.sh, netlify
•never do “microservices”
•use DX-friendly frontend tech stacks
• vue-cli, create-react-app, Gatsby, ionic
•don’t to TDD!
@stadolf @coding_earth
Green Fee
let drivers pay for their air pollution in real time
“Blockchain Hackathon Stuttgart 2” - Feb 2019
@stadolf @coding_earth
Challenge
•sponsored by huge German banks, Daimler, blockchain agencies
•improve “mobility” with ledger tech
• other challenges were “Industry 4.0 / IoT”, “Finance”
•they expect a “business” presentation 🙄
1. You pitch an idea
@stadolf @coding_earth
Idea: Green Fee
•track vehicles’ motion
•track environmental conditions (current air pollution ratio)
•price = constant * (your pollution / environmental pollution)
•track your pollution cost in “real time”
•compensate “the planet” in near realtime
2. you find friendly team mates
3. you hack 40 hours
@stadolf @coding_earth
Tools / APIs
•IOTA MAM (Masked Authenticated Messaging)
• write pollution costs onto an IOTA DAG ledger MAM
• every message contains an due amount of IOTA
• asnychronous process polls MAM stream and triggers payments
•open air pollution data service
• public.opendatasoft.com
•Leaflet / OSM / plain jQuery, Webpack Encore for fast asset building
•expressjs as backend
@stadolf @coding_earth
– The official IOTA project
It is possible to publish transactions to the Tangle that contain only messages, with no value. This
introduces many possibilities for data integrity and communication, but comes with the caveat that
message-only signatures are not checked. What we introduce is a method of symmetric-key
encrypted, signed data that takes advantage of merkle-tree winternitz signatures for extended
public key usability, that can be found trivially by those who know to look for it.
@stadolf @coding_earth
– Alexey Sobolev, Oct 2017
“The ID published to the tangle is the hash
of the hash of the message key seed.”
🤔
@stadolf @coding_earth
publish.js
const Mam = require('@iota/mam/lib/mam.client.js')
const { asciiToTrytes } = require('@iota/converter')
const fs = require("fs");
const mamState = Mam.init(config.provider, config.seed);
const lastState = fs.existsSync(LAST_STATE_FILENAME) ? fs.readFileSync(LAST_STATE_FILENAME).toString() : null;
if (lastState) {
mamState.channel = JSON.parse(lastState);
}
app.post('/msg', async function (req, response) {
var t = new Date()
const payload = {
d: t.toLocaleDateString() + " " + t.toLocaleTimeString(),
data: req.body
};
const trytes = asciiToTrytes(JSON.stringify(payload))
const message = Mam.create(mamState, trytes)
await Mam.attach(message.payload, message.address, 3, 9)
if (!mamState.channel.currentRoot) {
mamState.channel.currentRoot = message.root;
}
mamState.channel.lastRoot = message.root
fs.writeFileSync(LAST_STATE_FILENAME, JSON.stringify(mamState.channel))
response.json(mamState)
})
4. you present what you’ve done.
@stadolf @coding_earth
Demo
5. you do a team selfie
@stadolf @coding_earth
💡ideation
•if there are “sponsors”, select 1 with an API you can relate with
•don’t put all the sponsors’ APIs in one app
•do a design thinking session
• plan your idea for 2-3 hours!
•remove everything that’s not absolutely necessary
•do a “good looking” UI that’s responsive and usable on mobile
• vuetify, MUI, ionic, Bueify, Reactstrap
@stadolf @coding_earth
Blockstagram
Instagram on the blockchain
“Blockstack Hackathon Berlin” - Mar 2018
@stadolf @coding_earth
Challenge
•build something meaningful with “Blockstack”
•self sovereign “blockstack.id": a socially / stake backed identity (BTC)
•use their “Gaia” hub: file storage decentralization concept (~IPFS / Storj)
• P2P synced decentralized storage. 

Bring your own cloud or trust Blockstack
1. You pitch an idea
@stadolf @coding_earth
Idea: Blockstagram
•“Instagram” on Blockstack
•Upload your pictures to Gaia hub (controlled by you)
•acknowledge “friend” identities for read access
•provide a symmetric key for them to decrypt your images
•to unfriend (hide) someone, reencrypt all the images with a new key
2. you find friendly team mates
3. you hack 36 hours
@stadolf @coding_earth
Tools / APIs
•Blockstack
• Identity & Gaia Hub
•ReactJS / CRA (ejected)
•Netlify deployment
@stadolf @coding_earth
read your friend’s instagram data
async readSingleSubscribersImages(username) {
const indexData = await blockstack.getFile('index.json', {
username: username,
decrypt: false
})
const data = JSON.parse(indexData);
console.log('Subscribers indexData is', indexData);
data.images.forEach(async indexEntry => {
if (!this.subscriberImageLoaded({ ...indexEntry, username })) {
const imageData = await blockstack.getFile(indexEntry.path, { username,
decrypt: false })
this.updateFeed({ path: indexEntry.path, username: username, image:
imageData, created: indexEntry.created });
}
})
}
4. you present what you’ve done.
@stadolf @coding_earth
Demo
5. you do a team selfie
@stadolf @coding_earth
💡task distribution
•is very hard since you don’t know / trust each other
•one (experienced) guy must control the repo
• everyone must commit to the same repo!
•mock it till you make it
• https://www.mockbin.org
• use postman shared collections
•“I’m done, what can I do next?” -> “I’m done. I’d like to add xyz”
@stadolf @coding_earth
Survival Guides
Bonus
@stadolf @coding_earth
2pm: the idea wasteland
•talk to others and listen closely
•you may steal and reiterate their ideas!
• Most likely you’ll build sth else anyway!
•google the APIs and find related Stackoverflow questions
•try to come up with a real problem that you personally could have
😩
@stadolf @coding_earth
8pm: the desperation zone
•you will not get done anything until 8pm. That’s normal!
•Pair! Sitting next to each other always helps.
•look at the other teams. You’ll note that they’re also struggling *very* hard
•don’t argue or overthink! Do!
• you usually will never look back at the code!
•if you want to win: get rid of people who disturb the team. (Just ignore them)
•if you want to learn / earn karma points: discuss it out with them
🤯
@stadolf @coding_earth
4am: the blue hour of devastation
•things will start to work when you’re most desperate and expect it least
•stay awake!
• Fresh air, do a break every 10m if necessary. But stay on it!
• Bananas and cold pizza work better than coffee and Red Bull.
•tiredness goes away around ~8am (and punches you out by 1pm)
•do some simple tasks (e.g. frontend polish) for success feelings
☠
@stadolf @coding_earth
10am: prepare your presentation
•select one dedicated presentation guy
•usually your presentation will win the game, not your code
•build a story
• “my friend Dyrk called me yesterday and we’re solving his problem here”
•fake the demo if necessary but make it run!
•have 1 WOW effect
•skip “market research”, “business model” and “rollout strategy”
💁
@stadolf @coding_earth
too long, didn’t listen.
•Hackathons are for pragmatic developers, not clean coders
•solve as much as possible on the frontend (learn React or Vue & node!)
•it’s really a “thon”: you need to suffer to take away the grand prize
•it’s incredibly rewarding when your demo starts working at 4am
•the more tools and services you use, the better.
•people will remember you. Everything happens for a reason.
•never give up, never surrender.
6. not winning makes you weirder!
@stadolf @coding_earth
That’s all, folks
Stefan Adolf

https://www.facebook.com/stadolf

https://twitter.com/stadolf

https://github.com/elmariachi111

https://www.linkedin.com/in/stadolf/

Hack it like its hot!

  • 1.
    @stadolf @coding_earth Hack itlike it’s hot 😅 a 1 year hackathon wrap up
  • 2.
    2 Stefan Adolf Developer Ambassador #javascript#mongodb #serverless #blockchain #codingberlin #elastic #aws #php #symfony #react #digitalization #agile #b2b #marketplaces #spryker #php #k8s #largescale #turbinejetzt #iot #ux #vuejs @stadolf elmariachi111
  • 3.
  • 4.
    1. You pitchan idea
  • 5.
    2. you findfriendly team mates
  • 6.
    3. you hack40 hours
  • 7.
    4. you presentwhat you’ve done.
  • 8.
    5. you doa team selfie
  • 9.
    @stadolf @coding_earth Buy ByID Self sovereign identity meets eCommerce T-Labs Blockchain Group - “Decentralizing the Enterprise” - Jan 2019
  • 10.
    @stadolf @coding_earth Challenge: SelfSovereign Identity •authenticate / SSO by using an identity under your control •enabled by self signed DID documents on Ethereum •support verifiable claims • “my government claims that I’m Stefan and over 21”
  • 11.
    1. You pitchan idea
  • 12.
    @stadolf @coding_earth Buy ByID: Idea •add a “login with your identity” button to an headless shop system •integrate with Vue Storefront (headless adapter for Magento e.a.) •use Jolocom’s Smart Wallet for claim exchange
  • 13.
    2. you findfriendly team mates
  • 14.
    3. you hack24 hours
  • 15.
    @stadolf @coding_earth Tools /APIs •Jolocom: Typescript •Vue Storefront: ECMAScript / Vue •node / express, Redis & socket.io
  • 16.
    @stadolf @coding_earth Brainkillers /pitfalls •Both projects rely on Redis (VSF: cache, Jolocom: wallet storage) •Jolo’s samples rely on socket.io to detect phone activities (QR scanned) •socket.io can’t be bound to express apps (only to a http.Server inst) • socket.io relies on https •had to activate body parser on VSF •conflicting build setup (Jolocom / VSF) - had to align start scripts / ts-node •asynchronous calls conflicts with express route wiring
  • 17.
    @stadolf @coding_earth bind Jolocombackend to VSF const { getAsync, setAsync, delAsync } = configureRedisClient() const registry = JolocomLib.registries.jolocom.create() const vaultedKeyProvider = new JolocomLib.KeyProvider(seed, password) module.exports = async (expressApp: Express, server: http.Server) => { const identityWallet = await registry.authenticate(vaultedKeyProvider, {derivationPath: JolocomLib.KeyTypes.jolocomIdentityKey, encryptionPass: password}) configureRoutes(expressApp, {setAsync, getAsync, delAsync}, identityWallet, password) configureSockets(server, identityWallet, password, new DbWatcher(getAsync), {getAsync, setAsync, delAsync}) return identityWallet } const configureRoutes = (app: Express, redisApi: RedisApi, iw: IdentityWallet, password: string) => { /** * An authentication endpoint route for deep linking for demo-sso-mobile; */ app.get('/mobile/credentialRequest', async (req, res, next) => { …
  • 18.
    @stadolf @coding_earth listen tosmart wallet events in Vue continueWithJolo () { 
 const randomId = randomString(8); this.getQrCode(randomId).then(image => { this.$bus.$emit('modal-show', 'modal-jolo-user', null, 
 {image: image}) this.awaitUserData(randomId).then(data => { const parsed = JSON.parse(data) const userData = parsed.data this.personalDetails = { firstName: userData.givenName, lastName: userData.familyName, } this.$bus.$emit('modal-hide', 'modal-jolo-user') this.sendDataToCheckout() }) }).catch(err => { console.log(err) }) }, awaitUserData(randomId: string): Promise<string> { const socket = io(`/sso-status`, { query: { userId: randomId } }) return new Promise<string>(resolve => { socket.on(randomId, (data: string) => resolve(data)) }) } /* server: http.Server */ const baseSocket = io(server).origins('*:*') 
 baseSocket.of('/sso-status').on('connection', async socket => { const { userId } = socket.handshake.query console.log(`sockets.ts: waiting until ${userId} logs in`) dbWatcher.addSubscription(userId) dbWatcher.on(userId, async () => { const userData = await getAsync(userId) await delAsync(userId) socket.emit(userId, userData) }) }) getQrCode (randomId: string) { const socket = io('/qr-code', {query: { userId: randomId } }) return new Promise<string>(resolve => { socket.on(randomId, (qrCode: string) => resolve(qrCode)) }) }, Wait for auth Redis Checkout form
  • 19.
    4. you presentwhat you’ve done.
  • 20.
  • 21.
    5. you doa team selfie
  • 22.
    @stadolf @coding_earth 💡team building •findyour team ahead of the event if possible •be very careful of people who • consider themselves “very senior” (they’re not pragmatic) • are “designers” without knowing CSS (“Photoshoppers”) • talk about everything but the hackathon (just want to hire you) •first thing you do: agree on a messenger protocol (Slack) / channel
  • 23.
    @stadolf @coding_earth Tech Tinder Customizeyour Tech radar Schwarz Group - “CodeCamp Heilbronn” - Nov 2018
  • 24.
    @stadolf @coding_earth Challenge •“Schwarz group”:2nd largest grocery / supermarket in Germany / LIDL • ~500 developers over the world • no one knows all requirements •Build a tool that helps their dev teams to keep track of their tech stack
  • 25.
    1. You pitchan idea
  • 26.
    @stadolf @coding_earth Idea: Tech-Tinder •atech radar controlled by employees •everyone can add new technologies •vote on technologies using a “tinder” interface
  • 27.
    2. you findfriendly team mates
  • 28.
    3. you hack36 hours
  • 29.
    @stadolf @coding_earth Tools /APIs •Backend: MongoDB Atlas / Stitch (FaaS) •Frontend: Vue.js / Bueify •integrate “swing” swiping library (vue-swing2) •copy / paste and adjust Zalando’s TechRadar project
  • 30.
  • 31.
    @stadolf @coding_earth technology_aggregate.js (stitch) exports= function(technologyId){ const colTech = context.services.get("mongodb-atlas").db("tech- tinder").collection("technology"); const colVotes = context.services.get("mongodb-atlas").db("tech- tinder").collection("votes"); const aggregationPipeline = [ {"$group": { "_id": { tech: "$ref", opinion: "$op" }, "total": { "$sum": 1 } } }, {"$group": { "_id": "$_id.tech", "count": {"$sum": "$total"}, "stats": { "$push": { op: "$_id.opinion", total: "$total" } } } } ]; var pipeline; if (technologyId) { pipeline = [{$match:{ref: BSON.ObjectId(technologyId)} }] .concat(aggregationPipeline); } else { pipeline = aggregationPipeline; } return new Promise( (resolve, reject) => { //let technology = colTech.findOne({_id: techId}); colVotes.aggregate(pipeline).toArray().then(ag => { const techIds = ag.map(agg => agg._id); //stitch doesnt support $lookup colTech.find({_id: {"$in": techIds} }).toArray().then(technologies => { const combined = ag.map(agg => { let base = technologies.filter(tt => { return tt._id.toString() == agg._id.toString(); })[0]; if (!base) { return null; } base.votes = { total: agg.count, results: {} }; agg.stats.forEach(s => base.votes.results[s.op] = s.total ); return base; }); resolve(combined.filter(c => c != null)); }); }); }); };
  • 32.
    @stadolf @coding_earth vote.js (“tinder”) <divclass="container" v-if="technologies.length > 0"> <span class="tag is-info is-large tag-hint tag-top" :style="{ opacity: opacity.top }">interested</span> <span class="tag is-info is-large tag-hint tag-left" :style="{ opacity: opacity.left }">discouraged</span> <span class="tag is-info is-large tag-hint tag-right" :style="{ opacity: opacity.right }">using</span> <span class="tag is-info is-large tag-hint tag-bottom" :style="{ opacity: opacity.bottom }">evaluating</span> <div class="card-viewport"> <div class="card-stack"> <vue-swing v-for="technology in technologies" :key="technology._id" :config="cardConfig" @throwout="throwout" @throwin="throwin" > <div class="card card-item" :data-key="technology._id" > <div class="card-image"> <figure class="image"> <h1 class="title is-3">{{ technology.name }}</h1> </figure> </div> <div class="card-content"> <p class="is-5" v-html="technology.description"/> </div> </div> </vue-swing> </div> </div> </div>
  • 33.
    4. you presentwhat you’ve done.
  • 34.
  • 35.
    5. you doa team selfie
  • 36.
    @stadolf @coding_earth 👍 hackers’rules of thumb •you can’t learn a new language during a hackathon •use as much SaaS and PaaS services as possible • Contentful, Heroku, AWS Lambda / RDS, Firebase, now.sh, netlify •never do “microservices” •use DX-friendly frontend tech stacks • vue-cli, create-react-app, Gatsby, ionic •don’t to TDD!
  • 37.
    @stadolf @coding_earth Green Fee letdrivers pay for their air pollution in real time “Blockchain Hackathon Stuttgart 2” - Feb 2019
  • 38.
    @stadolf @coding_earth Challenge •sponsored byhuge German banks, Daimler, blockchain agencies •improve “mobility” with ledger tech • other challenges were “Industry 4.0 / IoT”, “Finance” •they expect a “business” presentation 🙄
  • 39.
    1. You pitchan idea
  • 40.
    @stadolf @coding_earth Idea: GreenFee •track vehicles’ motion •track environmental conditions (current air pollution ratio) •price = constant * (your pollution / environmental pollution) •track your pollution cost in “real time” •compensate “the planet” in near realtime
  • 41.
    2. you findfriendly team mates
  • 42.
    3. you hack40 hours
  • 43.
    @stadolf @coding_earth Tools /APIs •IOTA MAM (Masked Authenticated Messaging) • write pollution costs onto an IOTA DAG ledger MAM • every message contains an due amount of IOTA • asnychronous process polls MAM stream and triggers payments •open air pollution data service • public.opendatasoft.com •Leaflet / OSM / plain jQuery, Webpack Encore for fast asset building •expressjs as backend
  • 44.
    @stadolf @coding_earth – Theofficial IOTA project It is possible to publish transactions to the Tangle that contain only messages, with no value. This introduces many possibilities for data integrity and communication, but comes with the caveat that message-only signatures are not checked. What we introduce is a method of symmetric-key encrypted, signed data that takes advantage of merkle-tree winternitz signatures for extended public key usability, that can be found trivially by those who know to look for it.
  • 45.
    @stadolf @coding_earth – AlexeySobolev, Oct 2017 “The ID published to the tangle is the hash of the hash of the message key seed.” 🤔
  • 46.
    @stadolf @coding_earth publish.js const Mam= require('@iota/mam/lib/mam.client.js') const { asciiToTrytes } = require('@iota/converter') const fs = require("fs"); const mamState = Mam.init(config.provider, config.seed); const lastState = fs.existsSync(LAST_STATE_FILENAME) ? fs.readFileSync(LAST_STATE_FILENAME).toString() : null; if (lastState) { mamState.channel = JSON.parse(lastState); } app.post('/msg', async function (req, response) { var t = new Date() const payload = { d: t.toLocaleDateString() + " " + t.toLocaleTimeString(), data: req.body }; const trytes = asciiToTrytes(JSON.stringify(payload)) const message = Mam.create(mamState, trytes) await Mam.attach(message.payload, message.address, 3, 9) if (!mamState.channel.currentRoot) { mamState.channel.currentRoot = message.root; } mamState.channel.lastRoot = message.root fs.writeFileSync(LAST_STATE_FILENAME, JSON.stringify(mamState.channel)) response.json(mamState) })
  • 47.
    4. you presentwhat you’ve done.
  • 48.
  • 49.
    5. you doa team selfie
  • 50.
    @stadolf @coding_earth 💡ideation •if thereare “sponsors”, select 1 with an API you can relate with •don’t put all the sponsors’ APIs in one app •do a design thinking session • plan your idea for 2-3 hours! •remove everything that’s not absolutely necessary •do a “good looking” UI that’s responsive and usable on mobile • vuetify, MUI, ionic, Bueify, Reactstrap
  • 51.
    @stadolf @coding_earth Blockstagram Instagram onthe blockchain “Blockstack Hackathon Berlin” - Mar 2018
  • 52.
    @stadolf @coding_earth Challenge •build somethingmeaningful with “Blockstack” •self sovereign “blockstack.id": a socially / stake backed identity (BTC) •use their “Gaia” hub: file storage decentralization concept (~IPFS / Storj) • P2P synced decentralized storage. 
 Bring your own cloud or trust Blockstack
  • 53.
    1. You pitchan idea
  • 54.
    @stadolf @coding_earth Idea: Blockstagram •“Instagram”on Blockstack •Upload your pictures to Gaia hub (controlled by you) •acknowledge “friend” identities for read access •provide a symmetric key for them to decrypt your images •to unfriend (hide) someone, reencrypt all the images with a new key
  • 55.
    2. you findfriendly team mates
  • 56.
    3. you hack36 hours
  • 57.
    @stadolf @coding_earth Tools /APIs •Blockstack • Identity & Gaia Hub •ReactJS / CRA (ejected) •Netlify deployment
  • 58.
    @stadolf @coding_earth read yourfriend’s instagram data async readSingleSubscribersImages(username) { const indexData = await blockstack.getFile('index.json', { username: username, decrypt: false }) const data = JSON.parse(indexData); console.log('Subscribers indexData is', indexData); data.images.forEach(async indexEntry => { if (!this.subscriberImageLoaded({ ...indexEntry, username })) { const imageData = await blockstack.getFile(indexEntry.path, { username, decrypt: false }) this.updateFeed({ path: indexEntry.path, username: username, image: imageData, created: indexEntry.created }); } }) }
  • 59.
    4. you presentwhat you’ve done.
  • 60.
  • 61.
    5. you doa team selfie
  • 62.
    @stadolf @coding_earth 💡task distribution •isvery hard since you don’t know / trust each other •one (experienced) guy must control the repo • everyone must commit to the same repo! •mock it till you make it • https://www.mockbin.org • use postman shared collections •“I’m done, what can I do next?” -> “I’m done. I’d like to add xyz”
  • 63.
  • 64.
    @stadolf @coding_earth 2pm: theidea wasteland •talk to others and listen closely •you may steal and reiterate their ideas! • Most likely you’ll build sth else anyway! •google the APIs and find related Stackoverflow questions •try to come up with a real problem that you personally could have 😩
  • 65.
    @stadolf @coding_earth 8pm: thedesperation zone •you will not get done anything until 8pm. That’s normal! •Pair! Sitting next to each other always helps. •look at the other teams. You’ll note that they’re also struggling *very* hard •don’t argue or overthink! Do! • you usually will never look back at the code! •if you want to win: get rid of people who disturb the team. (Just ignore them) •if you want to learn / earn karma points: discuss it out with them 🤯
  • 66.
    @stadolf @coding_earth 4am: theblue hour of devastation •things will start to work when you’re most desperate and expect it least •stay awake! • Fresh air, do a break every 10m if necessary. But stay on it! • Bananas and cold pizza work better than coffee and Red Bull. •tiredness goes away around ~8am (and punches you out by 1pm) •do some simple tasks (e.g. frontend polish) for success feelings ☠
  • 67.
    @stadolf @coding_earth 10am: prepareyour presentation •select one dedicated presentation guy •usually your presentation will win the game, not your code •build a story • “my friend Dyrk called me yesterday and we’re solving his problem here” •fake the demo if necessary but make it run! •have 1 WOW effect •skip “market research”, “business model” and “rollout strategy” 💁
  • 68.
    @stadolf @coding_earth too long,didn’t listen. •Hackathons are for pragmatic developers, not clean coders •solve as much as possible on the frontend (learn React or Vue & node!) •it’s really a “thon”: you need to suffer to take away the grand prize •it’s incredibly rewarding when your demo starts working at 4am •the more tools and services you use, the better. •people will remember you. Everything happens for a reason. •never give up, never surrender.
  • 69.
    6. not winningmakes you weirder!
  • 70.
    @stadolf @coding_earth That’s all,folks Stefan Adolf
 https://www.facebook.com/stadolf
 https://twitter.com/stadolf
 https://github.com/elmariachi111
 https://www.linkedin.com/in/stadolf/