Comme j'ai écrit une crypto-monnaie centralisée en PHP. (Partie 1 - Résumés de base + Démarrage rapide)

Préface


Oui, pensez-y juste, une crypto-monnaie centralisée en PHP, ce n'est pas vrai. Mais mes limites sur les idées ont néanmoins fait leur chemin, donc, comme vous l'avez peut-être deviné, j'ai décidé d'écrire à ce sujet. Dans la toute première partie, nous vous dirons ce qu'est la crypto-monnaie, discuterons des notes initiales et créerons un système de portefeuille. Maintenant, commençons.

À quoi ressemble la crypto-monnaie?


informations tirées de Wikipedia

La crypto-monnaie est un type de monnaie numérique, dont la comptabilité des unités de règlement interne est fournie par un système de paiement décentralisé (il n'y a pas d'administrateur interne ou externe ou tout analogue de celui-ci), fonctionnant en mode entièrement automatique.

La crypto-monnaie elle-même n'a pas de matériel spécial ou de forme électronique - c'est juste un nombre indiquant la quantité de données des unités de règlement, qui est écrit à la position correspondante du paquet d'informations du protocole de transfert de données et n'est souvent même pas crypté, comme toutes les autres informations sur les transactions entre adresses système.

En bref, la crypto-monnaie fonctionne comme ceci:

  1. Un utilisateur du réseau, disposant d'un solde, envoie une transaction à un autre utilisateur anonyme.
  2. La transaction entre dans le réseau.
  3. Les mineurs (ou les utilisateurs créant des blocs) résolvent un problème généré par un algorithme spécial avec des conditions (par exemple, pour la présence des 10-30 zéros précédents dans le hachage, ou vice versa).
  4. Lorsqu'une condition (ou des conditions) est remplie dans un hachage, grâce à elle, le mineur envoie un message au réseau l'informant de la création d'un nouveau bloc et de la transaction.
  5. Le bénéficiaire reçoit les fonds et le mineur reçoit le montant de la rémunération, sous la forme d'une commission calculée lors de la préparation de la tâche.

Est-il judicieux d'écrire une crypto-monnaie centralisée, et également en PHP?


Je pense pas très. Mais essayez à nouveau comme il se doit.

Nous considérons les notes avant le développement


Nous utiliserons un système de vérification à double hachage utilisant la preuve de travail. Il est logique de vérifier les hachages au niveau des logiciels et des applications réseau. Cela est dû au processus d'optimisation de la charge sur le serveur. Parce que lorsque nous allons sur le serveur pour vérifier le hachage plusieurs fois, une telle charge apparaît. Par conséquent, je propose de faire la méthode suivante:

  1. Sur un mineur de logiciel, vérifiez localement le hachage pour satisfaire aux conditions.
  2. Lorsque les conditions sur le mineur logiciel coïncident avec les conditions nécessaires, nous effectuons une vérification au niveau du réseau d'application (au niveau du serveur).

À mon avis, c'est la meilleure façon de répartir la charge. Il est plus facile de vérifier plusieurs fois localement sur l'ordinateur que de spammer les demandes au serveur plusieurs fois.

Le nom - j'ai trouvé un nom simple et peut-être mémorable - FlyCoin avec un code de devise FLC à trois chiffres.

Base de données - J'utiliserai une option simple et pratique, PDO.

Portefeuilles cryptographiques - seront générés à l'aide du GUID et de mt_rand, et le temps POSIX sera utilisé comme graine.

Êtes-vous trop paresseux pour avoir une fonction de vérification du hachage? - Oui, c'est pourquoi j'ai décidé de prendre le code d'un ancien mineur (open source) d'une telle crypto-monnaie (déjà morte) Entropy, mon ami, Nikita.

Je ne peux pas croire qu'il ait créé une seule crypto-monnaie. Y a-t-il autre chose?
En général, toutes ses créations (que j'utilise parfois même), vous pouvez les retrouver dans son groupe VKontakte . J'espère qu'ils seront utiles aussi.

C'est parti!


Commençons par faire le cadre de notre futur système. Commençons par le développement de l'API d'application pour notre crypto-monnaie. Et le cadre semble si vide jusqu'à présent.

<?php /* * The API for FlyCoin */ function checkHash ($hash, $exp) //  $hash -     ,  $exp - .    Entropy Miner,   . { $sum = 0; //    . $len = strlen ($hash); // C  . for ($i = 0; $i < $len; ++$i) $sum += 2 * base_convert ($hash[$i], 16, 10); //        return $sum % 10 == 0 && substr ($hash, -$exp) === str_repeat ('0', $exp); //  false       true,         . } class Block { public $id; // ID  public $prev_hash; //    public $from; //   public $to; //  public $ammount; //  public $difficult; //   } class API { protected $db; public function __construct () { $dsn = "mysql:host=localhost;dbname=flc"; // DSN   $this->db = new PDO ($dsn, $username, $password); //     try { return true; //  . } catch (PDOException $exception) { return false; //  . } } } 

Le voici, le cadre de notre miracle. Tout d'abord, nous implémentons l'enregistrement et la génération de GUID pour nos portefeuilles. J'ai immédiatement créé une définition de fonction API vide et j'ai également trouvé une fonction de génération de GUID dans Google. N'oubliez pas les graines. Je viens de trouver une fonction pour obtenir des graines, pour obtenir un GUID unique.

  function make_seed () //      PHP { list ($usec, $sec) = explode (' ', microtime ()); return $sec + $usec * 1000000; } mt_srand (make_seed ()); 

Super. Et la fonction pour générer le GUID pour le portefeuille ressemble à ceci (ainsi que le talon lui-même):

  public function register () //    { } protected function genGUID4 () //  Google { return sprintf ('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand (0, 0xffff), mt_rand (0, 0xffff), mt_rand (0, 0xffff), mt_rand (0, 0x0fff) | 0x4000, mt_rand (0, 0x3fff) | 0x8000, mt_rand (0, 0xffff), mt_rand (0, 0xffff), mt_rand (0, 0xffff)); //     ,   . } 

Étant donné que nous faisons tout de manière anonyme, nous ne stockons pas IP ou e-mail. Pas de confirmation. Nous suffirons. En ~ 25 minutes, j'ai écrit une fonction d'enregistrement. Un seul mot de passe nous est demandé. La fonction API nous renverra le portefeuille.

  public function register ($password) //  $password -    { if ($this->db) //    { $walletId = 'FLC@' . $this->genGUID4 (); //      $hash = crc32 ($walletId) . $walletId . hash_hmac ('sha512', str_rot13 ($password), 'FLC'); //     . $hash = hash_hmac ('sha512', $hash, 'FLC2'); //     . $newUser = $this->db->prepare (" INSERT INTO `wallets` (walletId, loginHash, balance) VALUES (:walletId, :hash, :startBalance) "); //    . $newUser->bindParam (':walletId', $walletId, PDO::PARAM_STR); //     $newUser->bindParam (':hash', $hash, PDO::PARAM_STR); //     $newUser->bindParam (':startBalance', 0, PDO::PARAM_INT); //    (   ,   0!)   $newUser->execute (); //  . return ['walletId' => $walletId]; //     ( ) } else return false; //      . } 

Ici, j'ai brièvement décrit ce que fait telle ou telle ligne.

Message juste pour les gens et les programmeurs justes.
Si vous avez laissé vos contacts sur le site (sur lequel, peut-être, cette crypto-monnaie sera située), et ils vous écrivent quelque chose comme ceci:

"Bonjour, pouvez-vous aider?" J'ai gardé beaucoup de mani sur votre blockchain, et soudain j'ai perdu mon mot de passe, aidez-moi et vous serez bien »- n'hésitez pas à rejeter cette offre. L'essence de la crypto-monnaie est le stockage des numéros chiffrés en toute sécurité. Personne ne peut prouver qu'il possède un compte. Ainsi, n'importe quel attaquant peut même voler les fonds d'autres personnes même sans la participation de la victime! Ce n'est pas grave, bien que cette personne soit vraiment le propriétaire du compte, il vaut mieux refuser. Si vous avez perdu de l'argent, cela signifie que vous n'avez pas correctement stocké les données du compte. Pour plus de sécurité, nous n'implémenterons plus de récupération de mot de passe.

La fonction de hachage présentée ici peut être représentée comme suit:
hachage(w,pw)=crc32(w).w.hmac(pw)

La fonction fonctionne comme ceci:

Un mot de passe est entré, on vérifie si la base de données est connectée:

Oui, connecté. (Faisons un mot de passe 12345)
Nous générons l'adresse du portefeuille et écrivons dans $ walletId - nous obtenons quelque chose comme ceci: FLC @ c1cbe61d-a19d-4c82-ba17-3a577df0aeb5 (ce GUID a été généré par un autre site, j'ai ensuite ajouté le préfixe FLC @).

Nous calculons le hachage en texte brut. Dans la première série, nous obtenons les éléments suivants: 0087196442FLC @ c1cbe61d-A19D-4c82 -ba17-3a577df0aeb59ee77779db5a44ef3f60044fcb0e1170218e642cb9adc0789ddd08871ad95c7e1d3b1391c6c79774d319b5141bd3b13b717c3d389206ede659cb280949feac66 ( beaucoup de lettres, ne soyez pas surpris).
Au deuxième tour, le hachage deviendra à cent pour cent HMAC: 5e43cbb404c81efeb35162e5bba0766f20b340fbabcc66fd5f7a6a1993a8ccd43fc6384ac53f939acca4378681e2bb17912eacf6aaa6a6aa6

Nous écrivons tout cela dans la base de données.

En réponse, nous écrivons le numéro de portefeuille via lequel vous pouvez vous connecter.

Non, pas connecté.
Dans ce cas, vous ne devez pas vous attendre à quelque chose qui en vaille la peine, renvoyez FAUX.

Voici à quoi ressemble un système d'enregistrement sophistiqué. En fait, cela semble très simple. Et en termes de code - beaucoup plus compliqué.

Nous passerons plus de temps et ferons l'autorisation. Avec l'autorisation, la situation est plus simple. Nous recherchons un compte et essayons de nous connecter, connaissant les algorithmes de génération de hachage de mot de passe familiers. Ensuite, nous vérifions, et si les données sont correctes, nous donnons au client une ligne importante dans laquelle les données sont stockées pour la communication entre le serveur et le mineur.

De moi-même.
On dirait que nous ne faisons pas de crypto-monnaie, mais un système d'autorisation entre PHP sur le serveur et PHP utilisant php.exe. Dans la deuxième partie, nous ajouterons un deuxième gâteau à notre «gâteau», dans lequel nous verrons quelque chose lié à l'exploitation minière, à la blockchain et aux transactions.

Après 15 à 25 minutes supplémentaires, la fonction d'autorisation était prête. Voir ce code ci-dessous:

  public function login ($walletId, $password) //  { if ($this->db) //    { $hash = crc32 ($walletId) . $walletId . hash_hmac ('sha512', str_rot13 ($password), 'FLC'); //     . $hash = hash_hmac ('sha512', $hash, 'FLC2'); //     . $newUser = $this->db->prepare (" SELECT * FROM `wallets` WHERE walletId = :walletId AND loginHash = :hash LIMIT 0, 1 "); //    . $newUser->bindParam (':walletId', $walletId, PDO::PARAM_STR); //     $newUser->bindParam (':hash', $hash, PDO::PARAM_STR); //     $newUser->execute (); //  . $object = $newUser->fetch_object (); //   ,     if ($object AND hash_equals ($object->hash, $hash)) //   ,   . { $loginString = new stdClass; //    stdClass $loginString->hash = $hash; //       . $loginString->wallet = $walletId; return ['token' => serialize ($loginString)]; //      ,   . } else return false; //   / . } else return false; //    } 

Ce code est presque un enregistrement, mais fonctionne dans l'algorithme inverse. Le travail avec les utilisateurs a pris fin.

Postcondition


Pendant cette période intéressante de lecture de l'article, nous avons fait ce qui suit:

  • Nous avons brièvement fait connaissance avec la crypto-monnaie et comment la construire correctement.
  • Ils ont brièvement répondu à la question "Est-il judicieux de créer une crypto-monnaie centralisée, et également en PHP?"
  • Discuté des notes avant d'effectuer cette tâche
  • Implémentation d'un système de comptes cryptographiques.

Et maintenant, vous pouvez lire ce qui était derrière les stores:

Sous le rideau
Cet article a été écrit environ 4-5 heures (tout le coucher du soleil et le soir). Pendant ce temps, comme je l'ai écrit, j'ai évolué, mais quand il s'agit d'écrire un article sur Habrahabr, mon désir de réaliser mon rêve ne s'estompe pas. En effet, en raison du concept simple de POO, il était plus facile pour moi de l'utiliser que MySQLi, ou pire, les fonctions ordinaires avec le préfixe mysql_, qui sont considérées comme obsolètes et ne sont plus adaptées au développement en PHP.

Ce que nous ferons la prochaine fois:

  • Faisons l'exploitation minière.
  • Voyons comment les transactions et les blocs sont organisés.
  • Nous ferons des transactions et nous donnerons un sens à la classe Block inutilisée.

Merci d'avoir lu! A bientôt! Ceci est mon premier article - j'attends des critiques.

Source: https://habr.com/ru/post/fr481392/


All Articles