function sign($data, $privateKeyRaw = NULL) { if ($privateKeyRaw == null) { global $thisEntity; // Load the private key if needed (from a hex string): if (!isset($thisEntity['PrivateKeyBytes'])) { // Load it now: $thisEntity['PrivateKeyBytes'] = hex2bin($thisEntity['PrivateKey']); } // Grab the raw private key (bytes): $privateKeyRaw = $thisEntity['PrivateKeyBytes']; } // Get the double hash of the data: $msg32 = hash('sha256', hash('sha256', $data, true), true); // Create a context: $ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); // Sign: $signature; if (secp256k1_ecdsa_sign($ctx, $msg32, $privateKeyRaw, $signature) != 1) { // This is a 500 error. Unable to sign. serverError(); } // Serialize the signature: $serialized = ''; secp256k1_ecdsa_signature_serialize_der($ctx, $signature, $serialized); return $serialized; }
<?php // Signs a message using an accounts signing key. Used for smart contracts. postedTo(); if ($verifiedAccount == 0) { // Account required! error('account/required'); } // Get the signing key (bytes): $account = $dz->get_row('select `SignKey` from `Bank.Accounts` where ID=' . $verifiedAccount); if (!$account) { // System error. serverError(); } // Get the private key (bytes): $privateKey = $account['SignKey']; // The message can be just about anything. $message = safe('message', true); // Is it actually text? if (!is_string($message)) { // The message must be a string. error('field/invalid', 'message'); } // Sign the message (sig is bytes): $sig = sign($message, $privateKey); // Ok! echo '{"signature":"' . base64_encode($sig) . '"}';
if ($params) { $output = call_user_func_array(array($controller, $function), $params); } else { $output = $controller->{$function}(); } echo $output; } catch (NotFoundException $e) { notFound($format, $route->getUri()); } catch (UnauthorizedException $e) { unauthorized($format, $e, $route->getUri()); // User safe error message (usually invalid input, etc) } catch (UserSafeException $e) { userError($format, $e); // Unexpected Exception } catch (Exception $e) { serverError($format, $e, $env->isProduction()); } function notFound($format, $uri) { http_response_code(404); if ($format == 'plain') { echo "Resource Not Found\nThere is no resource located at {$uri}\n"; } else { if ($format == 'html') { $view = ViewFactory::createView('Error\\NotFound'); $view->setResource($uri); } else { $view = ViewFactory::createDataView(); $view->setError("There is no resource located at {$uri}"); } echo $view->generateView();
function getAddress(&$transferData) { global $dz, $thisEntity; $username = $transferData['Username']; $reference = $transferData['Reference']; $title = $transferData['Title']; // Get the entity of the user being paid: $toPay = $dz->get_row('select `Entity` from `Root.Usernames` where `Username`="' . $username . '"'); if (!$toPay) { // Username was not found. error('username/notfound'); } // Is the entity the same as this one? $entityID = $toPay['Entity']; // Transaction delay, if one is applicable. // This will almost always be zero representing that a transaction is expected to be in the 2s limit. $delay = '0'; if ($entityID == $thisEntity['ID']) { // Yes! This is an internal transaction (i.e. within this bank). No addressing required. $toGroup = $thisEntity['Group']; // return null; } // This is a transaction between banks. We'll need an address to send to: $entityInfo = $dz->get_row('select `Group`,`Endpoint` from `Root.Entities` where ID=' . $entityID); if (!$entityInfo) { // This server has out-of-date root information. serverError(); } // Got a from username? (Optional): if (isset($transferData['FromUsername'])) { // Add it: $privText = ',"from":"' . $transferData['FromUsername'] . '","name":"' . $transferData['Name'] . '"'; } else { $privText = ''; } // Send the username and reference pair to the username/send API. // In response we'll get an address to send to. $error; $remote = sendTo($entityInfo['Endpoint'], 'username/send', '{"username":"******","reference":"' . escape($reference, false) . '","title":"' . escape($title, false) . '","items":' . $transferData['ItemInformation'] . $privText . '}', $error); // Did it error? if ($error) { // Remote server errored. error('remote/error', $error); } // Update the to group: $transferData['ToGroup'] = $entityInfo['Group']; // JSON decode it: $remote = json_decode($remote, true); // Get the address info: $addrInfo = safe('address', VALID_ARRAY, $remote); // Optional delay info: $delay = safe('delay', VALID_NUMBER, $remote, true); // Get the status: $status = safe('status', VALID_ALPHA, $addrInfo); if ($status != 'OK') { // Remote server was unable to provide an address - try again shortly. error('remote/noaddr', $delay); } // Great - should have an address here: $address = safe('value', VALID_HEX, $addrInfo); if ($delay) { $transferData['Delay'] = $delay; } $transferData['ToAddress'] = $address; return $address; }
function processTxChange($change) { global $dz; // Get the row: $row = $dz->get_row('select * from `Bank.Incomings` where `Key`=unhex("' . $change['to']['address'] . '")'); if (!$row || $row['Status']) { // Some other bank, or we've already processed it etc. return; } // Update the status: $dz->query('update `Bank.Incomings` set `Status`=1 where `ID`=' . $row['ID']); // Get the from address: $from = $dz->get_row('select `Commodity` from `Root.Balances` where `Key`=unhex("' . $change['from']['address'] . '")'); if (!$from) { // Database is out of sync. serverError(); } // Build the details set for the receive call: $details = array('Commodity' => $from['Commodity'], 'Amount' => $change['amount'], 'Reference' => $row['Reference'], 'Title' => $row['Title'], 'Name' => $row['Name'], 'FromUsername' => $row['From'], 'ItemInformation' => $row['ItemInformation']); // Receive it: receive($details, $row['Account']); // Finish by completing the status: $dz->query('update `Bank.Incomings` set `Status`=2 where `ID`=' . $row['ID']); }