Contract send.

This commit is contained in:
sc0Vu 2018-01-02 11:54:57 +08:00
parent 36ba7a7573
commit c67ec3ccaa
3 changed files with 146 additions and 9 deletions

View File

@ -25,6 +25,8 @@ use Web3\Contracts\Types\Bytes;
use Web3\Contracts\Types\Integer; use Web3\Contracts\Types\Integer;
use Web3\Contracts\Types\Str; use Web3\Contracts\Types\Str;
use Web3\Contracts\Types\Uinteger; use Web3\Contracts\Types\Uinteger;
use Web3\Validators\AddressValidator;
use Web3\Formatters\Address as AddressFormatter;
class Contract class Contract
{ {
@ -145,9 +147,7 @@ class Contract
// if (empty($this->provider)) { // if (empty($this->provider)) {
// throw new \RuntimeException('Please set provider first.'); // throw new \RuntimeException('Please set provider first.');
// } // }
// $class = explode('\\', get_class()); // $class = explode('\\', get_class());
// if (preg_match('/^[a-zA-Z0-9]+$/', $name) === 1) { // if (preg_match('/^[a-zA-Z0-9]+$/', $name) === 1) {
// } // }
// } // }
@ -259,6 +259,23 @@ class Contract
return $this->eth; return $this->eth;
} }
/**
* at
*
* @param string $address
* @return $this
*/
public function at($address)
{
if (AddressValidator::validate($address) === false) {
var_dump($address);
throw new InvalidArgumentException('Please make sure address is valid.');
}
$this->toAddress = AddressFormatter::format($address);
return $this;
}
/** /**
* new * new
* Deploy a contruct with params. * Deploy a contruct with params.
@ -297,4 +314,49 @@ class Contract
}); });
} }
} }
/**
* send
* Send function method.
*
* @param mixed
* @return void
*/
public function send()
{
if (isset($this->functions)) {
$arguments = func_get_args();
$method = array_splice($arguments, 0, 1)[0];
$callback = array_pop($arguments);
if (!is_string($method) && !isset($this->functions[$method])) {
throw new InvalidArgumentException('Please make sure the method is existed.');
}
$function = $this->functions[$method];
if (count($arguments) < count($function['inputs'])) {
throw new InvalidArgumentException('Please make sure you have put all function params and callback.');
}
if (is_callable($callback) !== true) {
throw new \InvalidArgumentException('The last param must be callback function.');
}
$params = array_splice($arguments, 0, count($function['inputs']));
$data = $this->ethabi->encodeParameters($function, $params);
$functionSignature = $this->ethabi->encodeFunctionSignature($function['name']);
$transaction = [];
if (count($arguments) > 0) {
$transaction = $arguments[0];
}
$transaction['to'] = $this->toAddress;
$transaction['data'] = $functionSignature . Utils::stripZero($data);
$this->eth->sendTransaction($transaction, function ($err, $transaction) use ($callback){
if ($err !== null) {
return call_user_func($callback, $err, null);
}
return call_user_func($callback, null, $transaction);
});
}
}
} }

View File

@ -135,9 +135,6 @@ class Ethabi
*/ */
public function encodeParameters($types, $params) 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 // change json to array
if ($types instanceof stdClass && isset($types->inputs)) { if ($types instanceof stdClass && isset($types->inputs)) {
$types = Utils::jsonToArray($types, 2); $types = Utils::jsonToArray($types, 2);
@ -152,6 +149,9 @@ class Ethabi
} }
} }
} }
if (count($types) !== count($params)) {
throw new InvalidArgumentException('encodeParameters number of types must equal to number of params.');
}
$typesLength = count($types); $typesLength = count($types);
$solidityTypes = array_fill(0, $typesLength, 0); $solidityTypes = array_fill(0, $typesLength, 0);

View File

@ -277,6 +277,13 @@ class ContractTest extends TestCase
*/ */
protected $accounts; protected $accounts;
/**
* contractAddress
*
* @var string
*/
protected $contractAddress;
/** /**
* setUp * setUp
* *
@ -286,8 +293,8 @@ class ContractTest extends TestCase
{ {
parent::setUp(); parent::setUp();
// $this->contract = new Contract('http://localhost:8545', $this->testAbi); $this->contract = new Contract('http://localhost:8545', $this->testAbi);
$this->contract = new Contract($this->web3->provider, $this->testAbi); // $this->contract = new Contract($this->web3->provider, $this->testAbi);
$this->contract->eth->accounts(function ($err, $accounts) { $this->contract->eth->accounts(function ($err, $accounts) {
if ($err === null) { if ($err === null) {
if (isset($accounts->result)) { if (isset($accounts->result)) {
@ -307,14 +314,82 @@ class ContractTest extends TestCase
{ {
$contract = $this->contract; $contract = $this->contract;
// var_dump($this->contract->constructor);
if (!isset($this->accounts[0])) { if (!isset($this->accounts[0])) {
$account = '0x407d73d8a49eeb85d32cf465507dd71d507100c1'; $account = '0x407d73d8a49eeb85d32cf465507dd71d507100c1';
} else { } else {
$account = $this->accounts[0]; $account = $this->accounts[0];
} }
$contract->new(10000, 'Game Token', 1, 'GT', [ $contract->new(10000, 'Game Token', 1, 'GT', [
'from' => $account 'from' => $account,
'gas' => '0x200b20'
], function ($err, $result) use ($contract) {
if ($err !== null) {
// infura api gg
return $this->assertTrue($err !== null);
}
if ($result->result) {
echo "\nTransaction has made:) id: " . $result->result . "\n";
}
$transactionId = $result->result;
$this->assertTrue((preg_match('/^0x[a-f0-9]{64}$/', $transactionId) === 1));
$contract->eth->getTransactionReceipt($transactionId, function ($err, $transaction) {
if ($err !== null) {
return $this->fail($err);
}
if ($transaction->result) {
$this->contractAddress = $transaction->result->contractAddress;
echo "\nTransaction has mind:) block number: " . $transaction->result->blockNumber . "\n";
}
});
});
}
/**
* testSend
*
* @return void
*/
public function testSend()
{
$contract = $this->contract;
if (!isset($this->accounts[0])) {
$fromAccount = '0x407d73d8a49eeb85d32cf465507dd71d507100c1';
} else {
$fromAccount = $this->accounts[0];
}
if (!isset($this->accounts[1])) {
$toAccount = '0x407d73d8a49eeb85d32cf465507dd71d507100c2';
} else {
$toAccount = $this->accounts[1];
}
$contract->new(10000, 'Game Token', 1, 'GT', [
'from' => $fromAccount,
'gas' => '0x200b20'
], function ($err, $result) use ($contract) {
if ($err !== null) {
// infura api gg
return $this->assertTrue($err !== null);
}
if ($result->result) {
echo "\nTransaction has made:) id: " . $result->result . "\n";
}
$transactionId = $result->result;
$this->assertTrue((preg_match('/^0x[a-f0-9]{64}$/', $transactionId) === 1));
$contract->eth->getTransactionReceipt($transactionId, function ($err, $transaction) {
if ($err !== null) {
return $this->fail($err);
}
if ($transaction->result) {
$this->contractAddress = $transaction->result->contractAddress;
echo "\nTransaction has mind:) block number: " . $transaction->result->blockNumber . "\n";
}
});
});
$contract->at($this->contractAddress)->send('transfer', $toAccount, 100, [
'from' => $fromAccount
], function ($err, $result) use ($contract) { ], function ($err, $result) use ($contract) {
if ($err !== null) { if ($err !== null) {
// infura api gg // infura api gg