From 7e21d77471960ec2240271b0d839f0f97546d021 Mon Sep 17 00:00:00 2001 From: dawnvi <36158920+dawnvi@users.noreply.github.com> Date: Fri, 6 May 2022 12:50:35 +0800 Subject: [PATCH] update bytes string dynamic --- src/Contracts/SolidityType.php | 84 ++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 15 deletions(-) diff --git a/src/Contracts/SolidityType.php b/src/Contracts/SolidityType.php index 5adf572..a04bde2 100644 --- a/src/Contracts/SolidityType.php +++ b/src/Contracts/SolidityType.php @@ -92,6 +92,7 @@ class SolidityType */ public function nestedName($name) { + if (!is_string($name)) { throw new InvalidArgumentException('nestedName name must string.'); } @@ -197,12 +198,27 @@ class SolidityType * @return string */ public function encode($value, $name) - { + { if ($this->isDynamicArray($name)) { $length = count($value); $nestedName = $this->nestedName($name); $result = []; $result[] = IntegerFormatter::format($length); + //解决 encode + + if ($this->isDynamicType($nestedName)){ + $start = 0; + foreach ($value as $k => $val) { + if ($start == 0){ + $l = $length * 32; + }else{ + $v_1 = Utils::toHex($value[$k-1]); + $l = (floor((mb_strlen($v_1) + 63) / 64)+1) * 32; + } + $start += $l; + $result[] = IntegerFormatter::format($start); + } + } foreach ($value as $val) { $result[] = $this->encode($val, $nestedName); @@ -232,18 +248,47 @@ class SolidityType public function decode($value, $offset, $name) { if ($this->isDynamicArray($name)) { - $arrayOffset = (int) Utils::toBn('0x' . mb_substr($value, $offset * 2, 64))->toString(); - $length = (int) Utils::toBn('0x' . mb_substr($value, $arrayOffset * 2, 64))->toString(); + $arrayOffset = (int) Utils::toBn('0x' . mb_substr($value, $offset * 2, 64))->toString(); //32 + $length = (int) Utils::toBn('0x' . mb_substr($value, $arrayOffset * 2, 64))->toString(); //数组的个数 $arrayStart = $arrayOffset + 32; - + $nestedName = $this->nestedName($name); - $nestedStaticPartLength = $this->staticPartLength($nestedName); - $roundedNestedStaticPartLength = floor(($nestedStaticPartLength + 31) / 32) * 32; - $result = []; + + if($nestedName=='bytes' || $nestedName=='string') + { + $mA = $arrayStart*2; + $mAA = ($mA + (64*1)); + for($i=0;$i<$length;$i++) + { + $mAA = ($mA + (64*$i)); //目前的定位 + + $mB = (int) Utils::toBn('0x' . mb_substr($value, ($mA + (64*$i)), 64))->toString(); + + + $mBB= $mA+($mB*2); + #clear $mBB.PHP_EOL; + $mC = (int) Utils::toBn('0x' . mb_substr($value, $mBB, 64))->toString(); + $mCC = (floor($mC/32)+1)*64; + $mD = mb_substr($value, ($mBB+64), $mCC); + #echo $mD.PHP_EOL; + #echo mb_substr($value, $mBB, 64).PHP_EOL; + + #echo "mb ={$mB} mBB={$mBB} mc={$mC} mcc={$mCC}".PHP_EOL; + $result[] = $this->decode($value, $mBB , $nestedName); + } + + }else + { + $nestedStaticPartLength = $this->staticPartLength($nestedName); + $roundedNestedStaticPartLength = floor(($nestedStaticPartLength + 31) / 32) * 32; + $result = []; + + for ($i=0; $i<$length * $roundedNestedStaticPartLength; $i+=$roundedNestedStaticPartLength) { + $result[] = $this->decode($value, $arrayStart + $i, $nestedName); + } + } + - for ($i=0; $i<$length * $roundedNestedStaticPartLength; $i+=$roundedNestedStaticPartLength) { - $result[] = $this->decode($value, $arrayStart + $i, $nestedName); - } return $result; } elseif ($this->isStaticArray($name)) { $length = $this->staticArrayLength($name); @@ -259,10 +304,19 @@ class SolidityType } return $result; } elseif ($this->isDynamicType()) { - $dynamicOffset = (int) Utils::toBn('0x' . mb_substr($value, $offset * 2, 64))->toString(); - $length = (int) Utils::toBn('0x' . mb_substr($value, $dynamicOffset * 2, 64))->toString(); - $roundedLength = floor(($length + 31) / 32); - $param = mb_substr($value, $dynamicOffset * 2, ( 1 + $roundedLength) * 64); + + if($name=='bytes' || $name=='string') + { + $mC = (int) Utils::toBn('0x' . mb_substr($value, $offset, 64))->toString(); + $mCC = (floor($mC/32)+1)*64; + $param = mb_substr($value, ($offset), ($mCC+64)); + }else + { + $dynamicOffset = (int) Utils::toBn('0x' . mb_substr($value, $offset * 2, 64))->toString(); + $length = (int) Utils::toBn('0x' . mb_substr($value, $dynamicOffset * 2, 64))->toString(); + $roundedLength = floor(($length + 31) / 32); + $param = mb_substr($value, $dynamicOffset * 2, ( 1 + $roundedLength) * 64); + } return $this->outputFormat($param, $name); } $length = $this->staticPartLength($name); @@ -270,4 +324,4 @@ class SolidityType return $this->outputFormat($param, $name); } -} \ No newline at end of file +}