Ethereum PHP
PHP interface to Ethereum JSON-RPC API.
EthDataType.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Ethereum\DataType;
4 
7 
8 
44 abstract class EthDataType extends EthereumStatic implements EthDataTypeInterface
45 {
46 
52  private const ABI_MAP = [
53  // The following elementary types exist:
54  'uint' => 'EthQ',
55  'int' => 'EthQ',
56  'address' => 'EthD20',
57  // = uint 160?
58  'bool' => 'EthB',
59  // function, an address (20 bytes) followed by a function selector (4 bytes).
60  // Encoded identical to bytes24
61  // 'function' => ''
62 
63  // Fixed signed fixed-point decimal number of M bits, 8 <= M <= 256
64  // @todo fixed-point decimal number not implemented.
65  // 'fixed' => 'EthB',
66  // 'ufixed' => 'EthS',
67 
68  // string: dynamic sized unicode string assumed to be UTF-8 encoded.
69  'string' => 'EthS',
70  // bytes: dynamic sized byte sequence.
71  'bytes' => 'EthBytes',
72 
73  // Small Bytes < 32
74  // Are always padded to 32bytes (64 chars in hex).
75  //
76  // bytes<M>: enc(X) is the sequence of bytes in X padded
77  // with trailing zero-bytes to a length of 32 bytes.
78  //
79  // bytes<M>: binary type of M bytes, 0 < M <= 32
80  'bytes1' => 'EthD32',
81  'bytes2' => 'EthD32',
82  'bytes3' => 'EthD32',
83  'bytes4' => 'EthD32',
84  'bytes5' => 'EthD32',
85  'bytes6' => 'EthD32',
86  'bytes7' => 'EthD32',
87  'bytes8' => 'EthD32',
88  'bytes9' => 'EthD32',
89  'bytes10' => 'EthD32',
90  'bytes11' => 'EthD32',
91  'bytes12' => 'EthD32',
92  'bytes13' => 'EthD32',
93  'bytes14' => 'EthD32',
94  'bytes15' => 'EthD32',
95  'bytes16' => 'EthD32',
96  'bytes17' => 'EthD32',
97  'bytes18' => 'EthD32',
98  'bytes19' => 'EthD32',
99  'bytes20' => 'EthD20',
100  'bytes21' => 'EthD32',
101  'bytes22' => 'EthD32',
102  'bytes23' => 'EthD32',
103  'bytes24' => 'EthD32',
104  'bytes25' => 'EthD32',
105  'bytes26' => 'EthD32',
106  'bytes27' => 'EthD32',
107  'bytes28' => 'EthD32',
108  'bytes29' => 'EthD32',
109  'bytes30' => 'EthD32',
110  'bytes31' => 'EthD32',
111  'bytes32' => 'EthD32',
112 
113  // @todo Function not implemented.
114  // An address (20 bytes) followed by a function selector (4 bytes).
115  // Encoded identical to bytes24
116  // 'function' => 'EthD32' // ??? Might require a ABI bytes24 that the value won't get zero padded.
117  ];
118 
119 
131  public static function getClassByAbi(string $abiType)
132  {
133  $ns = 'Ethereum\DataType\\';
134 
135  // Exact types
136  // Are exact keys in ABI_MAP
137  // (e.g: bool, address, bytes, string)
138  if (isset(self::ABI_MAP[$abiType])) {
139  return $ns . self::ABI_MAP[$abiType];
140  }
141 
142  // Int types (int*, uint*)
143  $int = [];
144  preg_match("/^(?'type'[u]?int)([\d]*)$/", $abiType, $int);
145  // @see https://regex101.com/r/7JHrKG/1
146  if ($int && isset(self::ABI_MAP[$int['type']])) {
147  return $ns . self::ABI_MAP[$int['type']];
148  }
149 
150  throw new \Exception('Unknown ABI type: ' . $abiType);
151  }
152 
153 
161  public static function getDataLengthType()
162  {
163  return 'dynamic';
164  }
165 
176  public static function isPrimitive()
177  {
178  return false;
179  }
180 
181 
197  public function getProperty(string $property = 'value', bool $returnHexVal = false)
198  {
199  if (property_exists($this, $property)) {
200 
201  if (is_object($this->$property)) {
202  return ($returnHexVal) ? $this->$property->hexval() : $this->$property->val();
203  }
204 
205  if (is_array($this->$property)) {
206  $return = [];
207  foreach ($this->$property as $item) {
208  if (is_object($item)) {
209  $return[] = ($returnHexVal) ? $item->hexval() : $item->val();
210  }
211  }
212  return $return;
213  }
214  }
215  else {
216  throw new \InvalidArgumentException("Property '$property' does not exist.");
217  }
218  }
219 
220 
233  public function setValue($val, array $params = [])
234  {
235  if (method_exists($this, 'validate')) {
236  if (isset($params['abi'])) {
237  $this->abi = $params['abi'];
238  }
239  $this->value = $this->validate($val, $params);
240  }
241  else {
242  throw new \Exception('Validation of ' . __METHOD__ . ' not implemented yet.');
243  }
244  }
245 
246 
252  public function getClassName()
253  {
254  $ex = explode("\\", get_class($this));
255  return end($ex);
256  }
257 
258 
274  public static function getTypeClass(string $type, bool $typed_constructor = false)
275  {
276  $isArray = FALSE;
277  // Handling "[type]".
278  if (strpos($type, '[') !== FALSE) {
279  $type = str_replace(['[', ']'], '', $type);
280  $isArray = TRUE;
281  }
282 
283  $primitive_type = EthD::typeMap($type);
284 
285  if ($primitive_type) {
286  $type_class = $primitive_type;
287  }
288  else {
289  // Sadly arrayOf <type> is not supported by PHP.
290  if ($typed_constructor) {
291  $type_class = $isArray ? 'array' : $type;
292  }
293  else {
294  $type_class = $type;
295  }
296  }
297 
298  if (!$type_class) {
299  throw new \Exception('Could not determine type class at getTypeClass()');
300  }
301 
302  return $type_class;
303  }
304 
305 
311  public static function getAllTypeClasses()
312  {
314  return array_merge(
316  array_keys($schema['objects'])
317  );
318  }
319 }
320 
static getTypeClass(string $type, bool $typed_constructor=false)
static typeMap(string $type)
Definition: EthD.php:261
setValue($val, array $params=[])
getProperty(string $property='value', bool $returnHexVal=false)
static getPrimitiveTypes()
Definition: EthD.php:236
const static getClassByAbi(string $abiType)