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
- As I wrote a semi-decentralized cryptocurrency in PHP. (Part 1 - Collecting Libraries)
- 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
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.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.