taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

046-mumimo-contracts.rst (26721B)


      1 DD 46: Contract Format v1
      2 #########################
      3 
      4 Summary
      5 =======
      6 
      7 The contract v1 format enables a multitude of advanced interactions between
      8 merchants and wallets, including donations, subscriptions, coupons, currency
      9 exchange and more.
     10 
     11 Motivation
     12 ==========
     13 
     14 The existing v0 contract format is too simplistic to
     15 support many frequenly requested types of contracts.
     16 
     17 Requirements
     18 ============
     19 
     20 We want Taler to support various interesting use-cases:
     21 
     22   - Unlinkable, uncopyable subscriptions without accounts (reader can pay with
     23     Taler to subscribe to online publication, read unlimited number of
     24     articles during a certain period, transfer subscription to other devices,
     25     maintain unlinkability / full anonymity amongst all anonymous
     26     subscribers).
     27 
     28   - Coupons, discounts and stamps -- like receiving a discount on a product,
     29     product basket or subscription -- based on previous purchase(s). Again,
     30     with unlinkability and anonymity (modulo there being other users eligible
     31     for the discount).
     32 
     33   - Subscription tokens lost (due to loss of device without backup) should
     34     be recoverable from any previous backup of the subscription.
     35 
     36   - Currency conversion, that is exchanging one currency for another.
     37 
     38   - Donations, including privacy-preserving tax receipts that prove that the
     39     user donated to an entity that is eligible for tax-deductions but without
     40     revealing which entity the user donated to. At the same time, the entity
     41     issuing the tax receipt must be transparent (to the state) with respect to
     42     the amount of tax-deductable donations it has received.
     43 
     44   - Throttled political donations where each individual is only allowed to
     45     donate anonymously up to a certain amount per year or election cycle.
     46 
     47   - Unlinkable gifts -- enabling the purchase of digital goods (such as
     48     articles, albums, etc.) to be consumed by a third party. For example, a
     49     newspaper subscription may include a fixed number of articles that can be
     50     gifted to others each week, all while maintaining unlinkability and
     51     anonymity between the giver and the recipient.
     52 
     53   - Temporally-constrained, unlinkable event ticketing. Allowing visitors to
     54     use Taler to purchase a ticket for an event. This ticket grants entry and
     55     exit privileges to the event location during a specified time window, while
     56     preserving the anonymity of the ticket holder (within the group of all the
     57     ticket holders).
     58 
     59   - Event deposit systems. A deposit mechanism for events where customers
     60     receive a token alongside their cup or plate, which they are expected to
     61     return. This system validates that the cup or plate was legitimately
     62     acquired (i.e., not brought from home or stolen from a stack of dirty items)
     63     and incentivizes return after use.
     64 
     65 
     66 Proposed Solution
     67 =================
     68 
     69 Merchants will also blindly sign tokens (not coins) to indicate the
     70 eligibility of a user for certain special offers. Contracts will be modified
     71 to allow requiring multiple inputs (to be *provisioned* to the merchant) and
     72 multiple outputs (to be *yielded* by the merchant).  The wallet will then allow
     73 the user to select between the choices that the user could pay for, or possibly
     74 make an automatic choice if the correct choice is obvious. One output option is
     75 blindly signed coins from another exchange, possibly in a different currency.
     76 Another output option is blindly signed donation receipts from a DONation
     77 AUthority (DONAU). Subscriptions can be modeled by requiring the wallet to
     78 provision a token of the same type that is also yielded by the contract. For
     79 security, payments using subscription tokens (and possibly certain other special
     80 tokens?) will be limited to a list of domains explicitly defined as trusted by
     81 the token issuer.  When paying for a contract, the wallet must additionally sign
     82 over the selected sub-contract index and a hash committing it to the blinded
     83 envelopes (if any).  The merchant backend will (probably?) need to be changed
     84 to truly support multiple currencies (ugh).
     85 
     86 .. _contract-terms-v1:
     87 
     88 New Contract Terms Format
     89 -------------------------
     90 
     91 The contract terms v1 will have the following structure:
     92 
     93 .. ts:def:: DDContractTermsV1
     94 
     95   interface DDContractTermsV1 {
     96     // This is version 1, the previous contract terms SHOULD
     97     // be indicated using "0", but in v0 specifying the version
     98     // is optional.
     99     version: 1;
    100 
    101     // Unique, free-form identifier for the proposal.
    102     // Must be unique within a merchant instance.
    103     // For merchants that do not store proposals in their DB
    104     // before the customer paid for them, the ``order_id`` can be used
    105     // by the frontend to restore a proposal from the information
    106     // encoded in it (such as a short product identifier and timestamp).
    107     order_id: string;
    108 
    109     // URL where the same contract could be ordered again (if
    110     // available). Returned also at the public order endpoint
    111     // for people other than the actual buyer (hence public,
    112     // in case order IDs are guessable).
    113     public_reorder_url?: string;
    114 
    115     // Time when this contract was generated.
    116     timestamp: Timestamp;
    117 
    118     // After this deadline, the merchant won't accept payments for the contract.
    119     pay_deadline: Timestamp;
    120 
    121     // Transfer deadline for the exchange.  Must be in the
    122     // deposit permissions of coins used to pay for this order.
    123     wire_transfer_deadline: Timestamp;
    124 
    125     // Merchant's public key used to sign this proposal; this information
    126     // is typically added by the backend. Note that this can be an ephemeral key.
    127     merchant_pub: EddsaPublicKey;
    128 
    129     // Base URL of the (public!) merchant backend API.
    130     // Must be an absolute URL that ends with a slash.
    131     merchant_base_url: string;
    132 
    133     // More info about the merchant (same as in v0).
    134     merchant: Merchant;
    135 
    136     // Human-readable description of the contract.
    137     summary: string;
    138 
    139     // Map from IETF BCP 47 language tags to localized summaries.
    140     summary_i18n?: { [lang_tag: string]: string };
    141 
    142     // URL that will show that the order was successful after
    143     // it has been paid for.  Optional. When POSTing to the
    144     // merchant, the placeholder "${ORDER_ID}" will be
    145     // replaced with the actual order ID (useful if the
    146     // order ID is generated server-side and needs to be
    147     // in the URL).
    148     // Note that this placeholder can only be used once.
    149     // Either fulfillment_url or fulfillment_message must be specified.
    150     fulfillment_url?: string;
    151 
    152     // Message shown to the customer after paying for the order.
    153     // Either fulfillment_url or fulfillment_message must be specified.
    154     fulfillment_message?: string;
    155 
    156     // Map from IETF BCP 47 language tags to localized fulfillment
    157     // messages.
    158     fulfillment_message_i18n?: { [lang_tag: string]: string };
    159 
    160     // List of products that are part of the purchase (see `Product`).
    161     products: Product[];
    162 
    163     // After this deadline has passed, no refunds will be accepted.
    164     refund_deadline: Timestamp;
    165 
    166     // Specifies for how long the wallet should try to get an
    167     // automatic refund for the purchase. If this field is
    168     // present, the wallet should wait for a few seconds after
    169     // the purchase and then automatically attempt to obtain
    170     // a refund.  The wallet should probe until "delay"
    171     // after the payment was successful (i.e. via long polling
    172     // or via explicit requests with exponential back-off).
    173     //
    174     // In particular, if the wallet is offline
    175     // at that time, it MUST repeat the request until it gets
    176     // one response from the merchant after the delay has expired.
    177     // If the refund is granted, the wallet MUST automatically
    178     // recover the payment.  This is used in case a merchant
    179     // knows that it might be unable to satisfy the contract and
    180     // desires for the wallet to attempt to get the refund without any
    181     // customer interaction.  Note that it is NOT an error if the
    182     // merchant does not grant a refund.
    183     auto_refund?: RelativeTime;
    184 
    185     // Delivery location for (all!) products (same as in v0).
    186     delivery_location?: Location;
    187 
    188     // Time indicating when the order should be delivered.
    189     // May be overwritten by individual products.
    190     delivery_date?: Timestamp;
    191 
    192     // Nonce generated by the wallet and echoed by the merchant
    193     // in this field when the proposal is generated.
    194     // Note: required in contract, absent in order!
    195     nonce: string;
    196 
    197     // Array of possible specific contracts the wallet/customer
    198     // may choose from by selecting the respective index when
    199     // signing the deposit confirmation.
    200     choices: DDContractChoice[];
    201 
    202     // Map from token family slugs to meta data about the
    203     // respective token family.
    204     token_families: { [token_family_slug: string]: ContractTokenFamily };
    205 
    206     // Extra data that is only interpreted by the merchant frontend.
    207     // Useful when the merchant needs to store extra information on a
    208     // contract without storing it separately in their database.
    209     extra?: any;
    210 
    211     // Exchanges that the merchant accepts for this currency.
    212     exchanges: Exchange[];
    213   }
    214 
    215 .. ts:def:: DDContractChoice
    216 
    217   interface DDContractChoice {
    218     // Price to be paid for this choice. Could be 0.
    219     // The price is in addition to other instruments,
    220     // such as rations and tokens.
    221     // The exchange will subtract deposit fees from that amount
    222     // before transferring it to the merchant.
    223     amount: Amount;
    224 
    225     // List of inputs the wallet must provision (all of them) to
    226     // satisfy the conditions for the contract.
    227     inputs: DDContractInput[];
    228 
    229     // List of outputs the merchant promises to yield (all of them)
    230     // once the contract is paid.
    231     outputs: DDContractOutput[];
    232 
    233     // Maximum total deposit fee accepted by the merchant for this contract.
    234     max_fee: Amount;
    235   }
    236 
    237 .. ts:def:: DDContractInput
    238 
    239   type DDContractInput =
    240     | DDContractInputRation
    241     | DDContractInputToken;
    242 
    243 .. ts:def:: DDContractInputRation
    244 
    245   interface DDContractInputRation {
    246     type: "coin";
    247 
    248     // Price to be paid for the transaction.
    249     price: Amount;
    250 
    251     // FIXME-DOLD: do we want to move this into a 'details'
    252     // sub-structure as done with tokens below?
    253     class: "ration";
    254 
    255     // Base URL of the ration authority.
    256     ration_authority_url: string;
    257   };
    258 
    259 .. ts:def:: DDContractInputToken
    260 
    261   interface DDContractInputToken {
    262     type: "token";
    263 
    264     // Slug of the token family in the
    265     // 'token_families' map on the order.
    266     token_family_slug: string;
    267 
    268     // Start of the validity period of the token. This is used to find the
    269     // matching public key within the token family.
    270     valid_after: Timestamp;
    271 
    272     // Number of tokens of this type required.
    273     // Defaults to one if the field is not provided.
    274     number?: Integer;
    275   };
    276 
    277 .. ts:def:: DDContractOutput
    278 
    279   type DDContractOutput =
    280     | DDContractOutputCoin
    281     | DDContractOutputTaxReceipt
    282     | DDContractOutputToken;
    283 
    284 .. ts:def:: DDContractOutputCoin
    285 
    286   interface DDContractOutputCoin {
    287     type: "coins";
    288 
    289     // Amount of coins that will be yielded.
    290     // This excludes any applicable withdraw fees.
    291     brutto_yield: Amount;
    292 
    293     // Base URL of the exchange that will issue the
    294     // coins.
    295     exchange_url: string;
    296   };
    297 
    298 .. ts:def:: DDContractOutputTaxReceipt
    299 
    300   interface DDContractOutputTaxReceipt {
    301     type: "tax-receipt";
    302 
    303     // Base URL of the donation authority that will
    304     // issue the tax receipt.
    305     donau_url: string;
    306   };
    307 
    308 .. ts:def:: DDContractOutputToken
    309 
    310   interface DDContractOutputToken {
    311     type: "token";
    312 
    313     // Slug of the token family in the
    314     // 'token_families' map on the top-level.
    315     token_family_slug: string;
    316 
    317     // Start of the validity period of the token. This is used to find the
    318     // matching public key within the token family.
    319     valid_after: Timestamp;
    320 
    321     // Number of tokens to be issued.
    322     // Defaults to one if the field is not provided.
    323     number?: Integer;
    324   }
    325 
    326 .. ts:def:: DDContractTokenDetails
    327 
    328   type DDContractTokenDetails =
    329     | DDContractSubscriptionTokenDetails
    330     | DDContractDiscountTokenDetails
    331 
    332 .. ts:def:: DDContractSubscriptionTokenDetails
    333 
    334   interface DDContractSubscriptionTokenDetails {
    335     class: "subscription";
    336 
    337     // Array of domain names where this subscription
    338     // can be safely used (e.g. the issuer warrants that
    339     // these sites will re-issue tokens of this type
    340     // if the respective contract says so).  May contain
    341     // "*" for any domain or subdomain.
    342     trusted_domains: string[];
    343   };
    344 
    345 .. ts:def:: DDContractDiscountTokenDetails
    346 
    347   interface DDContractDiscountTokenDetails {
    348     class: "discount";
    349 
    350     // Array of domain names where this discount token
    351     // is intended to be used.  May contain "*" for any
    352     // domain or subdomain.  Users should be warned about
    353     // sites proposing to consume discount tokens of this
    354     // type that are not in this list that the merchant
    355     // is accepting a coupon from a competitor and thus
    356     // may be attaching different semantics (like get 20%
    357     // discount for my competitors 30% discount token).
    358     expected_domains: string[];
    359   };
    360 
    361 .. ts:def:: DDContractTokenFamily
    362 
    363   interface DDContractTokenFamily {
    364     // Human-readable name of the token family.
    365     name: string;
    366 
    367     // Human-readable description of the semantics of
    368     // this token family (for display).
    369     description: string;
    370 
    371     // Map from IETF BCP 47 language tags to localized descriptions.
    372     description_i18n?: { [lang_tag: string]: string };
    373 
    374     // Public keys used to validate tokens issued by this token family.
    375     keys: TokenIssuePublicKey[];
    376 
    377     // Class-specific information of the token
    378     details: ContractTokenDetails;
    379 
    380     // Must a wallet understand this token type to
    381     // process contracts that consume or yield it?
    382     critical: boolean;
    383 
    384     // Number of tokens issued according to ASS authority
    385     // FIXME: this is still rather speculative in the design...
    386     ass?: Integer;
    387 
    388     // Signature affirming sum of token issuance deposit (?) fees
    389     // collected by an exchange according to the ASS authority.
    390     // FIXME: this is still rather speculative in the design...
    391     ass_cost?: Amount;
    392 
    393     // Signature affirming the ass by the ASS authority.
    394     // FIXME: this is still rather speculative in the design...
    395     ass_sig?: EddsaSignature;
    396   };
    397 
    398 .. ts:def:: DDTokenIssuePublicKey
    399 
    400   type DDTokenIssuePublicKey =
    401     | DDTokenIssueRsaPublicKey
    402     | DDTokenIssueCsPublicKey;
    403 
    404 .. ts:def:: DDTokenIssueRsaPublicKey
    405 
    406   interface DDTokenIssueRsaPublicKey {
    407     cipher: "RSA";
    408 
    409     // RSA public key.
    410     rsa_pub: RsaPublicKey;
    411 
    412     // Start time of this key's validity period.
    413     valid_after: Timestamp;
    414 
    415     // End time of this key's validity period.
    416     valid_before: Timestamp;
    417   }
    418 
    419 .. ts:def:: DDTokenIssueCsPublicKey
    420 
    421   interface DDTokenIssueCsPublicKey {
    422     cipher: "CS";
    423 
    424     // CS public key.
    425     cs_pub: Cs25519Point;
    426 
    427     // Start time of this key's validity period.
    428     valid_after: Timestamp;
    429 
    430     // End time of this key's validity period.
    431     valid_before: Timestamp;
    432   }
    433 
    434 
    435 Alternative Contracts
    436 ---------------------
    437 
    438 The contract terms object may contain any number of alternative contracts that
    439 the user must choose between. The alternatives can differ by inputs, outputs
    440 or other details. The wallet must filter the contracts by those that the user
    441 can actually pay for, and move those that the user could currently not pay for
    442 to the end of the rendered list.  Similarly, the wallet must move up the
    443 cheaper contracts, so if a contract has a definitively lower price and
    444 consumes an available discount token, that contract should be moved up in the
    445 list.
    446 
    447 Which specific alternative contract was chosen by the user is indicated in the
    448 ``choice_index`` field of the :ref:`TALER_DepositRequestPS <taler_depositrequestps>`.
    449 
    450 
    451 Output Commitments
    452 ------------------
    453 
    454 When a contract has outputs, the wallet must send an array of blinded tokens,
    455 coins or tax receipts together with the payment request.  The order in the
    456 array must match the order in the outputs field of the contract.  For currency
    457 outputs, one array element must include all of the required planchets for a
    458 batch withdrawal, but of course not the reserve signature.
    459 
    460   .. note::
    461 
    462      We can probably spec this rather nicely if we first change the
    463      batch-withdraw API to only use a single reserve signature.
    464 
    465 This array of blinded values is hashed to create the output commitment hash
    466 (``h_outputs``) in the :ref:`TALER_DepositRequestPS <taler_depositrequestps>`.
    467 
    468 
    469 
    470 Subscriptions
    471 -------------
    472 
    473 The user buys a subscription (and possibly at the same time an article) using
    474 currency and the contract yields an additional subscription token as an
    475 output.  Active subscriptions are listed below the currencies in the wallet
    476 under a new heading.  Subscriptions are never auto-renewing, if the user wants
    477 to extend the subscription they can trivially pay for it with one click.
    478 
    479 When a contract consumes and yields exactly one subscription
    480 token of the same type in a trusted domain, the wallet may automatically
    481 approve the transaction without asking the user for confirmation (as it is free).
    482 
    483 The token expiration for a subscription can be past the "end date" to enable a
    484 previous subscription to be used to get a discount on renewing the
    485 subscription.  The wallet should show applicable contracts with a lower price
    486 that only additionally consume subscription tokens after their end date before
    487 higher-priced alternative offers.
    488 
    489 Subscription tokens are "critical" in that a wallet implementation must
    490 understand them before allowing a user to interact with this class of token.
    491 Subscription token secrets should be derived from a master secret associated
    492 with the subscription, so that the private keys are recoverable from backup.
    493 To obtain the blind signatures, a merchant must offer an endpoint where
    494 one can submit the public key of the N-1 subscription token and obtain the
    495 blinded signature over the N-th subscription token.  The wallet can then
    496 effectively recover the subscription from backup using a binary search.
    497 
    498 The merchant SPA should allow the administrator to create (maybe update) and
    499 delete subscriptions. Each subscription is identified by a subscription
    500 label and includes a validity period.
    501 
    502 The merchant backend must then automatically manage (create, use, delete) the
    503 respective signing keys.  When creating an order, the frontend can just refer
    504 to the subscription label (and possibly a start date) in the inputs or
    505 outputs. The backend should then automatically substitute this with the
    506 respective cryptographic fields for the respective time period and
    507 subscription label.
    508 
    509 
    510 
    511 
    512 Discounts
    513 ---------
    514 
    515 To offer a discount based on one or more previous purchases, a merchant must
    516 yield some discount-specific token as an output with the previous purchase,
    517 and then offer an alternative contract with a lower price that consumes currency
    518 and the discount token.  The wallet should show contracts with a lower price that
    519 only additionally consume discount tokens
    520 
    521 The merchant SPA should allow the administrator to create (maybe update) and
    522 delete discount tokens. Each discount token is identified by a discount
    523 label and includes an expiration time or validity duration.
    524 
    525 The merchant backend must then automatically manage (create, use, delete) the
    526 respective signing keys.  When creating an order, the frontend can just refer
    527 to the discount token label in the inputs or outputs. The backend should then
    528 automatically substitute this with the respective cryptographic fields for the
    529 respective discount token.
    530 
    531 
    532 Donation Authority
    533 ------------------
    534 
    535 A donation authority (DONAU) implements a service that is expected to be run
    536 by a government authority that determines eligibility for tax deduction.  A
    537 DONAU blindly signs tax receipts using a protocol very close to that of the
    538 Taler exchange's withdraw protocol, except that the reserves are not filled
    539 via wire transfers but instead represent accounts of the organizations
    540 eligible to issue tax deduction receipts. These accounts are basically
    541 expected to have only negative balances, but the DONAU can set a negative
    542 balance threshold per organization to limit the creation of tax deduction
    543 receipts to a plausible amount. DONAU administrators are expected to be
    544 able to add, update or remove these accounts using a SPA. Tax receipts are
    545 blindly signed by keys that always have a usage period of one calendar year.
    546 
    547 A stand-alone app for tax authorities can scan QR codes representing DONAU
    548 signatures to validate that a given tax payer has donated a certain amount.
    549 As RSA signatures are typically very large and a single donation may require
    550 multiple blind signatures, CS blind signatures must also be supported.  To
    551 avoid encoding the public keys, QR codes with tax receipts should reference
    552 the DONAU, the year and the amount, but not the specific public key.  A
    553 single donation may nevertheless be rendered using multiple QR codes.
    554 
    555 Revocations, refresh, deposits, age-restrictions and other exchange features
    556 are not applicable for a DONAU.
    557 
    558 The merchant SPA should allow the administrator to manage DONAU accounts in
    559 the merchant backend. Each DONAU account includes a base URL and a private
    560 signing key for signing the requests to the DONAU on behalf of the eligible
    561 organization.
    562 
    563 When creating an order, the frontend must specify a configured DONAU base URL
    564 in the outputs. The backend should then automatically interact with the DONAU
    565 when the wallet supplies the payment request with the blinded tax receipts.
    566 The DONAU interaction must only happen after the exchange confirmed that the
    567 contract was successfully paid.  A partial error must be returned if the
    568 exchange interaction was successful but the DONAU interaction failed. In this
    569 case, the fulfillment action should still be triggered, but the wallet should
    570 display a warning that the donation receipt could not be obtained. The wallet
    571 should then re-try the payment (in the background with an exponential
    572 back-off) to possibly obtain the tax receipt at a later time.
    573 
    574 
    575 Tax Receipts
    576 ------------
    577 
    578 Tax receipts differ from coins and tokens in that what is blindly signed over
    579 should be the taxpayer identification number of the tax payer.  The format of
    580 the taxpayer identification number should simply be a string, with the rest
    581 being defined by the national authority. The DONAU should indicate in its
    582 ``/config`` response what format this string should have, using possibly both
    583 an Anastasis-style regex and an Anastasis-style function name (to check things
    584 like checksums that cannot be validated using a regex).  Wallets must then
    585 validate the regex (if given) and if possible should implement the
    586 Anastasis-style logic.
    587 
    588 Wallets should collect tax receipts by year and offer an
    589 export functionality.  The export should generate either
    590 
    591     (a) a JSON file,
    592     (b) a PDF (with QR codes), or
    593     (c) a series of screens with QR codes.
    594 
    595 Wallets may only implement some of the above options due to resource
    596 constraints.
    597 
    598 The documents should encode the taxpayer ID, the amount and the DONAU
    599 signature (including the year, excluding the exact public key as there should
    600 only be one possible).
    601 
    602 
    603 Rationing (future work)
    604 -----------------------
    605 
    606 If per-capita rationing must be imposed on certain transactions, a rationing
    607 authority (RA) must exist that identifies each eligible human and issues that
    608 human a number of ration coins for the respective rationing period.  An RA
    609 largely functions like a regular exchange, except that eligible humans will
    610 need to authenticate directly to withdraw rations (instead of transferring
    611 fiat to an exchange).  Merchants selling rationed goods will be (legally)
    612 required to collect deposit confirmations in proportion to the amount of
    613 rationed goods sold.  A difference to regular exchanges is that RAs do not
    614 charge any fees.  RAs may or may not allow refreshing rations that are about
    615 to expire for ration coins in the next period.
    616 
    617 Once an RA is added to a wallet, it should automatically try to withdraw the
    618 maximum amount of ration coins it is eligible for. Available rations should be
    619 shown below the subscriptions by RA (if any).
    620 
    621   ..note::
    622 
    623     RAs are considered an idea for future work and not part of our current timeline.
    624 
    625 
    626 Limited Donations per Capita (future work)
    627 ------------------------------------------
    628 
    629 If per-capita limitations must be imposed on anonymous donations (for example
    630 for donations to political parties), an RA can be used to issue donation
    631 rations that limit the amount of donations that can be made for the respective
    632 period.
    633 
    634   ..note::
    635 
    636     RAs are considered an idea for future work and not part of our current timeline.
    637 
    638 
    639 
    640 Definition of Done
    641 ==================
    642 
    643   - Merchant backend support for multiple currencies
    644   - Merchant backend support for consuming and issuing tokens
    645   - Merchant SPA support for configuring new tokens of different types
    646   - Wallet-core support for various new contract types
    647   - Wallet-core filters for feasible contracts and possibly auto-executes subscriptions
    648   - Wallet-GUIs (WebEx, Android, iOS) render new contract types
    649   - Wallet-GUIs (WebEx, Android, iOS) allow user to select between multiple contracts
    650   - Documentation for developers is up-to-date
    651   - Token anonymity set size (ASS) authority implemented, documented
    652   - Merchants report anonymity set size increases to ASS authority
    653   - Wallets process anonymity set size reports from ASS authority
    654   - Bachelor thesis written on applications and design
    655   - Academic paper written on DONAU (requirements, design, implementation)
    656   - DONAU implemented, documented
    657   - DONAU receipt validation application implemented
    658   - Integration tests exist in wallet-core
    659   - Deliverables accepted by EC
    660 
    661 While rationing is part of the design, we expect the actual implementation to
    662 be done much later and thus should not consider it part of the "DONE" part.
    663 Rationing is complex, especially as a refunded contract should probably also
    664 refund the ration.
    665 
    666 
    667 Alternatives
    668 ============
    669 
    670 The first draft of this DD included the capability of paying with multiple
    671 currencies for the same contract (for example, USD:1 and EUR:5) plus tokens
    672 and rations. However, this is very complex, both for wallets (how to display),
    673 for other merchant APIs (does the refund API have to become multi-currency as
    674 well?) and there does not seem to be a good business case for it. So for now,
    675 the price is always only in one currency.
    676 
    677 
    678 Drawbacks
    679 =========
    680 
    681 Significant change, but actually good ratio compared to use-cases covered.
    682 
    683 
    684 Discussion / Q&A
    685 ================
    686 
    687 (This should be filled in with results from discussions on mailing lists / personal communication.)