feat: new chain
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user