如何更好的利用区块链API

区块链允许数据提供者和消费者直接在单个开放系统中交易信息,而不是订阅世界各地的数十个集中服务,并编写他们的软件来与每个API进行通信。阅读此区块链API教程,了解如何根据你的特定需求使用它。

API(应用程序编程接口)是单个计算机程序可以用来与另一个程序交互的方法(类,过程,函数,结构或常量)的描述。它通常包含在任何Internet协议(例如RFC)的描述中,软件框架或对操作系统函数的标准调用。它通常由单独的软件库或操作系统服务实现。开发人员通常使用区块链API来编写各种应用程序。

API定义程序(模块,库)提供的功能,并允许从该功能的实现方式中抽象出来。软件组件通过API相互交互。在这种情况下,组件通常形成层次结构:高级组件使用低级组件的API,而这些组件又使用甚至更低级别组件的API。通过因特网进行数据传输的协议是根据该原理构建的。

标准协议栈(OSI网络模型)包含7层(从物理位传输层到应用协议层,类似于HTTP和IMAP协议)。每个级别使用先前底层数据传输级别的功能,并为下一个覆盖级别提供必要的功能。

image

注意:协议的概念与API的概念意义相近。两者都是功能的抽象,除了协议涉及数据传输,而API与应用程序的交互相关。

区块链API品种

区块链软件的开发通常包括各种困难部分。其中最重要的是创建区块链API接口。有些项目通过提供以下API服务来帮助用户和开发人员:

网站收到比特币付款的难以置信的简便方式。这种服务是完全安全的,是商务或个人使用的理想选择:

  • 区块链链接的钱包服务。
  • 用于从区块链钱包发送和接收付款的API。
  • 每个块和交易的数据请求的JSON。
  • 用于请求的简单区块链API:用于查询区块链数据的文本格式的简单API。
  • Web套接字:具有低延迟的流式套接字,为新块和交易提供数据。

让我们从区块链钱包API评论开始。区块链Wallet API提供了一个简单的界面。要使用此API,你需要启动一个负责管理钱包的小型本地服务。你的应用程序通过HTTP API调用在本地与此服务进行交互。

image

现在,你可以从新的区块链钱包API转移比特币。所有交易均价值0.0001 BTC矿工的费用。这是它在PHP中的样子:

<?
$guid="GUID_HERE";
$firstpassword="PASSWORD_HERE";
$secondpassword="PASSWORD_HERE";
$amounta = "10000000";
$amountb = "400000";
$addressa = "1A8JiWcwvpY7tAopUkSnGuEYHmzGYfZPiq";
$addressb = "1ExD2je6UNxL5oSu6iPUhn9Ta7UrN8bjBy";
$recipients = urlencode('{
"'.$addressa.'": '.$amounta.',
"'.$addressb.'": '.$amountb.'
}');
$json_url = "http://localhost:3000/merchant/$guid/sendmany?password=$firstpassword&second_password=$secondpassword&recipients=$recipients";
$json_data = file_get_contents($json_url);
$json_feed = json_decode($json_data);
$message = $json_feed->message;
$txid = $json_feed->tx_hash;
?>

WebSocket API允许开发人员获取有关新交易和块的实时数据。

从URL链接wss://ws.blockchain.info/inv开始。部署套接字时,用户通过发送op消息{“op”:“ping”}来订阅该频道。然后,订阅有关所有新比特币交易的通知{“op”:“unconfirmed_sub”}。最后,订阅地址{“op”:”addr_sub”, “addr”:”$bitcoin_address”}

有关新交易的通知如下所示:

"op": "utx",
"x": {
"lock_time": 0,
"ver": 1,
"size": 192,
"inputs": [
{
"sequence": 4294967295,
"prev_out": {
"spent": true,
"tx_index": 99005468,
"type": 0,
"addr": "1BwGf3z7n2fHk6NoVJNkV32qwyAYsMhkWf",
"value": 65574000,
"n": 0,
"script": "76a91477f4c9ee75e449a74c21a4decfb50519cbc245b388ac"
},
"script": "483045022100e4ff962c292705f051c2c2fc519fa775a4d8955bce1a3e29884b2785277999ed02200b537ebd22a9f25fbbbcc9113c69c1389400703ef2017d80959ef0f1d685756c012102618e08e0c8fd4c5fe539184a30fe35a2f5fccf7ad62054cad29360d871f8187d"
}
],
"time": 1440086763,
"tx_index": 99006637,
"vin_sz": 1,
"hash": "0857b9de1884eec314ecf67c040a2657b8e083e1f95e31d0b5ba3d328841fc7f",
"vout_sz": 1,
"relayed_by": "127.0.0.1",
"out": [
{
"spent": false,
"tx_index": 99006637,
"type": 0,
"addr": "1A828tTnkVFJfSvLCqF42ohZ51ksS3jJgX",
"value": 65564000,
"n": 0,
"script": "76a914640cfdf7b79d94d1c980133e3587bd6053f091f388ac"

对于区块链数据API,如果向GET请求添加&cors=true参数,则可以使用CORS进行一些数据API调用。

CORS(跨源资源共享)是现代浏览器的一种技术,它提供可以访问另一个域的资源的网页。直到最近,克服同源策略对XSS请求施加的限制的主要方法是使用JSONP。JSONP本身有一个致命的限制:它只能通过GET方法接收数据。通过POST方法发送数据仍然无法访问。

image

技术本身非常简单。有三个域希望从服务器下载资源。为了实现这一点,提供内容的Web服务器足以在响应头中指示可信域列表Access-Control-Allow-Origin:A,B,C。然后相同源原则的限制 在请求的页面上将不适用于这些域的页面。要启动跨源请求,客户端浏览器会向HTTP请求(发出请求的站点域)添加原始请求。例如,页面http://www.a.com/page.html尝试从http://www.b.com/cors.txt页面获取数据。

在区块链数据API中,单个块如下所示:


"hash":"0000000000000bae09a7a393a8acded75aa67e46cb81f7acaa5ad94f9eacd103",
"ver":1,
"prev_block":"00000000000007d0f98d9edca880a6c124e25095712df8952e0439ac7409738a",
"mrkl_root":"935aa0ed2e29a4b81e0c995c39e06995ecce7ddbebb26ed32d550a72e8200bf5",
"time":1322131230,
"bits":437129626,
"nonce":2964215930,
"n_tx":22,
"size":9195,
"block_index":818044,
"main_chain":true,
"height":154595,
"received_time":1322131301,
"relayed_by":"108.60.208.156",
"tx":[--Array of Transactions--]

区块链图表和统计API允许与blockchain.info上显示的图表和统计信息进行交互。(区块链信息API)。

image

可以使用Charts API方法接收有关blockchain.info图表的信息:

"status": "ok",
"name": "Confirmed Transactions Per Day",
"unit": "Transactions",
"period": "day",
"description": "The number of daily confirmed Bitcoin transactions.",
"values": [
{
"x": 1442534400, // Unix timestamp (2015-09-18T00:00:00+00:00)
"y": 188330.0
},
...

Stats API可用于接收有关blockchain.info统计信息的信息:

"market_price_usd": 610.036975,
"hash_rate": 1.8410989266292908E9,
"total_fees_btc": 6073543165,
"n_btc_mined": 205000000000,
"n_tx": 233805,
"n_blocks_mined": 164,
"minutes_between_blocks": 8.2577,
"totalbc": 1587622500000000,
"n_blocks_total": 430098,
"estimated_transaction_volume_usd": 1.2342976868108143E8,
"blocks_size": 117490685,
"miners_revenue_usd": 1287626.6577490852,
"nextretarget": 431423,
"difficulty": 225832872179,
"estimated_btc_sent": 20233161880242,
"miners_revenue_btc": 2110,
"total_btc_sent": 184646388663542,
"trade_volume_btc": 21597.09997288,
"trade_volume_usd": 1.3175029536228297E7,
"timestamp": 1474035340000

比特币API

接受比特币支付变得越来越受欢迎和需求。在网站上接受比特币支付的方法有很多种。最方便的方法之一是区块链API。在这里,你不需要绑定特定语言或SDK;你甚至不需要在那里注册。所需要的只是拥有一个钱包来接受比特币,并有时间将相当简单的API连接到你的系统。此外,客户不会看到你的钱包,而是交易所的临时钱包。

image

在直接谈论代码之前(我们将在示例中使用PHP,但可以在Java,Python等中轻松实现),有必要阐明支付接受机制本身。

整个过程符合以下顺序:

  • 1.用户通过发送一系列数据从区块链请求临时钱包。
  • 2.区块链返回其临时钱包以接收对用户的付款。
  • 3.用户向客户端显示此钱包,以及有关如何处理的一小组说明。
  • 4.客户付款(将资金转入钱包)。
  • 5.用户应该等待比特币系统中的支付验证。
  • 6.在区块链系统成功验证的情况下,将在用户的站点上调用脚本(用户必须指明哪个),并且传输所有交易数据。
  • 7.之后,在用户系统内安全地确认支付。

要获得临时钱包,你应该发送一系列数据:

  • 在成功确认交易的情况下将被抄写的脚本的URL。值得注意的是,建议指定某个参数(甚至是一些参数),以便识别当前系统中的付款。只需在用户系统中指定客户端ID并将任何数据输入数据库,但只有在收到确认交易后才可以。但是,官方文档建议使用预先创建的付款编号和任何验证短语。总的来说,我们通过常规GET传输请求中的参数获取URL。对于区块链系统,此参数称为回调。应该将值编码为URL链接。
  • 用户钱包用于接收付款。区块链将把收到的钱转移到这个钱包。参数被称为地址。
  • 最后一个参数被称为方法,并用于创建临时钱包。

此数据将发送到区块链脚本(https://blockchain.info/api/receive),每个参数都是常用的GET参数。其执行结果由用户系统处理(结果将采用JSON格式)。关于区块链信息API的所有内容都在区块链API文档中说明。

现在,用户已准备好接受对钱包的付款,但无法从系统中注册其收据的事实。用户应该记住,在实际系统中,建议使用经过深思熟虑且编写良好的代码,以及存储准备好的付款的数据库(将付款号码,用户ID存储在系统和验证短语或其组成部分)。此外,验证付款的时间可能不同且非常重要,比特币汇率可能会发生变化。用户有两种选择:在付款时保留费率,或在收到交易确认后请求费率。

交易确认收据文件应该叫做receive_payment.php,并且应该存储在网站的根目录中;在请求临时钱包时,用户在创建$ callback_url时指定了其名称。

实际上,同一付款的脚本不仅会被调用一次,而且会根据其在各个节点上的确认数量来调用。这意味着用户必须先检查是否有确认。

区块链提供了许多参数:

  • Transaction_hash,唯一的交易哈希。
  • Input_transaction_hash,原始交易的唯一哈希值。
  • Input_address,将收到付款的区块链钱包。
  • Destination_address,将发送付款的用户的钱包。
  • Confirmations,按节点确认的数量(如果此参数的值大于或等于6,则建议接受付款确认)。

value参数在Satoshi中生成值,而不是比特币(1Satoshi=0.00000001BTC)。因此,结果值应该减少到比特币。名为invoice_id和secret的参数由用户在接收区块链钱包阶段设置。因此,可能存在更多或更少的它们,并且它们可以具有任何名称。

建议将收到的值存储在支付历史中的比特币中;但是,应该将其转换为另一种货币(例如美元),由用户系统使用。如果系统仅适用于比特币,则无需转换任何内容。

有单独的汇率API文档,用于将比特币转换为其他货币。用户必须指定两个参数:

  • 货币名称(货币列表在文档中可用,用户也可以使用调用Print_r($ Exchange_data_obj)获取它。
  • 用户想要兑换的比特币数量。

区块链开发平台和API

今天,有许多公司开发提供应用程序开发工具的平台和项目。Blockchain.info有许多区块链信息API,用于处理他们的电子钱包服务(这是最大的电子钱包服务之一),旨在发送和接收付款并执行其他操作。该链创建了用于访问分布式记录注册表的完整节点中包含的数据的接口,以及标准信息请求:例如,关于你的比特币余额。此外,你可以在特定地址执行操作时发送通知。

Stellar是一个半去中心化的(由网关组织服务,而不是矿工),可公开访问的日志和统一开发环境(区块链API,多签名API)绑定到Stripe支付网络。还有其他公司拥有带有多边签名的区块链钱包API,例如Block.io,Gem,BlockCypher等。

image

将来,需要更加统一的区块链API开发环境,包括区块链生态系统的各种不断变化的组件(存储,文件维护,钱包交互,移动支付,身份验证和声誉)。智能合约将允许我们创建一个全球气象数据市场meteorological data market,消费者将在其中请求实时数据并以通用格式接收数据(使用区块链信息API)。

集中数据提供商可以告别自己的格式和销售活动,而是将数据传送到全球可访问的气象市场dApp。可以将区块链的开发环境与其他大型网段联系起来:例如,机器到机器(M2M)通信和物联网网络的基础设施,用于快速应用程序开发。在遥远的未来,这种类型的高级集成应用程序的一个例子可以是与智能城市基础设施内的交通传感器交互的智能手表,以便使用比特币中的智能合约自动预留和支付流量。

API操作系统和多样性问题

几乎所有操作系统(UNIX,Windows,OS X等)都有一个API,程序员可以使用该API为操作系统创建应用程序。主API操作系统是一组系统调用。应该注意的是,开发人员通常有几种不同的API来实现相同的结果。此外,每个API通常使用较低抽象级别的API程序组件来实现。例如:为了看到“Hello,world!”这一行,在浏览器中,你只需创建一个具有最小标题的HTML文档和包含给定行的最简单的主体。

当浏览器打开此文档时,浏览器程序会将文件的名称(或已打开的文件描述符)传输到处理HTML文档的库,而库文件将使用操作API系统读取此文件,然后通过“clear window”类型的标准图形/基本操作的API库调用它。在所选字体中写下“Hello,world!”。在执行这些操作期间,图形基元库将使用相应的请求访问窗口接口库。该库已经与操作系统API联系,将数据写入视频卡缓冲区。

image

与此同时,几乎每个级别实际上都有几种可能的替代API。例如,我们可以不在HTML上编写源文档,而是在LaTeX上编写。我们可以使用任何浏览器进行显示。一般来说,不同的浏览器使用不同的HTML库,所有这些都可以使用不同的原始库和不同的操作系统进行编译。

因此,现有多级API系统的主要困难是:

  • 将软件代码从一个API系统移植到另一个API系统的复杂性(例如,更改操作系统时)。
  • 从较低级别移动到较高级别时的功能丧失。粗略地讲,每个API“层”被创建以促进一些标准操作集的执行。但同时,它真的很难,或者它根本不可能执行由较低API级别提供的其他操作。
  • 从一个API移动到另一个API时移植程序代码的困难。将模块传输到其他操作系统时经常会出现这些问题。
  • 从低级管理到高级管理时,降低接口功能的范围。在这种情况下,促进了严格定义的任务类别的实施。与此同时,访问其他监管机构的控制权已经失去了。毕竟,较低级别允许你轻松管理程序的基本组件。

软件接口的分类与通过它们控制的应用程序的目的和功能密切相关。事实上,在运行复杂系统时,通常有其他API可以通过其他方式解决相同的问题。

单独的组分配用于管理软件模块(wxWidgets,Qt,GTK等),操作系统(Amiga ROM内核,Cocoa,Linux内核API,OS/2 API,POSIX,Windows API),声音(DirectMusic /)的图形组件的接口DirectSound,OpenAL),窗口接口等。它们的分离取决于层次结构和功能中的应用程度。计算机游戏的用户通常不会怀疑这个图形API为他们提供如此快速的图片绘制和惊人的图像亮度。

全局区块链API通常包括各个编程语言的接口。在他们的帮助下,你可以管理非常具体和本地任务的解决方案。这一切都取决于具体算法的实现。

总结

区块链引发了大量极其重要的问题。它的使用具有广泛的优势:拒绝第三方,保护交易,安全交易,资源共享,保证交易,自动执行合约等。

让我们从角度看一下这项技术:

  • 区块链可以包含多个API,包括简单区块链API,区块链信息API,区块链钱包API,交易脚本语言,P2P节点通信API和用于检查网络中的交易的客户端API。
  • 应用程序编程接口(API)现在包含在密码保护的公共基础结构中(区块链)。
  • 区块链被用作数据库的一种新形式:例如,作为永久存储不可变密码区块链API密钥(或哈希)的分布式哈希表(DHT),与大量存储的数据链相关联。
  • 一种新型浏览器将允许用户运行去中心化式应用程序(Dapps),而不仅仅是网页(例如,以太坊中的Mist)。

它还可以解决许多更棘手的问题。其中之一是集中化。区块链技术在未来的世界中可能非常有用,在这个世界中,集中式和去中心化式模型都将得到应用。它不仅会破坏现有的陈规定型观念和计划,还有助于发展结合了旧的和创新的方法的大型生态系统。

如果你需要有关区块链技术的更多信息,请联系应用团队。

==================================================================

如果你想学习区块链并在Blockchain Technologies建立职业生涯,那么请查看我们分享的一些以太坊、比特币、EOS、Fabric等区块链相关的交互式在线编程实战教程:

  • java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
  • python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
  • php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。
  • 以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。
  • 以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
  • ERC721以太坊通证实战,课程以一个数字艺术品创作与分享DApp的实战开发为主线,深入讲解以太坊非同质化通证的概念、标准与开发方案。内容包含ERC-721标准的自主实现,讲解OpenZeppelin合约代码库二次开发,实战项目采用Truffle,IPFS,实现了通证以及去中心化的通证交易所。
  • C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。
  • java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。
  • php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。
  • c#比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在C#代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是C#工程师不可多得的比特币开发学习课程。
  • EOS入门教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。
  • 深入浅出玩转EOS钱包开发,本课程以手机EOS钱包的完整开发过程为主线,深入学习EOS区块链应用开发,课程内容即涵盖账户、计算资源、智能合约、动作与交易等EOS区块链的核心概念,同时也讲解如何使用eosjs和eosjs-ecc开发包访问EOS区块链,以及如何在React前端应用中集成对EOS区块链的支持。课程内容深入浅出,非常适合前端工程师深入学习EOS区块链应用开发。
  • Hyperledger Fabric 区块链开发详解,本课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、nodejs链码与应用开发的操作实践,是Nodejs工程师学习Fabric区块链开发的最佳选择。
  • Hyperledger Fabric java 区块链开发详解,课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、java链码与应用开发的操作实践,是java工程师学习Fabric区块链开发的最佳选择。
  • tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。

汇智网原创翻译,转载请标明出处。这里是如何更好的利用区块链API

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,423评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,147评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,019评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,443评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,535评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,798评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,941评论 3 407
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,704评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,152评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,494评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,629评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,295评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,901评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,742评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,978评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,333评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,499评论 2 348

推荐阅读更多精彩内容