A skeleton-logic proposal for another economic model of grant

When Ursula joins, she commits a sequence of hidden lottery numbers.

Alice creates KFrags, a TreasureMap, and a lottery punch. Gives the map and punch to Bob.

Alice proposes Arrangement, providing unsigned (and thus not yet valid) lottery ticket

Ursula checks contract to see how much funding Alice has for that ticket

Ursula says sure

Alice gives Ursula KFrag and signs lottery ticket

Bob seeks retrieval:

  • Gives Ursula WorkOrder consisting of hash of Capsules + punch-holes

  • Ursula responds by signing WorkOrder and saying “ready”

  • Bob sends clear Capsules and punch-holes

  • Ursula sends signed CFrags

Every block, every punch hole has a 1/1000 chance of winning for Ursula’s hidden numbers. If it’s a winner, Ursula reveals and receives the money from the contract.

This is a really interesting idea, and also stimulates some broader thoughts about our payment channel(s) and fee structure. I’ve argued previously that compensating Ursulas (= workers, stakers, nodes, proxies) based on only one of a. policy duration or b. re-encryption requests, leads to various problems – see https://github.com/nucypher/mint-paper/issues/7. In short, there is a risk of abuse if Alice and Bob are separate end-users with distinct, discretionary economic motives, and there isn’t a prevailing application layer channeling funds between users. Moreover:

  1. If Ursula is only paid when re-encrypting (or some % of them), but Bob issues very few or no requests over the course of the policy duration, then they will spend resources (the vast majority of overheads, in fact) maintaining an available policy/state, but receive little or no compensation.
  2. If Ursula is only paid for holding a policy, then this doesn’t help address the uptime problem. The infrequency with which an Alice would pay for a 3 or 6 or 12 month policy also makes probabilistic micropayments unnecessary and unsuitable.

Therefore a hybrid approach, where Alice pays once for the persistence of the policy, and Bob probabilistically pays for each re-encryption, might be a happy medium.

In this flow, Ursula accepts an Arrangement based on the (standardised) cost of being online for the policy’s duration, which is entirely covered by Alice’s deposit up front.

Later, Bob pings Ursula. Ursula checks he has sufficient funds (see verification point below), then commits to some random numbers. The rest of the process mirrors jMyles’s proposal above. This disentangles Bob from Alice, where he is no longer restricted by the ‘punch’ bestowed to him, and can request re-encryptions as many times as he is willing to pay for (and collateralise).

Some general points about probabilistic micropayments applied to the NuCypher network, regardless of the viability of this counter-proposal:

  • Ursula needs the ability to verify that the payer (whether its Alice or Bob) has enough funds to cover the situation in which ALL of the winning tickets are redeemed – i.e. for all their current policies or requests, and for all n Ursulas with whom there is presently a commercial relationship.
  • The risk remains of Ursula receiving the capsule and random numbers, withholding the CFrag, and proceeding to claim payouts. I have some thoughts on this, will summarise in another post.
  • In terms of sourcing randomness, why not use something akin to LivePeer’s approach:

Winning tickets are selected based a random value produced by hashing the payer’s random number with the payee’s secret random number.

1 Like

Let’s define a protocol. How about this.
We have Bob, and we have someone who pays (could be Alice, or Bob, or some third party - let’s call him Patrick). The protocol looks like the following:

  • Patrick escrows in some money;
  • Patrick makes a ticket pack where he defines a range of counters for Bob (ctr_min and ctr_max) and signs: s_p = patrick.sign(hash(ctr_min | ctr_max | pubkey_ursula | pubkey_bob), and the preticket is t_0 = s_p, ctr_min, ctr_max, pubkey_bob;
  • Bob gets t_0 and verifies that Patrick’s account in an escrow (where Ethereum address is derived from Patrick’s pubkey) has money locked for some time;
  • When Bob pays, he produces t_1 = t_0, ctr, bob.sign(t_0 | ctr) and gives to Ursula;
  • Ursula checks that Bob is indeed allowed to pay with this ticket pack (e.g. Patrick signed t_0) and that Bob signed t_1. Then, Ursula produces what is actually a ticket number: t_2 = t_1, ursula.sign(t_1). If remainder of dividing hash(t_2) by p, where p is how rare the lucky tickets are is 0, it means that Ursula won. She show this t_2 to an escrow and claim her reward;
  • If she didn’t win - too bad for her!
  • The smart contract tracks the claimed hashes, so that the same prize cannot be claimed twice.

In this protocol, no one knows, what hash Ursula will get (except for Ursula) before she actually calculates and broadcasts it. Neither can anyone guess, what Bob will produce (because no one can forge his signature). True randomness isn’t required.

Patrick makes tickets for Bob and for specific Ursulas (so that Bob can spend tickets only for the n Ursulas).

Does it work, or am I missing something?

Two things:

  • Perhaps s_p needs also a nonce, to avoid any kind of replay attack.
  • Unless we use deterministic signatures, Ursula can sign t_1 multiple times until she finds a t_2 that is a winner ticket.