Files
2026-08-11 02:26:43 +08:00

67 lines
1.7 KiB
PHP

<?php
namespace App\Services\Chain;
/**
* Minimal RLP encoder for legacy Ethereum transactions.
*/
final class EthRlp
{
/**
* @param list<string|list<mixed>> $list binary strings or nested lists
*/
public static function encodeList(array $list): string
{
$payload = '';
foreach ($list as $item) {
$payload .= is_array($item) ? self::encodeList($item) : self::encodeString($item);
}
return self::encodeLength(strlen($payload), 0xc0).$payload;
}
public static function encodeString(string $input): string
{
$len = strlen($input);
if ($len === 1 && ord($input) < 0x80) {
return $input;
}
return self::encodeLength($len, 0x80).$input;
}
/** Integer → minimal big-endian binary (empty for zero). */
public static function intToBin(string|int $value): string
{
if (is_int($value)) {
$value = (string) $value;
}
if (! preg_match('/^\d+$/', $value)) {
throw new \InvalidArgumentException('Invalid integer');
}
if (bccomp($value, '0') === 0) {
return '';
}
$hex = gmp_strval(gmp_init($value, 10), 16);
if (strlen($hex) % 2 !== 0) {
$hex = '0'.$hex;
}
return hex2bin($hex) ?: '';
}
private static function encodeLength(int $len, int $offset): string
{
if ($len < 56) {
return chr($len + $offset);
}
$hex = dechex($len);
if (strlen($hex) % 2 !== 0) {
$hex = '0'.$hex;
}
$bin = hex2bin($hex) ?: '';
return chr(strlen($bin) + $offset + 55).$bin;
}
}