NESTS - Named Entities in Simple Tiered Spaces

This document describes the structure of NESTS as implemented on any Unix-type filesystem but with reference to any specific programming language.

The structure has been designed to allow NESTS to be implemented using any combination of programming languages.

This is very much a work in progress. It will be extended gradually and it may take some time to eliminate inconsistencies.

NB, this document has just undergone a major revision to amalgamate a number of files (variables, flags, lists, etc.) into a smaller number of files, mostly JSON. This will have minimal impact on the code under development, but it will reduce the number of inodes used and may have a beneficial effect on execution speed.



Design objectives

  1. Allow users to identify themselves by full namespace path HRNS1, either by primary identity such as
        henry.crun.goons.radio.bbc.uk
    (where crun.goons.radio.bbc.uk is the registry in which the primary identity of that user is registered) or by a secondary identity such as
        henry.crun.goons.org

  2. Map each secondary identity of a user to its primary identity internally using links (FIP 1).

  3. Allow for the naming of named entities using UTF-8 characters, reserving one character ("." by default) for use as the namespace separator.

  4. A user must be able to list its own secondary identities.

  5. A user must be able to list the current state of each of its accounts, whether identified as belonging to its primary identity or to one of its secondary identities.

  6. A user must be able to list the transaction history for each of its accounts, whether identified as belonging to its primary identity or to one of its secondary identities.

  7. The steward 2 of a currency must be able to list the accounts using it, the primary identity of their owners, their current value and their current status.

  8. The steward 2 of a namespace must be able to list the stewards contained within it or any of its descendants along with all entities under their stewardship and the properties of those entities.

  9. It must be simple and straightforward to register in a specific namespace by following an invitation link, either by scanning a QR code or by following a Web link, encoding all the relevant and necessary information such as:

  10. It must also be possible, where appropriate an necessary, using a Web application and a card printer at a participating service provider (sucah as a shop or public library) to register for a validation card on which is printed a QR codes encoding authenticating informtion, i.e.

    Such cards are intended to make the service accessible to users who do not own a smartphone. They can be scanned by merchants (who are more likely to have a smartphone available at a point of sale), and authorized by entry of a password or a PIN. It might als be possible to make use of a device's built-in fingerprint scanner, but the feasibility of thatat remains to be determined.

NB: This is not an exhaustive list. It will be extended and refined.

The namespace conventions used in NESTS are those of open money/metrics.

Namespaces and other named entities

OM named entities fall into two main categories:

  1. Non-terminal namespaces, which can contain any type of named entities (including other non-terminal namespaces).

    By convention, the term namespace (unqualified) refers implicitly to a non-terminal namespace.

    All parent/ancestor namespaces fall into this category.

  2. Terminal namespaces, including all named entities other than non-terminal namespaces.

    Unlike non-terminal namespaces, these cannot contain other named entities.

    These are:

Notes:
  1. HRNS - Human-Readable NameSpace
    FIP = Full Internal Path
    FPH = Full Path Hash

    The FIP is siimply the full directory path from the root of the entities tree. It has a one-to-one correspondence with the HRNS, the FIP being the directory path from the NESTS data root, each directory being a fixed-length hash of the HRNS names read from right to left.

    Access is simplified (not least because it is both more compact and more consistent) by using the FPH, a fixed-length hash of the FIP. The FPH is mapped to the FIP using a fast key:value store (CDB).

    The compactness of the FPH also makes it considerably more suitable for use in URL encoding, SSH commands and REST calls. Although the FIP is faster and more straightforward to process internally, the compactness of the FPH makes it preferable for most purposes.

    Another major advantage of the FPH is that it can be provided as a unique reference ID to any entity, whether an identity, an account, a currency or a namespace.

    In both cases a 64-bit non-cryptographic hash with a very low collision rate (xxHash64) is used.

    The fast key:value retrieval system is currently provided by TinyCDB.

    Obsolescence of FPH to HRNS mappings

    The initial mapping of the FPH to the corresponding HRNS will generally remain unchanged for most of an entity's lifetime. However, in the event of a namespace sub-tree being changed (see note on the pruning and grafting of branches), the original FPH will no longer map on the the FIP and HRNS.

    It is important that none of the FPH of given to the user (those of its identities and accounts in particular) do not change every time the stewards of a namespace decide to move it and, consequently, all the entities it contains. An FPH should be immutable.

    Therefore a secondary mapping is needed, one from the original FPH of an entity to the current FPH of that entity, searched before the original FPH to FIP mapping (usually returning a null result in a negligible time). This changes the mapping from
        FPH > FIP > HRNS
    to
        FPH > FPH' > FIP > HRNS

    This will generally be a much smaller mapping (in most cases very small indeed) so the indirection required by this indirection should create only a minor overhead.

    A second reason to introduce this secondary mapping is that, although extremely improbable, a hash-collison is not impossible. In the unlikely event of a collision being detected, the secondary mapping will allow the new FPH to be replaced by one that is not conflicted.

    NB, at the time of writing this secondary mapping system has not yet been implemented.


  2. Stewards

    The only distinction between a steward and any other identity lies in the domain of the entities over which it holds stewardship.

    The stewardship of any entity is authorized conditionally by the stewards of the namespace containing/enclosing it. That is the case at every level of recursion from the root to the tips of the branches.

    The means by which stewardship propagates through the levels of recursions, maximizing autonomy throughout within the constraints defined by the foundational level (root) is beyond the scope of this document but will be laid down clearly elsewhere. The structures will be recognizable as those of the VSM.


  3. identities = terminal namespaces

    These may include accounts may include private accounts in a private currency - one shared only within a closed group (maybe hours recorded by parents in a self-organizing childcare group, or kWh recorded within a neighbourhood microgrid).


Organization of namespaces

  1. OM namespaces are organized in namespace trees. A path through such a tree is referred to as a namespace path and is, by convention, represented by a string listing namespace name from left (furthest branches) to right (the root of the tree).

  2. Although an OM namespace can resemble a URL, it bears no relationship to any other identifier. Its naming conventions are less constrained, and UTF8 allows a far larger character set to be used.

  3. Mappings of namespace to other entities can be shared (to the extent useful) between hosts.

  4. An OM namespace path can be used to uniquely identify the host on which any particular namespace (tree segment) exists.

  5. A namespace tree can be grafted on to any part of an existing namespace tree (other than itself), so

    e.g.

    can be added to

    as

  6. All namespaces have exactly the same structure and properties.

Tree path representation of namespaces

external

From lowest (most local) level to highest (most close to global) level accessible/visible within scope.

For example, a simple geopolitical namespace tree path might be represented as
    gardencity.chepstow.mon.cy.uk
while one possible bioregional namespace tree path intersecting the example above geographically might focus upon water catchment, flows, etc.
    beachley.mouth.lower.wye-valley.uk

Namespaces can be created and nested to suit any purpose.

internal

Within the NESTS implementation, the two namespace path examples above would be represented (respectively) below the trees' roots (in ROOT - e.g. /var/nests/roots/) by filesystem paths such as
    /dd5d03832c754be8/9ccec313762b2074/98f2f281a3bd013b/1d31cc469d128365/f9ac47bf5464167a/
and
    /dd5d03832c754be8/3054169c03341e0d/e6c970fe368550df/77e102468e08a446/39d5bb735d7c696f/
where each name, regardless of the alphabet used to represent it in human-readable form, is mapped on to a short collision-resistant hash (in this case of 8 hex character = 64 bits).

Each namespace contains other named entities.

Each named entity is a represented internally by a directory containing a number of different types of information (depending on the entity type).

Typically, ROOT might be one of the following (for example):
    /var/nests/
    /srv/nests/
    /mnt/srv/nests/

A NESTS hub might host several distinct root namespaces, each with its own collective of stewards but sharing a common collective of hub stewards (system administrators).

Every NESTS hub will include a root namespace "test" under which valid examples will be created to assist in automated testing. Internally this will be represented as both of the following:
     2d7f1808da1fa63c (xxhash64 hash of string "test")
     test -> 2d7f1808da1fa63c (symlink to the above)

Every NESTS hub will also include a root namespace "sandbox" in which users can experiment freely and harrmlessly with the commands available. The entire "sandbox" tree will be cleared automatically at regular intervals (on the hour by default, but this may be overridden by the NESTS hub system administrators. Internally this will be represented as both of the following:
     f0efa7d611aeaed7 (xxhash64 hash of string "sandbox")
     sandbox -> f0efa7d611aeaed7 (symlink to the above)

NB, the 64-bit xxhash64 hash may be replaced in due course with the 32-bit xxhash32 equivalent, or perhaps even the 128-bit version. Such a change will require only one substitution in the nshash function and a single pass of a script to traverse the trees renaming each directory in turn.


Table 1: Named entity types within NESTS namespaces
entity type visibility description
namespace public 1 A namespace enclosed (or nested) within this namespace. 5
currency semi-private 2 A definition of a variable type 6.
primary identity 9 private 3 The identity 9 of a person, organization, machine or any other type type of agent identified uniquely in a registry 8.
secondary identity 9 private 3

This is an alias of a primary identity contained within any namespace with the authorization of its steward(s).

A distinct collection of accounts will be associated with this secondary identity (but will remain the responsibility of the associated primary identity).

account 10 private 3 An account is a variable owned by a user. It is visible only to its owner (user/steward), to any other user to which the the owner has granted visibility, to the stewards of the namespace enclosing it, and (under exceptional circumstances) to the stewards of ancestral namespaces.

Notes for Table 1

  1. public: An entity both the name and the contents of which are visible to any user granted access to this namespace by its stewards.

  2. semi-private: An entity the name of which is visible to any user granted access to this namespace by its stewards but the contents of which are visible only to the owner (steward) of the entity, to the stewards of the namespace enclosing it, and to users to whom the steward (or stewards) of the entity have granted permission to view or use it.

  3. private: An entity the name of which is visible to any user granted access to this namespace by its stewards but the contents of which are visible only to the owner (steward) of the entity, to the stewards of the namespace enclosing it, and to users to whom the steward (or stewards) of the entity have granted permission to view or use.

  4. hidden: A nameless entity the contents or properties of which are visible only to the to stewards of the namespace enclosing it or those of an ancestral namespace.

  5. All namespaces are essentially similar. None has a higher "status" or priority than any other from the perspective of NESTS (or the OM definitions on which it is built (although users may assign such an interpretation where it is useful to do so). At its most fundamental level, the namespaces simply provide a variety management mechanism.

  6. A currency is any variable type. The name persists from the original application of this nested namespace structure - open money.

    A currency is an example of a semi-private entity. It may be created by any user within any namespace if (and only if) the stewards of that namespace have granted the necessary permissions.

    The creator (definer) of that currency may share the steward role with other users (again subject to the permissions granted by the stewards of the enclosing namespace.

  7. A user may exist in any namespace (subject to the permissions granted by its stewards), including the registry|namespace in which its primary identity is enclosed.

    A user is essentially a private namespace, both enclosing and concealing that user's accounts 7.

  8. A registry may may be embodied in any namespace.

    A registry is essentially a hidden 4 space enclosed within a public namespace.

    A registry encloses primary identities 9.

    Because a registry is inseparable from the namespace in which it is embodied, it can be regarded as a property of that namespace and identified by the same name.

  9. A primary identity (also known as a login identity) comprises a set of identifying data 9 sufficient to meet the requirements specified by the stewards of the enclosing namespace.

    It also includes a set of flags controlled only by the stewards of the immediately enclosing namespace or, under exceptional conditions, overridden or disabled by the stewards of an ancestral namespace. A subset of these flags may be visible to the owner of the primary identity if permitted by the stewards of the immediately enclosing namespace.

  10. Accounts are operated upon in various ways depending upon the currency 6 type definition 10 with which it is associated, the operations defined and implemented for it, and the permissions granted by its owner to agents capable of making use of such operations.

    In the case of the family of open money currency types, a special property is that the accounts belonging to all users of such an open money form a distributed ledger the sum of which is always zero. This provides the basis of a zero-sum, interest-free mutual credit (or mutual commitment) closure.

Internal implementation of namespaces

Every named entity is a namespace.


Table 2: Properties/contents of named entities
entity type containing comprising or including
primary identity identification
  • namespace
  • username 1
authentication
  • private key
  • hash of UI login password 2
  • (biometric data)
relationships
  • list of links (FIP) to secondary identities 3
accounts
  • both primary identities and secondary identities enclose accounts privately within the namespace 4
secondary identity identification
  • link (FIP) to namespace directory of primary identity
accounts
  • both primary identities and secondary identities enclose accounts privately within the namespace 4
account identification
  • link (FIP) to namespace directory of the associated currency
value
  • the persistent record (the type of which is defined by the associated currency.
ownership
  • the ownership of the account is defined by that of the user namespace enclosing it 4
namespace any type of
named entity
  • other namespaces of this type
  • primary identities 6
  • secondary identities
  • currencies
  • accounts
relationships
  • ancestor namespaces (other than parent) are identified by FIP or located by tracing back through directory tree branch
  • parent namespace is represented internally as containing directory
  • child namespace are represented internally as subdirectories
  • descendant namespace (other than children) are identified by FIP
stewards
  • list of links (FIP) to the primary identities of the stewards (governing users of the namespace)
currency identification
  • link (FIP) to directory in which the currency prototype is defined
parameters
  • overriding the defaults associated with the currency prototype
relationships
  • list of links (FIP) to accounts using the currency 5
stewards
  • list of links (FIP) to the primary identities of the stewards (governing users of the currency)
Notes
  1. Identified by full namespace path.

  2. Available if needed by an implementation making direct use of the NESTS package.

  3. When the namespace enclosing a primary identity is moved to any other position in the tree, the link (FIP) associating each secondary identity with it must be updated.

    This also allows listing of the secondary identities associate with a primary identity.

  4. Accounts

  5. When the namespace enclosing a currency is moved to any other position in the tree, the link (FIP) associating each account with it must be updated.

    This also allows listing of the accounts using a currency.

  6. In this case, the namespace serves as a registry.





Property elements/implementation for each entity type

Table 3: Entity types: linkages
entity type linkages contents/properties
links to as number
account currency FPH 1 many-to-one 2
  • value
  • status flags
identity FPH 1 many-to-one 2
currency accounts FPH 1 one-to-many 3
  • status flags
stewards FPH 1 one-to-many 3
stewards primary identity FPH 1 one-to-many 3
  • status flags
namespaces FPH 1 one-to-many|zero 4
currencies FPH 1 one-to-many|zero 4
namespace parent namespace directory parent 5 one-to-one 6
  • status flags
ancestor namespace directory parent (chained) 5 one-to-many 6
child namespaces subdirectories one-to-many|zero 4
stewards FPH 1 one-to-many|zero 4
secondary identity primary identity FPH 1 zero|many-to-one 7
  • status flags
namespace containing directory 5 one-to-one 6
accounts containing directory 5 one-to-many|zero 4
primary identity secondary identities FPH 1 one-to-many|zero 4
  • user identification data
  • user authorization data
  • user contact data
  • status flags
namespace containing directory 5 one-to-one 6
accounts containing directory 5 one-to-many|zero 4

Notes for Table 3

  1. FIP = Full Internal Path

    The FIP (reading from left to right) has a one-to-one correspondence with the names in the human-readable path (reading from right to left).

  2. At least one of the first entity type refers (links) to a specific instance of the second entity type.
  3. At least one of the second entity type is associated with (links) to a specific instance of the first entity type.
  4. Zero or more of the second entity type are associated with (links) to a specific instance of the first entity type.
  5. The relationship is defined by the filesystem parent-child relationship (relative) rather than by FIP (absolute location).
  6. A namespace can have only one parent but can have any number of ancestors.
  7. Zero or more of the first entity type are associated with (links) to a specific instance of the second entity type.




Table 4: Entity types: directory contents
This table lists the property elements within each entity type, each represented internally by a file or directory of some type. entity type applicable set/written by accessible to
namespace
primary identity
secondary identity
currency
account
operation
owner
others
steward
parent steward
ancestral steward
automatic process
owner
others
steward
parent steward
ancestral steward
automatic process
property
filename
property
file type
purpose or
significance
Table 4a: per-entity data
.name text (UTF8) x x x x x x Human-readable name 1. x x x x x x
.id JSON x Identification n-tuple (JSON). x x x x x x x
.auth JSON x Authorization n-tuple (JSON). See Table 4f below. x x
.contact JSON x Contact details (JSON). See Table 4e below. x x
.fph FPH x x x x x x Full Path Hash - hash of FIP 2. x x
.secid_list FPH list x List of associated secondary identities (FIP). x x
.primid FPH x Associated primary identity (FIP). x x
.type text x x x x x x The entity type 3. x x x x x
.prototype FPH x The currency prototype. x x x x x
.stewards FPH list x x List of stewards (FIP) of this entity 4. x x
.stewardships FPH list x List of entities (FIP) of which identity is a steward. x x
.cpolicy symlink x Entitity-creation policy set by stewards. x x x x x x x x
.enabled symlink x x x x x x symlink to: ../.enabled or false 5. x x x x x x x x
.locked symlink x Locking account during write operations. x x x x x x x x
.notes text x x x x x x Inter-steward communications log 10. x x x x x x x x
.owner FPH x The owner of the account (an identity). x x x x x x x x
.accounts FPH list x x x The list of account owned by an identity). x x x x x x x x
.readers FPH list x List of identities (FIP) able to read this variable. x x x x x x x x x
.writers FPH list x List of identities (FIP) able to write this variable. x x x x x x x x x
.status JSON x x x x x x Status n-tuple (JSON). See Table 4d below. x x x x x x x x x
.history TSV x x x x x x History/log of entity 19. x x x x x
.transactions TSV x x Transaction history for account or currency 20. x x x x x x
.value JSON x Current value of account 21 - JSON structure. x x x x x x
.qr/qr.png PNG file x x x x QR code 32 encoding path to entity. x x
.qr/qr.svg SVG file x x x x QR code 32 encoding path to entity. x x
.properties JSON x Entity type-dependent properties. x x
.operations FPH list x List of operations applicable. x x
.voucher_list FPH list x List of vouchers issued on this account 35 x x
Table 4b: global status data
.blacklist/email x Blacklisted email addresses 15, 8, 9. x x x x x x x x
.blacklist/phone text x Blacklisted phone numbers 16, 8, 9. x x x x x x x x
.blacklist/mac text x Blacklisted MAC addresses 17, 8, 9. x x x x x x x x
.blacklist/ip text x x x x x x Blacklisted IP addresses 18, 8, 9. x x x x x x x x
Table 4c: .value key:value pairs
key value type value description
variable type text Variable type: scalar | vector | matrix | n-tuple
value text Single value or nested JSON structure.
expiry text Expiry date 33.
decay_model text Decay process 34 identified by FPH.
decay_parameters text Decay parameters 34 list.
Table 4d: .status key:value pairs
key value type value description
f_pending_auth 0 | 1 Flags: pending authorization 11.
f_suspended 0 | 1 Flag indicating suspension 12.
f_blocked 0 | 1 Blocked from re-registering 13.
Table 4e: .contact key:value pairs
key value type value description
mobile_number text Mobile phone number 22.
email_1 text Email address 1 23.
email_2 text Email address 2 24.
surname text User's surname 25.
forenames text User's forenames 26.
grid_ref text Grid reference 27.
address text Postal address 28.
Table 4f: .auth key:value pairs
key value type value description
pwd_hash text Password hash 29.
public_key text SSH public key 30.
oauth_token text Oauth access token 31.

Notes for Table 4

  1. UTF-8 representation of human-readable full namespace/entity path.
  2. FIP = Full Internal Path (directory path from NESTS ROOTS directory to entity directory).
  3. History: creation, modification, status changes, etc.
  4. List of stewards for this entity (identified by FIP) 4.
  5. Daisy-chained AND gates.


    Implemented by switching between symlink to parent namespace's .enabled file and symlink to file containing a value interpreted as FALSE.

    There are no circumstances in which the parent namespace's .enabled state will be overriden to TRUE.

  6. AND gate

    Implemented by switching between symlink to enclosing namespace's .enabled file and symlink to file containing a value interpreted as FALSE.

  7. These may be the only sources of identification available and cannot generally be considered absolutely reliable. Therefore a mechanism for appeal and resolution must be available at the human (steward) level.

  8. Unless resolved in some satisfactory way, these data sets will in due course be copied to a global blacklist database as well as being preserved at the level of this namespace.

  9. Fixed-format notes/log for communication between stewards. Can also be written by automated alert process to inform stewards of activity requiring investigation and/or resolution.

    Meta-data applied and read by the underlying mechanisms constrain access as required by configured policy.

  10. The creation of this entity (whether a primary identity, a secondary identity, a currency, an account, a namespace or a procedure) has been initiated but is pending authorization.

    In most cases the authorization will be needed from a steward (of a namespace or currency) - in most cases given automatically by default - but in the case of a user registration, confirmation will also be required from that user.

  11. Upon detection of activity raising cause for concern by a steward or by automated oversight processes, an entity will be suspended (in a manner appropriate to that entity's type). When such a susepension is triggered by the .enabled "kill switch" or another entity's type-specific equivalent, the localized suspension flag will persist after the triggering flag has returned to its permissive state - pending resolution of an investigation.

  12. A user who has been a bad actor is marked as to be blocked from re-registering immediately.

    This flag indicates that, to the extent possible given available identifying data, this user must be prevented from immediately re-registering in this namespace or in any of its descendants.

  13. A user who has been a bad actor is marked as to be blocked permanently from re-registering.

    This flag indicates that, to the extent possible given available identifying data, this user must be prevented permanently from re-registering in this namespace or in any of its descendants.

  14. Locally-maintained list of blacklisted email addresses.

    A background process collects blacklisted email addresses from throughout the namespace tree into a globally-accessible list.

  15. Locally-maintained list of blacklisted phone numbers.

    A background process collects blacklisted phone umbers from throughout the namespace tree into a globally-accessible list.

  16. Locally-maintained list of blacklisted MAC addresses.

    A background process collects blacklisted MAC addresses from throughout the namespace tree into a globally-accessible list.

  17. Locally-maintained list of blacklisted IP addresses.

    A background process collects blacklisted IP addresses from throughout the namespace tree into a globally-accessible list.

  18. An automatically-written log of events relating to this entity, visible only to its stewards.

  19. The transaction is logged automatically and identically in the transaction history/log/journal for both accounts involved, each record comprising:

    • Date and time: YYYY-MM-DD hh:mm:ss
    • Date and time: UTC
    • Time zone
    • Payer (if an instance of open money) or initiator of a more general action affecting an account value
    • Payee (if an instance of open money)
    • Authorization action/event
    • Amount/value
    • Balance of payer's account (visible only to payer and the currency steward)
    • Balance of payee's account (visible only to payee and the currency steward)
    • Supplementary notes (optional)

    A transaction cannot be altered, cancelled or reversed. It can be negated only by a reverse transaction of equal value.

  20. The current (most recent) value (balance) of an account is updated each time a transaction is logged.

    The default policy (which can be overriden by the stewards of a currency) is to make this value visible only to:

    • The account's holder
    • The stewards of the currency
    • The stewards of the namespace containing the account
    • Upon request, and with the agreement of the other party, a prospective payer - in which case the two account holders are able to each other's account balance.

  21. The mobile phone number is optional. If provided, it can be used for login recovery purposes or to alert the user to an event (as configured) in the user's preferences.

  22. Primary email address. Optional. If provided, it can be used for login recovery purposes or to alert the user to an event (as configured) in the user's preferences.

  23. Secondary email address. Optional. If provided, it can be used for login recovery purposes or to alert the user to an event (as configured) in the user's preferences.

  24. [Optional]
  25. [Optional]
  26. [Optional]

  27. [Optional]

  28. Cryptographic hash of password.

  29. [Optional]

  30. []

  31. QR codes are used for:

    • Registration by invitation, encoding
      • full namespace path to the currency
      • the identity issuing the invitation
      Scanning the QR code takes the user directly to a registration form pre-filled with currency identifier.
    • Authorization of payments. In this case a typical usage would be scanning of an account holder's QR code (which might be on a printed card or displayed on a phone) by a merchant's smartphone.

    A unique QR code is generated for each primary identity upon registration.

    A unique QR code is also generated for each secondary identity (linking internally to a primary identity).

    An SVG version of the QR code may generated to improve print quality.

  32. A date string in YYYYMMDDhhmmssss format.

    This file exists only where needed and applies only to time-limited variables.

  33. If the variable is subject to decay (or other modification) over time, the function is identified by FIP. The parameters are saved in a separate file (one per line).

    This file exists only where needed and applies only to time-limited variables.

  34. Each row of the voucher list comprises the following semicolon-separated fields:

    • Date/time issued (YYYYMMDDhhmmssss)
    • Transaction ID - sequential count unique to each currency
    • The currency (FPH)
    • The issuer account (FPH)
    • Date for use (YYYYMMDD) (if applicable - otherwise empty)
    • Expiry date (YYYYMMDD) (if applicable - otherwise empty)
    • Time window (hhmm-hhmm) (if applicable - otherwise empty)
    • The quantified value (number, count or value) (if applicable - otherwise empty)
    • The unquantified value (category) (if applicable - otherwise empty)
    • List of places accepting these vouchers (FPH[,FPH[,FPH[,...]]]) (if applicable)
    • Pre-defined list of places accepting these vouchers (FPH) (if applicable)
    • List of purposes for which these vouchers are accepted (FPH[,FPH[,FPH[,...]]]) (if applicable)
    • Pre-defined list of purposes for which these vouchers are accepted (FPH) (if applicable)

    When scanned, the voucher is eliminated from the list. This event is logged in the account journals of the voucher issuer, the voucher holder and the currency's steward(s).




Version 0.0.29a - 2022-08-20 23.40 - Copyright © 2022 John Waters


home