Omni Layer 区块链 PHP 开发包【USDT 对接】

本贴最后更新于 1778 天前,其中的信息可能已经沧海桑田

OmniTool 开发包适用于为 PHP 应用快速增加对 Omni Layer/USDT 数字资产的支持能力,即支持使用自有 Omni Layer 节点的应用场景,也支持基于第三方 API 服务和离线裸交易的轻量级部署场景。下载地址:omni/usdt php 开发包

1、OmniTool 开发包简介

OmniTool 开发包主要包含以下特性:

  • 完善的 Omni Layer 节点 RPC 封装
  • 支持利用自有节点或第三方服务获取指定地址的 utxo 集合
  • 支持离线生成 omni 代币转账裸交易
  • 支持利用自有节点或第三方服务广播裸交易

OmniTool 支持本地部署的 Omnicored 节点,也支持 blockchain.info、btc.com 等提供的开放 API,要增加对其他第三方服务的支持也非常简单,只需要参考代码实现如下接口:

  • UtxoCollectorInterface:utxo 收集器
  • UtxoSelectorInterface:utxo 筛选器
  • BroadcasterInterface:裸交易广播器
  • ExplorerInterface:数据查询接口

OmniTool 软件包运行在**Php 7.1+**环境下,当前版本 1.0.0,主要类/接口及关系如下图所示:

omnitoolarch.png

OmniTool 的主要代码文件清单如下:

代码文件说明
omni.php/src/RpcClient.phpOmni Layer的RPC协议封装类
omni.php/src/RpcModule.phpOmni Layer的RPC协议分模块访问语法糖
omni.php/src/protocol-spec.jsonOmni Layer协议描述元信息
omni.php/src/SerializeBuffer.phpOmni Layer协议序列化缓冲区
omni.php/src/PayloadFactory.phpOmni Layer协议载荷工厂类
omni.php/src/Utxo.php未消费交易输出类
omni.php/src/UtxoBag.phpUtxo集合类
omni.php/src/UtxoCollectorInterface.phpUtxo收集器接口
omni.php/src/LocalUtxoCollector.php基于OmniCore节点的Utxo收集器实现
omni.php/src/CloudUtxoCollector.php基于第三方服务的Utxo收集器实现
omni.php/src/UtxoSelectorInterface.phpUtxo筛选器接口
omni.php/src/DefaultUtxoSelector.php默认的Utxo筛选器实现
omni.php/src/BroadcasterInterface.php裸交易广播器接口
omni.php/src/LocalBroadcaster.php基于OmniCore节点的裸交易广播器实现
omni.php/src/CloudBroadcaster.php基于第三方服务的裸交易广播器实现
omni.php/src/ExplorerInterface.php数据查询接口
omni.php/src/CloudExplorer.php基于第三方服务的数据查询接口实现
omni.php/src/LocalExplorer.php基于OmniCore节点的数据查询接口实现
omni.php/src/Utils.php常用辅助函数
omni.php/src/Wallet.php离线钱包类
demo/rpc-demo.phpRpcClient使用示例,完整实现OMNI代币的发行与转账
demo/omni-tx-cloud.php创建并广播Omni代币转账裸交易,使用第三方云服务API
demo/omni-tx-local.php创建并广播Omni代币转账裸交易,使用自有节点
demo/btc-tx-cloud.php创建并广播比特币转账裸交易,使用第三方云服务API
demo/btc-tx-local.php创建并广播比特币转账裸交易,使用自有节点
demo/explorer-cloud.php查询指定的地址比特币余额/Omni代币余额,使用第三方云服务API
demo/explorer-local.php查询指定地址的比特币余额/Omni代币余额,使用自有节点
demo/wallet-init.php本地钱包初始化
demo/wallet-demo.php钱包载入、裸交易构造和广播
vendor第三方依赖包目录
composer.jsoncomposer配置文件

2、RpcClient 类使用说明

RpcClient 类封装了 Omni Layer 的 RPC 接口协议。创建 RpcClient 对象时,需要传入包含有效身份信息的节点 RPC URL。例如,假设安装在本机的 omnicored 节点软件配置如下:

  • rpcuser:user
  • rpcpassword:123456
  • rpcport:8332

那么可以使用如下的代码来实例化 RpcClient:

use \OmniTool\RpcClient;

$client = new RpcClient(
            'http://user:123456@localhost:8332'   /*节点RPC接口的URL*/
          );

Omni Core 节点在 Bitcoin 原有的 RPC 接口之外,扩充了额外的接口用来操作 Omni 层的数据,这些扩展的 RPC 接口采用 omni_ 前缀以区隔于 Bitcoin 的原有 RPC 接口。为了便于区隔这两层的 RPC 调用,RpcClient 引入了协议子模块的概念,将 Bitcoin 的原始 RPC 接口和 Omni 的扩展 RPC 接口分别挂接到 btc 子模块和 omni 子模块。

例如,获取某个地址的 USDT 代币余额需要使用 Omni 层的 omni_getbalance 调用,这个 RPC 调用对应于 RpcClient 实例的 omni 子模块的 getBalance() 方法。下面的代码获取地址 1EXoDusjGwvnjZUyKkxZ4UHEf77z6A5S4P 的 USDT(资产 ID:31)余额:

$ret = $client->omni->getBalance(
          '1EXoDusjGwvnjZUyKkxZ4UHEf77z6A5S4P',   /*地址*/
          31                                      /*资产ID:USDT*/
       );

类似的,可以使用 omni_send 调用来执行简单的 USDT 转账,这个调用对应于 RpcClient 实例的 omni 子模块的 send() 方法。下面的代码从地址 3M9qvHKtgARhqcMtM5cRT9VaiDJ5PSfQGY 向地址 37FaKponF7zqoMLUjEiko25pDiuVH5YLEa
转入 100.0 个 USDT 代币:

$ret = $client->omni->send(
          '3M9qvHKtgARhqcMtM5cRT9VaiDJ5PSfQGY',    /*代币转出地址*/
          '37FaKponF7zqoMLUjEiko25pDiuVH5YLEa',    /*代币转入地址*/
          31,                                      /*代币ID:USDT*/
          "100.00"                                 /*转移的代币数量*/
       );

原有的 bitoin 层的 RPC 接口则可以通过 RpcClient 的 btc 子模块来访问。例如,使用 listunspent 调用来获取本地节点中指定地址的 utxo:

$ret = $client->btc->listUnspent(
          6,                                        /*最小确认数*/
          999999,                                   /*最大确认数*/
          ['mgnucj8nYqdrPFh2JfZSB1NmUThUGnmsqe']    /*地址清单*/  
       );

开发包中的 demo/rpc-demo.php 示例代码使用 RpcClient 类完整演示了在 Omni 层的代币发行与转账功能,如果你计划搭建自己的 Omni Core 节点,相信这个示例会有很大帮助。

3、Wallet 类使用说明

如果不愿意搭建自己的 Omni Core 节点,而是希望基于第三方 API 为自己的 PHP 应用增加对 Omni Layer/USDT 的支持,那么最简单的方法是使用离线交易的入口类 Wallet

Wallet 类的主要作用是根据创建并广播 Omni 代币转账裸交易或比特币转账裸交易,它的基本使用步骤如下:

  • 使用 Wallet::cloud() 静态方法创建一个支持云端 API 服务的 Wallet 实例
  • 使用 addKey() 方法将必要的私钥加入该 Wallet 实例,例如转出地址的私钥,因为 Wallet 需要利用私钥对裸交易进行签名
  • 使用 omniSendTx() 方法生成 Omni 代币转账裸交易,或者使用 btcSendTx() 方法比特币转账裸交易
  • 使用 broadcast() 方法广播裸交易

3.1 Omni 代币转账

使用 Wallet 实现的 Omni 代币转账示例代码如下,说明见注释:

<?php
require('../vendor/autoload.php');

use OmniTool\Wallet;                              /*引入开发包*/

$wallet = Wallet::cloud(
            './demo.wallet',                      /*钱包文件地址,自动创建*/
            'testnet'                             /*网络ID*/
          );
$prvKey = '4aec8e45106....00d5c5af494a4e05b';     /*私钥:16进制字符串*/            
$wallet->addKey($prvKey);                         /*将私钥加入钱包,只需加入一次*/

$addressList = $wallet->getAddressList();         /*返回钱包管理的所有地址,数组*/

$rawtx = $wallet->omniSendTx(
            $addressList[0],                      /*发送方地址,私钥必须已经加入钱包*/
            'mgYPLmNuZymK...e2XUNF6VFnT',         /*接收方地址*/
            2,                                    /*转账OMNI代币ID,2:TOMN*/
            '0.000001'                            /*转账OMNI代币数量*/
         );

$ret = $wallet->broadcast($rawtx);                /*广播OMNI裸交易*/
var_dump($ret);

注意:

  • Wallet 实例利用钱包中的私钥生成地址列表,并利用这些地址从第三方服务获取 utxo 信息。 因此需要钱包中 的私钥对应地址在链上有 utxo 存在,Wallet 对象才能够成功构造裸交易。
  • 转账目标地址应当与创建 Wallet 对象时指定的链 ID 一致,例如 mainnet 的 p2pkh 地址,前缀应当为 1

3.2 指定 Omni 交易的手续费支付地址

在 Omni 协议层不需要支付交易手续费,但是 Omni 交易所嵌入的比特币交易依然需要支付手续费。默认情况下 omniSendTx() 方法使用发送方地址支付比特币交易手续费,但可以传入额外的参数来指定其他地址支付交易手续费,当你的 PHP 应用需要实现多账户归集功能时,使用统一的手续费支付地址会更容易管理一些。

例如,下面的代码使用地址 mnRo8JyTHDd5NxRb3UvGbAhCBPQTQ4UZ8W 支付 omni 交易的手续费:

$rawtx = $wallet->omniSendTx(
            $addressList[0],                      /*发送方地址,私钥必须已经加入钱包*/
            'mgYPLmNuZymK...e2XUNF6VFnT',         /*接收方地址*/
            2,                                    /*转账OMNI代币ID,2:TOMN*/
            '0.000001',                           /*转账OMNI代币数量*/
            'mnRo8JyTHDd5...CBPQTQ4UZ8W'          /*交易手续费支付地址*/
         );

注意:

  • 即使指定了余额充足的手续费支付地址,Omni 交易的发送方依然必须有微量的比特币 余额(546 SATOSHI),因为 Omni 协议需要交易发送方至少有一个可用 UTXO。
  • 手续费支付地址同时也是找零地址,多余的比特币将返回至该地址

3.3 指定 Omni 交易的比特币转账数量

由于 Omni 交易要求发送方必须有可用的 UTXO,因此为了便于接收 Omni 代币的地址可以继续流通所持有的 Omni 代币,omniSendTx() 方法在默认情况下将向接收方地址转入微量的比特币(546 SATOSHI),可以在调用该方法时修改这个默认数值。

例如,下面的代码转入接收方 1000 个 SATOSHI:

$rawtx = $wallet->omniSendTx(
            $addressList[0],                      /*发送方地址,私钥必须已经加入钱包*/
            'mgYPLmNuZymK...e2XUNF6VFnT',         /*接收方地址
            2,                                    /*转账OMNI代币ID,2:TOMN*/
            '0.000001',                           /*转账OMNI代币数量*/
            'mnRo8JyTHDd5...CBPQTQ4UZ8W',         /*交易手续费支付地址*/
            1000                                  /*转账比特币数量,单位:SATOSHI*/
         );

3.4 比特币转账

OmniTool 也支持比特币转账裸交易的生成与广播。

例如,下面的代码从钱包的第一个地址向指定接受地址转入 1000 个 SATOSHI:

<?php
require('../vendor/autoload.php');

use OmniTool\Wallet;

$wallet = Wallet::cloud('./demo.wallet','testnet');
$addressList = $wallet->getAddressList();

$rawtx = $wallet->btcSendTx(
                    $addressList[0],                /*发送方地址*/
                    'moneyqMan7u...8qVrc9ikLP',     /*接收方地址*/
                    1000,                           /*转账比特币数量,单位:SATOSHI*/
                    500                             /*手续费,单位:SATOSHI*/
                  );                       
echo 'btc rawtx => ' . $rawtx . PHP_EOL;

$ret = $wallet->broadcast($rawtx);                  /*广播裸交易*/

默认情况下,btcSendTx() 使用发送方地址作为找零地址,也可以在调用时指定其他地址作为找零地址,例如,下面的代码创建一个新地址接收找零:

$changeAddress = $wallet->getNewAddress();          /*创建新地址*/
$rawtx = $wallet->btcSendTx(
                    $addressList[0],                /*发送方地址*/
                    'moneyqMan7u...8qVrc9ikLP',     /*接收方地址*/
                    1000,                           /*转账比特币数量,单位:SATOSHI*/
                    500,                            /*手续费,单位:SATOSHI*/
                    $changeAddress                  /*找零地址*/
                  );                       

4、UTXO 收集器

OmniTool 使用接口 UtxoCollectorInterface 来约定 UTXO 的收集功能。该接口的实现需要支持获取指定地址的候选 UTXO 集合,可指定多个地址。

接口方法:

  • collect($addressList):提取并返回候选 UTXO 集合

参数 $addressList 用来声明要收集 UTXO 的地址清单,类型为数组。

当前实现类:

  • CloudUtxoCollector:基于 blockchain.com 的开放 API 实现的 Utxo 收集器
  • LocalUtxoCollector:基于 omnicored 节点 RPC API 实现的 Utxo 收集器

例如,下面的代码使用 CloudUtxoCollector 获取地址 mi8BvbK73nDQfaN3acpaFGYQKhfQ5ysKRn 的 UTXO:

use OmniTool\CloudUtxoCollector;

$collector = new CloudUtxoCollector(
                    'testnet'                       /*测试网*/
                 );
$candidateBag = $collector->collect(
                    ['mi8BvbK73nDQ...KhfQ5ysKRn']   /*地址清单*/
                );

5、UTXO 筛选器

OmniTool 使用 UtxoSelectorInterface 来约定 UTXO 筛选功能。该接口的实现需要根据目标金额从候选 UTXO 中选择可用 UTXO,并返回新的 UtxoBag 实例。

接口方法:

  • select(target,candidates):选择可消费 UTXO,返回 UtxoBag 对象

参数 $target 声明要达成的最低金额目标,单位:wei。

参数 $candidates 是候选的 utxo 集合,通常是 UtxoCollectorInterface 实现对象的 collect()调用返回的 UtxoBag 对象。

当前实现类:

  • DefaultUtxoSelector

例如下面的代码使用 DefaultUtxoSelector 实例从候选 UTXO 中删选出至少 100000 wei 的 UTXO:

use OmniTool\DefaultUtxoSelector;

$selector = new DefaultUtxoSelector();
$selectedBag = $selector->select(
                  100000,                         /*最低目标金额*/
                  $candidateBag                   /*候选UTXO集合*/
               );

考虑到 UTXO 的不可分割性,筛选出的若干 UTXO 的总和,有可能超过目标金额。可以使用 UtxoBag 实例的 getTotal() 方法查看集合中的 UTXO 总额:

echo 'total wei in bag => ' . $selectedBag->getTotal() . PHP_EOL;

6、裸交易广播器

OmniTool 使用 BroadcasterInterface 来约定裸交易广播的功能。该接口的实现应当将裸交易广播到 Omni 网络中。

接口方法:

  • broadcast($rawtx):广播裸交易

参数 $rawtx 用来声明要广播的裸交易,类型为 16 进制字符串。

当前实现类:

  • CloudBroadcaster
  • LocalBroadcaster

例如,下面的代码使用 CloudBroadcaster 将裸交易码流广播到 Omni 网络中:

use OmniTool\CloudBroadcaster;

$broadcaster = new CloudBroadcaster(
                      'testnet'                     /*测试网*/
                   );
$ret = $broadcaster->broadcast(
        '01000000011da9283b4...59f58488ac00000000'  /*裸交易*/
       );

7、数据查询接口

OmniTool 使用 ExplorerInterface 来约定 Omni 数据查询功能。

接口方法:

  • getBtcBalance($address):查询指定地址的比特币余额
  • getOmniBalance(address,propertyId):查询指定地址的 Omni 代币余额

当前实现类:

  • CloudBroadcaster
  • LocalBroadcaster

例如,下面的代码使用 CloudExplorer 查询地址 1Jekm8ZswQmDhLFMp9cuYb1Kcq26riFp6m 的比特币余额与 USDT 代币余额:

use OmniTool\CloudExplorer;

$explorer = new CloudExplorer('mainnet');

$address = '1Jekm8ZswQmDhLFMp9cuYb1Kcq26riFp6m';

$balance = $explorer->getBtcBalance($address);
echo 'btc balance => ' . PHP_EOL;

$balance = $explorer->getOmniBalance($address,31);
echo 'usdt balance => ' . $balance['balance']. PHP_EOL;

OmniTool 下载地址:http://sina.lt/gbpd

  • USDT
    1 引用
  • 区块链

    区块链是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。所谓共识机制是区块链系统中实现不同节点之间建立信任、获取权益的数学算法 。

    91 引用 • 751 回帖
  • PHP

    PHP(Hypertext Preprocessor)是一种开源脚本语言。语法吸收了 C 语言、 Java 和 Perl 的特点,主要适用于 Web 开发领域,据说是世界上最好的编程语言。

    164 引用 • 407 回帖 • 526 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...