Ethabi encodeParameters and SolidityType encode.
This commit is contained in:
parent
51ece8f887
commit
518a72b422
@ -11,18 +11,32 @@
|
|||||||
|
|
||||||
namespace Web3\Contracts;
|
namespace Web3\Contracts;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use stdClass;
|
||||||
use Web3\Utils;
|
use Web3\Utils;
|
||||||
|
use Web3\Formatters\Integer as IntegerFormatter;
|
||||||
|
|
||||||
class Ethabi
|
class Ethabi
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* types
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $types = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* construct
|
* construct
|
||||||
*
|
*
|
||||||
|
* @param array $types
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __contruct()
|
public function __construct($types=[])
|
||||||
{
|
{
|
||||||
//
|
if (!is_array($types)) {
|
||||||
|
$types = [];
|
||||||
|
}
|
||||||
|
$this->types = $types;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,6 +71,18 @@ class Ethabi
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* callStatic
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param array $arguments
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function __callStatic($name, $arguments)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* encodeFunctionSignature
|
* encodeFunctionSignature
|
||||||
*
|
*
|
||||||
@ -84,4 +110,185 @@ class Ethabi
|
|||||||
}
|
}
|
||||||
return Utils::sha3($functionName);
|
return Utils::sha3($functionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* encodeParameter
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @param mixed $param
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function encodeParameter($type, $param)
|
||||||
|
{
|
||||||
|
if (!is_string($type)) {
|
||||||
|
throw new InvalidArgumentException('The type to encodeParameter must be string.');
|
||||||
|
}
|
||||||
|
return $this->encodeParameters([$type], [$param]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* encodeParameters
|
||||||
|
*
|
||||||
|
* @param stdClass|array $types
|
||||||
|
* @param array $params
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function encodeParameters($types, $params)
|
||||||
|
{
|
||||||
|
if (count($types) !== count($params)) {
|
||||||
|
throw new InvalidArgumentException('encodeParameters number of types must equal to number of params.');
|
||||||
|
}
|
||||||
|
// change json to array
|
||||||
|
if ($types instanceof stdClass && isset($types->inputs)) {
|
||||||
|
$types = Utils::jsonToArray($types, 2);
|
||||||
|
}
|
||||||
|
if (is_array($types) && isset($types['inputs'])) {
|
||||||
|
$inputTypes = $types;
|
||||||
|
$types = [];
|
||||||
|
|
||||||
|
foreach ($inputTypes['inputs'] as $input) {
|
||||||
|
if (isset($input['type'])) {
|
||||||
|
$types[] = $input['type'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$typesLength = count($types);
|
||||||
|
$solidityTypes = array_fill(0, $typesLength, 0);
|
||||||
|
|
||||||
|
foreach ($types as $key => $type) {
|
||||||
|
$match = [];
|
||||||
|
|
||||||
|
if (preg_match('/^([a-zA-Z]+)/', $type, $match) === 1) {
|
||||||
|
if (isset($this->types[$match[0]])) {
|
||||||
|
$className = $this->types[$match[0]];
|
||||||
|
|
||||||
|
if (call_user_func([$this->types[$match[0]], 'isType'], $type) === false) {
|
||||||
|
throw new InvalidArgumentException('Unsupport solidity parameter type: ' . $type);
|
||||||
|
}
|
||||||
|
$solidityTypes[$key] = $className;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$encodes = array_fill(0, $typesLength, '');
|
||||||
|
|
||||||
|
foreach ($solidityTypes as $key => $type) {
|
||||||
|
$encodes[$key] = call_user_func([$type, 'encode'], $params[$key], $types[$key]);
|
||||||
|
}
|
||||||
|
$dynamicOffset = 0;
|
||||||
|
|
||||||
|
foreach ($solidityTypes as $key => $type) {
|
||||||
|
$staticPartLength = $type->staticPartLength($types[$key]);
|
||||||
|
$roundedStaticPartLength = floor(($staticPartLength + 31) / 32) * 32;
|
||||||
|
|
||||||
|
if ($type->isDynamicType($types[$key]) || $type->isDynamicArray($types[$key])) {
|
||||||
|
$dynamicOffset += 32;
|
||||||
|
} else {
|
||||||
|
$dynamicOffset += $roundedStaticPartLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '0x' . $this->encodeMultiWithOffset($types, $solidityTypes, $encodes, $dynamicOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* encodeWithOffset
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @param \Web3\Contracts\SolidityType $solidityType
|
||||||
|
* @param mixed $encode
|
||||||
|
* @param int $offset
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function encodeWithOffset($type, $solidityType, $encoded, $offset)
|
||||||
|
{
|
||||||
|
if ($solidityType->isDynamicArray($type)) {
|
||||||
|
$nestedName = $solidityType->nestedName($type);
|
||||||
|
$nestedStaticPartLength = $solidityType->staticPartLength($type);
|
||||||
|
$result = $encoded[0];
|
||||||
|
|
||||||
|
if ($solidityType->isDynamicArray($nestedName)) {
|
||||||
|
$previousLength = 2;
|
||||||
|
|
||||||
|
for ($i=0; $i<count($encoded); $i++) {
|
||||||
|
if (isset($encoded[$i - 1])) {
|
||||||
|
$previousLength += abs($encoded[$i - 1][0]);
|
||||||
|
}
|
||||||
|
$result .= IntegerFormatter::format($offset + $i * $nestedStaticPartLength + $previousLength * 32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ($i=0; $i<count($encoded); $i++) {
|
||||||
|
// $bn = Utils::toBn($result);
|
||||||
|
// $divided = $bn->divide(Utils::toBn(2));
|
||||||
|
|
||||||
|
// if (is_array($divided)) {
|
||||||
|
// $additionalOffset = (int) $divided[0]->toString();
|
||||||
|
// } else {
|
||||||
|
// $additionalOffset = 0;
|
||||||
|
// }
|
||||||
|
$additionalOffset = floor(mb_strlen($result) / 2);
|
||||||
|
$result .= $this->encodeWithOffset($nestedName, $solidityType, $encoded[$i], $offset + $additionalOffset);
|
||||||
|
}
|
||||||
|
return mb_substr($result, 64);
|
||||||
|
} elseif ($solidityType->isStaticArray($type)) {
|
||||||
|
$nestedName = $solidityType->nestedName($type);
|
||||||
|
$nestedStaticPartLength = $solidityType->staticPartLength($type);
|
||||||
|
$result = '';
|
||||||
|
|
||||||
|
if ($solidityType->isDynamicArray($nestedName)) {
|
||||||
|
$previousLength = 0;
|
||||||
|
|
||||||
|
for ($i=0; $i<count($encoded); $i++) {
|
||||||
|
if (isset($encoded[$i - 1])) {
|
||||||
|
$previousLength += abs($encoded[$i - 1])[0];
|
||||||
|
}
|
||||||
|
$result .= IntegerFormatter::format($offset + $i * $nestedStaticPartLength + $previousLength * 32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ($i=0; $i<count($encoded); $i++) {
|
||||||
|
// $bn = Utils::toBn($result);
|
||||||
|
// $divided = $bn->divide(Utils::toBn(2));
|
||||||
|
|
||||||
|
// if (is_array($divided)) {
|
||||||
|
// $additionalOffset = (int) $divided[0]->toString();
|
||||||
|
// } else {
|
||||||
|
// $additionalOffset = 0;
|
||||||
|
// }
|
||||||
|
$additionalOffset = floor(mb_strlen($result) / 2);
|
||||||
|
$result .= $this->encodeWithOffset($nestedName, $solidityType, $encoded[$i], $offset + $additionalOffset);
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
return $encoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* encodeMultiWithOffset
|
||||||
|
*
|
||||||
|
* @param array $types
|
||||||
|
* @param array $solidityTypes
|
||||||
|
* @param array $encodes
|
||||||
|
* @param int $dynamicOffset
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function encodeMultiWithOffset($types, $solidityTypes, $encodes, $dynamicOffset)
|
||||||
|
{
|
||||||
|
$result = '';
|
||||||
|
|
||||||
|
foreach ($solidityTypes as $key => $type) {
|
||||||
|
if ($type->isDynamicType($types[$key]) || $type->isDynamicArray($types[$key])) {
|
||||||
|
$result .= IntegerFormatter::format($dynamicOffset);
|
||||||
|
$e = $this->encodeWithOffset($types[$key], $type, $encodes[$key], $dynamicOffset);
|
||||||
|
$dynamicOffset += floor(mb_strlen($e) / 2);
|
||||||
|
} else {
|
||||||
|
$result .= $this->encodeWithOffset($types[$key], $type, $encodes[$key], $dynamicOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($solidityTypes as $key => $type) {
|
||||||
|
if ($type->isDynamicType($types[$key]) || $type->isDynamicArray($types[$key])) {
|
||||||
|
$e = $this->encodeWithOffset($types[$key], $type, $encodes[$key], $dynamicOffset);
|
||||||
|
// $dynamicOffset += floor(mb_strlen($e) / 2);
|
||||||
|
$result .= $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
}
|
}
|
@ -11,6 +11,9 @@
|
|||||||
|
|
||||||
namespace Web3\Contracts;
|
namespace Web3\Contracts;
|
||||||
|
|
||||||
|
use Web3\Utils;
|
||||||
|
use Web3\Formatters\Integer as IntegerFormatter;
|
||||||
|
|
||||||
class SolidityType
|
class SolidityType
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -54,4 +57,162 @@ class SolidityType
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* callStatic
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param array $arguments
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function __callStatic($name, $arguments)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nestedTypes
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function nestedTypes($name)
|
||||||
|
{
|
||||||
|
if (!is_string($name)) {
|
||||||
|
throw new InvalidArgumentException('nestedTypes name must string.');
|
||||||
|
}
|
||||||
|
$matches = [];
|
||||||
|
|
||||||
|
if (preg_match_all('/(\[[0-9]*\])/', $name, $matches, PREG_PATTERN_ORDER) >= 1) {
|
||||||
|
return $matches[0];
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nestedName
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function nestedName($name)
|
||||||
|
{
|
||||||
|
if (!is_string($name)) {
|
||||||
|
throw new InvalidArgumentException('nestedName name must string.');
|
||||||
|
}
|
||||||
|
$nestedTypes = $this->nestedTypes($name);
|
||||||
|
|
||||||
|
if ($nestedTypes === false) {
|
||||||
|
return $name;
|
||||||
|
}
|
||||||
|
return mb_substr($name, 0, mb_strlen($name) - mb_strlen($nestedTypes[count($nestedTypes) - 1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* isDynamicArray
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isDynamicArray($name)
|
||||||
|
{
|
||||||
|
$nestedTypes = $this->nestedTypes($name);
|
||||||
|
|
||||||
|
return $nestedTypes && preg_match('/[0-9]{1,}/', $nestedTypes[count($nestedTypes) - 1]) !== 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* isStaticArray
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isStaticArray($name)
|
||||||
|
{
|
||||||
|
$nestedTypes = $this->nestedTypes($name);
|
||||||
|
|
||||||
|
return $nestedTypes && preg_match('/[0-9]{1,}/', $nestedTypes[count($nestedTypes) - 1]) === 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* staticArrayLength
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function staticArrayLength($name)
|
||||||
|
{
|
||||||
|
$nestedTypes = $this->nestedTypes($name);
|
||||||
|
|
||||||
|
if ($nestedTypes === false) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
$match = [];
|
||||||
|
|
||||||
|
if (preg_match('/[0-9]{1,}/', $nestedTypes[count($nestedTypes) - 1], $match) === 1) {
|
||||||
|
return (int) $match[0];
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* staticPartLength
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function staticPartLength($name)
|
||||||
|
{
|
||||||
|
$nestedTypes = $this->nestedTypes($name);
|
||||||
|
|
||||||
|
if ($nestedTypes === false) {
|
||||||
|
$nestedTypes = ['[1]'];
|
||||||
|
}
|
||||||
|
$count = 32;
|
||||||
|
|
||||||
|
foreach ($nestedTypes as $type) {
|
||||||
|
$num = mb_substr($type, 1, 1);
|
||||||
|
|
||||||
|
if (!is_numeric($num)) {
|
||||||
|
$num = 1;
|
||||||
|
} else {
|
||||||
|
$num = intval($num);
|
||||||
|
}
|
||||||
|
$count *= $num;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* encode
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @param string $name
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function encode($value, $name)
|
||||||
|
{
|
||||||
|
if ($this->isDynamicArray($name)) {
|
||||||
|
$length = count($value);
|
||||||
|
$nestedName = $this->nestedName($name);
|
||||||
|
$result = [];
|
||||||
|
$result[] = IntegerFormatter::format($length);
|
||||||
|
|
||||||
|
foreach ($value as $val) {
|
||||||
|
$result[] = $this->encode($val, $nestedName);
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
} elseif ($this->isStaticArray($name)) {
|
||||||
|
$length = $this->staticArrayLength($name);
|
||||||
|
$nestedName = $this->nestedName($name);
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
foreach ($value as $val) {
|
||||||
|
$result[] = $this->encode($val, $nestedName);
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
return $this->inputFormat($value, $name);
|
||||||
|
}
|
||||||
}
|
}
|
@ -6,9 +6,22 @@ use InvalidArgumentException;
|
|||||||
use Test\TestCase;
|
use Test\TestCase;
|
||||||
use Web3\Utils;
|
use Web3\Utils;
|
||||||
use Web3\Contracts\Ethabi;
|
use Web3\Contracts\Ethabi;
|
||||||
|
use Web3\Contracts\Types\Address;
|
||||||
|
use Web3\Contracts\Types\Boolean;
|
||||||
|
use Web3\Contracts\Types\Bytes;
|
||||||
|
use Web3\Contracts\Types\Integer;
|
||||||
|
use Web3\Contracts\Types\Str;
|
||||||
|
use Web3\Contracts\Types\Uinteger;
|
||||||
|
|
||||||
class EthabiTest extends TestCase
|
class EthabiTest extends TestCase
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* abi
|
||||||
|
*
|
||||||
|
* @var \Web3\Contracts\Ethabi
|
||||||
|
*/
|
||||||
|
protected $abi;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* testJsonMethodString
|
* testJsonMethodString
|
||||||
* from GameToken approve function
|
* from GameToken approve function
|
||||||
@ -36,15 +49,64 @@ class EthabiTest extends TestCase
|
|||||||
],
|
],
|
||||||
"payable": false,
|
"payable": false,
|
||||||
"stateMutability": "nonpayable",
|
"stateMutability": "nonpayable",
|
||||||
"type": "function"
|
"type": "function",
|
||||||
|
"test": {
|
||||||
|
"name": "testObject"
|
||||||
|
}
|
||||||
}';
|
}';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* abi
|
* tests
|
||||||
|
* from web3 eth.abi.encodeParameters test
|
||||||
|
* and web3 eth.abi.encodeParameter test
|
||||||
*
|
*
|
||||||
* @var \Web3\Contracts\Ethabi
|
* @param array
|
||||||
*/
|
*/
|
||||||
protected $abi;
|
protected $tests = [
|
||||||
|
[
|
||||||
|
'params' => [['uint256','string'], ['2345675643', 'Hello!%']],
|
||||||
|
'result' => '0x000000000000000000000000000000000000000000000000000000008bd02b7b0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000748656c6c6f212500000000000000000000000000000000000000000000000000'
|
||||||
|
], [
|
||||||
|
'params' => [['uint8[]','bytes32'], [['34','434'], '0x324567dfff']],
|
||||||
|
'result' => '0x0000000000000000000000000000000000000000000000000000000000000040324567dfff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000001b2'
|
||||||
|
], [
|
||||||
|
'params' => [['address','address','address', 'address'], ['0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1','','0x0', null]],
|
||||||
|
'result' => '0x00000000000000000000000090f8bf6a479f320ead074411a4b0e7944ea8c9c1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
||||||
|
], [
|
||||||
|
'params' => [['bool[2]', 'bool[3]'], [[true, false], [false, false, true]]],
|
||||||
|
'result' => '0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001'
|
||||||
|
], [
|
||||||
|
'params' => [['int'], [1]],
|
||||||
|
'result' => '0x0000000000000000000000000000000000000000000000000000000000000001'
|
||||||
|
], [
|
||||||
|
'params' => [['int'], [16]],
|
||||||
|
'result' => '0x0000000000000000000000000000000000000000000000000000000000000010'
|
||||||
|
], [
|
||||||
|
'params' => [['int'], [-1]],
|
||||||
|
'result' => '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
|
||||||
|
], [
|
||||||
|
'params' => [['int256'], [1]],
|
||||||
|
'result' => '0x0000000000000000000000000000000000000000000000000000000000000001'
|
||||||
|
], [
|
||||||
|
'params' => [['int256'], [16]],
|
||||||
|
'result' => '0x0000000000000000000000000000000000000000000000000000000000000010'
|
||||||
|
], [
|
||||||
|
'params' => [['int256'], [-1]],
|
||||||
|
'result' => '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
|
||||||
|
], [
|
||||||
|
'params' => [['int[]'], [[3]]],
|
||||||
|
'result' => '0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003'
|
||||||
|
], [
|
||||||
|
'params' => [['int256[]'], [[3]]],
|
||||||
|
'result' => '0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003'
|
||||||
|
], [
|
||||||
|
'params' => [['int256[]'], [[1,2,3]]],
|
||||||
|
'result' => '0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003'
|
||||||
|
], [
|
||||||
|
'params' => [['int[]','int[]'], [[1,2],[3,4]]],
|
||||||
|
'result' => '0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* setUp
|
* setUp
|
||||||
@ -54,7 +116,24 @@ class EthabiTest extends TestCase
|
|||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
$this->abi = new Ethabi();
|
// Error: Using $this when not in object context
|
||||||
|
// $this->abi = new Ethabi([
|
||||||
|
// 'address' => Address::class,
|
||||||
|
// 'bool' => Boolean::class,
|
||||||
|
// 'bytes' => Bytes::class,
|
||||||
|
// 'int' => Integer::class,
|
||||||
|
// 'string' => Str::class,
|
||||||
|
// 'uint' => Uinteger::class,
|
||||||
|
// ]);
|
||||||
|
|
||||||
|
$this->abi = new Ethabi([
|
||||||
|
'address' => new Address,
|
||||||
|
'bool' => new Boolean,
|
||||||
|
'bytes' => new Bytes,
|
||||||
|
'int' => new Integer,
|
||||||
|
'string' => new Str,
|
||||||
|
'uint' => new Uinteger,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,4 +181,18 @@ class EthabiTest extends TestCase
|
|||||||
|
|
||||||
$this->assertEquals($str, '0x095ea7b334ae44009aa867bfb386f5c3b4b443ac6f0ee573fa91c4608fbadfba');
|
$this->assertEquals($str, '0x095ea7b334ae44009aa867bfb386f5c3b4b443ac6f0ee573fa91c4608fbadfba');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testEncodeParameters
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testEncodeParameters()
|
||||||
|
{
|
||||||
|
$abi = $this->abi;
|
||||||
|
|
||||||
|
foreach ($this->tests as $test) {
|
||||||
|
$this->assertEquals($test['result'], $abi->encodeParameters($test['params'][0], $test['params'][1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
131
test/unit/SolidityTypeTest.php
Normal file
131
test/unit/SolidityTypeTest.php
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Test\Unit;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use Test\TestCase;
|
||||||
|
use Web3\Contracts\SolidityType;
|
||||||
|
|
||||||
|
class SolidityTypeTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* type
|
||||||
|
*
|
||||||
|
* @var \Web3\Contracts\SolidityType
|
||||||
|
*/
|
||||||
|
protected $type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setUp
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
$this->type = new SolidityType();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testNestedTypes
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testNestedTypes()
|
||||||
|
{
|
||||||
|
$type = $this->type;
|
||||||
|
|
||||||
|
$this->assertEquals($type->nestedTypes('int[2][3][4]'), ['[2]', '[3]', '[4]']);
|
||||||
|
$this->assertEquals($type->nestedTypes('int[2][3][]'), ['[2]', '[3]', '[]']);
|
||||||
|
$this->assertEquals($type->nestedTypes('int[2][3]'), ['[2]', '[3]']);
|
||||||
|
$this->assertEquals($type->nestedTypes('int[2][]'), ['[2]', '[]']);
|
||||||
|
$this->assertEquals($type->nestedTypes('int[2]'), ['[2]']);
|
||||||
|
$this->assertEquals($type->nestedTypes('int[]'), ['[]']);
|
||||||
|
$this->assertEquals($type->nestedTypes('int'), false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testNestedName
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testNestedName()
|
||||||
|
{
|
||||||
|
$type = $this->type;
|
||||||
|
|
||||||
|
$this->assertEquals($type->nestedName('int[2][3][4]'), 'int[2][3]');
|
||||||
|
$this->assertEquals($type->nestedName('int[2][3][]'), 'int[2][3]');
|
||||||
|
$this->assertEquals($type->nestedName('int[2][3]'), 'int[2]');
|
||||||
|
$this->assertEquals($type->nestedName('int[2][]'), 'int[2]');
|
||||||
|
$this->assertEquals($type->nestedName('int[2]'), 'int');
|
||||||
|
$this->assertEquals($type->nestedName('int[]'), 'int');
|
||||||
|
$this->assertEquals($type->nestedName('int'), 'int');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testIsDynamicArray
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testIsDynamicArray()
|
||||||
|
{
|
||||||
|
$type = $this->type;
|
||||||
|
|
||||||
|
$this->assertFalse($type->isDynamicArray('int[2][3][4]'));
|
||||||
|
$this->assertTrue($type->isDynamicArray('int[2][3][]'));
|
||||||
|
$this->assertFalse($type->isDynamicArray('int[2][3]'));
|
||||||
|
$this->assertTrue($type->isDynamicArray('int[2][]'));
|
||||||
|
$this->assertFalse($type->isDynamicArray('int[2]'));
|
||||||
|
$this->assertTrue($type->isDynamicArray('int[]'));
|
||||||
|
$this->assertFalse($type->isDynamicArray('int'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testIsStaticArray
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testIsStaticArray()
|
||||||
|
{
|
||||||
|
$type = $this->type;
|
||||||
|
|
||||||
|
$this->assertTrue($type->isStaticArray('int[2][3][4]'));
|
||||||
|
$this->assertFalse($type->isStaticArray('int[2][3][]'));
|
||||||
|
$this->assertTrue($type->isStaticArray('int[2][3]'));
|
||||||
|
$this->assertFalse($type->isStaticArray('int[2][]'));
|
||||||
|
$this->assertTrue($type->isStaticArray('int[2]'));
|
||||||
|
$this->assertFalse($type->isStaticArray('int[]'));
|
||||||
|
$this->assertFalse($type->isStaticArray('int'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testStaticArrayLength
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testStaticArrayLength()
|
||||||
|
{
|
||||||
|
$type = $this->type;
|
||||||
|
|
||||||
|
$this->assertEquals($type->staticArrayLength('int[2][3][4]'), 4);
|
||||||
|
$this->assertEquals($type->staticArrayLength('int[2][3][]'), 1);
|
||||||
|
$this->assertEquals($type->staticArrayLength('int[2][3]'), 3);
|
||||||
|
$this->assertEquals($type->staticArrayLength('int[2][]'), 1);
|
||||||
|
$this->assertEquals($type->staticArrayLength('int[2]'), 2);
|
||||||
|
$this->assertEquals($type->staticArrayLength('int[]'), 1);
|
||||||
|
$this->assertEquals($type->staticArrayLength('int'), 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testEncode
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testEncode()
|
||||||
|
{
|
||||||
|
$type = $this->type;
|
||||||
|
$this->assertTrue(true);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user