1.DevelopmentKitOverviewEosTool的目的是消除使用PHP开发EOS区块链应用的痛苦,例如:通过Nodeos和Keosd的RPC接口调用其功能离线生成EOS格式的私钥,公钥使用本地私有key生成符合EOS要求的交易签名将交易对象序列化为Nodeos要求的packed_trx格式你可以把EosTool看成是PHP版的eosjs,用它来完整实现EOS官方客户端Cleos的功能,或者在PHP应用中添加对EOS区块链的支持,非常方便,大大提高了开发效率。有兴趣的朋友也可以直接到这里参观。本文内容转自本博客:EOS区块链PHP开发包EosTool,运行于Php7.1+环境,当前版本为1.0.0,主要代码文件列表如下:代码文件说明eostool/src/client/NodeClient.php节点软件nodeosrpc接口封装类eostool/src/client/WalletClient.php钱包软件keosdrpc接口封装类eostool/src/client/RpcOutput.phpRPC返回结果封装类eostool/src/Crypto/PrivateKey.phpEOS私钥类eostool/src/Crypto/PublicKey.phpEOS公钥类eostool/src/Crypto/Signature.phpEOS签名类eostool/src/Serializer/AbiType.phpEOSABI类型封装类eostool/src/Serializer/AbiTypeFactory.phpABI类型工厂类eostool/src/Serializer/SerialBuffer.php序列化缓冲区实现类eostool/src/Serializer/Serializer.php序列化器实现类eostool/src/Signer/Signer.phpSigner接口eostool/src/Signer/KeosdSigner.phpKeosd签名器实现类eostool/src/Signer/LocalSigner.php本地离线签名器实现接口eostool/src/Contract.php合约类eostool/src/EosTool.php开发包入口类eostool/tests单元测试用例目录eostool/phpunit.xml单元测试配置文件eostool/vendor第三方依赖包eostool/composer.jsoncomposer配置文件2.访问节点服务器使用NodeClient类访问nodeos的rpc接口。例如下面的代码访问本机运行的Nodeos节点链插件的get_info接口:useEosTool\Client\NodeClient;$nc=newNodeClient();$ret=$nc->chain->getInfo();if($ret->hasError())抛出新异常($ret->getError());$info=$ret->getResult();2.1RPC调用分组Nodeos采用插件架构,不同插件的API也分为不同的组,EosTool采用一致的命名方式,根据api可以推导出NodeClient的调用方式:APIgrouping对应一个NodeClient的同名属性,API对应NoClient的分组同名属性下的process驼峰式转换的方法。例如:插件API分组RPCAPINodeClient方法chain_api_pluginchainget_info$nc->chain->getInfo()history_api_pluginhistoryget_transaction$nc->history->getTransaction()net_api_pluginnetstatus$nc->net->status()producer_api_pluginproducerget_runtime_options$nc->getTimeOducer->()dbsize_api_plugindbsizeget$nc->dbsize->get()RPCAPI官方文档:https://developers.eos.io/eosio-nodeos/reference2.2RPC调用参数对于Nodeos,有些调用需要通过在附加参数中,如链插件的get_block接口,使用EosTool调用时,将参数组织成关联数组,示例代码如下:$payload=['block_num_or_id'=>1];$ret=$nc->chain->getBlock($payload);2.3RPC调用返回值所有RPC调用的返回结果都是一个RpcOutput实例,调用它的hasError()方法判断调用是否错误,进一步使用getError()方法获取错误信息。RPC调用的响应可以通过getResult()方法得到,它是由原始JSON结果转换成的StdClass对象,方便提取属性信息,例如:echo'chainid'。$info->chain_id。PHP_EOL;2.4访问主网/测试网节点在创建NodeClient实例时,可以传入额外的参数执行指定要访问的EOS主网或测试网节点。例如,使用以下代码访问主网节点:$nc=newNodeClient(['base_uri'=>'https://api.eosnewyork.io:443/v1/']);或者访问jungletestnet某个节点:$nc=newNodeClient(['base_uri'=>'https://jungle.eosio.cr:443/v1/']);3、新版Keosd接入钱包服务器不再提供RPCAPI文档。这可能意味着它已经开始滑向EOS软件堆栈的边缘。但是,您可以在这个地址访问旧版本的文档:https://developers.eos.io/eosio-nodeos/v1.1.0/reference使用WalletClient类访问Keosd的rpc接口。例如以下代码访问本机运行的Keosd的list_wallets接口:useEosTool\Client\WalletClient;$wc=newWalletClient();$ret=$wc->listWallets();if($ret->hasError())抛出新异常($ret->getError());$wallets=$ret->getResult();由于Keosd的API不再分组,RPC对应的方法直接挂在了WalletClient对象上,这是一个不一样的地方。与NodeClient一样,WalletClient调用的返回结果也是一个RpcOutput对象。Keosd1.4版本默认使用UNIX套接字而不是HTTP来提供RPC接口。这可能是因为Keosd大多数情况下是在本地机器上运行的,使用IPC更安全。因此,这也是WalletClient默认的实例化选项。在大多数情况下,不需要传入额外的参数来实例化WalletClient。4.私钥和公钥EOS的密钥算法与比特币类似,只是做了一些调整,定义了自己的格式。使用PrivateKey类的静态方法new()生成随机私钥。例如:使用EosTool\Crypto\PrivateKey;$prv=私钥::新();echo$prv->toEos().PHP_EOL;//类似:5Hu6nxM6s6UQ3nYkr1s1GKA17zPqpceUuWxH3JBwK8ZorMSRqGitoEos()方法用于将私钥对象转换为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节点的十六进制流格式:useEosTool\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'序列化tx=>'。$hex.PHP_EOL;Serializer的静态方法fromAbi()根据指定的abi构造一个serializer实例,然后使用实例的serialize()方法序列化指定类型的数据,得到十六进制码流。6.签名EosTool提供了两种签名交易的方式:使用Keosd签名,或者使用本地私钥签名。使用KeosdSigner类完成与钱包服务器的签名。例如:使用EosTool\Signer\KeosdSigner;$signer=newKeosdSigner();$signatures=$signer->sign($tx,$pubKeys,$chainId);使用LocalSigner类,您可以避免使用keosd并使用离线私钥签名。例如:使用EosTool\Signer\LocalSigner;$prvKeys=['5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3'];$signer=newLocalSigner($prvKeys);$signatures=$signer->sign($tx,$pubKeys,$chaintransactionId);7.提交一笔交易数据,需要经过归一化、序列化、签名、打包等一系列操作,才能提交给Nodeos节点进行广播。EosTool类提供了transact()方法来隔离这些繁琐的操作。例如,以下代码使用NodeClient和LocalSigner创建EosTool实例,然后提交交易:useEosTool\Client\NodeClient;useEosTool\Signer\LocalSigner;useEosTool\EosTool;$nc=newNodeClient();$signer=newLocalSigner(['5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3']);$tool=newEosTool($nc,$signer);$tx=['actions'=>[['account'=>'eosio.token','name'=>'transfer','authorization'=>[['actor'=>'eosio','permission'=>'active']],'data'=>['from'=>'eosio','to'=>'tommy','数量'=>'200.0000EOS','备忘录'=>'保重']]]];$ret=$tool->transact($tx);echo$ret->getResult()->transaction_id。PHP_EOL;将签名者更改为KeosdSigner非常方便,例如:$nc=newNodeClient();$signer=newKeosdSigner();$tool=newEosTool($nc,$signer);8.调用单个合约动作使用EosTool的pushAction()方法调用单个合约动作。例如下面的代码调用tommy账户托管合约的hi()方法:$tool=newEosTool(newNodeClient(),newKeosdSigner());$ret=$tool->pushAction('tommy','hi',['user'=>'tommy']);9.部署合约使用EosTool的setContract()方法部署合约,例如:$tool=newEosTool(newNodeClient(),newKeosdSigner());$account='tommy';$abi=file_get_contents('hello.abi');$wasm=file_get_contents('hello.wasm');$ret=$tool->setContract($account,$abi,$wasm);感兴趣的朋友可以去这里:EOS区块链PHP开发包
