
Le 10 juin était le troisième jour de notre acclimatation à Hong Kong. Et les 26 dernières heures, nous avons passé presque sans dormir, à développer un projet prototype sous le nom de SensorPay à la première étape du hackathon EOS Global avec une cagnotte totale d'un million et demi de dollars. Le moment de démonstration du projet devant les juges approchait.
Si vous avez hâte de savoir comment cette histoire s'est terminée, jetez un coup d'œil à la dernière partie. Dans l'intervalle, nous commencerons à parler systématiquement des technologies EOS et de la manière dont nous sommes arrivés à l'idée de lier les paiements pour l'IoT à EOS. Juste après cela, il y aura une description détaillée du bourrage technique du projet.
0. Contexte
EOS est une blockchain de nouvelle génération, certains le considèrent même comme un tueur d'Ethereum. Si soudain vous ne savez pas ce qu'est une blockchain ou Ethereum, Google vous aidera. Et nous, il est arrivé, avons commencé à déterrer EOS il y a environ un an, notamment en étudiant les produits précédents de ses auteurs BitShares et Steem.
Les avantages d'EOS par rapport à Ethereum: le débit des transactions est supérieur de trois ordres de grandeur; développé un système d'autorisation pour les contrats intelligents; la possibilité de restaurer l'accès perdu et de corriger les erreurs dans la blockchain; gestion du réseau onchain. Faiblesses: problèmes de centralisation, consensus DPoS potentiellement plus vulnérable, code brut et courbe d'apprentissage plus abrupte pour les développeurs.
Puisque nous aimons cette technologie depuis longtemps et la considérons comme prometteuse, nous ne pouvons pas ignorer la série des hackathons, soutenue par les auteurs d'EOS. Nous voulions juste être là, réaliser nos idées dans cet environnement inspirant et les partager avec un large public. Bien sûr, l'opportunité de gagner beaucoup d'argent est également devenue une motivation supplémentaire.
Ainsi, EOS est la seule solution de travail pour la blockchain publique que nous savons où vous pouvez effectuer de nombreuses transactions. Où est-il nécessaire? Bien sûr dans l'IoT! En effet, si chaque grille-pain devient micropaiements, il paiera pour chaque morceau de pain au réfrigérateur (et c'est cool par défaut, comme vous le comprenez), il y aura beaucoup de transactions. Sans oublier toutes sortes d'autres applications en médecine, industrie et vie quotidienne.
Quelques semaines avant le hackathon, des idées alternatives surgissaient périodiquement et de petits brainstormings avaient lieu. Nous avons comparé des idées sur la base de critères d'arbitrage bien connus: l'utilisation des capacités EOS, la créativité, l'impact public et l'évolutivité. En conséquence, nous avons opté pour l'IoT + EOS - une solution qui prendrait les données des capteurs et enverrait de nombreuses transactions de paiement à EOS.
Soit dit en passant, nous voulions vraiment dire ici également comment nous avons élevé notre producteur de blocs pour EOS; comment ils prévoyaient de vider pour lui le constructeur de jetons de type ERC721 et le support de fonctions constantes; comment ont-ils déposé le protocole ACL Merkle Root. Mais tout cela ne rentre pas dans l'article, nous allons donc revenir à notre projet principal.

1. Préparation
1.1. IoT
Préparer la partie IoT du projet, c'est choisir le bon matériel. Dans le rôle du lecteur RFID, le RC522 fonctionnant sur le bus SPI a été choisi: il est populaire et facile à utiliser.

Lors de la recherche d'un compteur, nous nous sommes concentrés sur la présence d'une sortie impulsionnelle, car cela vous permet de lire les données très simplement: une impulsion est X kW⋅h (où X dépend du modèle), en conséquence, nous nous sommes arrêtés au compteur Mercury 201.5.

La chose la plus difficile a été de décider du contrôleur, qui devrait collecter les données des capteurs, former une transaction, la signer avec votre clé privée et l'envoyer au réseau. En conséquence, nous avions besoin d'un appareil avec un module réseau qui pourrait signer une transaction en utilisant ECDSA (dans ce cas, sur la courbe elliptique secp256k1, car il est utilisé dans EOS pour la signature).
Dans un premier temps, le choix s'est porté sur le microcontrôleur ESP8266, il dispose d'un module Wi-Fi et de toutes les interfaces nécessaires pour connecter nos capteurs. En même temps, il est très compact. Mais aucun micrologiciel n'a une implémentation native de primitives elliptiques. Il est possible d'écrire votre propre implémentation, mais ce n'est pas une tâche pour le hackathon. En conséquence, Raspberry Pi 3 B a été choisi pour le prototype et la bibliothèque eosjs a été utilisée pour générer et signer des transactions.

1.2. L'infrastructure
Quelques jours avant le hackathon, nous avons préparé localement et sur le serveur eos-hackathon.smartz.io un assemblage EOS ( source ). L'installation, l'assemblage et les tests de dépendances se sont étonnamment bien déroulés pour un projet aussi jeune (en utilisant la documentation ). Il n'y avait pas assez de temps pour la préparation d'autres infrastructures, et j'ai dû y faire face pendant le hackathon.
1.3. L'architecture
À la veille du hackathon, nous avons discuté de l'architecture et clarifié les détails du produit. Nous allions mettre en œuvre les principaux cas suivants: les paiements pour l'électricité et le paiement pour les achats marqués d'étiquettes RFID. Ils ont également prévu de rendre le produit facilement extensible et de l'utiliser dans d'autres domaines.

L'idée de l'architecture est que le fournisseur de services (producteur) crée un contrat - le point central d'interaction entre le fournisseur et les consommateurs. Chaque consommateur a son propre solde, qui peut être reconstitué, les fonds en sont débités en fonction des signaux des capteurs. Toutes les données - utilisateurs, capteurs, statistiques - sont stockées dans le contrat du fournisseur.
Les préférences utilisateur sont associées au consommateur, ou indicateurs (par exemple, une catégorie d'utilisateur préférentielle) - user_meta
. Plusieurs capteurs peuvent être connectés avec le consommateur, pour chacun d'eux un contrat et des paramètres de facturation ( billing_meta
) sont indiqués. Vous pouvez donc obtenir un contrat de facturation apatride immuable, utilisé pour un grand nombre de consommateurs; les données nécessaires apparaîtront lors de l'appel de la méthode de bill(payload, user_meta, billing_meta)
. En outre, la possibilité d'une logique de facturation différente, c'est-à-dire de contrats différents, est posée: par exemple, l'un considère l'électricité, l'autre - les biens. Chaque capteur dispose d'un «pointeur» sur son contrat de facturation.
On suppose que le consommateur fait confiance au fabricant du capteur, mais ne fait pas nécessairement confiance au fournisseur de services. L'interface d'interaction avec le capteur est extrêmement simple: il s'agit d'un appel à la méthode du contrat fournisseur avec un paramètre numérique, qui sera transféré à la facturation. Le fournisseur de services démarre les consommateurs, les capteurs, les contrats de facturation et leurs relations dans leur contrat, en utilisant des transactions de contrôle - des setters primitifs. Lorsqu'une transaction est reçue du capteur, les données sont vérifiées, les données de facturation sont générées, la facturation est appelée, le paiement est enregistré et les statistiques sont enregistrées.
Peut-être avons-nous surtout discuté des questions suivantes qui sont importantes pour l'applicabilité du produit dans le monde réel:
- Acomptes ou post-paiement? Recharger votre compte et l'utiliser (comme une connexion cellulaire) - ou l'utiliser, puis payer (comme AWS)? Il n'y a pas de bonne ou de mauvaise réponse ici: différentes entreprises préfèrent des modèles différents. Par souci de simplicité, nous avons décidé de prendre des acomptes.
- L'utilisateur doit-il tenir un compte distinct pour chaque fournisseur, ou tous les frais proviennent-ils d'un seul compte? Encore une fois - il n'y a pas de bonne et de mauvaise décision; en outre, la réponse est étroitement liée à la réponse à la question précédente. Les avances sont de bons amis avec les comptes de consommateurs individuels - elles ont été prises.
- Facturer des frais en EOS, un jeton de fournisseur de services ou une pièce stable (liée à la monnaie fiduciaire)? Les options autres que la pièce stable, bien sûr, ne sont pas pratiques pour le consommateur en raison de la volatilité, et la pièce stable dans le cadre d'EOS n'existe pas encore. A cette époque, même le réseau EOS principal n'était pas là! Par souci de simplicité, ils ont pris un jeton conditionnel.
2. Codage
Tout d'abord, ils ont précisé l'API et le cadre du contrat du fournisseur afin de commencer simultanément le développement du frontend, du code d'appareil, de la facturation et du contrat principal ( source ).
2.1. IoT
Le premier à implémenter un code de lecture d'impulsions depuis un compteur. Pour travailler avec GPIO (broches à usage général), la bibliothèque onoff JS a été utilisée. Plus tard, deux LED ont été ajoutées au circuit pour plus de clarté: la première a clignoté lorsqu'un signal a été reçu du compteur et la seconde lorsqu'une réponse concernant une transaction réussie est venue du nœud EOS. De même, nous avons développé un schéma et un code pour lire les étiquettes RFID, avec la seule différence: la lecture a eu lieu sur le bus SPI en utilisant la bibliothèque MFRC522-python. Il s'est avéré que le paramètre SPI du Raspberry Pi 3 est différent de celui des modèles de carte précédents; Cette instruction nous a aidés à comprendre.
Les appareils étaient alimentés par la banque d'alimentation, qui a été présentée avec succès à tous les participants au hackathon, et ils devaient partager eux-mêmes Internet avec l'iPhone 5, car le Wi-Fi du hackathon fonctionnait exclusivement à 5 GHz, cela ne fonctionnait pas pour le Raspberry Pi.
2.2. Infrastructure et services publics
Les organisateurs ont conseillé de prendre l'image docker d' eos-dev , mais nous étions confus par le manque de description et de documentation de l'image. Sur le serveur, ils ont continué à travailler avec l'assemblage préparé et, localement, pour éviter d'installer EOS systématiquement, ils ont utilisé eos-dev.
Il fallait de toute urgence la capacité de construire et de tester rapidement. Idéal: créer et exécuter un fichier exécutable localement. Cependant, il était impossible d'ignorer le fait qu'après l'assemblage, la sortie nécessitait WebAssembly et, dans l'environnement EOS, avec le boost correspondant, les bibliothèques, les contrats système. Les options de compilation nécessaires pourraient être espionnées dans eosiocpp.in , cependant, nous avons décidé de ne pas jouer à ce jeu. Le résultat prévu, quoique un peu plus lent, est plus important qu'une solution rapide avec un râteau potentiel. Par conséquent, pour l'assemblage, nous avons pris eoscpp, qui se trouve dans le conteneur eos-dev.
Cela s'est avéré plus difficile avec le lancement, j'ai dû augmenter la blockchain EOS locale, et encore une fois, il n'y avait pas de solution toute faite. Seul logiciel. La première version de l'infrastructure de lancement est donc apparue. L'idée est de masquer les nuances de montage et de configuration et d'obtenir un ensemble auto-cohérent de quatre à cinq «boutons» pour des actions typiques. Moins de contrôle, mais moins de risques d'erreur, plus un gain de temps.
Les principaux composants d'EOS comprennent les nœuds nodos, les démons keosd, l'utilitaire de console cleos et le compilateur eoscpp:
- nodeos - Nœud EOS, démon - participant au réseau, donne accès à la blockchain et produit éventuellement de nouveaux blocs;
- keosd - un démon pour gérer les portefeuilles locaux qui stockent des paires de clés;
- cleos fournit des commandes permettant d'obtenir des informations sur les transactions et de travailler avec des clés; il est implémenté sur la base d'appels dans nodeos et keosd via l'API HTTP;
- eoscpp compile les contrats dans WebAssembly et vous permet également d'obtenir l'interface binaire d'application basée sur le code source.
Il est immédiatement devenu clair que les commandes cleos liées aux appels keosd ne fonctionnaient pas. Comme une erreur a été émise indiquant l'inaccessibilité du réseau keosd, nous avons passé du temps à diagnostiquer les problèmes de réseau dans le réseau docker. Cependant, strace a montré que ce n'était pas le réseau: cleos accédait à la mauvaise adresse, toujours à localhost (et dans le cas de notre infrastructure, différents démons ont des adresses réseau différentes dans un réseau docker distinct). Un bug a été diagnostiqué dans cleos: la vérification de la disponibilité de keosd, qui est effectuée avant toute commande relative aux portefeuilles, prend en compte le port passé dans les arguments, mais ne tient pas compte de l'adresse. Dans le cadre du hackathon, nous sommes passés au réseau hôte dans docker comme solution de contournement.
L'étape suivante a été l'utilitaire de compilation de contrat utilisant le compilateur dans le conteneur ( commit ). Les répertoires d'entrée et de sortie ont été montés. Et enfin, la possibilité de télécharger un contrat dans la blockchain et d'envoyer des transactions ( commit ). Encore une fois - des utilitaires dans un style cohérent, de simples «boutons». Cela a mis fin à l'infrastructure de base, mais les surprises ont continué: nous sommes tombés sur le problème des fonctions C pour travailler avec la mémoire (plus en détail ci-dessous).
En conclusion, ils ont commencé à configurer des comptes dans un fichier (chaque contrat et chaque participant nécessitent des comptes séparés) ainsi que des paires de clés qui sont créées automatiquement au démarrage de la blockchain, afin qu'une équipe puisse augmenter l'environnement de test. Une copie de cet environnement a été déployée sur eos-hackathon.smartz.io.
2.3. Contrats intelligents
2.3.1. Contrat fournisseur et facturation électricité
Après le début du hackathon, nous avons commencé à établir la structure des contrats selon le schéma ci-dessus. Le système comprenait les contrats suivants:
supplier
- contrat supplier
;billing_electricity
- un contrat pour calculer le paiement de l'électricité pour chaque tick du compteur.
Dans le contrat supplier
, la plupart des travaux sont effectués par des opérations CRUD ordinaires: ajout d'utilisateurs, tarifs, compteurs, augmentation ou diminution du solde de l'utilisateur. Des méthodes plus complexes étaient chargées de recevoir les données du compteur, d'appeler un contrat pour calculer un paiement (facturation), de débiter le compte personnel d'un utilisateur après un rappel d'un contrat de facturation. Le contrat de facturation nécessaire a été déterminé en fonction du tarif de l'utilisateur.
Après l'appel dans le contrat de facturation, le paiement a été calculé et la méthode a été appelée pour débiter le paiement du compte personnel de l'utilisateur. Ayant jeté la logique principale, nous avons même pensé si nous faisions des contrats trop simples. Un peu plus tard, après le déploiement des contrats dans le nœud et leurs tests, il est devenu clair que les contrats peuvent être simples, mais il y a des nuances. :)
Après le déploiement, il s'est avéré que les appels de contrat attendus les uns des autres n'ont pas fonctionné. Pas assez de droits. Contrairement aux contrats intelligents dans Ethereum, où un contrat est appelé à partir d'un contrat au nom du contrat appelant, dans EOS, toute la chaîne commence par l'initiateur de la transaction. Lorsqu'un contrat est appelé à partir d'un contrat, il est vérifié si l'initiateur a autorisé le contrat à le faire.
Les mentors ont immédiatement suggéré comment agir dans un cas simple. Les droits sont ajoutés comme suit (en appelant le contrat intelligent du système eosio):
./cleos push action eosio updateauth '{"account":"electricity","permission":"active","parent":"owner","auth":{"keys":[{"key":"EOS7oPdzdvbHcJ4k9iZaDuG4Foh9YsjQffTGniLP28FC8fbpCDgr5","weight":1}],"threshold":1,"accounts":[{"permission":{"actor":"supplier","permission":"eosio.code"},"weight":1}],"waits":[]}}' -p electricity
Dans ce cas, le compte d' electricity
permet au contrat supplier
d'appeler d'autres contrats en son nom. Vous pouvez en savoir plus sur les droits dans Technical WP EOS . Dans notre pays, le contrat supplier
provoqué le contrat de billing
, et qui, à son tour, a de nouveau appelé le supplier
. L'ajout par analogie des droits sous cette forme n'a pas fonctionné:
./cleos push action eosio updateauth '{"account":"electricity","permission":"active","parent":"owner","auth":{"keys":[{"key":"EOS7oPdzdvbHcJ4k9iZaDuG4Foh9YsjQffTGniLP28FC8fbpCDgr5","weight":1}],"threshold":1,"accounts":[{"permission":{"actor":"supplier","permission":"eosio.code"},"weight":1},{"permission":{"actor":"billelectro","permission":"eosio.code"},"weight":1}],"waits":[]}}' -p electricity
Une erreur a été émise: autorité non valide. Ici, les mentors ne pouvaient plus nous aider: ils ont dit qu'ils ne l'avaient pas fait eux-mêmes. Et qui l'a fait? Peut-être seulement Dan Larimer. Nous n'avons pas pu trouver rapidement la cause de l'erreur dans le code EOS et avons déjà commencé à envisager des options alternatives, sans chaîne d'appels. Cela a empêché admirablement que le mécanisme d'appel d'autres contrats dans EOS soit également différent de l'éther. Lorsqu'un autre contrat est appelé, cet appel est mis en file d'attente et ne sera terminé qu'une fois l'appel en cours terminé. Il ne fonctionnera pas pour appeler le contrat et après l'appel pour lire les données enregistrées par ce contrat.
Plus tard, après tout, ils ont trouvé dans le code EOS la raison de l'erreur lors de la définition des droits pour deux contrats. Il s'avère que les comptes dans la liste des droits doivent être triés par compte: s'assure que toutes les clés sont uniques et triées et que toutes les autorisations de compte sont uniques et triées ( Authority.hpp ). Après avoir changé l'ordre des comptes, la mise à jour des droits a fonctionné - et notre système de contrats a commencé à fonctionner.
2.3.2. Le problème des fonctions C avec la mémoire
C'est ridicule à dire, mais au final nous n'avons pas pu utiliser les fonctions prêtes à l'emploi pour l'analyse des nombres (!) Pour lire la configuration de facturation. Après std::istringstream
fonction std::istringstream
été extraite, ce qui est plutôt étrange. Et lors de l'utilisation de atof
et similaires, ainsi que de sscanf
- env.realloc
resserré. Pour une raison quelconque, les fonctions mentionnées de travailler avec la mémoire de la bibliothèque C standard n'ont pas été trouvées lors du chargement de code dans nodeos. Les fonctions C ++ fonctionnant avec la mémoire ont fonctionné.
Bien sûr, lors de l'exécution du contrat WebAssembly, pas un allocateur de mémoire standard n'est utilisé, mais son propre sandbox, qui est fourni à chaque transaction sous certaines conditions. De plus, la prise en charge des fonctions C de travail avec la mémoire au-dessus de ce bac à sable a été implémentée depuis longtemps, leur implémentation est dans les contrats EOS standard . Quelque chose s'est probablement mal passé au stade de la liaison.
Après avoir passé environ une heure à chercher une issue, y compris avec l'aide de l'un des mentors, nous avons décidé de ne pas continuer et de contourner le problème: écrire notre propre code qui résout le problème de l'analyse des nombres. Le mécanisme de flux de données EOS ne nous convenait pas: il nécessitait la possibilité de sauvegarder des paquets de données de différentes structures dans un champ et de les former à la main (les configurations de facturation même).
2.3.3. Facturation des achats
Dans le second vent, qui a été ouvert soit par les ingénieurs en électricité, soit par le petit déjeuner matinal, ils ont écrit la facturation des achats dans le magasin. Le schéma général de travail est le suivant:
- Le fournisseur crée un contrat de facturation et le prescrit dans son contrat général.
- À la sortie du magasin, le fournisseur établit des cadres qui peuvent lire la RFID, interagir avec EOS et avoir leurs propres comptes prescrits dans le contrat de facturation.
- Chaque produit du magasin est équipé d'une étiquette RFID, toutes les étiquettes sont enregistrées dans le contrat de facturation.
- L'acheteur paie les marchandises en scannant sa RFID, et les marchandises sont retirées du contrat de facturation.
- À la sortie du magasin, les cadres lisent en outre les achats RFID. Si les marchandises sont toujours dans le magasin, la transaction ne passe pas et le cadre doit sonner l'alarme (oui, en fait, vous ne pouvez même pas envoyer la transaction, mais il suffit de lire le tableau).
Cela n'a aucun sens de s'attarder sur le code du contrat lui-même: il s'agit du standard C ++ 14 avec certaines constructions et bibliothèques spécifiques à EOS. Mieux dit dans le wiki EOSIO et le portail des développeurs EOSIO .
2.3.4. Frontend
La partie frontend du projet a été implémentée à l'aide de React. Au lieu de l'habituel, de nombreux Redux ont décidé d'utiliser MobX, ce qui accélère considérablement le développement et vous permet de gérer l'état global sans mal à la tête.
La phase d'intégration de la blockchain avant ne s'est pas déroulée aussi bien que prévu. Le package eosjs est en cours de finalisation très activement, suivi du portefeuille EOS pour le navigateur Scatter . Dans ce groupe, cela pose souvent des problèmes. Et pas le fait que le code qui a fonctionné hier fonctionnera très bien aujourd'hui. Nous avons marché sur ce râteau (et pas la première fois). Une heure d'essais et de débogage dans un état de somnolence - le problème est résolu.
Considérons un diagramme simplifié de l'interaction du côté client de l'application avec eos. Pour ce faire, vous avez besoin de la bibliothèque eosjs et de l'extension du navigateur Scatter.
Nous vous le rappelons! Scatter est activement mis à jour après eosjs, n'oubliez pas de mettre à jour la bibliothèque.
Ensuite, un bref aperçu de la lecture et de l'écriture. Il existe deux façons de communiquer avec les contrats intelligents dans EOS: l'envoi de transactions (il entraîne la modification de la chaîne de blocs, sans valeur de retour fournie) et la lecture de tables (action en lecture seule).
Considérez le code d'envoi de la transaction:
sendTransaction(funcName, data) { return this.scatter .suggestNetwork(this.network) .then(() => this.scatter.getIdentity({ accounts: [this.network] })) .then((identity) => { let accountName = this.getAccountName(identity); // wrap eos instance const eos = this.scatter.eos(this.network, Eos, this.configEosInstance); return eos.transaction(accountName, (contract) => { contract[funcName](data, { authorization: accountName }); }); }); }
Arguments d'entrée: nom et objet de la fonction, ses valeurs sont des arguments de cette fonction. Troisième ligne: nous confirmons le réseau par lequel nous interagissons avec EOS. Quatrième ligne: on obtient l' identity
, le paramètre est un objet avec le champ des accounts
(pour ce réseau). La fonction getAccountName
renvoie le premier compte de la liste de comptes reçue (dans l'objet d' identity
).
Dans cet exemple, Scatter est utilisé pour signer une transaction. Scatter est un wrapper sur une instance de la classe Eos
. À la ligne 9, nous appelons la méthode eos
, ses paramètres:
this.network
- un objet avec des paramètres de réseau.Eos
est une instance d'eosjs.this.configEosInstance
- un objet avec des paramètres pour une instance Eos (voir dock eosjs).
La dernière méthode de transaction
accepte accountName
et callback
en entrée, l'argument callback
est un contrat situé dans le compte accountName
. Dans callback
'e, nous appelons la méthode du contrat reçu avec l'objet, ses clés sont les arguments de la méthode appelée.
Considérez la méthode de lecture des tableaux:
readTable(data) { this.eos = this.scatter.eos(this.network, Eos, this.configEosInstance); return this.eos.getTableRows({ json: true, limit: 1, ...data, }); }
Ici, pour la lecture, nous n'avons besoin que d'une instance eos
.
Pour concevoir l'interface, nous avons abandonné Materialise, Semantic et Ant, nous avons concocté des styles. Dans les dernières heures du hackathon, une idée est apparue pour relancer l'interface utilisateur, ajouter une visualisation du processus. A mis en évidence les nouvelles lignes du tableau pendant deux secondes en vert et a obtenu un effet cool à la cote des actions. L'amélioration a considérablement accru l'attractivité du projet et est devenue la dernière étape de la construction de l'interface utilisateur.
3. Assemblage
Trois heures avant la fin du temps, nous avions un Raspberry Pi avec le compteur d'électricité Mercury et un lecteur RFID connectés, ainsi qu'une indication lumineuse. Toute l'électricité de la table passait par le Mercure. Pour chaque 0,3125 Wh / h dépensé, ainsi que pour chaque «achat», le Raspberry Pi a envoyé des transactions à notre blockchain, et le fournisseur de services pouvait gérer les utilisateurs, les capteurs, la facturation et voir les statistiques de consommation.

Pendant encore une heure, nous nous sommes engagés calmement dans les vérifications et avons ajouté la touche finale. Deux heures avant la fin des temps, nous avons reçu un produit complet avec deux boîtiers implémentés, illustrant pleinement le concept, et même aucun engagement dans les dernières minutes!
4. Démonstration
Les démonstrations de projets (alias emplacements) se sont déroulées en deux étapes. Lors de la première étape, 69 équipes participantes ont été réparties en quatre groupes, chacun d'eux étant nourri séparément devant deux juges et sans spectateurs. Les juges ont donné des notes (quatre critères de 5 points chacun), et sur la base de ces notes, les 10 meilleures équipes ont été sélectionnées pour la deuxième étape. Ces équipes ont eu la possibilité de monter un projet sur une grande scène devant le public et les huit juges.
Nous nous sommes retrouvés dans le premier groupe, nos juges étaient le PDG et le président (je me demande en quoi ces positions diffèrent) d'Everipedia. Trois minutes ont été allouées pour la représentation, elles ont été strictement surveillées par minuterie. Nous avons terminé notre incohérence, mais avons appelé à impressionner le discours 30 secondes avant la date prévue. Les juges ont demandé quelque chose superficiellement et assez rapidement, et la manifestation était terminée.
Nous, naïfs, avons été surpris de ne pas prêter attention à la capacité de travail réelle du produit, et plus encore au code du juge. Les problèmes de mise en œuvre technique ne les intéressaient même pas du tout. On pourrait tout aussi bien montrer les ampoules clignotantes du Raspberry Pi et l'image en façade.
Nous avons eu le sentiment qu'avec la présentation du projet, nous avons échoué, car nous nous attendions à impressionner par une solution réelle, un prototype, et pas seulement une description colorée d'un projet socialement ambitieux et ambitieux. Tout se jouait comme par des notes: nous décrivions le problème, la douleur, notre solution, montrions comment cela fonctionne et décrivions les plans de développement du projet. Connaissant à l'avance les méthodes de jugement, nous aurions fait beaucoup différemment.
Les juges des quatre volets du premier tour ont réduit leurs scores et échangé leurs points de vue 15 minutes après la fin des terrains. Après l'annonce des gagnants a commencé. Une ambiance nerveuse régnait dans la salle: fatigués après les 26 heures du marathon, les gens voulaient gagner, il y avait beaucoup d'équipes fortes, et ils savaient qu'ils pouvaient revendiquer la victoire. Et nous le savions - et attendions les résultats.
Pour empêcher les téléspectateurs de se détendre, les résultats ont été annoncés en trois parties. Les quatre premiers finalistes, puis trois de plus, puis trois autres. Entre les annonces et à la fin - performances. Nous ne sommes pas entrés dans le top 10 et n'avons pas eu l'opportunité d'entrer dans la grande scène. Deux équipes russophones se sont classées parmi les dix premières, dont l'une est finalement devenue la troisième. Félicitations aux gagnants, ils méritent leurs prix.
5. Conclusion et plans
AngelHack . , . — , , . , , , — .
26 IoT- EOS. , .
— UI ( — -- Smartz ), . - , blockchain-ready , , — . :)

, , «», «» . . 5 . , 100 , . SensorPay !
:
Yuvasee (entrepreneur)
algs (hardware & backend developer)
therealal (architect, backend developer, devops)
bolbu (frontend developer)
quantum (blockchain & backend developer)