As I wrote a semi-decentralized cryptocurrency in PHP. (Part 2 - Development)

Foreword


In one of the previous articles I talked about which libraries are useful to us and compared this idea with that unsuccessful one. In this part, we will develop the cryptocurrency itself and configure the tracker. Let's not hesitate, let's go.

List of Articles


  1. As I wrote a semi-decentralized cryptocurrency in PHP. (Part 1 - Collecting Libraries)
  2. As I wrote a semi-decentralized cryptocurrency in PHP. (Part 2 - Development)

Tracker Installation


Before we start installing the web tracker, I’ll tell you - the library supports two types of tracker - Native and Web. Native-tracker can be used on various VDS, and they will easily maintain lists of users on the network.
Here I will use a Web tracker that can be easily installed on the site.
We pass to the GitHub repository, which I talked about in the previous part. The master branch does not interest us, we select web. Download the archive with this thread, unpack it and open in index pad or somewhere else, where you prefer, the index.php file. Here is the content of the file:

index.php
<?php

/**
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * @package     Bit Points Network
 * @copyright   2020 Podvirnyy Nikita (Observer KRypt0n_)
 * @license     GNU GPLv3 <https://www.gnu.org/licenses/gpl-3.0.html>
 * @author      Podvirnyy Nikita (Observer KRypt0n_)
 * 
 * Contacts:
 *
 * Email: <suimin.tu.mu.ga.mi@gmail.com>
 * VK:    <https://vk.com/technomindlp>
 *        <https://vk.com/hphp_convertation>
 * 
 */

namespace BPN;

const TRACKER_KEY = 'EFJI#*$&(*#WEF(@Q#)(DFJSAO(@#*$)REFSKE)UJ*#@(&$';

require 'ext/DH-Generator/Generator.php';
require 'php/User.php';
require 'php/Tracker.php';

$tracker = new Tracker;
$tracker->update ();

if (isset ($_GET['r']))
    $tracker->processRequest ($_GET['r']);

You must change the TRACKER_KEY constant to many different characters so that it does not match the original file.

Let's say this:


const TRACKER_KEY = 'sdT*&Y&*YO*&T*OGTGYFIYYUFGKUHLIYIj9sfhysdphphdpsfhBLABLABLAhsidlfhlisd';

This is just an example. You must change in your own way. We post it all on the hosting. Web tracker setup is complete.

What is this tracker for?

Development


General


Since this is our application, you need to connect all the packages and components, namely the Composer and non-Composer packages, establish the structure of accounts and the local database of accounts, make the interaction between the application and the structures, and initialize the application itself.

General.php
<?php

declare (strict_types=1);

require_once __DIR__ . '/vendor/autoload.php'; #   

require_once 'PHP/Structure.php';              # 
require_once 'PHP/UserAPI.php';                # 

require_once 'NotComposer/vendor/autoload.php';#  - 

require_once 'PHP/App.php';                    # 


The library for BIP39 requires strict typing; we declare it in the first lines of code.
The BIP39 and BIP44 libraries themselves are loaded with the autoload.php file, standard for Composer.
We will declare the data structure in Structure.php.

Functions for working with wallets will be in the UserAPI.php file.

The BPN and phpblockchain libraries are not compatible with Composer, we create a file with a name similar to Composer.

We take out the application itself in App.php - it will be the last connected file there, since we must first load everything from above.

NotComposer / vendor / autoload.php


I already said that those two libraries are not compatible with Composer, there are files that aren’t native to them, or they don’t exist at all, and they are also absent on Packagist. You have to manually download them, and connect them. This file is designed for that.

Structure


The data structures here are designed to make it easier to handle wallets. The library is needed for UserAPI.php to do the work with wallets, namely registering and restoring the wallet, and for App.php to use these wallets.
Structure.php
<?php

class Account
{
	public $address;
	public $publicKey;
	protected $privateKey;

	public function getPrivateKey ()
	{
		return $this->privateKey;
	}

	public function setPrivateKey ($key)
	{
		$this->privateKey = $key;
	}
}

class AccountChain
{
	public $accounts;
}


Primitive code, right?

UserAPI.php


The intermediary between Structure.php and App.php is UserAPI.php. Through it, we will already operate with wallets, register new ones and restore existing ones.

Code of this file:

UserAPI.php
<?php

use \FurqanSiddiqui\BIP39\BIP39;
use BIP\BIP44;

class User
{
	public $account;

	public function registerNewAccount ($password)
	{
		$mnemonic = BIP39::Generate (18);
		$seed = $mnemonic->generateSeed ($password, 256);

		$HDKey = BIP44::fromMasterSeed ($seed)->derive ("m/44'/0'/0'/0/1");

		$newAccount = new Account;
		$newAccount->address = '1x' . hash ('ripemd160', hash ('sha512', $HDKey->publicKey));
		$newAccount->publicKey = $HDKey->publicKey;
		$newAccount->setPrivateKey ($HDKey->privateKey);

		$accountChain = new AccountChain;
		$accountChain->accounts = [];
		$accountChain->accounts[] = $newAccount;
		
		return ['words' => $mnemonic->words, 'chain' => $accountChain];
	}

	public function registerNewAccountInChain (&$chain, $password, $prevAccountMnemonic)
	{
		$mnemonic = BIP39::Words ($prevAccountMnemonic);
		$seed = $mnemonic->generateSeed ($password, 256);

		$accountsCount = sizeof ($chain->accounts) + 1;

		$HDKey = BIP44::fromMasterSeed ($seed)->derive ("m/44'/0'/0'/0/{$accountsCount}");

		$newAccount = new Account;
		$newAccount->address = '1x' . hash ('ripemd160', hash ('sha512', $HDKey->publicKey));
		$newAccount->publicKey = $HDKey->publicKey;
		$newAccount->setPrivateKey ($HDKey->privateKey);

		$chain->accounts[] = $newAccount;

		return ['chain' => $chain];
	}

	public function restoreAccount ($mnemonic, $password, $accountNo)
	{
		$mnemonic = BIP39::Words ($mnemonic);
		$seed = $mnemonic->generateSeed ($password, 256);

		$HDKey = BIP44::fromMasterSeed ($seed)->derive ("m/44'/0'/0'/0/{$accountNo}");

		$newAccount = new Account;
		$newAccount->address = '1x' . hash ('ripemd160', hash ('sha512', $HDKey->publicKey));
		$newAccount->publicKey = $HDKey->publicKey;
		$newAccount->setPrivateKey ($HDKey->privateKey);

		$accountChain = new AccountChain;
		$accountChain->accounts = [];
		$accountChain->accounts[] = $newAccount;

		return $accountChain;
	}
}


The app


The very logic of our client. She is responsible for everything, for working as a miner, getting a balance, sending transactions and making them homemade.

App.php
, . 3 — , .

To summarize


We talked a lot about something, about structures, about keeping wallets and a lot of things. In the next part, we will continue to show currency codes.

TL; DR
— — FlyCoin FLC

All Articles