olifanton/interop

Olifanton interop 库

1.4.3 2024-08-28 14:21 UTC

This package is auto-updated.

Last update: 2024-08-28 14:22:17 UTC


README

Code Coverage Badge Tests Latest Stable Version Total Downloads Based on TON Donation

💬 英文聊天 | 💬 俄文聊天

安装

composer require olifanton/interop

文档

入门

通过 Composer 安装 olifanton/interop 包并包含自动加载脚本

<?php declare(strict_types=1);

require __DIR__ . "/vendor/autoload.php";

use Olifanton\Interop\Boc\BitString;
use Olifanton\Interop\Boc\Cell;

// Now you can use Interop classes

组件

地址

Olifanton\Interop\Address

Address 是一个类,允许您在 TON 网络中处理智能合约地址。有关地址的更多信息,请参阅官方 文档

Address 构造函数
/**
 * @param string | \Olifanton\Interop\Address $anyForm
 */
public function __construct(string | Address $anyForm)

参数

  • $anyForm — 支持形式中的地址。支持值包括
    • 友好格式(base64 编码,URL 安全或不安全):EQBvI0aFLnw2QbZgjMPCLRdtRHxhUyinQudg6sdiohIwg5jL;
    • 原始格式:-1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260;
    • 其他 Address 实例,在这种情况下,新实例将是其他地址的不可变副本。

根据传递的值,地址实例将存储关于输入地址标志的信息。

如果输入值不是一个有效的地址,则将抛出 \InvalidArgumentException

Address 静态方法
isValid(string | \Olifanton\Interop\Address $anyForm): bool

检查传递的值是否为任何形式的有效地址。

Address 方法
toString(): string
/**
 * @param bool|null $isUserFriendly User-friendly flag
 * @param bool|null $isUrlSafe URL safe encoded flag
 * @param bool|null $isBounceable Bounceable address flag
 * @param bool|null $isTestOnly Testnet Only flag
 */
public function toString(?bool $isUserFriendly = null,
                         ?bool $isUrlSafe = null,
                         ?bool $isBounceable = null,
                         ?bool $isTestOnly = null): string

返回地址的字符串表示形式。

如果所有参数都保留为默认值,则地址将使用在构造函数中识别的相同标志进行格式化。

getWorkchain(): int

返回工作链 ID。对于 Masterchain 返回 -1,对于基本工作链返回 0

getHashPart(): Uint8Array

返回地址账户 ID。

isTestOnly(): bool

如果地址具有 isTestnetOnly 标志,则返回 true。

isBounceable(): bool

如果地址具有 isBounceable 标志,则返回 true。

isUserFriendly(): bool

如果地址是用户友好的,则返回 true。

isUrlSafe(): bool

如果地址仅使用 URL 安全字符进行编码,则返回 true。

位字符串

Olifanton\Interop\Boc\BitString

BitString 是一个类,允许您操作二进制数据。BitString 是 PHP 中 TVM 单元的表示核心。BitString 对存储二进制数据进行了内存优化。内部,BitString 使用由 olifanton/typed-arrays 包提供的 Uint8Array 实现来操作,并作为在 Olifanton 库的不同部分之间传输二进制数据的基本类型。

BitString 实例使用严格固定的长度创建。`write%`(writeBit,writeUint,...)方法移动内部游标。如果您尝试写入超出空闲位长度的值,将抛出 BitStringException 异常。

BitString 构造函数
/**
 * @param int $length
 */
public function __construct(int $length)

参数

  • $length — Uint8Array 的长度。TVM 单元的默认值:1023文档
BitString 方法
getFreeBits(): int

返回 BitString 的未使用位长度。

getUsedBits(): int

返回 BitString 的已使用位长度。

getUsedBytes(): int

返回BitString使用的字节长度。

get(): bool
/**
 * @param int $n Position
 */
public function get(int $n): bool

返回位于$n位置的位值。

on(): void
/**
 * @param int $n Position
 */
public function on(int $n): void

将位置$n的位值设置为1。

off(): void
/**
 * @param int $n Position
 */
public function off(int $n): void

将位置$n的位值设置为0。

toggle(): void
/**
 * @param int $n Position
 */
public function toggle(int $n): void

切换(取反)位置$n的位值。

iterate(): \Generator

返回已使用位的生成器。

示例

<?php declare(strict_types=1);

use Olifanton\Interop\Boc\BitString;

$bs = new BitString(4);
$bs->writeBit(1);
$bs->writeBit(0);
$bs->writeBit(1);
$bs->writeBit(1);

foreach ($bs->iterate() as $b) {
    echo (int)$b;
}
// Prints "1011"
writeBit(): void
/**
 * @param int|bool $b
 */
public function writeBit(int | bool $b): void

写入位并增加BitString内部游标。

writeBitArray(): void
/**
 * @param array<int | bool> $ba Array of bits
 */
public function writeBitArray(array $ba): void

写入位数组。

示例

<?php declare(strict_types=1);

use Olifanton\Interop\Boc\BitString;

$bs = new BitString(4);
$bs->writeBitArray([1, false, 0, true]);

foreach ($bs->iterate() as $b) {
    echo (int)$b;
}
// Prints "1001"
writeUint(): void
/**
 * @param int|\Brick\Math\BigInteger $number Unsigned integer
 * @param int $bitLength Integer size (8, 16, 32, ...)
 */
public function writeUint(int | BigInteger $number, int $bitLength): void

写入$bitLength位的无符号整数。

writeInt(): void
/**
 * @param int|\Brick\Math\BigInteger $number Signed integer
 * @param int $bitLength Integer size (8, 16, 32, ...)
 */
public function writeInt(int | BigInteger $number, int $bitLength): void

写入$bitLength位的有符号整数。

writeUint8(): void

writeUint()方法的别名,具有预定义的$bitLength参数值。

writeBytes(): void
/**
 * @param \Olifanton\TypedArrays\Uint8Array $ui8 Byte array
 */
public function writeBytes(Uint8Array $ui8): void

写入无符号8位整数数组。

writeString(): void
/**
 * @param string $value
 */
public function writeString(string $value): void

写入UTF-8字符串。

writeCoins(): void
/**
 * @param int|\Brick\Math\BigInteger $amount
 */
public function writeCoins(int | BigInteger $amount): void;

以纳诺吨币的形式写入币(1 TON === 1000000000 (10^9) 纳诺吨币)。

writeAddress(): void
/**
 * @param \Olifanton\Interop\Address|null $address TON Address
 */
public function writeAddress(?Address $address): void

写入TON地址

writeBitString(): void
/**
 * @param \Olifanton\Interop\Boc\BitString $anotherBitString BitString instance
 */
public function writeBitString(BitString $anotherBitString): void

将另一个BitString写入此BitString。

clone(): BitString

克隆此BitString并返回新的BitString实例。

toHex(): string

返回BitString的十六进制字符串表示。

getImmutableArray(): Uint8Array

返回内部Uint8Array的不变副本。

getLength(): int

返回BitString的位数大小。

Cell

Olifanton\Interop\Boc\Cell

Cell是一个类,它实现了PHP中的TVM Cells的概念。为了创建新的和处理从区块链接收的消息,您将使用Cell类的实例。

Cell构造函数

无参数。

Cell方法
fromBoc(): Array<Cell>
/**
 * @param string|Uint8Array $serializedBoc Serialized BoC
 * @return Cell[]
 */
public static function fromBoc(string|Uint8Array $serializedBoc): array

从字节数组或十六进制字符串创建Cell数组。

oneFromBoc(): Cell
/**
 * @param string|Uint8Array $serializedBoc Serialized BoC
 * @param bool $isBase64 Base64-serialized flag, default false
 */
public static function oneFromBoc(string|Uint8Array $serializedBoc, bool $isBase64 = false): Cell

从字节数组或十六进制字符串获取一个根Cell。

writeCell(): void
/**
 * @param Cell $anotherCell Another cell
 * @return Cell This Cell
 */
public function writeCell(Cell $anotherCell): self

将另一个Cell写入此Cell并返回此Cell。可变方法。

getMaxDepth(): int

返回子Cells的最大深度。

getBits(): BitString

返回用于写入和读取的内部BitString实例。

getRefs(): ArrayObject<Cell>

返回子Cells的类似数组对象。

hash(): Uint8Array

返回此Cell的SHA-256哈希值。

print(): string

递归打印单元格的内容,类似于Fift。

toBoc(): Uint8Array
/**
 * @param bool $has_idx Default _true_
 * @param bool $hash_crc32 Default _true_
 * @param bool $has_cache_bits Default _false_
 * @param int $flags Default _0_
 */
public function toBoc(bool $has_idx = true,
                      bool $hash_crc32 = true,
                      bool $has_cache_bits = false,
                      int  $flags = 0): Uint8Array

创建BoC字节数组。

Slice

Olifanton\Interop\Boc\Slice

Slice是单元格切片的类型。可以将单元格转换为切片,然后可以通过从切片中加载它们来获取单元格中的数据位和其他单元格的引用。

load%(loadBit,loadUint,...)方法移动Slice内部游标。如果您尝试读取超出空闲位长度的值,将抛出SliceException异常。

Slice构造函数
/**
 * @param \Olifanton\TypedArrays\Uint8Array $array
 * @param int $length
 * @param \Olifanton\Interop\Boc\Slice[] $refs
 */
public function __construct(Uint8Array $array, int $length, array $refs)

参数

  • $array — Uint8Array,它是Cell的BitString表示
  • $length — BitString长度
  • $refs — 子Cells切片
Slice方法
getFreeBits(): int

根据内部游标返回未读取的位。

get(): bool
/**
 * @param int $n
 */
public function get(int $n): bool

返回位置$n的位值。

loadBit(): bool

读取位并移动游标。

loadBits(): Uint8Array
/**
 * @param int $bitLength
 */
public function loadBits(int $bitLength): Uint8Array

读取位数组。

loadUint(): BigInteger
/**
 * @param int $bitLength
 */
public function loadUint(int $bitLength): BigInteger

读取无符号整数。

loadInt(): BigInteger
/**
 * @param int $bitLength
 */
public function loadInt(int $bitLength): BigInteger

读取有符号整数。

loadVarUint(): BigInteger
/**
 * @param int $bitLength
 */
public function loadVarUint(int $bitLength): BigInteger
loadCoins(): BigInteger

读取TON金额(以纳诺吨币计)。

loadAddress(): ?Address

读取地址。

loadRef(): Slice

读取一个子Cell。

Builder

Olifanton\Interop\Boc\Builder

Builder允许您快速创建单元格(在BitString实例内操作)。Builder类的所有实例都是可变的,并且所有方法都返回相同的实例。在大多数情况下,Builder接口与BitString类的接口相同。

Hashmap

Olifanton\Interop\Boc\Hashmap

Hashmap 类是 PHP 中对 TL-B 字典结构的表示。

使用 Hashmap 类时,需要考虑以下特性:

  • 键的内部状态始终是一个位数组;
  • 值的内部状态始终是 Cell;
  • 键的长度总是固定的。

由于内部状态的特性,在 Hashmap 中使用不同类型的键和值可能并不总是方便。为了简化字典的使用,可以将特殊闭包(作为 DictSerializers 的实例)传递给 Hashmap 类的构造函数,这些闭包简化了键到位数组的转换以及值到 Cells 的转换。

以下是一个使用字典的示例。键是一个有符号 32 位整数,值是一个无符号 128 位 BigInteger

use Olifanton\Interop\Boc\Hashmap;
use Olifanton\Interop\Boc\DictSerializers;
use Olifanton\Interop\Boc\Builder;
use Olifanton\Interop\Boc\Cell;
use Brick\Math\BigInteger;

$dict = new Hashmap(
    32, // Key size,

    // KV marshalling setup
    new DictSerializers(
        // closure converts a number into a bit array, using an intermediate cell (created by Builder) and toBitsA() helper method of BitString class
        keySerializer: static fn(int $userFriendlyKey, int $keySize): array => (new Builder())->writeInt($userFriendlyKey, $keySize)->cell()->bits->toBitsA(),
        // closure converts a bit array into a number, using an intermediate cell (created by Builder)
        keyDeserializer: static fn(array $bitsKey, int $keySize): int => (new Builder())->writeBitArray($bitsKey)->cell()->beginParse()->loadInt($keySize)->toInt(),

        // closure writes BigInteger value into Cell
        valueSerializer: static fn(BigInteger $userFriendlyValue): Cell => (new Builder())->writeUint($userFriendlyValue, 128)->cell(),
        // closure loads BigInteger value from Cell
        valueDeserializer: static fn(Cell $internalValue): BigInteger => $internalValue->beginParse()->loadUint(128),
    )
);

// add value to dictionary
$dict->set(1, BigInteger::fromBase("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16));
// now, internal Hashmap storage contains record with key [00000000000000000000000000000001] and Cell value

var_dump($dict->get(1)->toBase(10)); // 340282366920938463463374607431768211455

在开发过程中,您可以实现任何闭包,以便将您的标量 KV 类型转换为键数组和值 Cells。您还可以使用在 DictSerializers 类的静态构造函数中提供的预定义序列化器

  • DictSerializers::uintKey()
  • DictSerializers::intKey()
  • DictSerializers::addressKey()
  • DictSerializers::intValue()
  • DictSerializers::uintValue()

我们可以将示例重写为使用预定义序列化器并减少代码量

$dict = new Hashmap(
    32,
    DictSerializers::uintKey(isBigInt: false)->combine(DictSerializers::uintValue(128)),
);
$dict->set(1, BigInteger::fromBase("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16));

var_dump($dict->get(1)->toBase(10)); // 340282366920938463463374607431768211455

测试

composer run test

贡献

在提交 pull request 之前,请务必阅读 Olifanton 贡献指南

设置环境

为开发准备您的环境。

请注意,说明描述了在 *nix 系统(Linux 和可能 macOS)上工作,Windows 上的开发可能很困难,并且这些说明中不会涉及。

您需要

  1. 最小 PHP 版本:8.1;
  2. sodium 扩展;
  3. hash 扩展。

分支仓库

在您的 GitHub 账户中创建仓库分支。

克隆您的仓库

git clone git@github.com:<YOUR_GITHUB_NAME>/interop.git
cd interop

创建 feature/(或 hotfix/)分支

git branch feature/<FEATURE_NAME>
git checkout feature/<FEATURE_NAME>

创建 pull request

在您的本地分支实现新的功能(或热修复)后,您应该提交并推送更改到您的分支仓库。然后您可以创建 pull-request。

许可证

MIT