Sign.php 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. <?php
  2. use kornrunner\Secp256k1;
  3. use kornrunner\Serializer\HexSignatureSerializer;
  4. use kornrunner\Signature\Signature;
  5. use kornrunner\Util\Buffer;
  6. function signTransaction(array $transaction, string $privateKey): array {
  7. $rawData = $transaction['raw_data'];
  8. // 1. 将 raw_data 转为 JSON 字符串
  9. $rawDataJson = json_encode($rawData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
  10. if ($rawDataJson === false) {
  11. throw new \Exception("Invalid raw_data: " . json_last_error_msg());
  12. }
  13. // 2. 计算 SHA256 哈希(二进制形式)
  14. $msgHash = hash('sha256', $rawDataJson, true); // raw binary
  15. // 3. 构造私钥 buffer(二进制)
  16. $privateKeyBin = hex2bin($privateKey);
  17. if ($privateKeyBin === false || strlen($privateKeyBin) !== 32) {
  18. throw new \Exception("Invalid private key format");
  19. }
  20. // 4. 签名
  21. $secp256k1 = new Secp256k1();
  22. $signature = $secp256k1->sign($msgHash, $privateKeyBin);
  23. // 5. 生成 HEX 签名(包含 recovery ID)
  24. $serializer = new HexSignatureSerializer();
  25. $fullHex = $serializer->serialize($signature); // 130 hex chars: r + s + v (65 bytes)
  26. // ⚠️ Tron 要求 r + s(不带 v) => 64 字节,即 128 字符的 hex 字符串
  27. $r = substr($fullHex, 0, 64);
  28. $s = substr($fullHex, 64, 64);
  29. $sigHex = $r . $s;
  30. return [
  31. 'txID' => $transaction['txID'],
  32. 'raw_data' => $transaction['raw_data'],
  33. 'signature' => [$sigHex],
  34. ];
  35. }