diff --git a/README.md b/README.md index 22eca20..54c644d 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,16 @@ $rlp = new RLP; $encoded = $rlp->encode(['web3p', 'ethereum', 'solidity']); ``` +* Encode ethereum address + +There's an ability to force type of specific encoded item. For ethereum addresses, leading zeros can't be removed as these are specified as 20 byte array (not a string). To properly encode it you can pass it as hex_fixed. +``` +use Web3p\RLP\RLP; + +$rlp = new RLP; +$encoded = $rlp->encode(['web3p', '0x4f15a948f2e2a13731c9aa3cef52cdf8d3e6a120', 'test', '0x4f15a948f2e2a13731c9aa3cef52cdf8d3e6a120'], [1=>'hex_fixed', 3=>'hex_fixed']); +``` + #### decode Returns array recursive length prefix decoding of given data. diff --git a/src/RLP.php b/src/RLP.php index 055090a..c49fb10 100644 --- a/src/RLP.php +++ b/src/RLP.php @@ -64,19 +64,20 @@ class RLP * Return RLP encoded of the given inputs. * * @param mixed $inputs mixed type of data you want to RLP encode + * @param mixed $types mixed type of data you want to encode, if there's no $types[X] for corresponding $inputs[X] - will be autodetected * @return string RLP encoded hex string of inputs */ - public function encode($inputs) + public function encode($inputs, $types = false) { $output = ''; if (is_array($inputs)) { - foreach ($inputs as $input) { - $output .= $this->encode($input); + foreach ($inputs as $k=>$input) { + $output .= $this->encode($input, $types[$k] ?? false); } $length = mb_strlen($output) / 2; return $this->encodeLength($length, 192) . $output; } - $input = $this->encodeInput($inputs); + $input = $this->encodeInput($inputs, $types); $length = mb_strlen($input) / 2; // first byte < 0x80 @@ -247,20 +248,24 @@ protected function padToEven(string $input) * Main encode function to transform data to hex encoded string. * * @param mixed $input data + * @param string type data type to be encoded for not-numeric type * @return string hex encoded string */ - protected function encodeInput($input) - { - if (is_string($input)) { - if (strpos($input, '0x') === 0) { - return Str::encode($input, 'hex'); - } - return Str::encode($input); - } elseif (is_numeric($input)) { - return Numeric::encode($input); - } elseif ($input === null) { - return ''; - } - throw new InvalidArgumentException('The input type didn\'t support.'); - } + protected function encodeInput($input, $type = false) + { + if (is_string($input)) { + if ($type !== false) { + return Str::encode($input, $type); + } + if (strpos($input, '0x') === 0) { + return Str::encode($input, 'hex'); + } + return Str::encode($input); + } elseif (is_numeric($input)) { + return Numeric::encode($input); + } elseif ($input === null) { + return ''; + } + throw new InvalidArgumentException('The input type didn\'t support.'); + } } diff --git a/src/Types/Str.php b/src/Types/Str.php index 7cf210a..16f5e00 100644 --- a/src/Types/Str.php +++ b/src/Types/Str.php @@ -34,7 +34,15 @@ static function encode(string $input, string $encoding='utf8') { $output = ''; switch ($encoding) { - case 'hex': + // fixed length hex + case 'hex_fixed': + if (strpos($input, '0x') === 0) { + $input = str_replace('0x', '', $input); + } + $output = $input; + break; + + case 'hex': if (strpos($input, '0x') === 0) { $input = str_replace('0x', '', $input); }