Beispiel #1
0
if ($forwardedFromRoot != 0) {
    // Some other root forwarded the request here. Just return my challenge:
    echo $myChallenge;
    exit;
}
// Forward this request to other root nodes, stating that this root node is leading it.
// Custom forward call here because domain is almost always given over GET.
// I.e. php://input isn't being set to what we want it to be.
// pHeader (2nd parameter of sendToRoot) is the same string as seen inside the forward() function.
// Base64 the payload:
$payload = base64_encode('{"domain":"' . $domain . '"}');
// Forward now!
$results = sendToRoot($payload, 'eyJmd2QiOjF9');
// See above about this base64 text
// Results is now a set of successful responses. Each contains the signature
// of the challenge for a given endpoint and the public key.
// Verify each signature (except our own - we pass that in instead) to test if we have a majority.
// If we do, forward the whole set to complete the creation of a new entity!
$fullSet = testMajority($results, $hexPublicKey, $mySignature);
// Majority formed! - send it to the root so everyone can verify all the signatures too.
// Add the domain to it:
$fullSet = '{"domain":"' . $domain . '","challenges":' . $fullSet . '}';
// For info on the base64 string in the middle, see the forward() function.
sendToRoot(base64_encode($fullSet), 'eyJmd2QiOjF9', false, 'entity/challenge/success');
// Remove from pending:
$dz->query('delete from `Root.Entities.Pending` where `Endpoint`="' . $domain . '"');
// Transfer the entity to being an official entity:
$dz->query('insert into `Root.Entities` (`Key`,`Endpoint`,`Type`,`Group`,`Name`,`Country`) values (unhex("' . $hexPublicKey . '"),"' . $domain . '",' . $row['Type'] . ',' . $thisEntity['Group'] . ',"' . $row['Name'] . '",' . $row['Country'] . ')');
// Create the change event too:
changed('entity', array('key' => $hexPublicKey, 'type' => $row['Type'], 'endpoint' => $domain, 'group' => $thisEntity['Group'], 'name' => $row['Name'], 'country' => $row['Country']));
echo '{"entity":"' . $domain . '"}';
Beispiel #2
0
// A root node collected all those signatures and then sent the whole lot to every root node.
// This allows them to independently form a proof of majority.
// In this case, when the majority is successful, an issue occurs.
// Always JSON posted here:
postedTo();
if ($forwardedFromRoot == 0) {
    // Must have been forwarded by a root node.
    error('entity/notroot');
}
// Get the challenges:
// We want it as-is (it's an array)
$challenges = safe('challenges', VALID_ARRAY);
// Amount must be a positive non-zero number:
$amount = safe('amount', VALID_NUMBER);
$amount = (int) $amount;
if ($amount == 0) {
    // They specified 0 - this isn't valid:
    error('field/invalid', 'amount');
}
// Get the address to issue into:
$hexAddress = safe('address', VALID_HEX);
// Test for a majority. This time we check all signatures including our own
// because the whole set came from somewhere else (we're not leading the majority process here).
testMajority($challenges, $hexAddress . $amount);
// Majority formed!
// Note: From the previous test a few ms ago, we know the balance exists and is of the correct commodity.
// Because of the locking process, we know that the balance can't have been emptied and deleted.
// Update the amount now!
$dz->query('update `Root.Balances` set Balance=Balance+' . $amount . ',LockedBalance=LockedBalance-' . $amount . ' where `Key`=UNHEX("' . $hexAddress . '")');
// Create an issue record (occurs in issue/success as well):
changed('issue', array('amount' => $amount, 'to' => $hexAddress, 'tag' => $tag));
Beispiel #3
0
// In this case, when the majority is successful, an entity is created.
// Always JSON posted here:
postedTo();
if ($forwardedFromRoot == 0) {
    // Must have been forwarded by a root node.
    error('entity/notroot');
}
// Domain must be a valid domain name only:
$domain = safe('domain', VALID_DOMAIN);
// Get the challenges:
$challenges = safe('challenges', VALID_ARRAY);
// Get the pending request:
$row = $dz->get_row('select * from `Root.Entities.Pending` where `Endpoint`="' . $domain . '"');
if (!$row) {
    // Not found!
    error('entity/notfound');
}
// Get the public key bytes:
$publicKey = $row['Key'];
// Get the public key in hex:
$hexPublicKey = bin2hex($publicKey);
// Test for a majority. This time we check all signatures including our own
// because the whole set came from somewhere else (we're not leading the majority process here).
testMajority($challenges, $hexPublicKey);
// Majority formed!
// Remove from pending:
$dz->query('delete from `Root.Entities.Pending` where `Endpoint`="' . $domain . '"');
// Transfer the entity to being an official entity:
$dz->query('insert into `Root.Entities` (`Key`,`Endpoint`,`Type`,`Group`,`Name`,`Country`) values (unhex("' . $hexPublicKey . '"),"' . $domain . '",' . $row['Type'] . ',' . $thisEntity['Group'] . ',"' . $row['Name'] . '",' . $row['Country'] . ')');
// Create the change event too:
changed('entity', array('key' => $hexPublicKey, 'type' => $row['Type'], 'endpoint' => $domain, 'group' => $thisEntity['Group'], 'name' => $row['Name'], 'country' => $row['Country']));
Beispiel #4
0
// Validate the signature:
$signed = bin2hex($publicKey) . '.' . $balance;
if (!verify($signature, $signed, $address)) {
    // Invalid signature:
    error('signature/invalid');
}
// Valid claim!
// Sign it to say this node agrees, using some additional random data:
$challenge = randomString(45);
$myChallenge = '{"challenge":"' . $challenge . '","signature":"' . base64_encode(sign($challenge . $signed)) . '"}';
// Was this request forwarded?
if ($forwardedFromRoot != 0) {
    // Yes - just output my challenge. We'll wait for a majority.
    echo $myChallenge;
    exit;
}
// Forward:
$responses = forward();
// Did it obtain a majority?
$fullSet = testMajority($responses, $signed, $myChallenge);
// Yes - majority obtained! Forward the key set to the root now:
// Add the address:
$fullSet = '{"address":"' . $address . '","challenges":' . $fullSet . '}';
// For info on the base64 string in the middle, see the forward() function.
$encodedFullSet = base64_encode($fullSet);
// Send now:
sendToRoot($encodedFullSet, 'eyJmd2QiOjF9', false, 'balance/claim/success');
// Update the balance:
$dz->query('update `Root.Balances` set `Entity`=' . $verifiedEntity . ' where `Key`=unhex("' . $address . '")');
// Create a clm record (occurs in balance/claim/success as well):
changed('clm', array('entity' => $verifiedEntityEndpoint, 'address' => $address, 'signature' => $signature, 'balance' => $balance));
Beispiel #5
0
$myPair = '{"challenge":"' . $challenge . '","signature":"' . base64_encode($rootSignature) . '"}';
// Is this already forwarded? If so, just return my signature.
if ($forwardedFromRoot != 0) {
    // Some other root forwarded the request here.
    // Create a lock for this balance. This is for if a majority is not obtained and we need to reverse the lock:
    $dz->query('insert into `Root.Balances.Locks`(`RequestID`,`Amount`) values("' . $signedPublicID['id'] . '",' . $amount . ')');
    // Output the signature and stop:
    echo $myPair;
    exit;
}
// Forward to the group:
$results = forward();
// Next, verify all the signatures. If we have a valid majority, forward it to the group.
// At which point, a successful issue has occured.
// Note that the false turns off the error (and instead we look out for a 'false')
$fullSet = testMajority($results, $signed, $myPair, false);
if ($fullSet === false) {
    $majority = false;
    // No majority formed. Unlike transfer/create/success, this can occur in normal circumstances.
    // As this is the same file which creates the balance locks in the first place, we can (and must) safely
    // reverse those locks here:
    // Send the from amount back to it's balance:
    $dz->query('update `Root.Balances` set LockedBalance=LockedBalance-' . $amount . ',Balance=Balance+' . $amount . ' where `Key`=UNHEX("' . $fromAddress . '")');
    // And the to amount needs to simply have the locked amount reduced:
    $dz->query('update `Root.Balances` set LockedBalance=LockedBalance-' . $amount . ' where `Key`=UNHEX("' . $toAddress . '")');
    // Now we need to remove any remote locks too.
    // We do it by calling the same function but with an empty results set, which is set like so:
    $fullSet = '{}';
} else {
    $majority = true;
    // Majority obtained! Forward all the signatures (fullSet) to everyone else.
Beispiel #6
0
<?php

// This occurs when every root node has signed to say it believes an issue was valid.
// A root node collected all those signatures and then sent the whole lot to every root node.
// This allows them to independently form a proof of majority.
// In this case, when the majority is successful, an issue occurs.
// Always JSON posted here:
$publicKey = postedTo(true);
if ($forwardedFromRoot == 0) {
    // Must have been forwarded by a root node.
    error('entity/notroot');
}
// Get the challenges:
// We want it as-is (it's an array)
$challenges = safe('challenges', VALID_ARRAY);
// Get the signature, address and current balance:
$signature = safe('signature', VALID_BASE64);
$address = safe('address', VALID_HEX);
$balance = safe('balance', VALID_NUMBER);
// The signed data is as follows:
$signed = bin2hex($publicKey) . '.' . $balance;
// Test for a majority. This time we check all signatures including our own
// because the whole set came from somewhere else (we're not leading the majority process here).
$majority = testMajority($challenges, $signed);
// Majority formed!
// Update the balance:
$dz->query('update `Root.Balances` set `Entity`=' . $verifiedEntity . ' where `Key`=unhex("' . $address . '")');
// Create a clm record (occurs in balance/claim/success as well):
changed('clm', array('entity' => $verifiedEntityEndpoint, 'address' => $address, 'signature' => $signature, 'balance' => $balance));
Beispiel #7
0
}
// Get the address to issue into:
$hexAddress = safe('address', VALID_HEX);
// Lock the given amount into the given receiving address:
receiveLocked($hexAddress, $amount, $tag, $issuerID);
// Generate some random challenge data:
$challenge = randomString(45);
// Sign the challenge data along with the hex public key and amount:
$signature = sign($challenge . $hexAddress . $amount);
// Build my signature JSON:
$myPair = '{"challenge":"' . $challenge . '","signature":"' . base64_encode($signature) . '"}';
// Is this already forwarded? If so, just return my signature.
if ($forwardedFromRoot != 0) {
    // Some other root forwarded the request here. Just output the signature and stop:
    echo $myPair;
    exit;
}
// Forward to the group:
$results = forward();
// Next, verify all the signatures. If we have a valid majority, forward it to the group.
// At which point, a successful issue has occured.
$fullSet = testMajority($results, $hexAddress . $amount, $myPair);
// Majority obtained! Forward all the signatures to everyone else.
// Add the amount and address:
$fullSet = '{"amount":"' . $amount . '","address":"' . $hexAddress . '","challenges":' . $fullSet . '}';
// For info on the base64 string in the middle, see the forward() function.
sendToRoot(base64_encode($fullSet), 'eyJmd2QiOjF9', false, 'commodity/issue/success');
// Update the amount now!
$dz->query('update `Root.Balances` set Balance=Balance+' . $amount . ',LockedBalance=LockedBalance-' . $amount . ' where `Key`=UNHEX("' . $hexAddress . '")');
// Create an issue record (occurs in issue/success as well):
changed('issue', array('amount' => $amount, 'to' => $hexAddress, 'tag' => $tag));
Beispiel #8
0
$toGroup = safe('group', VALID_NUMBER, $to);
// Is it going to another group?
$outbound = $toGroup != $thisEntity['Group'];
// Get the amount to transfer:
$amount = safe('amount', VALID_NUMBER);
if ($amount == 0) {
    // Must be non-zero (we know it's positive as VALID_NUMBER doesn't accept -):
    error('field/invalid', 'amount');
}
// Get the signature for the address itself:
$signature = safe('signature', VALID_BASE64);
// The signed data is as follows:
$signed = $fromGroup . '/' . $fromAddress . '-' . $toGroup . '/' . $toAddress . '-' . $amount . '-' . $fromBalance;
// Test for a majority. This time we check all signatures including our own
// because the whole set came from somewhere else (we're not leading the majority process here).
$majority = testMajority($challenges, $signed, null, false);
if (!$majority) {
    // No majority formed. We were told about this so we can reverse our locks.
    // We must first check if we actually had a lock for this request like so:
    $lock = $dz->get_row('select Amount from `Root.Balances.Locks` where RequestID="' . $signedPublicID['id'] . '"');
    if ($lock) {
        // Remove the complete lock now, provided amounts match:
        if ($lock['Amount'] != $amount) {
            // Nope - invalid input.
            error('field/invalid', 'amount');
        }
        // Send the from amount back to it's balance:
        $dz->query('update `Root.Balances` set LockedBalance=LockedBalance-' . $amount . ',Balance=Balance+' . $amount . ' where `Key`=UNHEX("' . $fromAddress . '")');
        // Delete the lock row:
        $dz->query('delete from `Root.Balances.Locks` where RequestID="' . $signedPublicID['id'] . '"');
        // And the to amount needs to simply have the locked amount reduced: