Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
.idea
test.txt
test.php

vendor
**/__pycache__/
Blockchain/Python_Package/virtual_env/
37 changes: 37 additions & 0 deletions Blockchain/Backend/API/Client_calls/BaseCurl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php
class BaseCurl
{
public static function curlSkeletonIfDataSend($curlObj, $OpType, $data)
{
curl_setopt($curlObj, CURLOPT_CUSTOMREQUEST, $OpType);
curl_setopt($curlObj, CURLOPT_POSTFIELDS, $data);
curl_setopt($curlObj, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curlObj, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data))
// Set an authorization header if needed
// 'Authorization: Bearer YourAccessToken',
);
$response = curl_exec($curlObj);
// Get the HTTP response code
$httpCode = curl_getinfo($curlObj, CURLINFO_HTTP_CODE);

// Check for cURL errors and handle response code
if (curl_errno($curlObj))
{
return ["error"=>true, "errorType" => "Curl Error", "data"=>curl_error($curlObj)];
}
elseif ($httpCode >= 400)
{
return ["error" => true, "errorType" => "HTTP Error", "data" => $httpCode];
} else
{
return ["data" => $response];
}
}

public static function closeCurl($curlObj)
{
curl_close($curlObj);
}
}
25 changes: 25 additions & 0 deletions Blockchain/Backend/API/Client_calls/ClientAPI.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php
require_once 'Blockchain/Backend/API/Client_calls/BaseCurl.php';
class ClientAPI extends BaseCurl
{
public static $clientAddress = 'http://localhost:5000/generate_keys';

public static function postRequestAPI($curlObject)
{
curl_setopt($curlObject, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curlObject);

if (curl_errno($curlObject)) {
return ["error"=>true, "errorType" => "Curl Error", "data" => curl_error($curlObject)];
} else {
return ["data" => $response];
}
}

public static function errorHandleResponse($data): bool
{
return array_key_exists('error', $data);
}


}
22 changes: 22 additions & 0 deletions Blockchain/Backend/API/Client_calls/PluginHelperAPI.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
require_once 'Blockchain/Backend/API/Client_calls/BaseCurl.php';
class PluginHelperAPI extends BaseCurl
{
public static $clientAddress = 'http://localhost:5000/';

public static function postRequestAPI($url, $postData)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo "cURL Error: " . curl_error($ch);
die();
}
return $response;
}

}
10 changes: 7 additions & 3 deletions Blockchain/Backend/core/Blockchain.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require_once 'Blockchain/Backend/core/BlockHeader.php'; // Assuming the blockheader.php file path
require_once 'Blockchain/Backend/core/database/BaseDB.php'; // Assuming the blockheader.php file path
require_once 'Blockchain/Backend/util/util.php'; // Assuming the util.php file path
require_once 'Blockchain/Backend/core/transactions/Coinbase.php';

$ZERO_HASH = str_repeat('0', 64);
$VERSION = 1;
Expand Down Expand Up @@ -32,12 +33,15 @@ private function GenesisBlock() {

public function addBlock($BlockHeight, $prevBlockHash) {
$timestamp = time();
$Transaction = "Code Architect sent {$BlockHeight} Bitcoins to Indranil";
$merkleRoot = bin2hex(hash256($Transaction));
$coinbaseInstance = new Coinbase($BlockHeight);
$coinbaseTx = $coinbaseInstance->coinbaseTransaction();
$merkleRoot = ' ';
$bits = 'ffff001f';
$blockheader = new BlockHeader($GLOBALS['VERSION'], $prevBlockHash, $merkleRoot, $timestamp, $bits);
$blockheader->mine();
$block = new Block($BlockHeight, 1, (array)$blockheader, 1, $Transaction);
$block = new Block($BlockHeight, 1, (array)$blockheader, 1, $coinbaseTx);
// print_r((array)$block);
// die();
$this->writeOnDisk((array)$block);
}

Expand Down
21 changes: 21 additions & 0 deletions Blockchain/Backend/core/Script.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php
class Script
{
public $cmds;

public function __construct($cmds = null)
{
if ($cmds === null) {
$this->cmds = [];
} else {
$this->cmds = $cmds;
}
}

public static function p2pkhScript($h160)
{
// Takes a hash160 and returns the p2 public key hash ScriptPubKey
$script = new Script([0x76, 0xA9, $h160, 0x88, 0xAC]);
return $script;
}
}
130 changes: 130 additions & 0 deletions Blockchain/Backend/core/transactions/Coinbase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?php
require_once 'Blockchain/Backend/core/transactions/TxIn.php';
require_once 'Blockchain/Backend/core/transactions/TxOut.php';
require_once 'Blockchain/Backend/core/transactions/Tx.php';
require_once 'Blockchain/Backend/core/Script.php';
require_once 'Blockchain/Backend/util/util.php';
require_once 'Blockchain/Backend/API/Client_calls/PluginHelperAPI.php';

const ZERO_HASH = "0000000000000000000000000000000000000000000000000000000000000000";
const REWARD = 50;
const PRIVATE_KEY = "56114968769095885066321288702375272595970830268400415922098497799492460020984";
const MINER_ADDRESS = "1K3if2mFojLAWVtdD1eeYYKNVCwghpBvgb";

class Coinbase {
public function __construct($blockHeight) {
$this->blockHeightIntLittleEndian = intToLittleEndian($blockHeight, bytesNeeded($blockHeight));
}

public function coinbaseTransaction() {
$prevTx = hex2bin(ZERO_HASH);
$prevIndex = 0xFFFFFFFF;

$txIns = [];
$txIns[] = new TxIn($prevTx, $prevIndex);
$txIns[0]->scriptSig->cmds[] = $this->blockHeightIntLittleEndian;

$txOuts = [];
$targetAmount = REWARD * 100000000;
$hexValue = $this->decodeBase58API(MINER_ADDRESS);
$targetH160 = $hexValue;
$targetScript = Script::p2pkhScript($targetH160);
$txOuts[] = new TxOut($targetAmount, $targetScript);

return new Tx(1, $txIns, $txOuts, 0);
}

public function decodeBase58API($value)
{
$address = PluginHelperAPI::$clientAddress;
$url = $address."get_decode_base58";
$ch = curl_init($url);
$data = json_encode(array(
"value" => $value
));
$val = PluginHelperAPI::curlSkeletonIfDataSend($ch, "POST", $data);
$data = json_decode($val['data'], true);
return $data['byte_data'];
}

}

//$address = PluginHelperAPI::$clientAddress;
//$url = $address."get_decode_base58";
//$ch = curl_init($url);
//$data = json_encode(array(
// "value" => "1K3if2mFojLAWVtdD1eeYYKNVCwghpBvgb"
//));
//$val = PluginHelperAPI::curlSkeletonIfDataSend($ch, "POST", $data);
//$data = json_decode($val['data'], true);
//echo "\n\n";
//print_r($data['byte_data']);
//function decodeBase58API($value)
//{
// $address = PluginHelperAPI::$clientAddress;
// $url = $address . "get_decode_base58";
// $ch = curl_init($url);
// $data = json_encode(array(
// "value" => $value
// ));
// $val = PluginHelperAPI::curlSkeletonIfDataSend($ch, "POST", $data);
// $data = json_decode($val['data'], true);
// return $data['byte_data'];
//}
//
//$data = decodeBase58API("1K3if2mFojLAWVtdD1eeYYKNVCwghpBvgb");
//echo "\n\n";
//print_r($data);
//echo "\n\n";
//
//
//$binaryData = hex2bin($data);
//print_r($binaryData);
//echo "\n\n";
//
//// Perform operations on the binary data (if needed)
//
//// Convert the binary data back to a hexadecimal string
//$resultHexadecimal = bin2hex($binaryData);
//
//// Output the result
//echo $resultHexadecimal;

////$hexString = $data;
////$byteString = 'b"' . implode('\x', str_split($hexString, 2)) . '"';
//$byteString = hex2bin($data);
//$formattedBinary = 'b"';
//foreach (str_split($byteString) as $byte) {
// $formattedBinary .= '\x' . bin2hex($byte);
//}
//$formattedBinary .= '",';
//
//echo $formattedBinary;
//echo "\n\n";
//
//$hexString = '';
//$matches = [];
//if (preg_match('/b"(.+)",/', $formattedBinary, $matches)) {
// $hexBytes = explode('\x', $matches[1]);
// foreach ($hexBytes as $hexByte) {
// $hexString .= chr(hexdec($hexByte));
// }
// $hexString = bin2hex($hexString);
// echo $hexString;
//} else {
// echo "Invalid format.";
//}
//echo "\n\n";
//
//$hexString = '';
//$matches = [];
//
//if (preg_match('/b"(.+)",/', $formattedBinary, $matches)) {
// $hexBytes = explode('\x', $matches[1]);
// foreach ($hexBytes as $hexByte) {
// $hexString .= bin2hex(hex2bin($hexByte));
// }
// echo $hexString;
//} else {
// echo "Invalid format.";
//}
71 changes: 71 additions & 0 deletions Blockchain/Backend/core/transactions/Tx.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

class Tx
{
public $locktime;
public $txOuts;
public $txIns;
public $version;

public function __construct($version, $txIns, $txOuts, $locktime) {
$this->version = $version;
$this->txIns = $txIns;
$this->txOuts = $txOuts;
$this->locktime = $locktime;
}

public function serialize() {
$result = intToLittleEndian($this->version, 4);
$result .= count($this->txIns);

// Add serialization logic here

return $result;
}

public function isCoinbase() {
if (count($this->txIns) !== 1) {
return false;
}

$firstInput = $this->txIns[0];
if ($firstInput->prevTx !== hex2bin(ZERO_HASH)) {
return false;
}

if ($firstInput->prevIndex !== 0xFFFFFFFF) {
return false;
}

return true;
}

public function toDict() {
// Convert Transaction Input to dict
foreach ($this->txIns as $txIndex => $txIn) {
if ($this->isCoinbase()) {
$txIn->scriptSig->cmds[0] = littleEndianToInt($txIn->scriptSig->cmds[0]);
}

$txIn->prevTx = bin2hex($txIn->prevTx);

foreach ($txIn->scriptSig->cmds as $index => $cmd) {
if (is_string($cmd)) {
$txIn->scriptSig->cmds[$index] = bin2hex($cmd);
}
}

$txIn->scriptSig = (array) $txIn->scriptSig;
$this->txIns[$txIndex] = (array) $txIn;
}

// Convert Transaction Output to dict
foreach ($this->txOuts as $index => $txOut) {
$txOut->scriptPubkey->cmds[2] = bin2hex($txOut->scriptPubkey->cmds[2]);
$txOut->scriptPubkey = (array) $txOut->scriptPubkey;
$this->txOuts[$index] = (array) $txOut;
}

return (array) $this;
}
}
17 changes: 17 additions & 0 deletions Blockchain/Backend/core/transactions/TxIn.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php
require_once 'Blockchain/Backend/core/Script.php';

class TxIn
{
public $prevTx;
public $prevIndex;
public $scriptSig;
public $sequence;

public function __construct($prevTx, $prevIndex, $scriptSig = null, $sequence = 0xFFFFFFFF) {
$this->prevTx = $prevTx;
$this->prevIndex = $prevIndex;
$this->scriptSig = $scriptSig ?? new Script();
$this->sequence = $sequence;
}
}
12 changes: 12 additions & 0 deletions Blockchain/Backend/core/transactions/TxOut.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

class TxOut
{
public $amount;
public $scriptPubkey;

public function __construct($amount, $scriptPubkey) {
$this->amount = $amount;
$this->scriptPubkey = $scriptPubkey;
}
}
Loading