Salut !
J'ouvre ce post pour vous dire un peu comment l'implémentation avance.
J'ai fait beaucoup de recherches et me suis bien informé sur le fonctionnement de la blockchain parce que, naturellement, j'imaginais dans un premier temps que le Guzi aurait la même architecture que le Bitcoin ou la monnaie libre.
Mais non !
Voilà grosso modo. Maintenant pour le Guzi.
Comme je disais, j'ai pas mal buché. J'étais donc parti sur un système équivalent. Et puis je me suis dit "Pourquoi avoir des mineurs ? Est-il possible d'avoir un système 100% distribué sans réseau parallèle de validateurs ?" (Car en réalité, les mineurs ne servent qu'à vérifier et valider les transactions).
Alors je me suis lancé le défi d'avoir une application sur smartphone, point. Aucun serveur. Aucun mineur. Et en plus pouvoir faire des transactions sans aucune connexion à internet. Voici donc où j'en suis et mes dernières problématiques à résoudre ci-après.
Tout repose sur l’ÉNORME différence avec les autres monnaies qui est que chaque Guzi est unique et a un identifiant qui permet de le différencier de n'importe quel autre. On peut donc facilement détecter un faux Guzi, qu'il soit émis trop tôt, plusieurs fois ou par la mauvaise personne.
Pour la suite, sachez que chaque individu a une clé privée pour signer, et une clé publique pour que n'importe qui puisse valider la signature.
Et chaque Guzi, pour être valide, doit être signé par son propriétaire.
Transactions
De ce constat, pourquoi ne pas stocker une blockchain par individu ? En gros, sur mon application, j'ai ma blockchain qui contient toutes mes transactions.
Une transaction entre A et B, c'est ce JSON :
# (A=>B, A paye B)
{
"signé par A": {
"signé par B": {
"source": "A",
"cible": "B",
"date": "2012/01/18",
"guzis": ["id1", "id2", etc...],
}
}
}
Donc A et B stockent chacun cette transaction dans leur blockchain (qui pour l'instant sera, pour simplifier, une liste).
Bon, ici il y a une faille, c'est qu'en suivant le protocole, B peut se faire enfler :
B signe la transaction
B envoie la transaction signée à A
A signe le tout
Mais A, cette enflure, ne l'envoie pas à B
Puis A dit à tout le monde "Hey ! Regardez, j'ai fait cette transaction avec B (prouvé parce qu'elle est signée par B) alors que lui ne l'a pas chez lui, B est un tricheur !"
Donc première solution, on rend la transaction asymétrique :
# Chez B
{
"signé par A": {
"signé par B": {
"source": "A",
"cible": "B",
"date": "2012/01/18",
"guzis": ["id1", "id2", etc...],
}
}
}
# Chez A
{
"signé par B": {
"signé par A": {
"source": "A",
"cible": "B",
"date": "2012/01/18",
"guzis": ["id1", "id2", etc...],
}
}
}
Donc maintenant, le protocole est fiable :
1. B signe la transaction
2. B l'envoie à A
1 bis. A signe la transaction
2 bis. A l'envoie à B
3. B signe la transaction signée de A
4. B l'envoi à A
3 bis. A signe la transaction signée de B
4 bis. A l'envoi à B
Si après 4, A veut filouter, B peut prouver que la transaction a eu lieu parce qu'il a déjà la transaction avec 1 signature de la part de A.
Blockchain personnelle
Maintenant qu'on a défini une transaction, on peut mettre en place une blockchain locale. En gros une blockchain personnelle pour chaque utilisateur. Un bloc ressemblerait à ça :

En chainant plusieurs de ces blocs, cela donnerait :

Avec ça, lors d'une transaction, mon application peut demander son historique à l'autre et vérifier que sa chaine est valide.
Donc je peux vérifier que l'utilisateur :
n'a pas dépensé plusieurs fois un même Guzi ;
n'a pas créé plus de Guzis que son Total accumulé ne lui permettait ;
n'a pas dépensé des Guzis futurs ou périmés.
Note : Si un utilisateur veut s'auto-dépenser un Guzi (qui a ou va périmer par exemple), il est bien entendu qu'il lui faudra un parti extérieur pour signer la transaction.
Le problème restant
Peut-être qu'il y en a d'autres d'ailleurs, c'est pour ça que je vous en parle, mais je n'en ai détecté qu'un seul :
Que se passe-t-il si un utilisateur supprime sa dernière transaction ou carrément son dernier bloc ?
Par exemple, un utilisateur peut modifier le code de son application pour pouvoir :
Dépenser 10 Guzis envers A.
Retirer la transaction de son propre historique.
Dépenser les mêmes 10 Guzis envers B.
Dans ce cas, seul A et B peuvent détecter la faute parce qu'ils ont une preuve que ces 10 Guzis ont été dépensés chez eux. Il y a 2 cas de détections :
A fait une nouvelle transaction avec le truand, dans ce cas il remarque que la transaction est manquante ;
A fait une transaction avec B et ils réalisent qu'ils ont des Guzis en doublons.
Donc on peut évidemment détecter la fraude, mais au bout de combien de temps ?
Ma solution est de faire qu'à chaque transaction, j'ajoute d'une part la transaction en cours à ma blockchain, mais également une ou plusieurs transactions de l'historique de l'autre. Dans ce cas, une transaction frauduleuse serait dupliquée en plusieurs endroits et la probabilité de griller le truand augmente.
Comme je n'arrive pas à prouver quoi que ce soit mathématiquement, je me lance dans une simulation qui va générer des utilisateurs, leur faire faire des transactions avec ce modèle, insérer quelques tricheurs et voir en combien de transactions ils sont grillés.
Il reste également à répondre à plusieurs autres questions :
Le répertoire de clés publiques, où est-il stocké ? Et qui le rempli ?
La délation lorsqu'on détecte une fraude (et qu'on peut le prouver) se passe comment ?
Quelle est la punition pour un fraudeur ?
Voilà, gros post, mais j'avais beaucoup de notes à retranscrire ^^
Je suis preneur de toute remarque.
@Alexandre Dubus et @Mathieu NICOLAS , vous qui avez déjà touché de la blockchain, qu'en pensez-vous ?
Merci !
J'avance sur la théorie de l'implémentation. Voici ma première piste pour les étapes d'une transaction :
Alors j'ai eu une idée ! Ouais en ce moment ça n'arrête pas.
Ma problématique est que seules les personnes investies dans la transactions (donc 2) peuvent prouver une suppression. Donc si une des deux triche, ça ne laisse qu'une seule "personne preuve".
Donc ma solution est de partager une partie de l'historique de chacun à chaque transaction. Je m'explique.
Dans un premier temps, je pensais partager, par exemple, mes 10 dernières transactions. Ce qui fait qu'au cours de mes prochaines 10 transactions, je passerai la fameuse transaction fraude. Donc nous nous retrouvons avec potentiellement 11 (moi + les 10 partagées) "personnes preuves". C'est pas mal, mais le problème est que les "personnes preuves" seront uniquement dans mon entourage. Donc, si le truand fait en sorte de ne jamais faire de transaction à nouveau avec moi, ni avec mes interlocuteurs habituels, le voilà fraudeur pour toujours sans jamais être grillé.
Alors je pense avoir mieux !
Lors d'une transaction, on affecte à cette transaction un Time To Live (TTL) par exemple de 4. Et après chaque transaction, j'ai de nouveau une à TTL=4 et toutes les autres sont réduites de 1. Plutôt que de partager mon historique de 10, je partage plutôt toutes mes transactions dont le TTL > 0.
J'ai fait quelques calculs et cela nous permet d'avoir, avec X le TTL initial :
Un maximum de 2^X personnes preuves. Donc pour 4, par exemple, on a une transaction dupliquée 16 fois, chez des contacts directs mais aussi des indirects. Ce qui est moins prévisible pour le truand.
On a un historique de taille maximum de 2^X - 1 :
pour X=4, la taille maximum d'historique échangé serait de 15 transactions.
pour X=3, taille max = 7
Bien sûr, il y a toujours une probabilité, que je n'arrive pas à démontrer mathématiquement, qu'un truand ne soit jamais grillé, mais les chances semblent vraiment faibles.
Donc à défaut de maths, je vais ajouter ça aux simulations pour valider. Il y a encore du boulot ^^