2017.10.10

Bulk Settlement for Micropayments using GMO Blockchain


Proposal for a Micro-payment System for Services using GMO Blockchain

Problem: micro-payments are small and because an individual blockchain transactions incurs a fee (gas on Ethereum) that is quite expensive (currently averaging about 50 yen on Ethereum). We can’t just perform a blockchain transaction for each micro-payment.

 

Solution: it is preferable to consolidate many micro-payments into one blockchain transaction.

The transaction data of each micro-payment is created by the Service and signed by the User (Service Customer). This is done off-chain. The settlement is then done on the blockchain.

This is shown by the diagram below.


The diagram above is divided into 2 sections: Micropayments done off the blockchain, and Settlement done on the blockchain.

In this diagram there are 3 types of participants:
  1. Service – this is simply some type of Service that gets paid in micropayments. Some example services are media streaming (think youtube without ads), news, games. Since such services derive revenue from micropayments they obviously don’t need to display ads.
  2. Users – they use the Service and pay the Service with micropayments. The example Users in the diagram are Alice and Bob.
  3. Provider – handles the settlement of the summed micropayments on the blockchain.
 

Micropayments

Each micropayment is processed between a User and the Service. The Service creates the micropayment transaction data which the User signs.

Because only the User can sign for his address (Payment Account) micropayment transactions cannot be falsified. The Service checks that the signature is valid before accepting the micropayment.

This transaction contains the total payable by the user (from the last settlement up to and including the current micropayment).
Thus the latest signed transaction by a User is the sum of all the User’s micro-payments since the last settlement.
The amount of the current micro-payment is just the last total minus the current total.

The micropayment transaction also contains the current settlement number. This is used when settling to check that the User’s payment is for the correct settlement number and to ensure a User only pays once per settlement number. Given that a User can only pay once per settlement, the Service will submit the latest signed micropayment transaction which contains the maximum amount payable to the Service.

For Bob we see that the Service requests him to sign for one 10 wei micropayment for settlement number 3, which he did.

In the example of Alice, we see that she signed for two micropayments to the Service. The first transaction indicates the Service has requested Alice to sign for 15 wei for settlement number 3. Second we see the Service requested Alice to sign for 30 wei for settlement number 3. Because Alice always signs the total of her micropayments, this is the same as if she made two 15 wei micropayments.

If the Service knows the initial balance of a User then the Service can track that balance per micro-transaction. For example in the diagram above, if Alice initially had a balance of 50 wei, after the two micropayments totalling 30 wei, the Service calculates Alice only has 20 wei remaining. In this way the Service calculates locally the current balance of a User’s account.

The Service keeps track of the unsettled micropayment transactions and signatures. It will pass these to the Provider when requesting settlement.

The implementation of User transaction signing should probably be left up to the Service. A simple example would require valid signed settlement transaction to be passed as an HTTP request parameter to the Service URL. If the signed settlement transaction is present and valid the Service provides the URL contents, otherwise the Service may request a valid signed transaction by returning a settlement transaction to the User to sign. This simple example is shown in the diagram below.


 

Settlement

Settlement is done between the Service and the Provider.  The Service may settle with the Provider at any time. The Service passes the list of settlement transactions and their signatures to the Provider in order to settle.  The settlement transactions in the list are processed as one blockchain transaction.

Services pay the gas for the blockchain transaction and a settlement fee which is determined by the Provider.
This deters Services from settling too often and overloading the network and rewards the Provider for the work of settling and maintaining the list of Users.
On the other hand as the number of Users to settle increases so does the gas fee, so Services will not want to wait too long before settling.

User account’s are maintained by the Provider. Accounts contain the address and balance for each User that may be used to settle. The Provider also keeps track of the current settlement number which is validated against each User’s transaction number.

The actual settlement is a payment of wei from the Provider (on behalf of the User) to the Service. Because payment is done on behalf on Users by the Provider, it is required that Users initially make a deposit to the Provider. This deposit becomes the User’s settlement balance. The deposit process is beyond the scope of this blog. The payment of wei can be consolidated across all Users settling and done just once, further reducing processing required to settle.

 

The skeleton for the contract that handles settlement would look something like this:
contract MicropaymentSettlement {
   address provider = msg.sender; // the Provider address
   address service; // the Service address
   
   mapping(bytes32 => uint) users; // mapping of user addresses to user balances

   uint settlementNumber = 1; // the settlement number
   
   event Settlements(address[] users, uint[] settledAmounts, uint[] newBalances, uint[] settlementStatusCodes);

   function settle(address[] users, uint[] amounts, bytes[] signatures) onlyByService {...}

   function addUsers(address[] users, uint[] balances) onlyByProvider {...}

   function getUsers() constant returns (address[] users, uint[] balances) onlyByServiceOrProvider {...}

   function setSettlementFee(uint feeAmount) onlyByProvider {...}

   function setService(address service) onlyByProvider {...}

}
 

settle function

  • users – array of addresses for Users who have amounts to settle
  • amounts – the settlement amount for each User
  • signatures – the signatures for each settlement
This method settles for each user in users having a valid settlement transaction.

A settlement transaction is valid if:
  • the user exists in the users array stored in MicropaymentSettlement.
  • the User has sufficient funds. If the User does not have a sufficient balance, the User’s remaining balance will be transferred to the Service.
  • the settlement number matches the current settlement number stored in MicropaymentSettlement.
  • the settlement transaction signature is valid.
If a User’s settlementStatusCode is 0 the User’s settlement was successful.

If the transaction is valid the amount in wei is paid from the user account to the Service account.
On successful completion a Settlement event is generated so that the listening Service may obtain the settlement status and new balance for each user. The internally stored settlementNumber is also incremented after successful completion.

The actual payment of wei to the Service by the Provider is the consolidated amount of each individual User settlement and only done once per call to the settle function.

throws – Besides invalid transactions Errors are thrown if the arrays are different lengths, or if any User is included in the transaction list more than once.

Only callable by the Service.

Note: Solidity doesn’t yet allow passing arrays of structs as parameters to public methods, so we need to pass 3 separate arrays.

Settlements event

  • users – array of addresses of Users that were settled for.
  • settledAmounts – amount settled for each User. Will be less than the requested settlement amount in the case where there was insufficient balance.
  • newBalances – latest balance for each settled User in the users array
  • settlementStatusCodes – integer code representing settlement status
    • If the User doesn’t exist the User’s corresponding settlementStatusCode will be 1.
    • If the User does not have a sufficient balance settlementStatusCode will be 2.
    • If the transaction settlement number does not match settlementStatusCode will be 1.
    • If the signature is invalid the settlementStatusCode will be 1.

addUsers function

  • users – array of addresses
  • balances – array of initial user balances
This function adds the users in the users array and sets their balance to the balance in the balances array. This method can also be used to update existing User’s balances. If the user already exists in the MicropaymentSettlement users mapping, the balance in the balances parameter is added to the existing balance.

Only callable by the Provider.

getUsers function

Get the users and their balances. Only callable by the Provider or the Service.

setSettlementFee function

Set the settlement fee. Only callable by the Provider.

setService function

Set the Service. Only callable by the Provider.

 

Further Ideas

The ideas listed here just cover the minimum viable product and many improvements are possible.
  • In a serious implementation we would want a smooth way for new users to register and make an initial deposit into their accounts, perhaps utilizing existing common online payment systems.
  • We could further increase the flexibility of the micropayments system by processing Ethereum ERC20 Tokens instead of wei.
  • Allow users to cancel and withdraw their remaining deposit. This could be achieved quite simply by removing the User from the users map and returning the remaining balance to the User.
  • We could store the settlement number in MicropaymentSettlement separately for each User. This means we can have more flexibility with when and how we settle, delaying settlement for some Users while settling others.
 

Summary

Performing individual micropayment processing off-chain then consolidating many micropayments into one blockchain settlement transaction the cost of the blockchain transaction can be spread across the micropayments.

The ideas here outline the possibility of performing off-chain micropayments between Users and a Service. Providers ensure settlements are tracked that Users only settle once per bulk settlement. Implementation of the micropayment transaction process is left up to the Service allowing freedom for different types of Services whether HTTP based or IoT using some other protocol. Tracking of User deposit balances between settlements is also left up to the Service.

Users are required to make in initial deposit for use of a Service. This could be combined with the deposit required for the Alternative Payment system in GMO Blockchain.

Many ideas for off-chain micropayments exist utilizing payment channels,  such as Lightning for bitcoin and Raiden for Ethereum. These payment channels are two-way allowing payment in both directions. Two way channels are not required for Service – User micropayments. This proposal describes a less complex solution with a lower barrier to use.