taler-docs

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

046-mumimo-contracts.rst (26908B)


      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: Slug;
    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?: WebURL;
    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: WebURL;
    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     // Because of that placeholder, the value given here is merely a
    150     // string and not yet a `WebURL`; only after the substitution has
    151     // been performed is the result a `WebURL`.
    152     // Either fulfillment_url or fulfillment_message must be specified.
    153     fulfillment_url?: string;
    154 
    155     // Message shown to the customer after paying for the order.
    156     // Either fulfillment_url or fulfillment_message must be specified.
    157     fulfillment_message?: string;
    158 
    159     // Map from IETF BCP 47 language tags to localized fulfillment
    160     // messages.
    161     fulfillment_message_i18n?: { [lang_tag: string]: string };
    162 
    163     // List of products that are part of the purchase (see `ProductSold`).
    164     products: ProductSold[];
    165 
    166     // After this deadline has passed, no refunds will be accepted.
    167     refund_deadline: Timestamp;
    168 
    169     // Specifies for how long the wallet should try to get an
    170     // automatic refund for the purchase. If this field is
    171     // present, the wallet should wait for a few seconds after
    172     // the purchase and then automatically attempt to obtain
    173     // a refund.  The wallet should probe until "delay"
    174     // after the payment was successful (i.e. via long polling
    175     // or via explicit requests with exponential back-off).
    176     //
    177     // In particular, if the wallet is offline
    178     // at that time, it MUST repeat the request until it gets
    179     // one response from the merchant after the delay has expired.
    180     // If the refund is granted, the wallet MUST automatically
    181     // recover the payment.  This is used in case a merchant
    182     // knows that it might be unable to satisfy the contract and
    183     // desires for the wallet to attempt to get the refund without any
    184     // customer interaction.  Note that it is NOT an error if the
    185     // merchant does not grant a refund.
    186     auto_refund?: RelativeTime;
    187 
    188     // Delivery location for (all!) products (same as in v0).
    189     delivery_location?: Location;
    190 
    191     // Time indicating when the order should be delivered.
    192     // May be overwritten by individual products.
    193     delivery_date?: Timestamp;
    194 
    195     // Nonce generated by the wallet and echoed by the merchant
    196     // in this field when the proposal is generated.
    197     // Note: required in contract, absent in order!
    198     nonce: string;
    199 
    200     // Array of possible specific contracts the wallet/customer
    201     // may choose from by selecting the respective index when
    202     // signing the deposit confirmation.
    203     choices: DDContractChoice[];
    204 
    205     // Map from token family slugs to meta data about the
    206     // respective token family.
    207     token_families: { [token_family_slug: Slug]: ContractTokenFamily };
    208 
    209     // Extra data that is only interpreted by the merchant frontend.
    210     // Useful when the merchant needs to store extra information on a
    211     // contract without storing it separately in their database.
    212     extra?: any;
    213 
    214     // Exchanges that the merchant accepts for this currency.
    215     exchanges: Exchange[];
    216   }
    217 
    218 .. ts:def:: DDContractChoice
    219 
    220   interface DDContractChoice {
    221     // Price to be paid for this choice. Could be 0.
    222     // The price is in addition to other instruments,
    223     // such as rations and tokens.
    224     // The exchange will subtract deposit fees from that amount
    225     // before transferring it to the merchant.
    226     amount: Amount;
    227 
    228     // List of inputs the wallet must provision (all of them) to
    229     // satisfy the conditions for the contract.
    230     inputs: DDContractInput[];
    231 
    232     // List of outputs the merchant promises to yield (all of them)
    233     // once the contract is paid.
    234     outputs: DDContractOutput[];
    235 
    236     // Maximum total deposit fee accepted by the merchant for this contract.
    237     max_fee: Amount;
    238   }
    239 
    240 .. ts:def:: DDContractInput
    241 
    242   type DDContractInput =
    243     | DDContractInputRation
    244     | DDContractInputToken;
    245 
    246 .. ts:def:: DDContractInputRation
    247 
    248   interface DDContractInputRation {
    249     type: "coin";
    250 
    251     // Price to be paid for the transaction.
    252     price: Amount;
    253 
    254     // FIXME-DOLD: do we want to move this into a 'details'
    255     // sub-structure as done with tokens below?
    256     class: "ration";
    257 
    258     // Base URL of the ration authority.
    259     ration_authority_url: WebURL;
    260   };
    261 
    262 .. ts:def:: DDContractInputToken
    263 
    264   interface DDContractInputToken {
    265     type: "token";
    266 
    267     // Slug of the token family in the
    268     // 'token_families' map on the order.
    269     token_family_slug: Slug;
    270 
    271     // Start of the validity period of the token. This is used to find the
    272     // matching public key within the token family.
    273     valid_after: Timestamp;
    274 
    275     // Number of tokens of this type required.
    276     // Defaults to one if the field is not provided.
    277     number?: Integer;
    278   };
    279 
    280 .. ts:def:: DDContractOutput
    281 
    282   type DDContractOutput =
    283     | DDContractOutputCoin
    284     | DDContractOutputTaxReceipt
    285     | DDContractOutputToken;
    286 
    287 .. ts:def:: DDContractOutputCoin
    288 
    289   interface DDContractOutputCoin {
    290     type: "coins";
    291 
    292     // Amount of coins that will be yielded.
    293     // This excludes any applicable withdraw fees.
    294     brutto_yield: Amount;
    295 
    296     // Base URL of the exchange that will issue the
    297     // coins.
    298     exchange_url: WebURL;
    299   };
    300 
    301 .. ts:def:: DDContractOutputTaxReceipt
    302 
    303   interface DDContractOutputTaxReceipt {
    304     type: "tax-receipt";
    305 
    306     // Base URL of the donation authority that will
    307     // issue the tax receipt.
    308     donau_url: WebURL;
    309   };
    310 
    311 .. ts:def:: DDContractOutputToken
    312 
    313   interface DDContractOutputToken {
    314     type: "token";
    315 
    316     // Slug of the token family in the
    317     // 'token_families' map on the top-level.
    318     token_family_slug: Slug;
    319 
    320     // Start of the validity period of the token. This is used to find the
    321     // matching public key within the token family.
    322     valid_after: Timestamp;
    323 
    324     // Number of tokens to be issued.
    325     // Defaults to one if the field is not provided.
    326     number?: Integer;
    327   }
    328 
    329 .. ts:def:: DDContractTokenDetails
    330 
    331   type DDContractTokenDetails =
    332     | DDContractSubscriptionTokenDetails
    333     | DDContractDiscountTokenDetails
    334 
    335 .. ts:def:: DDContractSubscriptionTokenDetails
    336 
    337   interface DDContractSubscriptionTokenDetails {
    338     class: "subscription";
    339 
    340     // Array of domain names where this subscription
    341     // can be safely used (e.g. the issuer warrants that
    342     // these sites will re-issue tokens of this type
    343     // if the respective contract says so).  May contain
    344     // "*" for any domain or subdomain.
    345     trusted_domains: string[];
    346   };
    347 
    348 .. ts:def:: DDContractDiscountTokenDetails
    349 
    350   interface DDContractDiscountTokenDetails {
    351     class: "discount";
    352 
    353     // Array of domain names where this discount token
    354     // is intended to be used.  May contain "*" for any
    355     // domain or subdomain.  Users should be warned about
    356     // sites proposing to consume discount tokens of this
    357     // type that are not in this list that the merchant
    358     // is accepting a coupon from a competitor and thus
    359     // may be attaching different semantics (like get 20%
    360     // discount for my competitors 30% discount token).
    361     expected_domains: string[];
    362   };
    363 
    364 .. ts:def:: DDContractTokenFamily
    365 
    366   interface DDContractTokenFamily {
    367     // Human-readable name of the token family.
    368     name: string;
    369 
    370     // Human-readable description of the semantics of
    371     // this token family (for display).
    372     description: string;
    373 
    374     // Map from IETF BCP 47 language tags to localized descriptions.
    375     description_i18n?: { [lang_tag: string]: string };
    376 
    377     // Public keys used to validate tokens issued by this token family.
    378     keys: TokenIssuePublicKey[];
    379 
    380     // Class-specific information of the token
    381     details: ContractTokenDetails;
    382 
    383     // Must a wallet understand this token type to
    384     // process contracts that consume or yield it?
    385     critical: boolean;
    386 
    387     // Number of tokens issued according to ASS authority
    388     // FIXME: this is still rather speculative in the design...
    389     ass?: Integer;
    390 
    391     // Signature affirming sum of token issuance deposit (?) fees
    392     // collected by an exchange according to the ASS authority.
    393     // FIXME: this is still rather speculative in the design...
    394     ass_cost?: Amount;
    395 
    396     // Signature affirming the ass by the ASS authority.
    397     // FIXME: this is still rather speculative in the design...
    398     ass_sig?: EddsaSignature;
    399   };
    400 
    401 .. ts:def:: DDTokenIssuePublicKey
    402 
    403   type DDTokenIssuePublicKey =
    404     | DDTokenIssueRsaPublicKey
    405     | DDTokenIssueCsPublicKey;
    406 
    407 .. ts:def:: DDTokenIssueRsaPublicKey
    408 
    409   interface DDTokenIssueRsaPublicKey {
    410     cipher: "RSA";
    411 
    412     // RSA public key.
    413     rsa_pub: RsaPublicKey;
    414 
    415     // Start time of this key's validity period.
    416     valid_after: Timestamp;
    417 
    418     // End time of this key's validity period.
    419     valid_before: Timestamp;
    420   }
    421 
    422 .. ts:def:: DDTokenIssueCsPublicKey
    423 
    424   interface DDTokenIssueCsPublicKey {
    425     cipher: "CS";
    426 
    427     // CS public key.
    428     cs_pub: Cs25519Point;
    429 
    430     // Start time of this key's validity period.
    431     valid_after: Timestamp;
    432 
    433     // End time of this key's validity period.
    434     valid_before: Timestamp;
    435   }
    436 
    437 
    438 Alternative Contracts
    439 ---------------------
    440 
    441 The contract terms object may contain any number of alternative contracts that
    442 the user must choose between. The alternatives can differ by inputs, outputs
    443 or other details. The wallet must filter the contracts by those that the user
    444 can actually pay for, and move those that the user could currently not pay for
    445 to the end of the rendered list.  Similarly, the wallet must move up the
    446 cheaper contracts, so if a contract has a definitively lower price and
    447 consumes an available discount token, that contract should be moved up in the
    448 list.
    449 
    450 Which specific alternative contract was chosen by the user is indicated in the
    451 ``choice_index`` field of the :ref:`TALER_DepositRequestPS <taler_depositrequestps>`.
    452 
    453 
    454 Output Commitments
    455 ------------------
    456 
    457 When a contract has outputs, the wallet must send an array of blinded tokens,
    458 coins or tax receipts together with the payment request.  The order in the
    459 array must match the order in the outputs field of the contract.  For currency
    460 outputs, one array element must include all of the required planchets for a
    461 batch withdrawal, but of course not the reserve signature.
    462 
    463   .. note::
    464 
    465      We can probably spec this rather nicely if we first change the
    466      batch-withdraw API to only use a single reserve signature.
    467 
    468 This array of blinded values is hashed to create the output commitment hash
    469 (``h_outputs``) in the :ref:`TALER_DepositRequestPS <taler_depositrequestps>`.
    470 
    471 
    472 
    473 Subscriptions
    474 -------------
    475 
    476 The user buys a subscription (and possibly at the same time an article) using
    477 currency and the contract yields an additional subscription token as an
    478 output.  Active subscriptions are listed below the currencies in the wallet
    479 under a new heading.  Subscriptions are never auto-renewing, if the user wants
    480 to extend the subscription they can trivially pay for it with one click.
    481 
    482 When a contract consumes and yields exactly one subscription
    483 token of the same type in a trusted domain, the wallet may automatically
    484 approve the transaction without asking the user for confirmation (as it is free).
    485 
    486 The token expiration for a subscription can be past the "end date" to enable a
    487 previous subscription to be used to get a discount on renewing the
    488 subscription.  The wallet should show applicable contracts with a lower price
    489 that only additionally consume subscription tokens after their end date before
    490 higher-priced alternative offers.
    491 
    492 Subscription tokens are "critical" in that a wallet implementation must
    493 understand them before allowing a user to interact with this class of token.
    494 Subscription token secrets should be derived from a master secret associated
    495 with the subscription, so that the private keys are recoverable from backup.
    496 To obtain the blind signatures, a merchant must offer an endpoint where
    497 one can submit the public key of the N-1 subscription token and obtain the
    498 blinded signature over the N-th subscription token.  The wallet can then
    499 effectively recover the subscription from backup using a binary search.
    500 
    501 The merchant SPA should allow the administrator to create (maybe update) and
    502 delete subscriptions. Each subscription is identified by a subscription
    503 label and includes a validity period.
    504 
    505 The merchant backend must then automatically manage (create, use, delete) the
    506 respective signing keys.  When creating an order, the frontend can just refer
    507 to the subscription label (and possibly a start date) in the inputs or
    508 outputs. The backend should then automatically substitute this with the
    509 respective cryptographic fields for the respective time period and
    510 subscription label.
    511 
    512 
    513 
    514 
    515 Discounts
    516 ---------
    517 
    518 To offer a discount based on one or more previous purchases, a merchant must
    519 yield some discount-specific token as an output with the previous purchase,
    520 and then offer an alternative contract with a lower price that consumes currency
    521 and the discount token.  The wallet should show contracts with a lower price that
    522 only additionally consume discount tokens
    523 
    524 The merchant SPA should allow the administrator to create (maybe update) and
    525 delete discount tokens. Each discount token is identified by a discount
    526 label and includes an expiration time or validity duration.
    527 
    528 The merchant backend must then automatically manage (create, use, delete) the
    529 respective signing keys.  When creating an order, the frontend can just refer
    530 to the discount token label in the inputs or outputs. The backend should then
    531 automatically substitute this with the respective cryptographic fields for the
    532 respective discount token.
    533 
    534 
    535 Donation Authority
    536 ------------------
    537 
    538 A donation authority (DONAU) implements a service that is expected to be run
    539 by a government authority that determines eligibility for tax deduction.  A
    540 DONAU blindly signs tax receipts using a protocol very close to that of the
    541 Taler exchange's withdraw protocol, except that the reserves are not filled
    542 via wire transfers but instead represent accounts of the organizations
    543 eligible to issue tax deduction receipts. These accounts are basically
    544 expected to have only negative balances, but the DONAU can set a negative
    545 balance threshold per organization to limit the creation of tax deduction
    546 receipts to a plausible amount. DONAU administrators are expected to be
    547 able to add, update or remove these accounts using a SPA. Tax receipts are
    548 blindly signed by keys that always have a usage period of one calendar year.
    549 
    550 A stand-alone app for tax authorities can scan QR codes representing DONAU
    551 signatures to validate that a given tax payer has donated a certain amount.
    552 As RSA signatures are typically very large and a single donation may require
    553 multiple blind signatures, CS blind signatures must also be supported.  To
    554 avoid encoding the public keys, QR codes with tax receipts should reference
    555 the DONAU, the year and the amount, but not the specific public key.  A
    556 single donation may nevertheless be rendered using multiple QR codes.
    557 
    558 Revocations, refresh, deposits, age-restrictions and other exchange features
    559 are not applicable for a DONAU.
    560 
    561 The merchant SPA should allow the administrator to manage DONAU accounts in
    562 the merchant backend. Each DONAU account includes a base URL and a private
    563 signing key for signing the requests to the DONAU on behalf of the eligible
    564 organization.
    565 
    566 When creating an order, the frontend must specify a configured DONAU base URL
    567 in the outputs. The backend should then automatically interact with the DONAU
    568 when the wallet supplies the payment request with the blinded tax receipts.
    569 The DONAU interaction must only happen after the exchange confirmed that the
    570 contract was successfully paid.  A partial error must be returned if the
    571 exchange interaction was successful but the DONAU interaction failed. In this
    572 case, the fulfillment action should still be triggered, but the wallet should
    573 display a warning that the donation receipt could not be obtained. The wallet
    574 should then re-try the payment (in the background with an exponential
    575 back-off) to possibly obtain the tax receipt at a later time.
    576 
    577 
    578 Tax Receipts
    579 ------------
    580 
    581 Tax receipts differ from coins and tokens in that what is blindly signed over
    582 should be the taxpayer identification number of the tax payer.  The format of
    583 the taxpayer identification number should simply be a string, with the rest
    584 being defined by the national authority. The DONAU should indicate in its
    585 ``/config`` response what format this string should have, using possibly both
    586 an Anastasis-style regex and an Anastasis-style function name (to check things
    587 like checksums that cannot be validated using a regex).  Wallets must then
    588 validate the regex (if given) and if possible should implement the
    589 Anastasis-style logic.
    590 
    591 Wallets should collect tax receipts by year and offer an
    592 export functionality.  The export should generate either
    593 
    594     (a) a JSON file,
    595     (b) a PDF (with QR codes), or
    596     (c) a series of screens with QR codes.
    597 
    598 Wallets may only implement some of the above options due to resource
    599 constraints.
    600 
    601 The documents should encode the taxpayer ID, the amount and the DONAU
    602 signature (including the year, excluding the exact public key as there should
    603 only be one possible).
    604 
    605 
    606 Rationing (future work)
    607 -----------------------
    608 
    609 If per-capita rationing must be imposed on certain transactions, a rationing
    610 authority (RA) must exist that identifies each eligible human and issues that
    611 human a number of ration coins for the respective rationing period.  An RA
    612 largely functions like a regular exchange, except that eligible humans will
    613 need to authenticate directly to withdraw rations (instead of transferring
    614 fiat to an exchange).  Merchants selling rationed goods will be (legally)
    615 required to collect deposit confirmations in proportion to the amount of
    616 rationed goods sold.  A difference to regular exchanges is that RAs do not
    617 charge any fees.  RAs may or may not allow refreshing rations that are about
    618 to expire for ration coins in the next period.
    619 
    620 Once an RA is added to a wallet, it should automatically try to withdraw the
    621 maximum amount of ration coins it is eligible for. Available rations should be
    622 shown below the subscriptions by RA (if any).
    623 
    624   ..note::
    625 
    626     RAs are considered an idea for future work and not part of our current timeline.
    627 
    628 
    629 Limited Donations per Capita (future work)
    630 ------------------------------------------
    631 
    632 If per-capita limitations must be imposed on anonymous donations (for example
    633 for donations to political parties), an RA can be used to issue donation
    634 rations that limit the amount of donations that can be made for the respective
    635 period.
    636 
    637   ..note::
    638 
    639     RAs are considered an idea for future work and not part of our current timeline.
    640 
    641 
    642 
    643 Definition of Done
    644 ==================
    645 
    646   - Merchant backend support for multiple currencies
    647   - Merchant backend support for consuming and issuing tokens
    648   - Merchant SPA support for configuring new tokens of different types
    649   - Wallet-core support for various new contract types
    650   - Wallet-core filters for feasible contracts and possibly auto-executes subscriptions
    651   - Wallet-GUIs (WebEx, Android, iOS) render new contract types
    652   - Wallet-GUIs (WebEx, Android, iOS) allow user to select between multiple contracts
    653   - Documentation for developers is up-to-date
    654   - Token anonymity set size (ASS) authority implemented, documented
    655   - Merchants report anonymity set size increases to ASS authority
    656   - Wallets process anonymity set size reports from ASS authority
    657   - Bachelor thesis written on applications and design
    658   - Academic paper written on DONAU (requirements, design, implementation)
    659   - DONAU implemented, documented
    660   - DONAU receipt validation application implemented
    661   - Integration tests exist in wallet-core
    662   - Deliverables accepted by EC
    663 
    664 While rationing is part of the design, we expect the actual implementation to
    665 be done much later and thus should not consider it part of the "DONE" part.
    666 Rationing is complex, especially as a refunded contract should probably also
    667 refund the ration.
    668 
    669 
    670 Alternatives
    671 ============
    672 
    673 The first draft of this DD included the capability of paying with multiple
    674 currencies for the same contract (for example, USD:1 and EUR:5) plus tokens
    675 and rations. However, this is very complex, both for wallets (how to display),
    676 for other merchant APIs (does the refund API have to become multi-currency as
    677 well?) and there does not seem to be a good business case for it. So for now,
    678 the price is always only in one currency.
    679 
    680 
    681 Drawbacks
    682 =========
    683 
    684 Significant change, but actually good ratio compared to use-cases covered.
    685 
    686 
    687 Discussion / Q&A
    688 ================
    689 
    690 (This should be filled in with results from discussions on mailing lists / personal communication.)