This commit is contained in:
dawnvi 2022-05-06 04:53:07 +00:00 committed by GitHub
commit a1d9553b5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -92,6 +92,7 @@ class SolidityType
*/ */
public function nestedName($name) public function nestedName($name)
{ {
if (!is_string($name)) { if (!is_string($name)) {
throw new InvalidArgumentException('nestedName name must string.'); throw new InvalidArgumentException('nestedName name must string.');
} }
@ -197,12 +198,27 @@ class SolidityType
* @return string * @return string
*/ */
public function encode($value, $name) public function encode($value, $name)
{ {
if ($this->isDynamicArray($name)) { if ($this->isDynamicArray($name)) {
$length = count($value); $length = count($value);
$nestedName = $this->nestedName($name); $nestedName = $this->nestedName($name);
$result = []; $result = [];
$result[] = IntegerFormatter::format($length); $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) { foreach ($value as $val) {
$result[] = $this->encode($val, $nestedName); $result[] = $this->encode($val, $nestedName);
@ -232,18 +248,47 @@ class SolidityType
public function decode($value, $offset, $name) public function decode($value, $offset, $name)
{ {
if ($this->isDynamicArray($name)) { if ($this->isDynamicArray($name)) {
$arrayOffset = (int) Utils::toBn('0x' . mb_substr($value, $offset * 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(); $length = (int) Utils::toBn('0x' . mb_substr($value, $arrayOffset * 2, 64))->toString(); //数组的个数
$arrayStart = $arrayOffset + 32; $arrayStart = $arrayOffset + 32;
$nestedName = $this->nestedName($name); $nestedName = $this->nestedName($name);
$nestedStaticPartLength = $this->staticPartLength($nestedName);
$roundedNestedStaticPartLength = floor(($nestedStaticPartLength + 31) / 32) * 32; if($nestedName=='bytes' || $nestedName=='string')
$result = []; {
$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; return $result;
} elseif ($this->isStaticArray($name)) { } elseif ($this->isStaticArray($name)) {
$length = $this->staticArrayLength($name); $length = $this->staticArrayLength($name);
@ -259,10 +304,19 @@ class SolidityType
} }
return $result; return $result;
} elseif ($this->isDynamicType()) { } 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(); if($name=='bytes' || $name=='string')
$roundedLength = floor(($length + 31) / 32); {
$param = mb_substr($value, $dynamicOffset * 2, ( 1 + $roundedLength) * 64); $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); return $this->outputFormat($param, $name);
} }
$length = $this->staticPartLength($name); $length = $this->staticPartLength($name);
@ -270,4 +324,4 @@ class SolidityType
return $this->outputFormat($param, $name); return $this->outputFormat($param, $name);
} }
} }