EOS区块链PHP开发包

作者: 编程狂魔 | 来源:发表于2018-12-06 09:13 被阅读17次

    1. 开发包概述

    EosTool的目的是消除使用PHP开发EOS区块链应用的痛苦,例如:

    • 通过Nodeos和Keosd的RPC接口调用其功能
    • 离线生成EOS格式的私钥和公钥
    • 使用本地私钥生成符合EOS要求的交易签名
    • 将交易对象序列化为Nodeos要求的packed_trx格式

    可以认为EosTool是PHP版本的eosjs,利用它可以完整地实现EOS官方客户端Cleos的功能, 也可以很方便地在PHP应用中增加对EOS区块链的支持能力,极大地提高开发效率。

    有兴趣的朋友也可以直接访问这里,本文内容即转自该博客:EOS区块链PHP开发包

    EosTool运行在Php 7.1+环境下,当前版本1.0.0,主要代码文件清单如下:

    代码文件 说明
    eostool/src/client/NodeClient.php 节点软件nodeos的rpc接口封装类
    eostool/src/client/WalletClient.php 钱包软件keosd的rpc接口封装类
    eostool/src/client/RpcOutput.php RPC返回结果封装类
    eostool/src/Crypto/PrivateKey.php EOS私钥类
    eostool/src/Crypto/PublicKey.php EOS公钥类
    eostool/src/Crypto/Signature.php EOS签名类
    eostool/src/Serializer/AbiType.php EOS的ABI类型封装类
    eostool/src/Serializer/AbiTypeFactory.php ABI类型工厂类
    eostool/src/Serializer/SerialBuffer.php 序列化缓冲区实现类
    eostool/src/Serializer/Serializer.php 序列化器实现类
    eostool/src/Signer/Signer.php 签名器接口
    eostool/src/Signer/KeosdSigner.php Keosd签名器实现类
    eostool/src/Signer/LocalSigner.php 本地离线签名器实现接口
    eostool/src/Contract.php 合约类
    eostool/src/EosTool.php 开发包入口类
    eostool/tests 单元测试用例目录
    eostool/phpunit.xml 单元测试配置文件
    eostool/vendor 第三方依赖包
    eostool/composer.json composer配置文件

    2. 访问节点服务器

    使用NodeClient类访问nodeos的rpc接口。例如,下面的代码访问本机运行的 Nodeos节点的chain插件的get_info接口:

    use EosTool\Client\NodeClient;
    
    $nc = new NodeClient();
    $ret = $nc->chain->getInfo();
    if($ret->hasError()) throw new Exception($ret->getError());
    $info = $ret->getResult();
    
    

    2.1 RPC调用分组

    Nodeos采用了插件化架构,不同的插件的API也归入不同的分组,EosTool采用了保持一致的 命名方法,根据api即可推断出NodeClient的调用方法:API分组对应于NodeClient的一个同名 属性,API则对应与No的Client的分组同名属性下的一个经过camelCase转化的方法。例如:

    插件 API分组 RPC API NodeClient方法
    chain_api_plugin chain get_info $nc->chain->getInfo()
    history_api_plugin history get_transaction $nc->history->getTransaction()
    net_api_plugin net status $nc->net->status()
    producer_api_plugin producer get_runtime_options $nc->producer->getRunTimeOptions()
    dbsize_api_plugin dbsize get $nc->dbsize->get()

    RPC API的官方文档:https://developers.eos.io/eosio-nodeos/reference

    2.2 RPC调用参数

    对于Nodeos而言,有些调用需要传入额外的参数,例如chain插件的get_block接口, 使用EosTool进行调用时,将参数组织为一个关联数组即可,示例代码如下:

    $payload = [  'block_num_or_id' => 1 ];
    $ret = $nc->chain->getBlock($payload);
    
    

    2.3 RPC调用返回值

    所有RPC调用的返回结果都是一个RpcOutput实例,调用其hasError()方法可以 判断是否调用出错,进一步可以利用getError()方法获取错误信息。

    RPC调用的响应则可以通过getResult()方法获取,它是一个由原始的JSON结果 转化出的StdClass对象,因此可以方便的提取属性信息,例如:

    echo 'chain id' . $info->chain_id . PHP_EOL;
    
    

    2.4 访问主网/测试网节点

    在创建NodeClient实例时,可以传入额外的参数执行来制定要访问的EOS主网或测试网节点。 例如,使用下面的代码访问某个主网节点:

    $nc = new NodeClient(['base_uri' => 'https://api.eosnewyork.io:443/v1/']);
    
    

    或者访问jungle测试网的某个节点:

    $nc = new NodeClient(['base_uri' => 'https://jungle.eosio.cr:443/v1/']);
    
    

    3、访问钱包服务器

    新版的Keosd已经不提供RPC API文档,这可能意味着它在EOS软件栈中已经开始滑向边缘地位。 不过可以在这个地址访问老版的文档:https://developers.eos.io/eosio-nodeos/v1.1.0/reference

    使用WalletClient类访问Keosd的rpc接口。例如,下面的代码访问本机运行的 Keosd的list_wallets接口:

    use EosTool\Client\WalletClient;
    
    $wc = new WalletClient();
    $ret = $wc->listWallets();
    if($ret->hasError()) throw new Exception($ret->getError());
    $wallets = $ret->getResult();
    
    

    由于Keosd的API不再分组,因此RPC对应的方法直接挂在WalletClient对象上,这是一个不同之处。 与NodeClient一样的是,WalletClient的调用返回结果也是一个RpcOutput对象。

    1.4版的Keosd默认使用UNIX套接字而不是HTTP提供RPC接口,这可能是考虑到绝大多数情况下 Keosd都运行在本机,使用IPC会更安全一些。因此这也是WalletClient的默认实例化选项, 在绝大多数情况下,不需要传入额外的参数来实例化WalletClient。

    4. 私钥与公钥

    EOS的密钥算法类似于比特币,但做了一些调整,定义了自己的格式。

    使用PrivateKey类的静态方法new()生成随机私钥。例如:

    use EosTool\Crypto\PrivateKey;
    
    $prv = PrivateKey::new();
    echo $prv->toEos() . PHP_EOL; //类似:5Hu6nxM6s6UQ3nYkr1s1GKA17zPqpceUuWxH3JBwK8ZorMSRqGi
    
    

    toEos()方法用来将私钥对象转换为EOS的自定义格式。

    4.1 公钥推导

    从私钥可以推导出公钥,例如:

    $pub = $prv->getPublicKey();
    echo $pub->toEos() . PHP_EOL; //类似:EOS6wQ6t3n148GfzLzgxq7cC8ARDKxeaB3hQXdXn7oZYdwEyAXiSv
    
    

    同样,使用toEos()方法将公钥转换为EOS的自定义格式。

    4.2 导入EOS私钥

    可以将一个EOS格式的私钥转化为EosTool的PrivateKey对象,例如,下面的 代码将指定的EOS私钥导入,并显示其对应的EOS公钥:

    $prv = PrivateKey::fromEos('5Hu6nxM6s6UQ3nYkr1s1GKA17zPqpceUuWxH3JBwK8ZorMSRqGi');
    echo $prv->getPublicKey()->toEos() . PHP_EOL;
    
    

    4.3 权威签名

    PrivateKey的sign()方法支持普通签名和EOS节点要求的权威签名。例如下面的代码返回一个 普通签名:

    $hex = '1234567890abcdef...';
    $signature = $prv->sign($hex);
    
    

    传入额外的参数来获得指定数据的权威签名:

    $hex = '1234567890abcdef...';
    $signature = $prv->sign($hex,true);
    
    

    5. 序列化

    EOS要求交易在提交节点push_transaction之前先进行序列化,这也是在PHP中操作EOS交易 绕不过去的一个环节。

    在EosTool中,使用Serializer类进行序列化操作。例如,下面的代码将一个EOS转账交易 序列化为可以提交给EOS节点旳16进制码流格式:

    use EosTool\Serializer\Serializer;
    
    $abi = json_decode(file_get_contents('transaction.abi'),true);
    $serializer = Serializer::fromAbi($abi);  
    
    $tx = [
      'expiration'=>'2018-12-04T17:00:00',
      'ref_block_num' => 2878,
      'ref_block_prefix' => 29012031,
      'max_net_usage_words' => 0,
      'max_cpu_usage_ms' => 0,
      'delay_sec' => 0,
      'context_free_actions' => [],
      'actions' => [[
        'account' => 'eosio.token',
        'name' => 'transfer',
        'authorization' => [[
          'actor' => 'eosio',
          'permission' => 'active'
        ]],
        'data' => '1122334455667788990011223344556677.....889900'
      ]],
      'transaction_extensions' => []
    ];
    $hex = $serializer->serialize('transaction',$tx);
    echo  'serialized tx => ' .  $hex . PHP_EOL;
    
    

    Serializer的静态方法fromAbi()用来根据一个指定的abi构造序列化器实例,然后 利用实例的serialize()方法对指定类型的数据进行序列化操作,得到16进制码流。

    6. 签名

    EosTool提供了两种进行交易签名的方法:利用Keosd进行签名,或者使用本地私钥进行签名。

    使用KeosdSigner类来利用钱包服务器完成签名。例如:

    use EosTool\Signer\KeosdSigner;
    
    $signer = new KeosdSigner();
    $signatures = $signer->sign($tx,$pubKeys,$chainId);
    
    

    利用LocalSigner类,则可以避免使用keosd,直接利用离线私钥签名。例如:

    use EosTool\Signer\LocalSigner;
    
    $prvKeys = ['5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3'];
    $signer = new LocalSigner($prvKeys);
    $signatures = $signer->sign($tx,$pubKeys,$chainId);
    
    

    7. 交易提交

    一个交易数据,需要经过规范化、序列化、签名、打包一系列操作,才可以提交给 Nodeos节点广播出去。EosTool类提供了transact()方法来隔离这些繁琐的操作。

    例如,下面的代码使用NodeClient和LocalSigner创建一个EosTool实例,然后提交 一个交易:

    use EosTool\Client\NodeClient;
    use EosTool\Signer\LocalSigner;
    use EosTool\EosTool;
    
    $nc = new NodeClient();
    $signer = new LocalSigner(['5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3']);
    $tool = new EosTool($nc,$signer);
    
    $tx = [
      'actions' => [[
        'account' => 'eosio.token',
        'name' => 'transfer',
        'authorization' => [[
          'actor' => 'eosio',
          'permission' => 'active'
        ]],
        'data' => [
          'from' => 'eosio',
          'to' => 'tommy',
          'quantity' => '200.0000 EOS',
          'memo' => 'take care'
        ]
      ]]
    ];
    $ret = $tool->transact($tx);
    echo $ret->getResult()->transaction_id . PHP_EOL;
    
    

    可以很方便地将签名器改为KeosdSigner,例如:

    $nc = new NodeClient();
    $signer = new KeosdSigner();
    $tool = new EosTool($nc,$signer);
    
    

    8. 调用单个合约动作

    使用EosTool的pushAction()方法调用单个合约动作。例如,下面的代码调用tommy 账户托管合约的hi()方法:

    $tool = new EosTool(new NodeClient(),new KeosdSigner());
    $ret = $tool->pushAction('tommy','hi',['user'=>'tommy']);
    
    

    9. 部署合约

    使用EosTool的setContract()方法部署合约,例如:

    $tool = new EosTool(new NodeClient(),new KeosdSigner());
    
    $account = 'tommy';
    $abi = file_get_contents('hello.abi');
    $wasm = file_get_contents('hello.wasm');
    $ret = $tool->setContract($account,$abi,$wasm);
    

    有兴趣的朋友可以去这里:EOS区块链PHP开发包

    相关文章

      网友评论

        本文标题:EOS区块链PHP开发包

        本文链接:https://www.haomeiwen.com/subject/uvlncqtx.html