38 $m = $this->getParamDefinition($methodName);
40 if (count($m->inputs) !== count($values)) {
41 throw new \InvalidArgumentException(
'Expected ' . count($m->inputs) .
' params but got ' . count($values));
45 $params = $this->getSignature($m);
46 foreach ($values as $i => $val) {
47 $expectedType = $m->inputs[$i]->type;
48 $validAbiType = self::convertByAbi($expectedType, $val);
49 $params .= EthereumStatic::removeHexPrefix($validAbiType->encodedHexVal());
51 return new EthD($params);
67 $params = $this->getParamDefinition($method);
69 $return = $this->decode($params->outputs, self::removeHexPrefix($rawReturn->
hexVal()));
72 if (count($return) === 1) {
90 public static function decode(array $params,
string $msgData)
92 if (self::hasHexPrefix($msgData) || !ctype_xdigit($msgData)) {
93 throw new \Exception(
'msgData must be a unprefixed hex value.');
98 foreach ($params as $p => $param) {
101 $class = EthD::getClassByAbi($param->type);
103 $lengthType = $class::getdataLengthType($param->type);
105 if ($lengthType ===
'static') {
107 $thisValue = substr($msgData, $pos, 64);
108 $return[$p] =
new $class(self::ensureHexPrefix($thisValue), [
'abi' => $param->type]);
110 elseif ($lengthType ===
'dynamic') {
112 $offsetInChars = 2 * Rlp::getByteValueAtOffsetPos($msgData, $pos);
113 $rlpDecoded = Rlp::decode(substr($msgData, $offsetInChars));
115 if (count($rlpDecoded) === 1) {
116 $return[$p] =
new $class(self::ensureHexPrefix($rlpDecoded[0]->
get()), [
'abi' => $param->type]);
119 foreach ($rlpDecoded as $rlpItem) {
120 $return[$p][] =
new $class(self::ensureHexPrefix($rlpItem->get()), [
'abi' => $param->type]);
125 throw new \Exception(
'Length type must be "dynamic" or "static".');
143 foreach ($this->abi as $item) {
144 if (isset($item->name)
145 && isset($item->type)
146 && $item->type ===
'function' 147 && $item->name === $methodName
152 throw new \Exception(
'Called undefined contract method: ' . $methodName .
'.');
162 private static function getSignature($m)
164 $sign = $m->name .
'(';
165 foreach ($m->inputs as $i => $item) {
166 $sign .= $item->type;
167 if ($i < count($m->inputs) - 1) {
172 return self::getMethodSignature($sign);
211 if (strpos($abiType,
'[')) {
217 if (strpos($abiType,
'(')) {
221 $class = EthDataType::getClassByAbi($abiType);
223 return new $class($value->
hexVal(), [
'abi' => $abiType]);
226 throw new \Exception(
'Can not convert to unknown type ' . $abiType .
'. Might be not implemented yet.');
238 foreach ($this->abi as $item) {
239 if (isset($item->type)
240 && $item->type ===
'event' 242 $events[] =
new Event($item);
259 foreach ($this->getEvents() as $event) {
260 $events[$event->getTopic()] = $event;
encodeFunction(string $methodName, array $values)
getParamDefinition(string $methodName)
decodeMethod(string $method, EthD $rawReturn)
static convertByAbi(string $abiType, EthD $value)