# SEP201: Simple Stochastic Payment

This SEP proposes a simple interface standard to perform stochastic payment on smartBCH.

Stochastic payment can support transfers of extremely small value.

Suppose Alice provides a kind of service and every time she serves Bob, Bob should pay 0.001 USD to her. Since 0.001 USD is a very small value, the miner fee (or gas fee) on most blockchains are much higher than it. Of course Bob is not willing to pay her 0.001 USD service fee while paying the network 0.1 USD as miner fee.

So, Alice and Bob agreed to gamble on the payment. At each payment, Alice has 0.1% probability to get 1 USD from Bob. If they perform the payment many times, then averagely Bob pays 0.1 USD to Alice in one single time of payment.

Unlike pre-payment or post-payment, stochastic payment is trustless. So it has its unique value in many use cases.

A standard interface allows wallets and service provides interact smoothly.

This SEP is under draft.

A smart contract acts as the agent for stochastic payment. It's interface is specified here.

**NOTES**:

- The following specifications use syntax from Solidity
**0.8.9**(or above)

**5.1.1.1 pay**

Before the payer and the payee start the payment. They prepare two 248-bit random number

`payerSalt`

and `payeeSalt`

seperately and then keep them as secrets.When they agree to start the payment, the payee transfers

`payeeSaltHash`

(the keccak256 hash of `payeeSalt`

) and her address `payeeAddr`

, to the payer. And they negotiate to decide the following parameters:- 1.
`dueTime`

: a 64-bit timestamp, after which time this payment cannot take effect on chain - 2.
`sep20Contract`

: the address of the SEP20 token, which is used in this payment - 3.
`amount`

how many coins the payee may possibly get. It must be less than`2**96`

. - 4.
`prob`

a 32-bit integer.`prob/(2**32)`

is the probability that payee get the`amount`

coins

Then the payer queries

`payerAllowance`

, his allowance of the SEP20 token to the stochastic payment agent contract, before he signs the following parameters using the EIP712 standard:- 1.
`payerSalt`

- 2.
`payeeSaltHash`

- 3.
`payeeAddr_dueTime64_prob32`

: concatenation of`payeeAddr`

(bit 255-96),`dueTime64`

(bit 95-32)`prob32`

(bit 31-0). - 4.
`payerAllowance`

- 5.
`sep20Contract_amount`

: concatenation of`sep20Contract`

(bit 255-96),`amount`

(bit 95-0).

The signature generated by him contains three parts: 256-bit

`r`

, 256-bit `s`

and 8-bit `v`

. All the above parameters and this signature are sent to the payee, who must provide the service to the payer and may call the stochastic agent contract's `pay`

function with following arguments:function pay(uint256 payeeSalt_v,

uint256 payerSalt,

bytes32 payeeSaltHash,

uint256 payeeAddr_dueTime64_prob32,

uint256 payerAllowance,

uint256 sep20Contract_amount,

bytes32 r, bytes32 s) external;

The argument

`payeeSalt_v`

is the concatenation of `payeeSalt`

(bit 255-8) and `v`

(bit 7-0). The other arguments' meaning has been described above.The payment agent recovers the payer's address from the signature and then transfer

`amount`

tokens from payer to payee if and only if the following expression holds:uint32(uint(keccak256(abi.encodePacked(payerSalt+(payeeSalt_v>>8))))) < uint32(payeeAddr_dueTime64_prob32)

This boolean expression's value depends on both

`payerSalt`

and `payeeSalt`

, so no single party can control it. And because the payer never knows `payeeSalt`

, he does not know the result beforehand. The payee knows every argument and infer the result before her sending transaction to call the agent contract: if the result is "not paying", she never broadcasts the transaction, which is meaningless.The payment agent must check whether the argument

`payerAllowance`

exactly equals the payer's current allowance to the agent. If it is not, the payment must fail. Once the payee get paid, the payer's allowance to the agent is deducted. Thus the payee cannot call the agent again with the same argument to get the coins again.The payer can cancel his allowance to the payment agent at any time by setting the allowance to zero. When he wants to approve allowance to the agent again, the allowance value must be set as

`block.number << 192`

, where `block.number`

is the latest block height. Using this method, the his allowance value to the agent will never have duplicated values, since the maximum amount paid in each time is less than `2**96`

.