Merge pull request #157 from sc0Vu/add-defaultblock

Add defaultblock in Contract.call
This commit is contained in:
Peter Lai 2019-10-02 10:42:08 +08:00 committed by GitHub
commit 0659ec04dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 95 additions and 46 deletions

View File

@ -28,8 +28,10 @@ use Web3\Contracts\Types\Str;
use Web3\Contracts\Types\Uinteger; use Web3\Contracts\Types\Uinteger;
use Web3\Validators\AddressValidator; use Web3\Validators\AddressValidator;
use Web3\Validators\HexValidator; use Web3\Validators\HexValidator;
use Web3\Formatters\AddressFormatter;
use Web3\Validators\StringValidator; use Web3\Validators\StringValidator;
use Web3\Validators\TagValidator;
use Web3\Validators\QuantityValidator;
use Web3\Formatters\AddressFormatter;
class Contract class Contract
{ {
@ -96,14 +98,22 @@ class Contract
*/ */
protected $ethabi; protected $ethabi;
/**
* defaultBlock
*
* @var mixed
*/
protected $defaultBlock;
/** /**
* construct * construct
* *
* @param string|\Web3\Providers\Provider $provider * @param string|\Web3\Providers\Provider $provider
* @param string|\stdClass|array $abi * @param string|\stdClass|array $abi
* @param mixed $defaultBlock
* @return void * @return void
*/ */
public function __construct($provider, $abi) public function __construct($provider, $abi, $defaultBlock = 'latest')
{ {
if (is_string($provider) && (filter_var($provider, FILTER_VALIDATE_URL) !== false)) { if (is_string($provider) && (filter_var($provider, FILTER_VALIDATE_URL) !== false)) {
// check the uri schema // check the uri schema
@ -137,6 +147,11 @@ class Contract
} }
} }
} }
if (TagValidator::validate($defaultBlock) || QuantityValidator::validate($defaultBlock)) {
$this->defaultBlock = $defaultBlock;
} else {
$this->$defaultBlock = 'latest';
}
$this->abi = $abiArray; $this->abi = $abiArray;
$this->eth = new Eth($this->provider); $this->eth = new Eth($this->provider);
$this->ethabi = new Ethabi([ $this->ethabi = new Ethabi([
@ -212,7 +227,7 @@ class Contract
/** /**
* setProvider * setProvider
* *
* @param \Web3\Providers\Provider $provider * @param \Web3\Providers\Provider $provider
* @return $this * @return $this
*/ */
@ -225,8 +240,34 @@ class Contract
} }
/** /**
* getFunctions * getDefaultBlock
* *
* @return string
*/
public function getDefaultBlock()
{
return $this->defaultBlock;
}
/**
* setDefaultBlock
*
* @param mixed $defaultBlock
* @return $this
*/
public function setDefaultBlock($defaultBlock)
{
if (TagValidator::validate($defaultBlock) || QuantityValidator::validate($defaultBlock)) {
$this->defaultBlock = $defaultBlock;
} else {
$this->$defaultBlock = 'latest';
}
return $this;
}
/**
* getFunctions
*
* @return array * @return array
*/ */
public function getFunctions() public function getFunctions()
@ -236,7 +277,7 @@ class Contract
/** /**
* getEvents * getEvents
* *
* @return array * @return array
*/ */
public function getEvents() public function getEvents()
@ -254,7 +295,7 @@ class Contract
/** /**
* getConstructor * getConstructor
* *
* @return array * @return array
*/ */
public function getConstructor() public function getConstructor()
@ -264,7 +305,7 @@ class Contract
/** /**
* getAbi * getAbi
* *
* @return array * @return array
*/ */
public function getAbi() public function getAbi()
@ -535,7 +576,7 @@ class Contract
/** /**
* call * call
* Call function method. * Call function method.
* *
* @param mixed * @param mixed
* @return void * @return void
*/ */
@ -563,47 +604,17 @@ class Contract
throw new \InvalidArgumentException('The last param must be callback function.'); throw new \InvalidArgumentException('The last param must be callback function.');
} }
// check the last one in arguments is transaction object // check the arguments
$argsLen = count($arguments); $argsLen = count($arguments);
$transaction = []; $transaction = [];
$hasTransaction = false; $defaultBlock = $this->defaultBlock;
if ($argsLen > 0) {
$transaction = $arguments[$argsLen - 1];
}
if (
isset($transaction["from"]) ||
isset($transaction["to"]) ||
isset($transaction["gas"]) ||
isset($transaction["gasPrice"]) ||
isset($transaction["value"]) ||
isset($transaction["data"]) ||
isset($transaction["nonce"])
) {
$hasTransaction = true;
} else {
$transaction = [];
}
$params = []; $params = [];
$data = ""; $data = "";
$functionName = ""; $functionName = "";
foreach ($functions as $function) { foreach ($functions as $function) {
if ($hasTransaction) {
if ($argsLen - 1 !== count($function['inputs'])) {
continue;
} else {
$paramsLen = $argsLen - 1;
}
} else {
if ($argsLen !== count($function['inputs'])) {
continue;
} else {
$paramsLen = $argsLen;
}
}
try { try {
$params = array_splice($arguments, 0, $paramsLen); $paramsLen = count($function['inputs']);
$params = array_slice($arguments, 0, $paramsLen);
$data = $this->ethabi->encodeParameters($function, $params); $data = $this->ethabi->encodeParameters($function, $params);
$functionName = Utils::jsonMethodToString($function); $functionName = Utils::jsonMethodToString($function);
} catch (InvalidArgumentException $e) { } catch (InvalidArgumentException $e) {
@ -614,11 +625,40 @@ class Contract
if (empty($data) || empty($functionName)) { if (empty($data) || empty($functionName)) {
throw new InvalidArgumentException('Please make sure you have put all function params and callback.'); throw new InvalidArgumentException('Please make sure you have put all function params and callback.');
} }
// remove arguments
array_splice($arguments, 0, $paramsLen);
$argsLen -= $paramsLen;
if ($argsLen > 1) {
$defaultBlock = $arguments[$argsLen - 1];
$transaction = $arguments[$argsLen - 2];
} else if ($argsLen > 0) {
if (is_array($arguments[$argsLen - 1])) {
$transaction = $arguments[$argsLen - 1];
} else {
$defaultBlock = $arguments[$argsLen - 1];
}
}
if (!TagValidator::validate($defaultBlock) && !QuantityValidator::validate($defaultBlock)) {
$defaultBlock = $this->defaultBlock;
}
if (
!is_array($transaction) &&
!isset($transaction["from"]) &&
!isset($transaction["to"]) &&
!isset($transaction["gas"]) &&
!isset($transaction["gasPrice"]) &&
!isset($transaction["value"]) &&
!isset($transaction["data"]) &&
!isset($transaction["nonce"])
) {
$transaction = [];
}
$functionSignature = $this->ethabi->encodeFunctionSignature($functionName); $functionSignature = $this->ethabi->encodeFunctionSignature($functionName);
$transaction['to'] = $this->toAddress; $transaction['to'] = $this->toAddress;
$transaction['data'] = $functionSignature . Utils::stripZero($data); $transaction['data'] = $functionSignature . Utils::stripZero($data);
$this->eth->call($transaction, function ($err, $transaction) use ($callback, $function){ $this->eth->call($transaction, $defaultBlock, function ($err, $transaction) use ($callback, $function){
if ($err !== null) { if ($err !== null) {
return call_user_func($callback, $err, null); return call_user_func($callback, $err, null);
} }
@ -738,7 +778,7 @@ class Contract
$transaction['data'] = $functionSignature . Utils::stripZero($data); $transaction['data'] = $functionSignature . Utils::stripZero($data);
} }
$this->eth->estimateGas($transaction, function ($err, $gas) use ($callback){ $this->eth->estimateGas($transaction, function ($err, $gas) use ($callback) {
if ($err !== null) { if ($err !== null) {
return call_user_func($callback, $err, null); return call_user_func($callback, $err, null);
} }

View File

@ -1134,7 +1134,7 @@ class ContractTest extends TestCase
$contract->at($contractAddress); $contract->at($contractAddress);
foreach ($functions as $function) { foreach ($functions as $function) {
$contract->call($function['name'], function ($err, $res) use ($function) { $contract->call($function['name'], [], 'latest', function ($err, $res) use ($function) {
if ($err !== null) { if ($err !== null) {
echo 'Error when call ' . $function['name'] . '. Message: ' . $err->getMessage() . "\n"; echo 'Error when call ' . $function['name'] . '. Message: ' . $err->getMessage() . "\n";
return; return;
@ -1468,13 +1468,22 @@ class ContractTest extends TestCase
// $this->assertEquals($contract->ethabi->encodeEventSignature($contract->events['Say']), $topics[0]); // $this->assertEquals($contract->ethabi->encodeEventSignature($contract->events['Say']), $topics[0]);
$this->assertEquals('0x' . IntegerFormatter::format($testNumber), $topics[1]); $this->assertEquals('0x' . IntegerFormatter::format($testNumber), $topics[1]);
} }
$contract->call('number', function ($err, $res) use ($testNumber) { $blockNumber = Utils::toBn($transaction->blockNumber);
$contract->call('number', Utils::toHex($blockNumber, true), function ($err, $res) use ($testNumber) {
if ($err !== null) { if ($err !== null) {
echo 'Error when call ' . $function['name'] . '. Message: ' . $err->getMessage() . "\n"; echo 'Error when call ' . $function['name'] . '. Message: ' . $err->getMessage() . "\n";
return; return;
} }
$this->assertEquals((string) $testNumber, $res[0]->toString()); $this->assertEquals((string) $testNumber, $res[0]->toString());
}); });
$blockNumber = $blockNumber->subtract(Utils::toBn(1));
$contract->call('number', Utils::toHex($blockNumber, true), function ($err, $res) use ($testNumber) {
if ($err !== null) {
echo 'Error when call ' . $function['name'] . '. Message: ' . $err->getMessage() . "\n";
return;
}
$this->assertEquals((string) $testNumber-1, $res[0]->toString());
});
}); });
}); });