See: Enjin\BlockchainTools\HexConverter
Contains static utility functions for handling decimal and hex data.
Method | From | To |
---|---|---|
hexToInt |
signed int (base 16) | signed int (base 10) |
intToHex |
signed int (base 10) | signed int (base 16) |
intToHexPrefixed |
0x prefixed |
|
hexToUInt |
unsigned int (base 16) | unsigned int (base 10) |
uIntToHex |
unsigned int (base 10) | unsigned int (base 16) |
uIntToHexPrefixed |
0x prefixed |
|
hexToString |
hex encoded string (base 16) | decoded string |
stringToHex |
decoded string | hex encoded string (base 16) |
stringToHexPrefixed |
0x prefixed |
|
hexToBytes |
hex encoded bytes (base 16) | array of bytes |
bytesToHex |
array of bytes | hex encoded bytes (base 16) |
bytesToHexPrefixed |
0x prefixed |
|
hexToAddress |
hex string | address |
hexToAddressPrefixed |
0x prefixed |
|
addressToEventTopic |
address | address padded to event topic |
addressToEventTopicPrefixed |
0x prefixed |
See: Enjin\BlockchainTools\BigHex
Object for handling large hex numbers.
$longHex = '0xabc1234...';
$hex = new BigHex($longHex);
$hex->toStringPrefixed(); // '0xabc1234...'
$hex->toStringUnPrefixed(); // 'abc1234...'
// convert to phpseclib\Math\BigInteger
$bigInt = $hex->toBigInt();
Classes to represent and convert all valid UInt values are in the HexNumber\HexUInt
namespace.
// ways to create a HexNumber instance
// all will throw an exception if an invalid value is provided
// the value must be within the min/max range
// if it is a hex it must have the correct number of characters
$hexUInt16 = new HexUInt16('0x1234');
$hexUInt16 = HexUInt16::fromHex('0x1234');
$hexUInt16 = HexUInt::fromHexUInt16('0x1234');
$hexUInt16 = HexUInt::fromHexUIntBitSize(16, '0x1234');
// creating from a base 10 decimal value
$hexUInt16 = HexUInt16::fromUInt('4660');
$hexUInt16 = HexUInt::fromUIntBitSize(16, '4660');
$hexUInt16->toPrefixed(); // '0x1234'
$hexUInt16->toUnPrefixed(); // '1234'
$hexUInt16->toDecimal(); // '4660'
$hexUInt16->toHexUInt64(); // '0x0000000000001234'
// can only convert to top/bottom of lower bit sizes
HexUInt16::fromHex('0x1200')->toHexInt8Top(); // '0x12'
HexUInt16::fromHex('0x0034')->toHexInt8Bottom(); // '0x34'
// returned exactly as provided (with our without prefix)
$hexUInt16->toHex(); // '0x1234'
// note that prefix remains intact when provided
HexUInt::fromHexUInt24('123456')->toHexUInt64(); // '0000000000123456'
HexUInt::fromHexUInt24('0x123456')->toHexUInt64(); // '0x0000000000123456'
// provide a hex without left padded zeroes
$paddedHex = HexUInt16::padLeft('0x12'); // '0x0012'
Classes to represent and convert all valid Int values are in the HexNumber\HexInt
namespace.
// ways to create a HexNumber instance
// all will throw an exception if an invalid value is provided
// the value must be within the min/max range
// if it is a hex it must have the correct number of characters
$hexInt16 = new HexInt16('0xfefc');
$hexInt16 = HexInt16::fromHex('0xfefc');
$hexInt16 = HexInt::fromHexInt16('0xfefc');
$hexInt16 = HexInt::fromHexIntBitSize(16, '0xfefc');
// creating from a base 10 decimal value
$hexInt16 = HexInt16::fromInt('-260');
$hexInt16 = HexInt::fromIntBitSize(16, '-260');
$hexInt16->toPrefixed(); // '0xfefc'
$hexInt16->toUnPrefixed(); // 'fefc'
$hexInt16->toDecimal(); // '-260'
$hexInt16->toHexInt64(); // '0x000000000000fefc'
// can only convert to top/bottom of lower bit sizes
HexInt16::fromHex('0xfe00')->toHexInt8Top(); // '0xfe'
HexInt16::fromHex('0x00fc')->toHexInt8Bottom(); // '0xfc'
// returned exactly as provided (with our without prefix)
$hexInt16->toHex(); // '0xfefc'
// note that prefix remains intact when provided
HexInt::fromHexInt24('123456')->toHexInt64(); // '0000000000123456'
HexInt::fromHexInt24('0x123456')->toHexInt64(); // '0x0000000000123456'
// provide a hex without left padded zeroes
$paddedHex = HexInt16::padLeft('0x12'); // '0x0012'
- string[]
- bytes[]
- multi-dimensional arrays (uint16[][])
- tuple
- fixed
- ufixed
Used to lazy load and re-use parsed abi json data. Create and re-use an instance of this class in your application to lazy load and cache processed abi files.
See: Enjin\BlockchainTools\Ethereum\ABI\ContractStore
use Enjin\BlockchainTools\Ethereum\ABI\ContractStore;
$store = new ContractStore();
$store->registerContracts([
[
'name' => 'my-contract',
'address' => '0xabc...',
'jsonFile' => '/path/to/abi/json/file'
]
]);
// OR
$store->registerContract('my-contract', '0xabc...', '/path/to/abi/json/file');
$contract = $store->contract('my-contract');
$contract = $store->contractByAddress('0xabc...');
Custom serializers may be registered for contracts or specific functions/events.
See: Enjin\BlockchainTools\Ethereum\ABI\DataBlockDecoder
See: Enjin\BlockchainTools\Ethereum\ABI\DataBlockDecoder
See: Enjin\BlockchainTools\Ethereum\ABI\DataBlockDecoder\BasicDecoder
See: Enjin\BlockchainTools\Ethereum\ABI\DataBlockDecoder\BasicEncoder
use Enjin\BlockchainTools\Ethereum\ABI\ContractStore;
use Enjin\BlockchainTools\Ethereum\ABI\Serializer;
use Enjin\BlockchainTools\Ethereum\ABI\DataBlockDecoder\BasicDecoder;
use Enjin\BlockchainTools\Ethereum\ABI\DataBlockEncoder\BasicEncoder;
$default = Serializer::makeDefault();
// make a serializer instance with a custom decoder/encoder classes
// basic decoder/encoder converts:
// - string to/from hex
// - bytes to/from array of bytes to hex
// - php bool to/from hex
// - address to/from hex (converted to correct length with prefix removed)
$basic = new Serializer(
BasicDecoder::class,
BasicEncoder::class
);
$store = new ContractStore();
$serializers = [
// default for all functions and events
'default' => $default,
'functions' => [
'myFunction1' => [
// replaces contract default
// default for input and output of myFunction
'default' => $basic,
// replaces function default for input
'input' => $default,
// replaces function default for output
'output' => $basic,
],
'myFunction2' => [
'default' => $basic,
],
// ...
],
'events' => [
// events only have input and only decode
// so are assigned serializers directly
'myEvent1' => $basic,
'myEvent2' => $basic,
// ...
]
];
$store->registerContracts([
[
'name' => 'my-contract',
'address' => '0xabc...',
'jsonFile' => '/path/to/abi/json/file',
'serializers' => $serializers,
]
]);
$store->registerContract('my-contract', '0xabc...', '/path/to/abi/json/file', $serializers);
Interface to interact with an ABI contract.
See: Enjin\BlockchainTools\Ethereum\ABI\Contract
$contract = $contractStore->contract('contract-name');
$name = $contract->name();
$address = $contract->address();
/* Functions */
$arrayOfFunctions = $contract->functions();
$function = $contract->function('function-name');
// first 8 characters of encoded input/output
$methodId = '...';
$function = $contract->findFunctionByMethodId($methodId);
$encodedInput = '...';
// looks up method from first 8 characters of encoded string and decodes
$decoded = $contract->decodeFunctionInput($encodedInput);
$decoded = $contract->decodeFunctionOutput($encodedInput);
/* Events */
$arrayOfEvents = $contract->events();
$event = $contract->event('event-name');
// topic[0] event signature
$signatureTopic = '...';
$event = $contract->findEventBySignatureTopic($signatureTopic);
$topics = [];
$data = '...';
// lookup event by topic[0] and decode input
$decoded = $contract->decodeEventInput($topics, $data);
Represents an ABI contract function.
See: Enjin\BlockchainTools\Ethereum\ABI\Contract\ContractFunction
$contract = $contractStore->contract('contract-name');
$function = $contract->function('function-name');
$name = $function->name();
$constant = $function->constant();
$payable = $function->payable();
$stateMutability = $function->stateMutability();
// signature example: myFunction(uint16,string)
$signature = $function->signature();
// first 4 bytes of Keccak hashed signature
$methodId = $function->methodId();
$arrayOfInputs = $function->inputs();
$arrayOfOutputs = $function->outputs();
$data = [
'foo' => 'bar',
'key' => 'value',
];
$dataBlock = $function->encodeInput($data);
// or
$dataBlock = $function->encodeOutput($data);
// methodId from function
$dataBlock->methodId();
// convert to encoded string
$dataBlock->toString();
// convert to array of 64 character chunks (excluding methodId)
$dataBlock->toArray();
// convert to array of 64 character chunks with metadata about each chunk (helps with debugging)
$dataBlock->toArrayWithMeta();
// data string with or without methodId at the start
$dataString = '...';
// returns key value pairs as array
$decoded = $function->decodeInput($dataString);
$decoded = $function->decodeOutput($dataString);
Represents an ABI contract event.
See: Enjin\BlockchainTools\Ethereum\ABI\Contract\ContractEvent
$contract = $contractStore->contract('contract-name');
$event = $contract->event('event-name');
$name = $event->name();
$anonymous = $event->anonymous();
// signature example: myFunction(uint16,string)
$signature = $event->signature();
// Keccak hashed signature found in topic[0] of encoded event input
$methodId = $event->signatureTopic();
$arrayOfInputs = $event->inputs();
$input = $event->input('input-name');
$topics = ['...'];
$data = '...';
// convert event to array of key-value pairs
$decoded = $event->decodeInput($topics, $data);
The following classes are generated by running php ./bin/generate-classes.php
:
\Enjin\BlockchainTools\HexNumber\HexInt
\Enjin\BlockchainTools\HexNumber\HexUInt
\Enjin\BlockchainTools\HexNumber\HexInt\HexInt*
\Enjin\BlockchainTools\HexNumber\HexUInt\HexUInt*
To generate the HexUInt
and HexInt