PHP WebShell
Текущая директория: /var/www/bitcardoApp
Просмотр файла: save_keycard_and_print.php
<?php
/**
* save_keycard_and_print.php
* One step:
* - Fetch your TRON wallet (mainnet) from BitGo Express on 127.0.0.1:3081
* - Fetch the 3 keychains (user / backup / bitgo)
* - Save a printable HTML KeyCard (includes encrypted user private key)
* - Print your exact summary lines
*
* NOTE: This reads sensitive info. Run on the same host as Express.
* After use, store the KeyCard offline and rotate any secrets you pasted.
*/
date_default_timezone_set('Africa/Lagos'); // GMT+1
// ====== FILL THESE 3 VALUES ======
$BITGO_ACCESS_TOKEN = 'v2x47b80e4e874e1af4a227a13bbfc2b3c2684db6eafd1c3739e9f3f01cb0b57be2';
$WALLET_ID = '68bacb35a8cee6d614f8353dec449a39';
$BITGO_EXPRESS_BASE = 'http://127.0.0.1:3081/api/v2'; // Express you started on 3081
// =================================
$COIN = 'trx'; // mainnet
$KEYCARD_DIR = __DIR__ . '/keycards';
if (!is_dir($KEYCARD_DIR)) { mkdir($KEYCARD_DIR, 0700, true); }
// ---- helpers ----
function http_get_json($url, $token) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Authorization: Bearer ' . $token,
],
CURLOPT_TIMEOUT => 20,
]);
$resp = curl_exec($ch);
if ($resp === false) { $err = curl_error($ch); curl_close($ch); throw new Exception("HTTP request failed: $err"); }
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code < 200 || $code >= 300) { throw new Exception("HTTP $code: $resp"); }
return json_decode($resp, true);
}
function safe($v) { return htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); }
function gmt_offset_label(DateTime $dt) {
$offset = (int)$dt->getOffset(); $sign = $offset >= 0 ? '+' : '-';
$h = (string) floor(abs($offset)/3600);
$m = str_pad((string) ((abs($offset)%3600)/60), 2, '0', STR_PAD_LEFT);
return "GMT{$sign}{$h}" . ($m !== '00' ? ":{$m}" : "");
}
// ---- 1) Fetch wallet ----
$walletUrl = rtrim($BITGO_EXPRESS_BASE, '/') . "/$COIN/wallet/$WALLET_ID";
$wallet = http_get_json($walletUrl, $BITGO_ACCESS_TOKEN);
$label = $wallet['label'] ?? '';
$walletId = $wallet['id'] ?? $WALLET_ID;
$coin = $wallet['coin'] ?? $COIN;
$receiveAddr = $wallet['receiveAddress']['address'] ?? ($wallet['receiveAddress'] ?? '');
$permissions = $wallet['permissions'] ?? [];
$createdRaw = $wallet['createDate'] ?? ($wallet['created'] ?? ($wallet['ctime'] ?? null));
$created = null;
try {
$createdUtc = $createdRaw ? new DateTime($createdRaw, new DateTimeZone('UTC')) : new DateTime('now', new DateTimeZone('UTC'));
$createdUtc->setTimezone(new DateTimeZone('Africa/Lagos'));
$created = $createdUtc;
} catch (Exception $e) {
$created = new DateTime('now', new DateTimeZone('Africa/Lagos'));
}
// keys array can be 'keys' (ids) or 'keyIds'
$keyIds = $wallet['keys'] ?? ($wallet['keyIds'] ?? []);
if (count($keyIds) < 3) {
throw new Exception("Unexpected: wallet keys missing; got " . json_encode($keyIds));
}
// ---- 2) Fetch keychains ----
$getKey = function($keyId) use ($BITGO_EXPRESS_BASE, $COIN, $BITGO_ACCESS_TOKEN) {
$url = rtrim($BITGO_EXPRESS_BASE, '/') . "/$COIN/key/$keyId";
return http_get_json($url, $BITGO_ACCESS_TOKEN);
};
$keyA = $getKey($keyIds[0]);
$keyB = $getKey($keyIds[1]);
$keyC = $getKey($keyIds[2]);
// classify: user has encryptedXprv or encryptedPrv; bitgo has isBitGo=true; backup is the remaining one
$keys = [$keyA, $keyB, $keyC];
$userKey = $bitgoKey = $backupKey = null;
foreach ($keys as $k) {
$isBitGo = !empty($k['isBitGo']);
$hasEnc = isset($k['encryptedXprv']) || isset($k['encryptedPrv']);
if ($isBitGo) { $bitgoKey = $k; continue; }
if ($hasEnc && !$userKey) { $userKey = $k; continue; }
}
foreach ($keys as $k) {
if ($k !== $bitgoKey && $k !== $userKey) { $backupKey = $k; break; }
}
if (!$userKey || !$backupKey || !$bitgoKey) {
throw new Exception("Could not classify keychains properly. Raw keys: " . json_encode($keys));
}
$userXpub = $userKey['xpub'] ?? '';
$userEncPrv = $userKey['encryptedXprv'] ?? ($userKey['encryptedPrv'] ?? '');
$backupXpub = $backupKey['xpub'] ?? '';
$backupProv = $backupKey['provider'] ?? ($backupKey['source'] ?? 'local');
$bitgoXpub = $bitgoKey['xpub'] ?? '';
// ---- 3) Save KeyCard (HTML) ----
$keycardFileName = preg_replace('/[^A-Za-z0-9_\-]/', '_', $label ?: 'Wallet') . '_KeyCard_' . date('Ymd_His') . '.html';
$keycardPath = $KEYCARD_DIR . DIRECTORY_SEPARATOR . $keycardFileName;
$html = "<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8'>
<title>KeyCard – " . safe($label) . "</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<style>
body { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', monospace; line-height: 1.35; padding: 24px; }
.box { border: 1px solid #999; border-radius: 6px; padding: 16px; margin: 16px 0; background: #fafafa; }
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.muted { color: #555; font-size: 0.92em; }
code { white-space: pre-wrap; word-break: break-word; }
@media print { body { padding:0; } .no-print { display:none; } }
</style>
</head>
<body>
<h1>KeyCard (TRON / TRC20)</h1>
<div class='box'><strong>SECURITY:</strong> Print and store offline. Keep your passphrase and this card safe.</div>
<div class='box'>
<h2>Wallet</h2>
<div class='grid'>
<div><strong>Label</strong><br><code>" . safe($label) . "</code></div>
<div><strong>Coin</strong><br><code>" . safe($coin) . "</code></div>
<div><strong>Wallet ID</strong><br><code>" . safe($walletId) . "</code></div>
<div><strong>Receive Address</strong><br><code>" . safe($receiveAddr) . "</code></div>
</div>
</div>
<div class='box'>
<h2>User Keychain (You)</h2>
<div class='grid'>
<div><strong>xpub</strong><br><code>" . safe($userXpub) . "</code></div>
<div><strong>encryptedXprv</strong><br><code>" . safe($userEncPrv) . "</code></div>
</div>
<p class='muted'>Your private key is <em>encrypted</em> with your passphrase.</p>
</div>
<div class='box'>
<h2>Backup Keychain</h2>
<div class='grid'>
<div><strong>xpub</strong><br><code>" . safe($backupXpub) . "</code></div>
<div><strong>provider</strong><br><code>" . safe($backupProv) . "</code></div>
</div>
</div>
<div class='box'>
<h2>BitGo Keychain (Co-signer)</h2>
<div><strong>xpub</strong><br><code>" . safe($bitgoXpub) . "</code></div>
</div>
<p class='no-print muted'>Generated: " . safe((new DateTime('now'))->format('c')) . " • File: <code>" . safe($keycardFileName) . "</code></p>
</body>
</html>";
file_put_contents($keycardPath, $html);
chmod($keycardPath, 0600);
// ---- 4) Print EXACT summary lines ----
$signatureProtocol = 'Multisignature';
$perm = 'Admin';
if (is_array($permissions) && count($permissions)) {
$pl = array_map('strtolower', $permissions);
if (in_array('admin', $pl, true)) { $perm = 'Admin'; }
elseif (in_array('spend', $pl, true)) { $perm = 'Spend'; }
elseif (in_array('view', $pl, true)) { $perm = 'View'; }
else { $perm = ucfirst($permissions[0]); }
}
$dateLabel = $created->format('M j, Y, g:i:s A') . ' ' . gmt_offset_label($created);
echo "Label: {$label}\n";
echo "Wallet ID: {$walletId}\n";
echo "Wallet Add: {$receiveAddr}\n";
echo "Signature Protocol: {$signatureProtocol}\n";
echo "Your Permissions: {$perm}\n";
echo "Creation Date: {$dateLabel}\n\n";
echo "KeyCard saved to: {$keycardPath}\n";
Выполнить команду
Для локальной разработки. Не используйте в интернете!