| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 | 
							- <?php
 
- /**
 
-  * This file is part of rlp package.
 
-  *
 
-  * (c) Kuan-Cheng,Lai <alk03073135@gmail.com>
 
-  *
 
-  * @author Peter Lai <alk03073135@gmail.com>
 
-  * @license MIT
 
-  */
 
- namespace App\Services\Web3\RLP;
 
- use InvalidArgumentException;
 
- use RuntimeException;
 
- class RLP
 
- {
 
-     /**
 
-      * encode
 
-      *
 
-      * @param mixed $inputs array of string
 
-      * @return Buffer
 
-      */
 
-     public function encode($inputs): Buffer
 
-     {
 
-         $output = new Buffer;
 
-         if (is_array($inputs)) {
 
-             $result = new Buffer;
 
-             foreach ($inputs as $input) {
 
-                 $output->concat($this->encode($input));
 
-             }
 
-             return $result->concat($this->encodeLength($output->length(), 192), $output);
 
-         }
 
-         $input = $this->toBuffer($inputs);
 
-         $length = $input->length();
 
-         if ($length === 1 && $input[0] < 128) {
 
-             return $input;
 
-         } else {
 
-             return $output->concat($this->encodeLength($length, 128), $input);
 
-         }
 
-     }
 
-     /**
 
-      * decode
 
-      * Maybe use bignumber future.
 
-      *
 
-      * @param string $input
 
-      * @return array
 
-      */
 
-     public function decode(string $input): array
 
-     {
 
-         // if (!is_string($input)) {
 
-         //     throw new InvalidArgumentException('Input must be string when call decode.');
 
-         // }
 
-         $input = $this->toBuffer($input);
 
-         $decoded = $this->decodeData($input);
 
-         return $decoded['data'];
 
-     }
 
-     /**
 
-      * decodeData
 
-      * Maybe use bignumber future.
 
-      *
 
-      * @param Buffer $input
 
-      * @return array
 
-      */
 
-     protected function decodeData(Buffer $input): array
 
-     {
 
-         $firstByte = $input[0];
 
-         $output = new Buffer;
 
-         if ($firstByte <= 0x7f) {
 
-             return [
 
-                 'data' => $input->slice(0, 1),
 
-                 'remainder' => $input->slice(1)
 
-             ];
 
-         } elseif ($firstByte <= 0xb7) {
 
-             $length = $firstByte - 0x7f;
 
-             $data = new Buffer([]);
 
-             if ($firstByte !== 0x80) {
 
-                 // for ($i = 1; $i < $length; $i++) {
 
-                 //     $data[] = $input[$i];
 
-                 // }
 
-                 $data = $input->slice(1, $length);
 
-             }
 
-             if ($length === 2 && $data[0] < 0x80) {
 
-                 throw new RuntimeException('Byte must be less than 0x80.');
 
-             }
 
-             return [
 
-                 'data' => $data,
 
-                 'remainder' => $input->slice($length)
 
-             ];
 
-         } elseif ($firstByte <= 0xbf) {
 
-             $llength = $firstByte - 0xb6;
 
-             $hexLength = $input->slice(1, $llength)->toString('hex');
 
-             if ($hexLength === '00') {
 
-                 throw new RuntimeException('Invalid RLP.');
 
-             }
 
-             $length = hexdec($hexLength);
 
-             $data = $input->slice($llength, $length + $llength);
 
-             if ($data->length() < $length) {
 
-                 throw new RuntimeException('Invalid RLP.');
 
-             }
 
-             return [
 
-                 'data' => $data,
 
-                 'remainder' => $input->slice($length + $llength)
 
-             ];
 
-         } elseif ($firstByte <= 0xf7) {
 
-             $length = $firstByte - 0xbf;
 
-             $innerRemainder = $input->slice(1, $length);
 
-             $decoded = [];
 
-             while ($innerRemainder->length()) {
 
-                 $data = $this->decodeData($innerRemainder);
 
-                 $decoded[] = $data['data'];
 
-                 $innerRemainder = $data['remainder'];
 
-             }
 
-             return [
 
-                 'data' => $decoded,
 
-                 'remainder' => $input->slice($length)
 
-             ];
 
-         } else {
 
-             $llength = $firstByte - 0xf6;
 
-             $hexLength = $input->slice(1, $llength)->toString('hex');
 
-             $decoded = [];
 
-             if ($hexLength === '00') {
 
-                 throw new RuntimeException('Invalid RLP.');
 
-             }
 
-             $length = hexdec($hexLength);
 
-             $totalLength = $llength + $length;
 
-             if ($totalLength > $input->length()) {
 
-                 throw new RuntimeException('Invalid RLP: total length is bigger than data length.');
 
-             }
 
-             $innerRemainder = $input->slice($llength, $totalLength);
 
-             if ($innerRemainder->length() === 0) {
 
-                 throw new RuntimeException('Invalid RLP: list has invalid length.');
 
-             }
 
-             while ($innerRemainder->length()) {
 
-                 $data = $this->decodeData($innerRemainder);
 
-                 $decoded[] = $data['data'];
 
-                 $innerRemainder = $data['remainder'];
 
-             }
 
-             return [
 
-                 'data' => $decoded,
 
-                 'remainder' => $input->slice($length)
 
-             ];
 
-         }
 
-     }
 
-     /**
 
-      * encodeLength
 
-      *
 
-      * @param int $length
 
-      * @param int $offset
 
-      * @return Buffer
 
-      */
 
-     protected function encodeLength(int $length, int $offset): Buffer
 
-     {
 
-         // if (!is_int($length) || !is_int($offset)) {
 
-         //     throw new InvalidArgumentException('Length and offset must be int when call encodeLength.');
 
-         // }
 
-         if ($length < 56) {
 
-             // var_dump($length, $offset);
 
-             return new Buffer(strval($length + $offset));
 
-         }
 
-         $hexLength = $this->intToHex($length);
 
-         $firstByte = $this->intToHex($offset + 55 + (strlen($hexLength) / 2));
 
-         return new Buffer(strval($firstByte . $hexLength), 'hex');
 
-     }
 
-     /**
 
-      * intToHex
 
-      *
 
-      * @param int $value
 
-      * @return string
 
-      */
 
-     protected function intToHex(int $value): string
 
-     {
 
-         // if (!is_int($value)) {
 
-         //     throw new InvalidArgumentException('Value must be int when call intToHex.');
 
-         // }
 
-         $hex = dechex($value);
 
-         return $this->padToEven($hex);
 
-     }
 
-     /**
 
-      * padToEven
 
-      *
 
-      * @param string $value
 
-      * @return string
 
-      */
 
-     protected function padToEven(string $value): string
 
-     {
 
-         // if (!is_string($value)) {
 
-         //     throw new InvalidArgumentException('Value must be string when call padToEven.');
 
-         // }
 
-         if ((strlen($value) % 2) !== 0 ) {
 
-             $value = '0' . $value;
 
-         }
 
-         return $value;
 
-     }
 
-     /**
 
-      * toArray
 
-      * Format input to value, deprecated when we have toBuffer.
 
-      *
 
-      * @param mixed $input
 
-      * @return array
 
-      */
 
-      protected function toArray($input)
 
-      {
 
-          if (is_string($input)) {
 
-              if (strpos($input, '0x') === 0) {
 
-                  // hex string
 
-                  $value = str_replace('0x', '', $input);
 
-                  return $input;
 
-              } else {
 
-                  return str_split($input, 1);
 
-              }
 
-          }
 
-          throw new InvalidArgumentException('The input type didn\'t support.');
 
-      }
 
-     /**
 
-      * toBuffer
 
-      * Format input to buffer.
 
-      *
 
-      * @param mixed $input
 
-      * @return Buffer
 
-      */
 
-     protected function toBuffer($input): Buffer
 
-     {
 
-         if (is_string($input)) {
 
-             if (strpos($input, '0x') === 0) {
 
-                 // hex string
 
-                 // $input = str_replace('0x', '', $input);
 
-                 return new Buffer($input, 'hex');
 
-             }
 
-             return new Buffer(str_split($input, 1));
 
-         } elseif (is_numeric($input)) {
 
-             if (!$input || $input < 0) {
 
-                 return new Buffer([]);
 
-             }
 
-             if (is_float($input)) {
 
-                 $input = number_format($input, 0, '', '');
 
-                 var_dump($input);
 
-             }
 
-             $gmpInput = gmp_init($input, 10);
 
-             return new Buffer('0x' . gmp_strval($gmpInput, 16), 'hex');
 
-         } elseif ($input === null) {
 
-             return new Buffer([]);
 
-         } elseif (is_array($input)) {
 
-             return new Buffer($input);
 
-         } elseif ($input instanceof Buffer) {
 
-             return $input;
 
-         }
 
-         throw new InvalidArgumentException('The input type didn\'t support.');
 
-     }
 
- }
 
 
  |