Skip to content

Commit

Permalink
Merge pull request #13 from sc0Vu/fix-12
Browse files Browse the repository at this point in the history
Fix #12
  • Loading branch information
sc0Vu authored Jun 13, 2018
2 parents 4e1d214 + ebeafc8 commit c1ff45c
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 96 deletions.
65 changes: 53 additions & 12 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

178 changes: 116 additions & 62 deletions src/Transaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,39 +13,80 @@

use InvalidArgumentException;
use RuntimeException;
use kornrunner\Keccak;
use Web3p\RLP\RLP;
use Elliptic\EC;
use Elliptic\EC\KeyPair;
use ArrayAccess;
use Web3p\EthereumUtil\Util;

class Transaction implements ArrayAccess
{
/**
* SHA3_NULL_HASH
*
* @const string
*/
const SHA3_NULL_HASH = 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470';

/**
* txData
* attributeMap
*
* @var array
*/
protected $map = [
'from' => -1,
'chainId' => -2,
'nonce' => 0,
'gasPrice' => 1,
'gasLimit' => 2,
'gas' => 2,
'to' => 3,
'value' => 4,
'data' => 5,
'v' => 6,
'r' => 7,
's' => 8
protected $attributeMap = [
'from' => [
'key' => -1
],
'chainId' => [
'key' => -2
],
'nonce' => [
'key' => 0,
'length' => 32,
'allowLess' => true,
'allowZero' => true
],
'gasPrice' => [
'key' => 1,
'length' => 32,
'allowLess' => true,
'allowZero' => true
],
'gasLimit' => [
'key' => 2,
'length' => 32,
'allowLess' => true,
'allowZero' => true
],
'gas' => [
'key' => 2,
'length' => 32,
'allowLess' => true,
'allowZero' => true
],
'to' => [
'key' => 3,
'length' => 20,
'allowZero' => true,
],
'value' => [
'key' => 4,
'length' => 32,
'allowLess' => true,
'allowZero' => false
],
'data' => [
'key' => 5,
'allowLess' => true,
'allowZero' => true
],
'v' => [
'key' => 6,
'allowZero' => true
],
'r' => [
'key' => 7,
'length' => 32,
'allowZero' => true
],
's' => [
'key' => 8,
'length' => 32,
'allowZero' => true
]
];

/**
Expand Down Expand Up @@ -76,6 +117,13 @@ class Transaction implements ArrayAccess
*/
protected $privateKey;

/**
* util
*
* @var \Web3p\EthereumUtil\Util
*/
protected $util;

/**
* construct
*
Expand All @@ -86,18 +134,16 @@ public function __construct($txData=[])
{
$this->rlp = new RLP;
$this->secp256k1 = new EC('secp256k1');
$tx = [];
$this->util = new Util;

if (is_array($txData)) {
foreach ($txData as $key => $data) {
$txKey = isset($this->map[$key]) ? $this->map[$key] : null;

if (is_int($txKey)) {
$tx[$txKey] = $data;
}
$this->offsetSet($key, $data);
}
} elseif (is_string($txData)) {
if (strpos($txData, '0x') === 0) {
$tx = [];

if ($this->util->isHex($txData)) {
$txData = $this->rlp->decode($txData);

foreach ($txData as $txKey => $data) {
Expand All @@ -112,8 +158,8 @@ public function __construct($txData=[])
}
}
}
$this->txData = $tx;
}
$this->txData = $tx;
}

/**
Expand Down Expand Up @@ -168,10 +214,35 @@ public function __toString()
*/
public function offsetSet($offset, $value)
{
$txKey = isset($this->map[$offset]) ? $this->map[$offset] : null;

if (is_int($txKey)) {
$this->txData[$txKey] = $value;
$txKey = isset($this->attributeMap[$offset]) ? $this->attributeMap[$offset] : null;

if (is_array($txKey)) {
$checkedValue = ($value) ? (string) $value : '';
$isHex = $this->util->isHex($checkedValue);
$checkedValue = $this->util->stripZero($checkedValue);

if (!isset($txKey['allowLess']) || (isset($txKey['allowLess']) && $txKey['allowLess'] === false)) {
// check length
if (isset($txKey['length'])) {
if ($isHex) {
if (strlen($checkedValue) > $txKey['length'] * 2) {
throw new InvalidArgumentException($offset . ' exceeds the length limit.');
}
} else {
if (strlen($checkedValue) > $txKey['length']) {
throw new InvalidArgumentException($offset . ' exceeds the length limit.');
}
}
}
}
if (!isset($txKey['allowZero']) || (isset($txKey['allowZero']) && $txKey['allowZero'] === false)) {
// check zero, 0x0
if ($checkedValue === '0' && ($value === 0 || $value === '0x0' || $value === '0x')){
// set value to empty string
$value = '';
}
}
$this->txData[$txKey['key']] = $value;
}
}

Expand All @@ -183,10 +254,10 @@ public function offsetSet($offset, $value)
*/
public function offsetExists($offset)
{
$txKey = isset($this->map[$offset]) ? $this->map[$offset] : null;
$txKey = isset($this->attributeMap[$offset]) ? $this->attributeMap[$offset] : null;

if (is_int($txKey)) {
return isset($this->txData[$txKey]);
if (is_array($txKey)) {
return isset($this->txData[$txKey['key']]);
}
return false;
}
Expand All @@ -199,10 +270,10 @@ public function offsetExists($offset)
*/
public function offsetUnset($offset)
{
$txKey = isset($this->map[$offset]) ? $this->map[$offset] : null;
$txKey = isset($this->attributeMap[$offset]) ? $this->attributeMap[$offset] : null;

if (is_int($txKey) && isset($this->txData[$txKey])) {
unset($this->txData[$txKey]);
if (is_array($txKey) && isset($this->txData[$txKey['key']])) {
unset($this->txData[$txKey['key']]);
}
}

Expand All @@ -214,10 +285,10 @@ public function offsetUnset($offset)
*/
public function offsetGet($offset)
{
$txKey = isset($this->map[$offset]) ? $this->map[$offset] : null;
$txKey = isset($this->attributeMap[$offset]) ? $this->attributeMap[$offset] : null;

if (is_int($txKey) && isset($this->txData[$txKey])) {
return $this->txData[$txKey];
if (is_array($txKey) && isset($this->txData[$txKey['key']])) {
return $this->txData[$txKey['key']];
}
return null;
}
Expand All @@ -232,23 +303,6 @@ public function getTxData()
return $this->txData;
}

/**
* sha3
* keccak256
*
* @param string $value
* @return string
*/
public function sha3(string $value)
{
$hash = Keccak::hash($value, 256);

if ($hash === $this::SHA3_NULL_HASH) {
return null;
}
return $hash;
}

/**
* serialize
*
Expand Down Expand Up @@ -344,7 +398,7 @@ public function hash($includeSignature=false)
}
$serializedTx = $this->rlp->encode($txData)->toString('utf8');

return $this->sha3($serializedTx);
return $this->util->sha3($serializedTx);
}

/**
Expand Down Expand Up @@ -383,7 +437,7 @@ public function getFromAddress()
} else {
$publicKey = $this->privateKey->getPublic(false, 'hex');
}
$from = '0x' . substr($this->sha3(substr(hex2bin($publicKey), 1)), 24);
$from = '0x' . substr($this->util->sha3(substr(hex2bin($publicKey), 1)), 24);

$this->offsetSet('from', $from);
return $from;
Expand Down
Loading

0 comments on commit c1ff45c

Please sign in to comment.