2月 142019
 


HARVEY MIEI (2018/06/04)
https://developers.ripple.com/checks.html
https://developers.ripple.com/checkcreate.html
https://developers.ripple.com/checkcash.html
https://developers.ripple.com/checkcancel.html

Checks
支票
The Checks feature in the XRP Ledger allows users to create deferred payments that can be canceled or cashed by the intended recipients. Like personal paper checks, XRP Ledger Checks start with the sender of the funds creating a Check that specifies an amount and receiver. The receiver cashes the check to pull the funds from the sender’s account into the receiver’s account. No money moves until the receiver cashes the Check. Because funds are not put on hold when the Check is created, cashing a Check can fail if the sender doesn’t have enough funds when the receiver tries to cash it, just like traditional checks. If there’s a failure cashing the check, the sender can retry until the check expires.
XRP总账网络的Checks支票特性允许用户创建可以被预期接收方取消或兑现的延期付款。与纸质支票一样,XRP总账网络支票由资金发送方创建一张指定额度和接受方的支票。接受方提取支票内的资金,该资金从发送方账户进入接收方账户。在接收方兑现支票之前不会发生任何资金转移。在签发支票时,资金并不会有任何变化。与传统支票一样,发送方账户资金不足会导致接收方支票兑现失败,但在支票过期以前,接收方可以重复兑现操作。

XRP Ledger Checks have expiration times after which they may no longer be cashed. If the receiver doesn’t successfully cash the Check before it expires, the Check object remains in the XRP Ledger until someone cancels it. Anyone may cancel the Check after it expires. Only the sender and receiver can cancel the Check before it expires or is cashed. The Check object is removed from the Ledger when the sender successfully cashes the check or someone cancels it.
XRP总账网络支票在长时间未兑现后则可能会过期。如果接收方在支票过期前未成功兑现,该支票对象将保留在XRP总账网络中直到被人取消。任何人都可以在支票过期后取消支票,只有发送方和接收方可以在支票过期前或兑现前取消支票。支票对象将在接收方成功兑现或有人取消时从总账中移除。

Checks are similar to Escrow and Payment Channels, but there are some important differences between those features and Checks:
You can send issued currency with Checks. With Payment Channels and Escrow, you can only send XRP.
Checks do not tie up any funds. The XRP involved in Payment Channels and Escrow cannot be spent until it is redeemed with a claim provided by the sender (Payment Channels), or released by an expiration or crypto-condition (Escrow).
You can send XRP to yourself through Escrow. You cannot use Checks or Payment Channels to send XRP (or, in the case of Checks, issued currencies) to yourself.

支票与托管和Payment Channels付款渠道相似,但他们之间有一些重要的不同:
用户可以使用支票发送已发行货币,但支付渠道和托管只能发送XRP。
支票不捆绑任何资金。涉及支付渠道和和托管的XRP只有在发送方进行清偿或者托管到期或加密条件释放。
可以以托管方式发送XRP给自己,但不能以支票或付款渠道发送XRP给自己。

Why Checks?

为什么使用支票

Traditional paper checks allow people to transfer balances without immediately exchanging physical currency. XRP Ledger Checks allow people to exchange funds asynchronously using a process that is familiar to and accepted by the banking industry.

传统纸质支票允许用户无需立即兑换实际货币的情况下进行转账付款。XRP总账网络支票允许用户使用近似传统银行支票业务的方式异步处理资金。

XRP Ledger Checks also solve a problem that is unique to the XRP Ledger: they allow users to reject unwanted payments or accept only a portion of a payment. This is useful for institutions that need to be careful about accepting payments for compliance reasons.

XRP总账网络支票也解决了XRP总账网络的唯一问题。允许用户拒绝不想接受的付款或仅接受一部分付款。这对于因合规原因需要小心接受付款的机构很有用。

Checks potentially enable many other use cases. Ripple encourages the community to find new and creative applications for Checks.

Ripple鼓励社区为支票寻找新的和创造性的应用场景。

Use Case: Payment Authorization
案例:付款授权

Problem: To comply with regulations like BSA, KYC, AML, and CFT, financial institutions must provide documentation about the source of funds they receive. Such regulations seek to prevent the illicit transfer of funds by requiring institutions to disclose the source and destination of all payments processed by the institution. Because of the nature of the XRP Ledger, anyone could potentially send XRP (and, under the right circumstances, issued currencies) to an institution’s account on the XRP Ledger. Dealing with such unwanted payments adds significant cost and time delays to these institutions’ compliance departments, including potential fines or penalties.
为遵守像BSA,KYC,AML和CFT这样的规定 ,金融机构必须提供关于他们收到资金来源的文件。 这些法规旨在要求机构披露所有付款的来源和目的地来防止非法转移资金。 由于XRP分类账的性质,任何人都可能将XRP(并且在适当的情况下,已发行货币)发送到XRP分类账的机构账户。 处理这些不必要的支付会给这些机构的合规部门带来巨大的成本和时间延迟,还有可能的罚款或处罚。

Solution: Institutions can enable Deposit Authorization on their XRP Ledger accounts by setting the asfDepositAuth flag in an AccountSet transaction. This makes the account unable to receive Payment transactions. Accounts with Deposit Authorization enabled can only receive funds through Escrow, Payment Channels, or Checks. Checks are the most straightforward, familiar, and flexible way to transfer funds if Deposit Authorization is enabled.

解决方案:机构可以通过其XRP总账网络相关账号发起AccountSet交易并设置asfDepositAuth标志开启付款授权。此后该账号将不能接收付款交易。启用付款授权的账户只能通过托管,付款渠道或者支票接收资金。如果启用付款授权,支票将是最直接,熟悉,灵活的转账方式。

Checks typically have the lifecycle described below.

Step 1: To create a Check, the sender submits a CheckCreate transaction and specifies the receiver (Destination), expiration time (Expiration), and maximum amount that may be debited from the sender’s account (SendMax).

创建支票,发送人提交CheckCreate交易并制定接收人,过期时间,以及可从发送人账户转移的资金额度上限。

Step 2: After the CheckCreate transaction is processed, a Check object is created on the XRP Ledger. This object contains the properties of the Check as defined by the transaction that created it. The object can only be modified by the sender (by canceling it with a CheckCancel transaction) or receiver (by canceling it or cashing it) before the expiration time passes. After the expiration time, anyone may cancel the Check.

当CheckCreate交易处理后,将在XRP总账网络中创建一个Check对象,该对象包含创建交易所定义的支票属性信息。该对象只能被发送人(发起CehckCancel交易取消)或接收人(取消或兑现)在其过期前进行修改。

Step 3: To cash the check, the receiver submits a CheckCash transaction. The receiver has two options for cashing the check:

要兑现支票,接收人提交CheckCash交易,接收人有两个选项兑现支票。

Amount — The receiver can use this option to specify an exact amount to cash. This may be useful for cases where the sender has padded the check to cover possible transfer fees and the receiver can only accept the exact amount on an invoice or other contract.

Amount(额度),

DeliverMin — The receiver can use this option to specify the minimum amount they are willing to receive from the Check. If the receiver uses this option, rippled attempts to deliver as much as possible and will deliver at least this amount. The transaction fails if the amount that can be credited to the receiver is not at least this amount.

DeliverMin(最小兑现)接收方使用该选项指定其期望从支票中兑现的最小额度。如果接收方使用该选项,则最少兑现指定额度。如果发送方账户的可用额度小于该值,则兑现交易失败。

If the sender has enough funds to cover the Check and the expiration time has not passed, the funds are debited from the sender’s account and credited to the receiver’s account, and the Check object is is destroyed.

如果发送方账户有足够金额足以兑现支票,且支票未过期。资金将从发送方账户转移至接收方账户,同时Check对象将被销毁。

Expiration Case

In the case of expirations, Checks have the lifecycle described below.

All Checks start the same way, so Steps 1 and 2 are the same.

Step 3a: If the Check expires before the receiver can cash it, the Check can no longer be cashed but remains in the ledger.

当接收方在兑现支票时支票已过期,则支票不能被兑现,但仍存在于总账网络中。

Step 4a: After a Check expires, anyone may cancel it by submitting a CheckCancel transaction. That transaction removes the Check from the ledger.

支票过期后,任何人都可以通过提交CheckCancel交易取消支票,支票将在总账网络中被移除。

Availability of Checks
支票可用性
Checks require rippled v0.90.0 or later.

2月 122019
 


https://developers.ripple.com/cross-currency-payments.html

Cross-Currency Payments
跨币种支付
In the XRP Ledger, you can send cross-currency payments that exchange one or more issued currencies, XRP, or both. Like direct XRP payments, these payments use the Payment transaction type. Cross-currency payments within the XRP Ledger are fully atomic, meaning that either the payment fully executes or no part of it executes.

在XRP总账网络中,支付发送与XRP或一种多种已发行货币的付款,与直接进行XRP付款一样,跨货币付款使用Payment交易类型。XRP总账网络中的跨货币付款完全是原子的,也就意味着支付只能完全执行成功而不可能部分执行成功。

By default, cross-currency payments deliver a fixed amount to their destination at a variable cost to their source. Cross-currency payments can also be partial payments, which deliver a variable amount to the destination within a fixed sending limit.

默认情况下,跨货币付款基于可变的交易成本并发送给目的用户的确定的固定额度。当然,跨货币付款也可以是部分付款,在固定付款限额内发送可变的付款金额。

Prerequisites

先决条件

By definition, a cross-currency payment involves at least two currencies, which means that at least one currency involved must be a non-XRP issued currency.

按照定义,跨货币交易至少包括两种货币,且至少包括一种非XRP的已发行货币。

    Typically, this means using one or more currencies issued by an XRP Ledger Gateway. Such currencies are backed by funds outside the XRP Ledger, and can be withdrawn through the gateway.

通常,用户持有的一种或多种XRP总账网络中发行的货币,该货币可以在XRP总账网络以外的网关服务商处进行提现操作。

    You could also use digital tokens that are only issued within the XRP Ledger and has no outside backing, as long as the parties transacting are willing to send or receive those tokens and treat them as something of value.

一种情况是,只要交易双方都愿意在XRP总账网络中发送和接收这些数字资产,并认可其价值(资产数字化),用户也可以不必转出至外部。

There must be at least one Path between the sender and receiver, and the total liquidity across all paths must be enough to facilitate the payment. For cross-currency payments, this usually means consuming Offers to convert from one currency to another.

在付款发送者和接收者之间必须有至少一条交易路径,且交易路径所带来的流动性应当足以促成交易。在跨货币付款中,这通常意味着消耗Offers(报价单)以实现一种货币转换为另一种货币。

Autobridging

自动桥接

Cross-currency payments that exchange two issued currencies automatically use XRP, when it decreases the cost of the payment, by connecting order books to deepen the pool of available liquidity. For example, a payment sending from USD to MXN automatically converts USD to XRP and then XRP to MXN if doing so is cheaper than converting USD to MXN directly.

跨货币支付自动使用XRP来作为两种已发行货币的中间媒介,以降低付款成本,同时使用order book增加已发行货币的流动性。举例来讲,如果使用XRP作为中间媒介转换的成本,比直接进行USD及MXN兑换更低的话,付款自USD兑换成MXN的过程就会首先将USD兑换为XRP,然后再将XRP兑换为MXN。

2月 102019
 

https://developers.ripple.com/capacity-planning.html
https://developers.ripple.com/history-sharding.html
https://github.com/ripple/rippled/blob/master/cfg/rippled-example.cfg

Node Size参数

The node_size parameter determines the size of database caches. Larger database caches decrease disk I/O requirements at a cost of higher memory requirements. Ripple recommends you always use the largest database cache your available memory can support. See the following table for recommended settings.

配置文件中的node_size参数决定了可用数据库缓存的大小。较大数据库缓存以更多内存开销为代价来降低磁盘IO要求。Ripple建议使用尽可能高的内存配置以提供更多数据库缓存。

Recommendation
Available RAM for rippled node_size value Notes
< 8GB tiny Not recommended
8GB low
16GB medium
32GB huge Recommended for production servers

Node DB Type
节点数据库类型
The type field in the node_db section of the rippled.cfg file sets the type of key-value store that rippled uses to persist the XRP Ledger in the ledger store. You can set the value to either rocksdb or nudb.
配置文件rippled.cfg中node_db区段的type字段,指定了用于rippled总账数据存储的持久化键值存储类型。用户可以设置该值为rocksdb或nudb。

rippled offers a history sharding feature that allows you to store a randomized range of ledgers in a separate shard store. You may want to configure the shard store to use a different type of key-value store than the ledger store. For more information about how to use this feature, see History Sharding.

rippled提供的历史分片特性允许用户在一个独立的分片存储中存储随机范围内的总账数据。用户可能希望配置分片存储使用一个不同类型的键值存储来存储总账数据。更多信息,应参阅“历史分片”部分。

RocksDB vs NuDB
比较
RocksDB requires approximately one-third less disk storage than NuDB and provides a corresponding improvement in I/O latency. However, this comes at a cost of increased memory utilization as storage size grows. NuDB, on the other hand, has nearly constant performance and memory footprint regardless of storage.
RocksDB比NuDB少占用越三分之一的磁盘存储,且相应改善了I/O延迟。但是,随着存储容量的增加,内存开销也变大。相反,NuDB具有几乎恒定的性能和内存占用,而无关存储容量变化。

rippled servers that operate as validators should keep only a few days’ worth of data or less. Ripple recommends using RocksDB for validators. For all other uses, Ripple recommends using NuDB for the ledger store.
作为Validitors的rippled服务器,应仅保留几天或者更少的数据。Ripple建议Validators使用RocksDB,除此之外的场景,Ripple建议使用NuDB用于总账数据存储。

RocksDB has performance-related configuration options you can modify to achieve maximum transaction processing throughput. (NuDB does not have performance-related configuration options.) Here is an example of the recommended configuration for a rippled server using RocksDB:
RocksDB具有性能相关的配置选项,用户可以修改这些参数以达到最大交易处理吞吐量。(NuDB不具有性能相关的配置选项。)以下为有关RocksDB的一个推荐配置示例。

[node_db]

type=rocksdb
open_files=512
file_size_mb=64
file_size_mult=2
filter_bits=12
cache_mb=512
path={path_to_ledger_store}

XRP Ledger Network Data Integrity
XRP总账网络的数据完整性
The history of all ledgers is shared by servers agreeing to keep particular ranges of historical ledgers. This makes it possible for servers to confirm that they have all the data they agreed to maintain, and produce proof trees or ledger deltas. Since rippled servers that are configured with history sharding randomly select the shards that they store, the entire history of all closed ledgers is stored in a normal distribution curve, increasing the probability that the XRP Ledger Network evenly maintains the history.

Shard Store Configuration
分片存储配置
To configure your rippled to store shards of ledger history, add a shard_db section to your rippled.cfg file.
要配置rippled启用历史总账分片存储功能,需要在rppled.cfg中添加shard_db配置段。

Shard Configuration Example
分片配置示例
The following snippet from an example rippled.cfg file shows the configuration fields for adding sharding to a rippled server:

[shard_db]

type=NuDB
path=/var/lib/rippled/db/shards/nudb
max_size_gb=50

Tip:Ripple recommends using NuDB for the shard store (type=NuDB). NuDB uses fewer file handles per shard than RocksDB. RocksDB uses memory that scales with the size of data it stores, which may require excessive memory overhead.

提示:Ripple建议将NuDB用于分片存储(type=NuDB)。NuDB比RocksDB在每个分片上使用更少的文件句柄。RocksDB使用的内存随着数据存储的增长而增长,会导致更多的内存开销。

Tip:While both validator and tracking (or stock) rippled servers can be configured to use history shard stores, Ripple recommends adding history sharding only for non-validator rippled servers to reduce overhead for validators. If you run a validator and want to manage ledger history using sharding, run a separate rippled server with sharding enabled.
提示:虽然Validator和Stock Server都可以配置为开启历史分片存储,但Ripple建议仅在非Validator服务器上开启,以减轻Validator负载和开销。如果用户当前已运行Validator并希望使用分片管理历史总账数据,建议额外运行一个独立的开启分片的rippled服务器。

For more information, reference the [shard_db] example in the rippled.cfg configuration example.
更多信息,请参照rippled.cfg配置文件中的[shard_db] 区段示例。

Sizing the Shard Store
调整分片存储
Determining a suitable size for the shard store involves careful consideration. You should consider the following when deciding what size your shard store should be:

Although redundant, it is possible to hold full ledger history in the ledger store and the history shard store.
An effective configuration might limit the ledger store only to recent history.
The ledger store history size should at minimum be twice the ledgers per shard, due to the fact that the current shard may be chosen to be stored and it would be wasteful to reacquire that data.
The time to acquire, number of file handles, and memory cache usage is directly affected by sizing.
Each shard contains 2^14 ledgers (16384).
A shard occupies approximately 200 MB to 4 GB based on the age of the shard. Older shards are smaller because there was less activity in the XRP Ledger at the time.

2月 062019
 

Tick Size
Requires the TickSize amendment.
When an Offer is placed into an order book, its exchange rate is truncated based on the TickSize values set by the issuers of the currencies involved in the Offer. When a trader offers to exchange XRP and an issued currency, the TickSize from the issuer of the currency applies. When a trader offers to exchange two issued currencies, the offer uses the smaller TickSize value (that is, the one with fewer significant digits). If neither currency has a TickSize set, the default behavior applies.
当一个报价单放入一个order book时,其汇率将按照货币发行人所设置的TickSize而截断位数(匹配精度)。当交易者在一个报价单中进行XRP和已发行货币见兑换时,适用由该货币发行人设置的TickSize设置。当交易者在一个报价单中进行两种已发行货币的兑换时,报价单使用较小TickSize的值(即具有更少位数的那个)。如果两种货币对应发行人的TickSize设置相同,则默认适用。
The TickSize value truncates the number of significant digits in the exchange rate of an offer when it gets placed in an order book. Issuers can set TickSize to an integer from 3 to 15 using an AccountSet transaction. The exchange rate is represented as significant digits and an exponent; the TickSize does not affect the exponent. This allows the XRP Ledger to represent exchange rates between assets that vary greatly in value (for example, a hyperinflated currency compared to a rare commodity). The lower the TickSize an issuer sets, the larger the increment traders must offer to be considered a higher exchange rate than the existing Offers.
在order book中的报价单,会受TickSize设置而截断交易汇率中的有效位数。发行人可以使用AccountSet交易类型设置3-15位整数长度的TickSize设置值(精度)。汇率表示为有效数字和指数,TickSize设置不影响指数。这允许XRP总账网络在两个差异化资产价值之间提供汇率(例如通涨货币和稀缺商品之间)。发行人设置的TickSize越小, 越多的交易商就会考虑比当前已存在报价单更高的汇率的报价单。

The TickSize does not affect the part of an Offer that can be executed immediately. (For that reason, OfferCreate transactions with tfImmediateOrCancel are unaffected by TickSize values.) If the Offer cannot be fully executed, the transaction processing engine calculates the exchange rate and truncates it based on TickSize. Then, the engine rounds the remaining amount of the Offer from the “less important” side to match the truncated exchange rate. For a default OfferCreate transaction (a “buy” Offer), the TakerPays amount (the amount being bought) gets rounded. If the tfSell flag is enabled (a “sell” Offer) the TakerGets amount (the amount being sold) gets rounded.
TickSize设置不会影响报价单中能够立即执行的部分。(OfferCreate交易中开启tfImmediateOrCancel标志的不受tickSize设置影响。)如果报价单不能被完整执行,交易处理引擎会计算汇率并基于TickSize设置截断位数。然后,引擎将来自“不太重要”一侧的剩余额度进行汇率截断。例如典型交易OfferCreate(买入报价),其中TakerPays额度将被舍入。如果tfSell标志启用(卖出报价),则TakerGets额度将被舍入。
When an issuer enables, disables, or changes the TickSize, Offers that were placed under the previous setting are unaffected.
发行人启用,关闭,修改TickSize设置,以按照先前设置提交的报价单不受此部分行为影响。

1月 282019
 

https://developers.ripple.com/autobridging.html
Auto-Bridging

自动桥接

Any OfferCreate that would exchange two non-XRP currencies could potentially use XRP as an intermediary currency in a synthetic order book. This is because of auto-bridging, which serves to improve liquidity across all currency pairs by using XRP as a vehicle currency. This works because of XRP’s nature as a native cryptocurrency to the XRP Ledger. Offer execution can use a combination of direct and auto-bridged offers to achieve the best total exchange rate.

所有OfferCreate交易进行两种非XRP货币的转换潜在都可能以XRP做为中间货币,这就是自动桥接,其通过使用XRP作为承载实现了跨货币交易过程中货币的流通性。这也是XRP作为XRP总账网络内原生加密货币的本质。报价单可以以直接兑换和自动桥接组合的方式实现最佳交易费率。

Example: Anita places an offer to sell GBP and buy BRL. She might find that this uncommon currency market has few offers. There is one offer with a good rate, but it has insufficient quantity to satisfy Anita’s trade. However, both GBP and BRL have active, competitive markets to XRP. Auto-bridging software finds a way to complete Anita’s offer by purchasing XRP with GBP from one trader, then selling the XRP to another trader to buy BRL. Anita automatically gets the best rate possible by combining the small offer in the direct GBP:BRL market with the better composite rates created by pairing GBP:XRP and XRP:BRL offers.

示例:Anita要以英镑兑换巴西雷亚尔,但发现市场上BRL几乎没有报价单。然而英镑和XRP之间,以及巴西雷亚尔和XRP之间,都有大量的交易报价单。自动桥接通过将英镑兑换为XRP,再将XRP兑换为巴西雷亚尔的方式,实现了Anita的目的。且费用低廉。

Auto-bridging happens automatically on any OfferCreate transaction. Payment transactions do not autobridge by default, but path-finding can find paths that have the same effect.

自动桥接自动发生在所有OfferCreate交易中,Payment交易默认不使用自动桥接,但是路径发现功能可以发现具有相同效果的路径。

1月 262019
 


https://developers.ripple.com/offers.html
https://developers.ripple.com/offercreate.html
https://developers.ripple.com/offercancel.html

Offers
报价单

In the XRP Ledger’s decentralized exchange, orders to trade currency are called “Offers”. Offers can trade XRP with issued currencies, or issued currencies with each other, including issued currencies with the same currency code but different issuers. (Currencies with the same code but different issuers can also sometimes be exchanged through rippling.)
在XRP总账网络的去中心化汇兑中,用以交易货币的订单称为Offers报价单。报价单交易可以是在XRP和已发行货币之间,也可以是在不同已发行货币之间,包括不同发行人发行的具有相同货币代码的已发行货币。(通常不同发行人发行的具有相同货币代码的已发行货币也可以通过rippling进行交易。)

To create an Offer, send an OfferCreate transaction.

要创建报价单,需要提交一个OfferCreate交易。
Offers that aren’t fully filled immediately become Offer objects in the ledger data. Later Offers and Payments can consume the Offer object from the ledger.

报价单

Cross-currency payments consume offers to provide liquidity.

跨货币支付

TakerGets The amount and type of currency being provided by the offer creator.
报价单创建者提供的货币类型和数额

TakerPays The amount and type of currency being requested by the offer creator.
报价单创建者需要的货币类型和数额

Lifecycle of an Offer
报价单生命周期

When an OfferCreate transaction is processed, it automatically consumes matching or crossing offers to the extent possible. (If existing offers provide a better rate than requested, the offer creator could pay less than the full TakerGets amount to receive the entire TakerPays amount.) If that does not completely fulfill the TakerPays amount, then the offer becomes an Offer object in the ledger. (You can use OfferCreate Flags to modify this behavior.)
当OfferCreate交易处理后,系统自动进行消费匹配或在可接受范围内交叉报价。(如果现有报价单比已请求报价具有更优费率,报价单创建者可以支付少于TakerGets的数额,而收到TakerPays的全额。)如果不满足TakerPays数额要求,则该订单将作为Offer对象存在于总账网络中。

An offer in the ledger can be fulfilled either by additional OfferCreate transactions that match up with the existing offers, or by Payment transactions that use the offer to connect the payment path. Offers can be partially fulfilled and partially funded. A single transaction can consume up to 850 Offers from the ledger. (Any more than that, and the metadata becomes too large, resulting in tecOVERSIZE.)
总账网络中的报价单可以与其他由OfferCreate交易创建的报价单进行匹配交易,也可以在付款交易中使用报价单来连接付款路径。报价单支持部分匹配和部分兑现,单笔交易在总账网络中最多消耗850个报价单。(超过该限制,将导致metadata数据过大,相关参数为tecOVERSIZE)

You can create an offer so long as you have at least some (any positive, nonzero amount) of the currency specified by the TakerGets parameter of the offer. The offer sells as much of the currency as you have, up to the TakerGets amount, until the TakerPays amount is satisfied. An offer cannot place anyone in debt.
只要你的账户中拥有TakerGets参数所指定的货币种类和余额就可以创建报价单。报价单所指定的TakerGets数额不能超过你所具有该货币的实际数额。报价单不会使交易双方产生债务。

It is possible for an offer to become temporarily or permanently unfunded:
报价单可能产生临时或永久额度不足的情况:

If the creator no longer has any of the TakerGets currency.
    The offer becomes funded again when the creator obtains more of that currency.

当创建者不再持有TakerGets所指定的货币时。当创建者再次取得该货币时报价单及资金才变为可用状态。

If the currency required to fund the offer is held in a frozen trust line.
    The offer becomes funded again when the trust line is no longer frozen.

如果交易货币资金处在冻结状态的信任线上,只有当信任线不再冻结以后报价单及资金才变为可用状态。

If the creator does not have enough XRP for the reserve amount of a new trust line required by the offer. (See Offers and Trust.)
    The offer becomes funded again when the creator obtains more XRP, or the reserve requirements decrease.

当创建者XRP余额不能满足储备金要求以建立满足该报价单的新信任线时。报价单在创建者获取更多XRP或储备金标准降低时报价单才变为可用状态。

If the Expiration time included in the offer is before the close time of the most recently-closed ledger. (See Offer Expiration.)

如果报价单的过期时间在最近关闭的总账版本时间之前。

An unfunded offer can stay on the ledger indefinitely, but it does not have any effect. The only ways an offer can be permanently removed from the ledger are:
没有资金交付的报价单可以一直留存在总账网络中,但是没有任何效应。从总账网络中永久移除报价单的方式如下:

It becomes fully claimed by a Payment or a matching OfferCreate transaction.

完全被支付消耗或匹配其他OfferCreate交易。

An OfferCancel or OfferCreate transaction explicitly cancels the offer.

由OfferCancel或OfferCreate交易明确取消。

An OfferCreate transaction from the same account crosses the earlier offer. (In this case, the older offer is automatically canceled.)

由同一账户发起重叠的OfferCreate交易。(在这种情况下,旧报价单自动取消)

An offer is found to be unfunded during transaction processing, typically because it was at the tip of the orderbook.

报价单在处理交易时发现资金额度不可用。通常因为该报价单位于orderbook最末端。

    This includes cases where one side or the other of an offer is found to be closer to 0 than rippled's precision supports.

这包括一方或者另一个报价单挂出比rippled支持精度更接近0的报价。

Tracking Unfunded Offers
追踪无资金报价单

Tracking the funding status of all offers can be computationally taxing. In particular, addresses that are actively trading may have a large number of offers open. A single balance can affect the funding status of many offers to buy different currencies. Because of this, rippled does not proactively find and remove offers.
追踪报价单的资金状态以便进行税费计算。特别是活跃的账户地址通常保有大量进行中的报价单。单一的账户余额会影响到所有买入不同货币交易的资金状态。因此,rippled默认设计为不积极主动查找和移除报价单。

A client application can locally track the funding status of offers. To do this, first retreive an order book using the book_offers method and check the taker_gets_funded field of offers. Then, subscribe to the transactions stream and watch the transaction metadata to see which offers are modified.
客户端程序可以本地追踪报价单资金状态。首先使用book_offers方法检索order book并检查taker_gets_funded字段。然后参阅交易流及交易metadata元数据信息以确认哪些报价单发生了变化。

Offers and Trust
报价单与信任

The limit values of trust lines (See TrustSet) do not affect offers. In other words, you can use an offer to acquire more than the maximum amount you trust an issuer to redeem.
信任线的限额设置不影响报价单。也就是用户可以获取超过信任线限额或发行人偿付能力的货币。

However, holding non-XRP balances still requires a trust line to the address issuing those balances. When an offer is taken, it automatically creates any necessary trust lines, setting their limits to 0. Because trust lines increase the reserve an account must hold, any offers that would require a new trust line also require the address to have enough XRP to meet the reserve for that trust line.
但是,持有非XRP货币余额仍需与发行地址建立信任线。创建报价单时将自动创建必需的信任线,并设置限额为0。因为信任线与账户储备金相关,任何报价单创建时所需要的信任线关系都需要具有满足储备金要求的XRP。

A trust line indicates an issuer you trust enough to accept their issuances as payment, within limits. Offers are explicit instructions to acquire certain issuances, so they are allowed to go beyond those limits.
信任线限额是用户足够信任并接受能够使用发行进行付款的额度。报价单则是明确表明要获得的发行及额度,所以允许超出该限制。

Offer Preference
报价单偏好

Existing offers are grouped by exchange rate (sometimes called “offer quality”), which is measured as the ratio between TakerGets and TakerPays. Offers with a higher exchange rate are taken preferentially. (That is, the person accepting the offer receives as much as possible for the amount of currency they pay out.) Offers with the same exchange rate are taken on the basis of which offer was placed in the earliest ledger version.
现有报价单按汇率(也叫报价质量)进行分组,即TakerGets和TakerPays的比率。具有较高汇率的报价单将优先处理。(也就是说是尽量少的成本获取尽量多的回报)。具有相同汇率的报价单则根据其出现在总账版本的时间顺序优先处理。

When offers of the same exchange rate are placed in the same ledger version, the order in which they are taken is determined by the canonical order in which the transactions were applied to the ledger. This behavior is designed to be deterministic, efficient, and hard to game.
如果发生具有相同汇率的报价单出现在相同的总账版本中,订单将按照报价单交易提交至总账网络的权威顺序处理。这种行为被设计为确定的,高效的,难以捉弄的。

Offer Expiration
报价单过期

Since transactions can take time to propagate and confirm, the timestamp of a ledger is used to determine offer validity. An offer only expires when its Expiration time is before the most-recently validated ledger. In other words, an offer with an Expiration field is still considered “active” if its expiration time is later than the timestamp of the most-recently validated ledger, regardless of what your local clock says.
因为交易需要时间传递和确认,总账网络中的时间戳用以确认报价单有效性。报价单过期时间早于最近已验证总账时间则认为报价单过期。报价单过期时间晚于最新已验证总账时间,则认为是有效的报价单。

You can determine the final disposition of an offer with an Expiration as soon as you see a fully-validated ledger with a close time equal to or greater than the expiration time.
当用户看到报价单的过期时间等于或远远大于最新已验证总账的关闭时间时,即可以确认该报价单的最终意向。

Note:
Since only new transactions can modify the ledger, an expired offer can stay on the ledger after it becomes inactive. The offer is treated as unfunded and has no effect, but it can continue to appear in results (for example, from the ledger_entry command). Later on, the expired offer can get finally deleted as a result of another transaction (such as another OfferCreate) if the server finds it while processing.
只有新的交易可以修改总账,报价单可以留存在已生成和验证(过期)的总账中。不会有任何影响,但该报价单仍会出现在命令执行的结果中(如ledger_entry命令)。最终该报价单会在进行另外一笔OffercCreate交易时被删除。

要删除一项旧的报价并更换为新的报价,用户可以使用带有一个OfferSequence参数的OfferCreate 交易来代替使用OfferCancel并创建另一个OfferCreate交易。

If an OfferCreate transaction has an Expiration time that has already passed when the transaction first gets included in a ledger, the transaction does not execute the offer. The result code of such a transaction depends on whether the Checks amendment is enabled. With the Checks amendment enabled, the transaction has the tecEXPIRED result code. Otherwise, the transaction has the tesSUCCESS transaction code. In either case, the transaction has no effect except to destroy the XRP paid as a transaction cost.
如果OfferCreate交易的过期时间在提交至总账网络之前就已经过期,报价单将不会被使用。其交易返回代码将将根据是否启用Checks amendment支票修正设置而不同。该设置开启时,交易返回tecEXPIRED,未开启时返回tesSUCCESS。任何情况下,除取消该报价单时产生的XRP交易费用外,该报价单不会有任何效应。

1月 112019
 

安装Remi及EPEL仓库

[root@localhost ~]# yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
[root@localhost ~]# yum makecache

安装Jitamin基本运行环境软件包

[root@localhost ~]# yum install unzip net-tools php56-php php56-php-pdo php56-php-mysql php56-php-mbstring php56-php-gd httpd mariadb mariadb-server git

开启防火墙端口

[root@localhost ~]# firewall-cmd --permanent --add-service=http
success
[root@localhost ~]# firewall-cmd --reload
success
[root@localhost ~]#

配置数据库

[root@localhost ~]# systemctl enable mariadb
Created symlink from /etc/systemd/system/multi-user.target.wants/mariadb.service to /usr/lib/systemd/system/mariadb.service.
[root@localhost ~]# systemctl start mariadb
[root@localhost ~]#

[root@localhost ~]# mysql -uroot -p
MariaDB [(none)]> create database jitamin;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> grant all on jitamin.* to jitamin@localhost;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> set password for jitamin@localhost=password('jitamin');
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> exit
Bye

修改php.ini时区配置

[root@localhost ~]# vi /opt/remi/php56/root/etc/php.ini
date.timezone = Asia/Shanghai

[root@localhost ~]# php56 --version
PHP 5.6.40 (cli) (built: Jan 9 2019 12:21:54)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
[root@localhost ~]#

[root@localhost ~]# cd /usr/bin/
[root@localhost bin]# ln -s php56 php

安装Composer

[root@localhost ~]# php56 -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
[root@localhost ~]# php56 -r "if (hash_file('sha384', 'composer-setup.php') === '93b54496392c062774670ac18b134c3b3a95e5a5e5c8f1a9f115f203b75bf9a129d5daa8ba6a13e2cc8a1da0806388a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
Installer verified
[root@localhost ~]# php56 composer-setup.php
All settings correct for using Composer
Downloading...

Composer (version 1.8.0) successfully installed to: /root/composer.phar
Use it: php composer.phar

[root@localhost ~]# php56 -r "unlink('composer-setup.php');"
[root@localhost ~]# mv composer.phar /usr/bin/composer
[root@localhost ~]#

使用普通用户权限下载并配置Jitamin

[root@localhost ~]# useradd harveymei
[root@localhost ~]# su - harveymei
[harveymei@localhost ~]$ git clone https://github.com/jitamin/jitamin.git
Cloning into 'jitamin'...
remote: Enumerating objects: 13, done.
remote: Counting objects: 100% (13/13), done.
remote: Compressing objects: 100% (13/13), done.
remote: Total 14323 (delta 1), reused 0 (delta 0), pack-reused 14310
Receiving objects: 100% (14323/14323), 4.92 MiB | 663.00 KiB/s, done.
Resolving deltas: 100% (10492/10492), done.
[harveymei@localhost ~]$

[harveymei@localhost ~]$ cd jitamin/
[harveymei@localhost jitamin]$ cp .env.example .env
[harveymei@localhost jitamin]$
[harveymei@localhost jitamin]$ vi .env
APP_NAME=Jitamin
APP_ENV=production
APP_DEBUG=true
APP_KEY=SomeRandomString
APP_TIMEZONE=Asia/Shanghai
APP_LOCALE=zh-CN
APP_THEME=black
APP_LOG=daily
APP_LOG_LEVEL=error
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=jitamin
DB_USERNAME=jitamin
DB_PASSWORD=jitamin

使用composer安装项目PHP依赖

[harveymei@localhost jitamin]$ composer install -o --no-dev
> php -r "file_exists('.env') || copy('.env.example', '.env');"
Loading composer repositories with package information
Installing dependencies from lock file
Package operations: 27 installs, 0 updates, 0 removals
- Installing christian-riesen/base32 (1.3.1): Downloading (100%)
- Installing christian-riesen/otp (1.4.3): Downloading (100%)
- Installing eluceo/ical (0.10.1): Downloading (100%)
- Installing erusev/parsedown (1.6.0): Downloading (100%)
- Installing gregwar/captcha (v1.1.1): Downloading (100%)
- Installing jitamin/json-rpc (v1.2.2): Downloading (100%)
- Installing jitamin/picodb (v1.0.15): Downloading (100%)
- Installing jitamin/picofeed (v0.1.25): Downloading (100%)
- Installing jitamin/simple-logger (v1.0.2): Downloading (100%)
- Installing jitamin/simple-queue (v1.0.1): Downloading (100%)
- Installing jitamin/simple-validator (v1.0.2): Downloading (100%)
- Installing symfony/polyfill-mbstring (v1.9.0): Downloading (100%)
- Installing symfony/translation (v3.2.14): Downloading (100%)
- Installing nesbot/carbon (1.33.0): Downloading (100%)
- Installing paragonie/random_compat (v2.0.11): Downloading (100%)
- Installing pimple/pimple (v3.0.2): Downloading (100%)
- Installing symfony/yaml (v2.8.7): Downloading (100%)
- Installing psr/log (1.0.2): Downloading (100%)
- Installing symfony/debug (v3.4.14): Downloading (100%)
- Installing symfony/console (v3.4.14): Downloading (100%)
- Installing symfony/polyfill-ctype (v1.9.0): Downloading (100%)
- Installing symfony/filesystem (v3.4.14): Downloading (100%)
- Installing symfony/config (v3.4.14): Downloading (100%)
- Installing robmorgan/phinx (v0.6.6): Downloading (100%)
- Installing swiftmailer/swiftmailer (v5.4.5): Downloading (100%)
- Installing symfony/event-dispatcher (v3.4.14): Downloading (100%)
- Installing vlucas/phpdotenv (v2.5.1): Downloading (100%)
Generating optimized autoload files
[harveymei@localhost jitamin]$

创建并初始化数据库

[harveymei@localhost jitamin]$ vendor/bin/phinx migrate
Phinx by Rob Morgan - https://phinx.org. 0.6.6

using config file ./phinx.php
using config parser php
using migration path database/migrations
using seed path database/seeds
warning no environment specified, defaulting to: mysql
using adapter mysql
using database jitamin

== 20161222061456 CreateUsersTable: migrating
== 20161222061456 CreateUsersTable: migrated 0.0055s

== 20161222065743 CreateRememberMeTable: migrating
== 20161222065743 CreateRememberMeTable: migrated 0.0027s

== 20161222071058 CreateGroupsTable: migrating
== 20161222071058 CreateGroupsTable: migrated 0.0031s

== 20161222071513 CreateSettingsTable: migrating
== 20161222071513 CreateSettingsTable: migrated 0.0017s

== 20161222072332 CreateProjectsTable: migrating
== 20161222072332 CreateProjectsTable: migrated 0.0021s

== 20161222073541 CreateActionsTable: migrating
== 20161222073541 CreateActionsTable: migrated 0.0018s

== 20161222073852 CreateColumnsTable: migrating
== 20161222073852 CreateColumnsTable: migrated 0.0026s

== 20161222074452 CreateTasksTable: migrating
== 20161222074452 CreateTasksTable: migrated 0.0032s

== 20161222081719 CreateCommentsTable: migrating
== 20161222081719 CreateCommentsTable: migrated 0.0025s

== 20161222082417 CreateSwimlanesTable: migrating
== 20161222082417 CreateSwimlanesTable: migrated 0.0023s

== 20161222083010 CreateTagsTable: migrating
== 20161222083010 CreateTagsTable: migrated 0.0018s

== 20161222083245 CreateSubtasksTable: migrating
== 20161222083245 CreateSubtasksTable: migrated 0.0020s

== 20161222083935 CreateLinksTable: migrating
== 20161222083935 CreateLinksTable: migrated 0.0046s

== 20161222084249 CreateTransitionsTable: migrating
== 20161222084249 CreateTransitionsTable: migrated 0.0034s

== 20161222084940 CreateCustomFiltersTable: migrating
== 20161222084940 CreateCustomFiltersTable: migrated 0.0023s

== 20161222085354 CreateLastLoginsTable: migrating
== 20161222085354 CreateLastLoginsTable: migrated 0.0020s

== 20161222085809 CreatePasswordResetTable: migrating
== 20161222085809 CreatePasswordResetTable: migrated 0.0019s

== 20161222091052 CreatePluginSchemaVersionsTable: migrating
== 20161222091052 CreatePluginSchemaVersionsTable: migrated 0.0018s

== 20161222091605 CreateProjectActivitiesTable: migrating
== 20161222091605 CreateProjectActivitiesTable: migrated 0.0028s

== 20161222092217 CreateProjectDailyColumnStatsTable: migrating
== 20161222092217 CreateProjectDailyColumnStatsTable: migrated 0.0025s

== 20161222092312 CreateProjectDailyStatsTable: migrating
== 20161222092312 CreateProjectDailyStatsTable: migrated 0.0019s

== 20161222093033 CreateSchemaVersionTable: migrating
== 20161222093033 CreateSchemaVersionTable: migrated 0.0014s

== 20161222093333 CreateActionHasParamsTable: migrating
== 20161222093333 CreateActionHasParamsTable: migrated 0.0019s

== 20161222094356 CreateProjectHasRolesTable: migrating
== 20161222094356 CreateProjectHasRolesTable: migrated 0.0016s

== 20161222094851 CreateColumnHasRestrictionsTable: migrating
== 20161222094851 CreateColumnHasRestrictionsTable: migrated 0.0023s

== 20161222094859 CreateColumnHasMoveRestrictionsTable: migrating
== 20161222094859 CreateColumnHasMoveRestrictionsTable: migrated 0.0024s

== 20161222095207 CreateGroupHasUsersTable: migrating
== 20161222095207 CreateGroupHasUsersTable: migrated 0.0030s

== 20161222095739 CreateProjectHasCategoriesTable: migrating
== 20161222095739 CreateProjectHasCategoriesTable: migrated 0.0017s

== 20161222100221 CreateProjectHasFilesTable: migrating
== 20161222100221 CreateProjectHasFilesTable: migrated 0.0016s

== 20161222104316 CreateProjectHasGroupsTable: migrating
== 20161222104316 CreateProjectHasGroupsTable: migrated 0.0017s

== 20161222104338 CreateProjectHasMetadataTable: migrating
== 20161222104338 CreateProjectHasMetadataTable: migrated 0.0019s

== 20161222104355 CreateProjectHasStarsTable: migrating
== 20161222104355 CreateProjectHasStarsTable: migrated 0.0020s

== 20161222104411 CreateProjectHasNotificationTypesTable: migrating
== 20161222104411 CreateProjectHasNotificationTypesTable: migrated 0.0016s

== 20161222104427 CreateProjectHasUsersTable: migrating
== 20161222104427 CreateProjectHasUsersTable: migrated 0.0022s

== 20161222112306 CreateProjectRoleHasRestrictionsTable: migrating
== 20161222112306 CreateProjectRoleHasRestrictionsTable: migrated 0.0022s

== 20161222112615 CreateSubtaskTimeTrackingTable: migrating
== 20161222112615 CreateSubtaskTimeTrackingTable: migrated 0.0019s

== 20161222113157 CreateTaskHasExternalLinksTable: migrating
== 20161222113157 CreateTaskHasExternalLinksTable: migrated 0.0016s

== 20161222113205 CreateTaskHasFilesTable: migrating
== 20161222113205 CreateTaskHasFilesTable: migrated 0.0017s

== 20161222113217 CreateTaskHasLinksTable: migrating
== 20161222113217 CreateTaskHasLinksTable: migrated 0.0032s

== 20161222113234 CreateTaskHasMetadataTable: migrating
== 20161222113234 CreateTaskHasMetadataTable: migrated 0.0018s

== 20161222113239 CreateTaskHasTagsTable: migrating
== 20161222113239 CreateTaskHasTagsTable: migrated 0.0017s

== 20161222114814 CreateUserHasMetadataTable: migrating
== 20161222114814 CreateUserHasMetadataTable: migrated 0.0020s

== 20161222114828 CreateUserHasNotificationTypesTable: migrating
== 20161222114828 CreateUserHasNotificationTypesTable: migrated 0.0016s

== 20161222114837 CreateUserHasNotificationsTable: migrating
== 20161222114837 CreateUserHasNotificationsTable: migrated 0.0024s

== 20161222114844 CreateUserHasUnreadNotificationsTable: migrating
== 20161222114844 CreateUserHasUnreadNotificationsTable: migrated 0.0016s

== 20161225123941 AlterTableUsersAddApiTokenColumn: migrating
== 20161225123941 AlterTableUsersAddApiTokenColumn: migrated 0.0042s

== 20161228031419 AlterTableUsersAddLayoutColumn: migrating
== 20161228031419 AlterTableUsersAddLayoutColumn: migrated 0.0031s

== 20161231134810 AlterTableUsersAddDashboardColumn: migrating
== 20161231134810 AlterTableUsersAddDashboardColumn: migrated 0.0124s

== 20170105040003 AlterTableProjectsAddDefaultViewColumn: migrating
== 20170105040003 AlterTableProjectsAddDefaultViewColumn: migrated 0.0028s

== 20171228053201 AlterTableActionsAddPositionColumn: migrating
== 20171228053201 AlterTableActionsAddPositionColumn: migrated 0.0150s

All Done. Took 0.1642s
[harveymei@localhost jitamin]$
[harveymei@localhost jitamin]$ vendor/bin/phinx seed:run
Phinx by Rob Morgan - https://phinx.org. 0.6.6

using config file ./phinx.php
using config parser php
using migration path database/migrations
using seed path database/seeds
warning no environment specified, defaulting to: mysql
using adapter mysql
using database jitamin

== LinkSeeder: seeding
== LinkSeeder: seeded 0.0079s

== SettingSeeder: seeding
== SettingSeeder: seeded 0.0043s

== UserSeeder: seeding
== UserSeeder: seeded 0.0911s

All Done. Took 0.1050s
[harveymei@localhost jitamin]$

修改目录权限

[harveymei@localhost jitamin]$ chmod -R 777 bootstrap/cache/
[harveymei@localhost jitamin]$ chmod -R 777 storage/
[harveymei@localhost jitamin]$

清除缓存

[harveymei@localhost jitamin]$ php artisan config:cache
Configuration cached successfully!
[harveymei@localhost jitamin]$ php artisan route:cache
Routes cached successfully!
[harveymei@localhost jitamin]$

修改项目路径及配置Apache服务

[harveymei@localhost ~]$ exit
logout
[root@localhost ~]#
[root@localhost ~]# mv /home/harveymei/jitamin/ /usr/local/
[root@localhost ~]# cd /usr/local/
[root@localhost local]# chown -R apache.apache jitamin/
[root@localhost local]#

修改默认主机名

[root@localhost ~]# vi /etc/httpd/conf/httpd.conf
ServerName localhost

添加虚拟主机配置

[root@localhost ~]# vi /etc/httpd/conf.d/jitamin.conf
<VirtualHost *:80>
ServerName 192.168.108.67
DocumentRoot "/usr/local/jitamin/public/"

ErrorLog "logs/jitamin-error_log"
CustomLog "logs/jitamin-access_log" combined

<Directory "/usr/local/jitamin/public/">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>

检查配置文件并启动Apache服务

[root@localhost ~]# apachectl -t
Syntax OK
[root@localhost ~]# systemctl enable httpd
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
[root@localhost ~]# systemctl start httpd
[root@localhost ~]#

使用浏览器访问Jitamin服务

10月 152018
 

47.52.163.213

VERSION=2.1.47 /bin/bash -c “$(curl -s https://cms-agent-cn-hongkong.oss-cn-hongkong-internal.aliyuncs.com/cms-go-agent/cms_go_agent_install.sh)”

[root@iZj6cd9flzbx5kd084fw97Z ~]# yum -y update

[root@iZj6cd9flzbx5kd084fw97Z ~]# hostnamectl set-hostname pms
[root@iZj6cd9flzbx5kd084fw97Z ~]# init 6

[root@pms ~]# yum -y install https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm
[root@pms ~]# vi /etc/yum.repos.d/mysql-community.repo

[mysql56-community]
enabled=1

[mysql80-community]
enabled=0

[root@pms ~]# yum makecache

[root@pms ~]# yum install httpd php php-gd php-mbstring php-pdo php-mysql mysql-community-server mysql-community-client

[root@pms ~]# curl -O http://dl.cnezsoft.com/zentao/10.5/ZenTaoPMS.10.5.stable.zip
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 6718k 100 6718k 0 0 2854k 0 0:00:02 0:00:02 –:–:– 2855k
[root@pms ~]#

[root@pms ~]# yum -y install unzip

[root@pms ~]# unzip ZenTaoPMS.10.5.stable.zip
[root@pms ~]# mv zentaopms/ /usr/local/

[root@pms ~]# vi /etc/httpd/conf/httpd.conf
ServerName 127.0.0.1

[root@pms ~]# vi /etc/httpd/conf.d/zentaopms.conf
#<VirtualHost *:80>
# ServerName 149.28.192.83
# RewriteEngine On
# RewriteRule ^(.*)$ http://www.domain.com$1 [R,L]
#</VirtualHost>

<VirtualHost *:80>
ServerName 10.172.100.222
DocumentRoot “/usr/local/zentaopms/www”

ErrorLog “logs/zentaopms-error_log”
CustomLog “logs/zentaopms-access_log” combined

<Directory “/usr/local/zentaopms”>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>

# RewriteEngine On
# RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R,L]
</VirtualHost>

#<VirtualHost *:80>
# ServerName 149.28.192.83
# RewriteEngine On
# RewriteRule ^(.*)$ http://www.domain.com$1 [R,L]
#</VirtualHost>

#<VirtualHost *:80>
# ServerName cn.paycpro.io
# DocumentRoot “/usr/local/www.domain.com”
#
# ErrorLog “logs/www.domain.com-error_log”
# CustomLog “logs/www.domain.com-access_log” combined
#
# <Directory “/usr/local/www.domain.com”>
# Options Indexes FollowSymLinks
# AllowOverride All
# Require all granted
# </Directory>

# RewriteEngine On
# RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R,L]
#</VirtualHost>

[root@pms ~]# vi /etc/php.ini
date.timezone = Asia/Shanghai

[root@pms ~]# apachectl -t
Syntax OK
[root@pms ~]#

[root@pms ~]# systemctl status httpd
● httpd.service – The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: inactive (dead)
Docs: man:httpd(8)
man:apachectl(8)
[root@pms ~]# systemctl enable httpd
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
[root@pms ~]# systemctl start httpd
[root@pms ~]#

[root@pms ~]# vi /etc/my.cnf
#
bind-address = 0.0.0.0
character-set-server = utf8mb4
log_bin = mysql-bin
binlog_format = mixed
expire_logs_days = 7

[root@pms ~]# systemctl status mysqld
● mysqld.service – MySQL Community Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: inactive (dead)
[root@pms ~]# systemctl start mysqld
[root@pms ~]#

[root@pms ~]# mysql -uroot -p

mysql> create database zentaopms;
Query OK, 1 row affected (0.00 sec)

mysql> grant all on zentaopms.* to zentaopms@localhost;
Query OK, 0 rows affected (0.00 sec)

mysql> set password for zentaopms@localhost=password(‘#sk3832EsoeqA’);
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> exit
Bye

[root@pms ~]# systemctl enable firewalld
Created symlink from /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service to /usr/lib/systemd/system/firewalld.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/firewalld.service to /usr/lib/systemd/system/firewalld.service.
[root@pms ~]# systemctl start firewalld
[root@pms ~]# firewall-cmd –list-all
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

[root@pms ~]#

[root@pms ~]# firewall-cmd –permanent –add-service=http
success
[root@pms ~]# firewall-cmd –reload
success
[root@pms ~]# firewall-cmd –list-all
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh dhcpv6-client http
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

[root@pms ~]#

http://47.52.163.213/install.php

[root@pms ~]# cd /usr/local/zentaopms/www/
[root@pms www]# rm -rf index.php
[root@pms www]#