enjin / php-blockchain-tools
处理十六进制数字和解码合约数据的工具。
Requires
- php: ^8.0|^8.1
- kornrunner/keccak: ^1.0
- phpseclib/phpseclib: ^3.0
Requires (Dev)
- fakerphp/faker: ^1.18
- mockery/mockery: ^1.5
- nette/php-generator: ^v3.6
- phpunit/phpunit: ^9.5
- symfony/var-dumper: ^6.0
This package is auto-updated.
Last update: 2024-08-30 01:23:38 UTC
README
十六进制数据
HexConverter
查看: Enjin\BlockchainTools\HexConverter
包含处理十进制和十六进制数据的静态实用函数。
转换方法参考
BigHex
查看: Enjin\BlockchainTools\BigHex
处理大十六进制数字的对象。
$longHex = '0xabc1234...'; $hex = new BigHex($longHex); $hex->toStringPrefixed(); // '0xabc1234...' $hex->toStringUnPrefixed(); // 'abc1234...' // convert to phpseclib\Math\BigInteger $bigInt = $hex->toBigInt();
HexUInt 类
表示和转换所有有效 Uint 值的类位于 HexNumber\HexUInt
命名空间。
// 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'
HexInt 类
表示和转换所有有效 Int 值的类位于 HexNumber\HexInt
命名空间。
// 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'
ABI 合约
当前不支持以下合约数据类型
- string[]
- bytes[]
- 多维数组(uint16[][])
- tuple
- fixed
- ufixed
ContractStore
用于懒加载和重用解析的 abi json 数据。在您的应用程序中创建并重用此类的实例以懒加载和缓存处理过的 abi 文件。
查看: 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...');
自定义合约序列化器
可以为合约或特定函数/事件注册自定义序列化器。
查看: Enjin\BlockchainTools\Ethereum\ABI\DataBlockDecoder
查看: Enjin\BlockchainTools\Ethereum\ABI\DataBlockDecoder
查看: Enjin\BlockchainTools\Ethereum\ABI\DataBlockDecoder\BasicDecoder
查看: 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);
合约
用于与 ABI 合约交互的接口。
查看: 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);
合约函数
表示 ABI 合约函数。
查看: 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);
合约事件
表示 ABI 合约事件。
查看: 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);
生成的类
以下类是通过运行 php ./bin/generate-classes.php
生成的
\Enjin\BlockchainTools\HexNumber\HexInt
\Enjin\BlockchainTools\HexNumber\HexUInt
\Enjin\BlockchainTools\HexNumber\HexInt\HexInt*
\Enjin\BlockchainTools\HexNumber\HexUInt\HexUInt*
生成 HexUInt
和 HexInt