We explore how we designed and utilize smart contracts for PPIO’s data delivery services for a fair and balanced storage platform.

In our previous articles on The Secrets of PPIO’s Data Delivery Technology Parts 1 and 2, we introduced the design and advantages of PPIO from the perspective of architecture and P2P transmission technology. Those things are, of course, not closely related to the blockchain and smart contracts. In this article, we will introduce PPIO’s blockchain and smart contract design at the data delivery level while also leading a community discussion to help perfect this design.

The Payment Method for Data Delivery

The payment method of data delivery is different from data storage. The business model of data storage is based user payments which means the user pays for storage. However, the scenario of data delivery is distinct. Generally speaking, bandwidth and traffic are paid by developers or operators. Thus, when we designed the payment method for data delivery scenarios, we gave more attention to smart contracts which are paid by developers. Because of this, we invented the Owner role.

The Role of the Owner

The Owner is not a P2P transmission role, but a payment and settlement role. In the PCDN architecture, each Peer needs to specify an Owner. The cost of this Peer is borne by his Owner, and the income earned by the Peer is also received by his Owner.

As shown in the figure below, the same Owner can connect multiple Peers.

If it is on the demand side, it can be understood as a “CPool”. We have previously covered our proxy payment gateway, in our article “Why PPIO Designed Coin Pool Nodes”). If it is on the supply side, it can be understood as a “mine pool”. For PCDN services, the cost of using bandwidth is generally borne by the content publisher and the settlement which is on the chain should be conducted between Owners.

For the developer, you can either deploy the CoinPool (the Owner) or access other third-party CoinPools (also the Owner in this situation). Thus, the data transmission between Peers of the same Owner does not involve settlement on the blockchain.

The Contract For Data Delivery (Simple Model)

Next, we will introduce smart contracts for data delivery. For the reader’s understanding, we will simplify the model and build a simple scenario that involves communication between two Peers. Each of the Peers belongs to Owner 1 and Owner 2 respectively. When a Peer downloads data from another Peer, what happens between Owner 1 and Owner 2?

In this simplest model, the interaction process is as follows:

  1. Owner 1 puts a deposit into a smart contract.
  2. The User requests a check (like a bank check) from Owner 1. The check will contain the address of the smart contract, the max amount the voucher will pay, the CheckID, the expiration time, and so on.
  3. The Owner reviews whether the check request meets his requirements or not. If it meets the requirements, the check is returned to the User; if it does not match, for example, if it applies for too many tokens, it can be rejected.
  4. The User requests data from the Miner (via the P2P data transfer protocol) and successfully receives data.
  5. The User will expand the check to a voucher (similar to credentials) and will send it to a Miner. The process in steps 4 and 5 should be repeated several times, and the amount involved in the voucher will continue to increase.
  6. No matter if the download finishes or is aborted, the voucher with the max recorded amount (which is also the latest recorded amount) will be submitted to the Miner’s Owner — Owner 2.
  7. Owner 2 receives the voucher and initiates a withdrawal to the blockchain smart contract.
  8. If the Voucher is correct and has not expired, then the withdrawal will be successful.

As shown in the above figure, the transaction process of Owner 1 and Owner 2 is finally completed through the smart contract. In this process, only the withdrawal of the Voucher is the operational behavior on-the-chain; all other steps are off-chain. The communication between Peers also uses state channels for trusted transmissions. The state channel mechanism for data delivery is a very clever design, which we intend to cover in a future article.

However, the actual situation is not always this simple. A variety of problems can occur in the download process:

The first is the issue of expiration. When the Owner gives the Check, he/she will declare the expiration time of the Check; therefore, the withdrawal by the Voucher can only be successful within the stated time. If the expiration time has been exceeded, the Voucher will not be able to withdraw funds on the chain.

The second issue is that of trust. There may be fraud between Peer 1 (User) and Peer 2 (Miner). For example, Peer 1 first applies for data from Peer 2. After Peer 2 gives all the complete data, Peer 1 should give the Voucher to Peer 2 so that Peer 2 can perform the contract withdrawal on the chain. However, what can be done to prevent fraud if Peer 1 has downloaded all the data, and does not give Peer 2 the Voucher?

There is a simple solution here: Peer 2 transmits data to Peer 1 in ciphertext, which needs a key to decrypt the data before it can be used. Peer 2 grants a key to Peer 1 after ensuring that the Voucher is obtained, and that Peer 1 can use the data.

As effective as that solution is, the PPIO platform will use a different approach from that for two important reasons:

  1. PCDN has strong requirements for the real-time performance of data transmission, especially when applied to media streaming. This ciphertext decryption method cannot be adapted quite so well for media streaming and has more practicality for data storage.
  2. Peer 2 also has the possibility of performing malicious activities such as the key not being given on time or giving the wrong key.

This simple solution does not perfectly solve the trust issue. Therefore, PPIO has adopted a micropayment scheme where a Check can correspond to multiple Vouchers. More specifically, each time a small amount of data is transmitted, Peer 1 can give a Voucher (Voucher 1) which declares a withdrawal part; then a small part of the data is transmitted. Peer 1 again gives a new Voucher (Voucher 2), which declares that more parts of the withdrawal can be made. This process is repeated several times until the transfer is completed, Peer 2 receives Voucher N, and Peer 2 finally uses Owner 2 to withdraw all the money with Voucher N.

In the figure above, we divide steps 4 and 5 into multiple steps. This improvement greatly reduces the risk of doing something malicious. Imagine if Peer 1, after receiving the data, does not give the Voucher, then Peer 2 will not transmit new data so that the loss of Peer 2 can be kept to a minimum.

Note that for multiple Vouchers corresponding to the same Check, there is an overlapping relationship between them. Owner 2 tries to withdraw only with the maximum withdrawal amount of the Voucher, and does not need to use each Voucher to withdraw, because the new Voucher will cover the old Voucher. This design reduces the TPS requirements for the blockchain.

The Strategy of Sharing Owners

When the Owner is the same, all peers that transmit data correspond to that Owner. From a transaction point of view, this is when the internal transaction is between Peer 1 and Peer 2. Since the payment of Peer 1 and the collection of Peer 2 are completed by the Owner, the Owner pays and collects the money, which is equivalent to conducting an internal transaction. Thus, the whole process is not required to be on the chain.

As shown in the figure above, if the Owner makes sure that the data is only transmitted between internal peers, then step 1 can be omitted.

Why is PPIO designed like this? In a real-life scenario, the role of the Owner is akin to tech developers. Let’s say a developer created an app which is used by many people. Each app functions as a Peer. All of these apps come together to build a P2P network. When one app (Peer) wants to download data, it will get data from another app (Peer) to download. Since these apps belong to the same developer, all transmission costs are offset by that developer. In other words, the cost of a P2P transmission established for the same developer is zero. Because no new data needs to be uploaded on the chain, it does not generate any TPS overhead for the blockchain. This design is compatible with the classic P2P mechanism, which means supply and demand are bound together, e.g. BitTorrent, eDonkey, and PPTV.

For data transmission across developers, or Owners, there is a cost. If the developer establishes a P2P network that is exporting traffic, the developer will make a profit. Conversely, if the developer’s app receives traffic from another Owner’s Peers, the developer will pay the fee to another developer.

Below we will introduce our Multi-Peer Transmission Strategy which is used when there are different Owners.

The Transmission Strategy of Multiple Peers Under Different Owners

All of the above are relatively single transmissions, now we will analyze a more complex multi-Peer transmission.

When designing PPIO, another consideration was implementing a hierarchical structure for the Owner and Peer. The Owner layer is responsible for the flow of funds, while the Peer layer is responsible for the flow of data. Smart contracts on the blockchain need to be executed only when funds vary between different Owners.

The are several problems with this design: how the Check from the blockchain smart contract (which is applied by Owner 1) can be split and given to multiple peers; how to expand this into multiple Vouchers; and finally how Peer 2 collects and withdraws money from the blockchain smart contract.

The following is a simple example when a developer (Owner 1) corresponds with multiple Peers, which are Peer 1 and Peer 3 respectively. The mine group Owner 2 corresponds with multiple Miners, which are Peer 2 and Peer 4 respectively. In the scheduling of the P2P network, there is a case where Peer 1 downloads data from Peer 2, and Peer 3 downloads data from Peer 4. As shown below:

  1. As the figure of the simplest download process model mentioned earlier, the Owner first puts enough prepayments into the smart contract. These funds are then split into multiple Checks, namely Check_a, Check_b, Check_c, Check_d, etc. As for the amount of money included in each check, it will depend on the business situation.
  2. Peer 1 is connected to Peer 2 and wants to download data. Peer 1 then applies for a Check from Owner 1. Owner 1 will restrict the amount of money and gives Check_a.
  3. At the same time, Peer 3 is connected to Peer 4 and wants to download data. Similar to step 2, Peer 3 applies for Check_b.
  4. Peer 1 continuously downloads data from Peer 2. Peer 1 gives Peer 2 the Voucher of Check_a multiple times until the money in Check_a is used up. Peer 2 eventually gets the complete Voucher_a.
  5. Similar to Step 4, Peer 3 keeps downloading data from Peer 4 until the money in Check_b’s is used up. Peer 4 eventually gets the complete Voucher_b.
  6. Peer 2 will pass Check_a’s final Voucher, Voucher_a, to its Owner, Owner 2.
  7. Owner 2 withdraws the smart contract from the blockchain with Voucher_a.
  8. Peer 4 will pass Check_b’s final Voucher, Voucher_b, to his Owner, Owner 2.
  9. Owner 2 withdraws the smart contract from the blockchain with Voucher_b.
  10. If Peer 1 has used up the amount of Check_a but the data has not been downloaded yet, then an application for a new Check (Check_c) from Owner 1 is made to continue downloading.
  11. If Peer 2 has used up the amount of Check_b but the data has not been downloaded yet, then an application for a new Check (Check_d) from Owner 2 is made to continue downloading.
  12. Repeat the previous steps if necessary.

This design is extremely helpful for improving security for three main reasons:

  1. Preventing an Owner’s Peer of the payer from making outside deals: When the Owner receives a request for a new check from a Peer, the Owner can decide whether to give a new Check or not based on the Peer history request record and the PPIO token amount that the Peer has consumed. This can effectively prevent a malicious Peer from using unlimited applications to take advantage of other systems in order to make money.
  2. Prohibiting the payer Peer to double-spend the same Check: The Check specifies the Pool address, the Owner address of the payee Peer, and the public key of the payee Peer. Therefore, since the payer Peer cannot apply for one check and consume it with two different payee Peers, the possibility of double-spending is eliminated.
  3. The micropayment method minimizes possible losses: the Voucher and data transactions are implemented using a micro payment method which is similar to the state channel. The Miner gives a little data, the User provides the corresponding money, the Miner then gives a little data to the User again, and then the User gives another part of the corresponding money. This process repeats several times until the download is completed. If any party defaults during the transaction, they can find the problem in time and minimize the loss.

The Data Structure of Smart Contracts

Until now, we have introduced the design concept of smart contracts for PPIO’s data delivery mechanism, in the next part, we will introduce the design of blockchain smart contracts. With the design concept covered, it is not difficult to see that only the Check and Voucher are related to the smart contract.

Check: Since all Peers do not have an account on the chain, when a Peer of an Owner is paying to other Peers, it should first apply for a check to its Owner. The Check contains the unique Check ID, the maximum amount spent, the expiration date, the withdrawal smart contract address, the Owner address of the payee, and the public key of the payment Peer and collection Peer. The Check will include the signature of the Owner.

type Check struct {pool           base.Address     // Contract addresspayer          base.PublicKey   // The payer peer’s public keyreceiver       base.Address     // The receiver owner’s addresspayee          base.PublicKey   // The payee peer’s public keymaxAmount      base.Uint256     // The max amount payer can spendcheckId        base.Uint256     // The unique CheckIdexpiry         uint64           // The expiry time of this checkownerSignature base.Signature   // The signature of payer peer’s owner}

Voucher: The complete Voucher logically contains the entire Check content, plus an additional amount of the actual amount paid. Also, the Voucher carries the signature of the payment Peer.

type Voucher struct {Check     // The Checkamount         base.Uint256 // The amount payer peer spendspayerSignature base.Signature   // The payer peer’s signature}

The actual amount of the Voucher generated may be less than the maximum amount of the Check. Therefore, when applying for the Check, the amount can be greater than the actual amount forecasted.

Owner SDK

PPIO has designed the Owner SDK (CoinPool SDK). Based on the download and delivery scenarios, third-party developers can use the Owner SDK to quickly create an Owner, a proxy payment gateway (CoolPool), or a mine pool (MinePool).

The Owner SDK is designed based on the gRPC framework and it achieves two protocols:

  1. ApplyCheck: The Check requested by the Peer is used to download resources from other Peers
  2. ReportVoucher: The Peer reports the Voucher it gets. These Vouchers are issued through other Peer nodes.

Similarly, developers must implement two callback interfaces that correspond to the following protocols:

  1. OnApplyCheck: Used to inform the application of the Check
  2. OnRecvVoucher: Used to inform the receipt of the Voucher

We have improved on the original smart contract to make it more flexible, to conform for use with data delivery, to ensure QoS, and to enable users to enjoy the best experience.

No matter if you are a fan of PPIO or curious about what we do, we invite you to join our Discord group or to post your opinions on Github about what you think about our smart contract system. We would love to hear your thoughts and hope your feedback can help improve what we do.

Share your thoughts with our Discord community or on our Github.