Skip to content

Commit

Permalink
Add test features for abi (from ethers.js)
Browse files Browse the repository at this point in the history
  • Loading branch information
sc0Vu committed Jan 26, 2024
1 parent a6725ec commit a20f2a6
Show file tree
Hide file tree
Showing 9 changed files with 88,981 additions and 37 deletions.
2 changes: 1 addition & 1 deletion phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
<directory suffix="Test.php">./test/unit</directory>
</testsuite>
<php>
<ini name="memory_limit" value="256M"/>
<ini name="memory_limit" value="50M"/>
</php>
</phpunit>
22 changes: 12 additions & 10 deletions src/Contracts/Ethabi.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,10 @@ public function nestedName($name)
*/
public function isDynamicArray($name)
{
$nestedTypes = $this->nestedTypes($name);

return $nestedTypes && preg_match('/[0-9]{1,}/', $nestedTypes[count($nestedTypes) - 1]) !== 1;
if (preg_match('/\[\]$/', $name) >= 1) {
return true;
}
return false;
}

/**
Expand All @@ -161,9 +162,10 @@ public function isDynamicArray($name)
*/
public function isStaticArray($name)
{
$nestedTypes = $this->nestedTypes($name);

return $nestedTypes && preg_match('/[0-9]{1,}/', $nestedTypes[count($nestedTypes) - 1]) === 1;
if (preg_match('/\[[\d]+\]$/', $name) >= 1) {
return true;
}
return false;
}

/**
Expand All @@ -174,7 +176,7 @@ public function isStaticArray($name)
*/
public function isTuple($name)
{
if (preg_match_all('/(tuple)?\((.*)\)/', $name, $matches, PREG_PATTERN_ORDER) >= 1) {
if (preg_match('/^(tuple)?\((.*)\)$/', $name) >= 1) {
return true;
}
return false;
Expand Down Expand Up @@ -234,7 +236,7 @@ protected function findAbiType($type)
return $result;
} elseif ($this->isTuple($type)) {
$nestedType = $this->parseTupleType($type);
$parsedNestedTypes = preg_split('/,/', $nestedType);
$parsedNestedTypes = (!$this->isTuple($nestedType)) ? preg_split('/,/', $nestedType) : [ $nestedType ];
$tupleAbi = [
'type' => $type,
'dynamic' => false,
Expand Down Expand Up @@ -382,7 +384,7 @@ public function encodeParameters($types, $params)
$abiTypes = $this->parseAbiTypes($types);

// encode with tuple type
return '0x' . $this->types['tuple']->encode($params, $abiTypes);
return '0x' . $this->types['tuple']->encode($params, [ 'coders' => $abiTypes ]);
}

/**
Expand Down Expand Up @@ -433,7 +435,7 @@ public function decodeParameters($types, $param)

// decode with tuple type
$results = [];
$decodeResults = $this->types['tuple']->decode(Utils::stripZero($param), 0, $abiTypes);
$decodeResults = $this->types['tuple']->decode(Utils::stripZero($param), 0, [ 'coders' => $abiTypes ]);
for ($i = 0; $i < $typesLength; $i++) {
if (isset($outputTypes['outputs'][$i]['name']) && empty($outputTypes['outputs'][$i]['name']) === false) {
$results[$outputTypes['outputs'][$i]['name']] = $decodeResults[$i];
Expand Down
4 changes: 3 additions & 1 deletion src/Contracts/Types/BaseArray.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,10 @@ public function encodeElements($value, $name)
$tailOffsets[] = (int) mb_strlen($val) / 2;
}
$headChunks = [];
$totalOffset = 0;
foreach ($tailOffsets as $offset) {
$headChunks[] = IntegerFormatter::format($headLength + $offset);
$totalOffset += $offset;
$headChunks[] = IntegerFormatter::format($headLength + $totalOffset);
}
return array_merge($headChunks, $results);
}
Expand Down
8 changes: 5 additions & 3 deletions src/Contracts/Types/Tuple.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public function inputFormat($params, $abiTypes)
$result = [];
$rawHead = [];
$tail = [];
foreach ($abiTypes as $key => $abiType) {
foreach ($abiTypes['coders'] as $key => $abiType) {
if ($abiType['dynamic']) {
$rawHead[] = null;
$tail[] = $abiType['solidityType']->encode($params[$key], $abiType);
Expand All @@ -87,11 +87,13 @@ public function inputFormat($params, $abiTypes)
$tailOffsets[] = (int) (mb_strlen($val) / 2);
}
$headChunks = [];
$totalOffset = 0;
foreach ($rawHead as $key => $head) {
if (!array_key_exists($key, $tail)) continue;
$offset = $tailOffsets[$key];
if (is_null($head)) {
$headChunks[] = IntegerFormatter::format($headLength + $offset);
$totalOffset += $offset;
$headChunks[] = IntegerFormatter::format($headLength + $totalOffset);
continue;
}
$headChunks[] = $head;
Expand All @@ -110,7 +112,7 @@ public function outputFormat($value, $abiTypes)
{
$results = [];
$staticOffset = 0;
foreach ($abiTypes as $key => $abiType) {
foreach ($abiTypes['coders'] as $key => $abiType) {
if ($abiType['dynamic']) {
$startPosHex = mb_substr($value, $staticOffset, 64);
$startPos = Utils::hexToNumber($startPosHex);
Expand Down
13 changes: 10 additions & 3 deletions src/Formatters/IntegerFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class IntegerFormatter implements IFormatter
*/
public static function format($value)
{
$isNegative = (int) $value < 0;
$value = (string) $value;
$arguments = func_get_args();
$digit = 64;
Expand All @@ -35,10 +36,16 @@ public static function format($value)
$bn = Utils::toBn($value);
$bnHex = $bn->toHex(true);
$bnHexLen = mb_strlen($bnHex);
$padded = mb_substr($bnHex, 0, 1);
$padded = ($isNegative) ? 'f' : mb_substr($bnHex, 0, 1);

if ($bnHexLen >= $digit) {
$zeroPos = mb_strrpos($bnHex, '0');
if ($bnHexLen > $digit) {
$zeroPos = 0;
for ($i = 0; $i < $bnHexLen; $i++) {
if ($bnHex[$i] !== '0') {
break;
}
$zeroPos += 1;
}
if ($zeroPos !== false) {
$bnHex = mb_substr($bnHex, $zeroPos, $digit);
$bnHexLen = mb_strlen($bnHex);
Expand Down
27 changes: 9 additions & 18 deletions test/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,17 @@ class TestCase extends BaseTestCase
* @var string
*/
protected $EMPTY_ADDRESS = '0x0000000000000000000000000000000000000000';

/**
* test fixtures
*
* TODO: add more fixtures
* @var array
* loadFixtureJsonFile
*/
protected $testFixtures = [];
public function loadFixtureJsonFile($fixtureFileName) {
$json = \file_get_contents($fixtureFileName);
if (false === $json) {
throw new \RuntimeException("Unable to load file {$fixtureFileName}");
}
return \json_decode($json, true);
}

/**
* setUp
Expand Down Expand Up @@ -92,18 +95,6 @@ public function setUp(): void
$this->coinbase = $coinbase;
// }
});

// load test fixtures
$fixtureFileName = __DIR__ . '/fixtures/typed-data.json';
$json = \file_get_contents($fixtureFileName);
if (false === $json) {
throw new \RuntimeException("Unable to load file {$fixtureFileName}");
}

$data = \json_decode($json, true);
$this->testFixtures = [
'typed-data' => $data
];
}

/**
Expand Down
Loading

0 comments on commit a20f2a6

Please sign in to comment.