Skip to content

Commit

Permalink
Fix decoding and make test happier
Browse files Browse the repository at this point in the history
  • Loading branch information
sc0Vu committed Jan 28, 2024
1 parent 18660ea commit 254344d
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/Contracts/Ethabi.php
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ public function decodeParameter($type, $param)
public function decodeParameters($types, $param)
{
if (!is_string($param)) {
throw new InvalidArgumentException('The type or param to decodeParameters must be string.');
throw new InvalidArgumentException('The param must be string.');
}

// change json to array
Expand Down
22 changes: 22 additions & 0 deletions src/Contracts/SolidityType.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,28 @@ public function isDynamicType()
return false;
}

/**
* deepCalculateDataLength
* Calculate static data size recursively.
* TODO: Improve this function, or calculate data length when parse abi.
*
* @param array $data
* @return integer
*/
public function deepCalculateDataLength($data)
{
if (!is_array($data)) return 1;
$dataCount = 0;
foreach ($data as $d) {
if (is_array($d)) {
$dataCount += $this->deepCalculateDataLength($d);
} else {
$dataCount += 1;
}
}
return $dataCount;
}

/**
* encode
*
Expand Down
12 changes: 1 addition & 11 deletions src/Contracts/Types/BaseArray.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,6 @@ public function inputFormat($value, $name)
*/
public function outputFormat($value, $name)
{
$checkZero = str_replace('0', '', $value);

if (empty($checkZero)) {
return '0';
}
if (preg_match('/^bytes([0-9]*)/', $name, $match) === 1) {
$size = intval($match[1]);
$length = 2 * $size;
$value = mb_substr($value, 0, $length);
}
return '0x' . $value;
throw new InvalidArgumentException('Should not call outputFormat in BaseArray directly');
}
}
10 changes: 8 additions & 2 deletions src/Contracts/Types/DynamicArray.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,17 @@ public function outputFormat($value, $abiType)
}
$lengthHex = mb_substr($value, 0, 64);
$length = (int) Utils::hexToNumber($lengthHex);
$offset = 64;
$offset = 0;
$value = mb_substr($value, 64);
$results = [];
$decoder = $abiType['coders'];
for ($i = 0; $i < $length; $i++) {
$results[] = $decoder['solidityType']->decode($value, $offset, $decoder);
$decodeValueOffset = $offset;
if ($decoder['dynamic']) {
$decodeValueOffsetHex = mb_substr($value, $offset, 64);
$decodeValueOffset = (int) Utils::hexToNumber($decodeValueOffsetHex) * 2;
}
$results[] = $decoder['solidityType']->decode($value, $decodeValueOffset, $decoder);
$offset += 64;
}
return $results;
Expand Down
21 changes: 12 additions & 9 deletions src/Contracts/Types/SizedArray.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,18 +82,21 @@ public function outputFormat($value, $abiType)
}
$length = is_array($abiType) ? $this->staticArrayLength($abiType['type']) : 0;
$offset = 0;
if ($abiType['dynamic']) {
$valueLengthHex = mb_substr($value, 0, 64);
$valueLength = (int) Utils::hexToNumber($valueLengthHex) / 32;
if ($length !== $valueLength) {
throw new InvalidArgumentException('Invalid sized array length decode, expected: ' . $lenght . ', but got ' . $valueLength);
}
$offset += 64;
}
$results = [];
$decoder = $abiType['coders'];
for ($i = 0; $i < $length; $i++) {
$results[] = $decoder['solidityType']->decode($value, $offset, $decoder);
$decodeValueOffset = $offset;
if ($decoder['dynamic']) {
$decodeValueOffsetHex = mb_substr($value, $offset, 64);
$decodeValueOffset = (int) Utils::hexToNumber($decodeValueOffsetHex) * 2;
}
$decoded = $decoder['solidityType']->decode($value, $decodeValueOffset, $decoder);
$results[] = $decoded;
$dataCount = 1;
if (!$decoder['dynamic']) {
$dataCount = $this->deepCalculateDataLength($decoded);
}
$offset += (64 * $dataCount);
}
return $results;
}
Expand Down
3 changes: 3 additions & 0 deletions src/Contracts/Types/Str.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ public function outputFormat($value, $abiType)
if (preg_match('/^[0]+([a-f0-9]+)$/', $strLen, $match) === 1) {
$strLen = BigNumberFormatter::format('0x' . $match[1])->toString();
}
if (is_float((int) $strLen * 2)) {
var_dump($strValue, $strLen, mb_substr($value, 0, 64), BigNumberFormatter::format('0x' . mb_substr($value, 0, 64))->toString());
}
$strValue = mb_substr($strValue, 0, (int) $strLen * 2);

return Utils::hexToBin($strValue);
Expand Down
6 changes: 4 additions & 2 deletions src/Contracts/Types/Tuple.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,10 @@ public function outputFormat($value, $abiTypes)
$staticOffset += 64;
$results[] = $abiType['solidityType']->decode($value, $startPos * 2, $abiType);
} else {
$results[] = $abiType['solidityType']->decode($value, $staticOffset, $abiType);
$staticOffset += 64;
$decoded = $abiType['solidityType']->decode($value, $staticOffset, $abiType);
$dataCount = $this->deepCalculateDataLength($decoded);
$staticOffset += 64 * $dataCount;
$results[] = $decoded;
}
}
return $results;
Expand Down
5 changes: 2 additions & 3 deletions test/unit/EthabiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -326,11 +326,10 @@ public function testAbiFixtures()
$testFixtures = $this->loadFixtureJsonFile(dirname(__DIR__) . '/fixtures/abi.json');
$abi = $this->abi;
foreach ($testFixtures as $test) {
// if (is_string($test['value']) || is_string($test['type'])) {
// var_dump($test);
// }
$result = $abi->encodeParameters([$test['type']], [$test['value']]);
$this->assertEquals($test['encoded'], $result);
$decodeResult = $abi->decodeParameters([$test['type']], $result);
$this->assertTrue(!is_null($decodeResult));
}
}
}

0 comments on commit 254344d

Please sign in to comment.