diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f81c4d1091b661865f34757176484d614fc0fe38 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +default: convert +convert: + bash publication.sh +clean: +git: + # git add files + #git add whitepaper.md whitepaper.html + #git add chapters/1_intro.md.txt chapters/2_looking_at_Bitcoin.md.txt chapters/3_blockchain.md.txt chapters/4_Web_Of_Trust.md.txt chapters/5_individualized_difficulty.md.txt chapters/6_conclusion.md.txt chapters/9_sources.md.txt + #git add publication.sh + + #we want to add the .pdf only for publication + # git add whitepaper.pdf diff --git a/README.md b/README.md index d412047f85ceba139a424ac610ede38bfc8e5d73..0fe884efa29f73fee6d5395d2d30b52dafa8f8a6 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,13 @@ Rédaction d'un Whitepaper pour le projet Duniter. Je ne suis pas compétent pour entrer dans les détails du projet. Cependant, je le suis assez pour rédiger la majeure partie du texte explicatif. J'invite qui le souhaite à m'accompagner dans cette rédaction. +## Installation et compilation sur système Debian +Pour compiler les sources markdown vers les versions html, ebook et pdf vous allez avoir besoin de ces dépendances: +```bash +sudo apt install texlive-latex-base pandoc texlive-fonts-recommended calibre +make +``` + ## TODO * grouper les assets dans ce dépot dans src/img et non les mettre en hotlink. * Table Of Content sur la version HTML. diff --git a/build/whitepaper_en.epub b/build/whitepaper_en.epub new file mode 100644 index 0000000000000000000000000000000000000000..eda7e1b9a2db2be6bb5498c09dfc2c0cb538171c Binary files /dev/null and b/build/whitepaper_en.epub differ diff --git a/build/whitepaper_en.fb2 b/build/whitepaper_en.fb2 new file mode 100644 index 0000000000000000000000000000000000000000..feb6aa868b1caae740125a8dda16cab8f8d489ae --- /dev/null +++ b/build/whitepaper_en.fb2 @@ -0,0 +1,739 @@ +<?xml version="1.0" encoding="UTF-8"?> +<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:xlink="http://www.w3.org/1999/xlink"> + <description> + <title-info> + <genre>antique</genre> + <author><first-name></first-name><last-name>Inconnu(e)</last-name></author> + <book-title>whitepaper en</book-title> + + <lang>fr</lang> + + + + </title-info> + <document-info> + <author><first-name></first-name><last-name>Inconnu(e)</last-name></author> + <program-used>calibre 3.46.0</program-used> + <date>5.5.2020</date> + <id>5e6bf4d6-ac49-48cd-9e7e-afc96068fd4a</id> + <version>1.0</version> + </document-info> + <publish-info> + + + + </publish-info> + </description> +<body> +<section> +<empty-line /><p>Duniter: A libre currency blockchain generator.</p> + +<p>Abstract</p> + +<p>Many currency principles involve non-equal rights to monetary creation between humans. We propose a monetary creation based on the Relative Theory of Money, which guarantee equal monetary creation for each willing human. This type of currency can be centralised, however, this could lead to censorship and arbitrary choices of the central institution. Thus, strongly inspired by Bitcoin example, we want the currency to be as decentralised as possible, in the transaction network as in the human identification process. We use a Web of Trust between living humans for identification. This web of trust allows us to impose personalised difficulty for transaction validation, keeping the calculation accessible to low-end hardware and allowing all competent members to secure the currency.</p> + +<p>Introduction</p> + +<p>Duniter is a software to create and manage “libre currencies”. Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question :</p> + +<p>How should a currency be created to match the principle of equality between all humans, now and between generations ?</p> + +<p>The results of this demonstration implies a monetary creation :</p> + +<p>on a regular basis</p> + +<p>for each human being</p> + +<p>which amount has to be reassessed on fixed intervals according to a fixed formula.</p> + +<p>Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula :</p><empty-line /><p>$$ UD(t+1) = UD(t) + c²*( {M(t) \over N(t) }) $$</p><empty-line /><p>Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin.</p> + +<p>The first currency created through Duniter is Ğ1, pronounced “June”. It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software.</p> + +<p>1. State of the art : Bitcoin case</p> + +<p>Duniter uses the crypto-currency concept introduced by Bitcoin<sup>1</sup>, which is to use cryptographic tools such as signatures to create trustless digital currencies. Duniter fits this definition, but it has two completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects.</p> + +<p>1.1. Monetary creation of Bitcoin : a space-time asymmetry</p> + +<p>Space-time asymmetry refers to the relative access of individuals to newly created money<sup>2</sup>. Concretely, most existing currencies (c. 2020) are both spatially and temporally asymmetrical for their users. Let's take Bitcoin as an example to understand why.</p> + +<p>1.1.1. Spatial asymmetry</p> + +<p>When new Bitcoins are created, only some Bitcoin users (the miners) are given new Bitcoins, while everyone else get nothing. We believe this is the first injustice. However, some might say:</p> + +<p>"Miners used their electricity and time to get it!"</p> + +<p>... we would answer that this work should not have been rewarded by newly created Bitcoins. New units should be distributed to the whole community. Miners should be rewared another way, but not by money issuance. Of course, Bitcoin cannot create money through Basic Income since Bitcoin users are not strongly identified, and one might benefit from money creation multiple times if they owned several wallets. Duniter gets rid of this problem by identifying its users and creating the same amount of Basic Income to everyone.</p> + +<p>1.1.2. Temporal-asymmetry</p> + +<p>Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, how will future joiners get Bitcoins? Just like most of us do for Euros or Dollars: to get money, they will have to work for the ones who already own it.</p> + +<p>We believe this is the second injustice. Every member of a monetary community should be equal concerning monetary creation, and get the same relative amount of money over time, even if they are a late adopter. Duniter aims to fix this by making the Universal Dividend (a.k.a. UD) grow by the time according to precise rules, thus making members equal toward money issuance on a half-lifespan.</p> + +<p>Most currencies present one of these two asymmetries, including metal currencies and mutual credit, as exposed in the RTM.</p> + +<p>1.1.3. A solution</p> + +<p>Bitcoin has taught us that it is possible to create a currency system allowing one to both create digital money and to exchange it without a central authority. What we need to change is the way money is issued so we finally have a symmetrical system. We need Bitcoin + Universal Dividend. But Universal Dividend implies that the community consists of only identified people. This is where the Web of Trust (WoT) comes into place.</p> + +<p>This concept, introduced by cryptography with the OpenPGP format<sup>3</sup>, allows us to identify people in a decentralized manner. It works as follows: each person creates a personal identity that is linked to its cyptographic certificate. The identity must be confirmed by others members who use their own cryptographic key. It is that simple: people choose who is part of the community and who is not, not a central authority.</p> + +<p>However, Duniter will not use OpenPGP for its cryptographic features: Elliptic Curves<sup>4</sup> will be used instead for the conciseness of its generated keys and its pratical advantages. Duniter has its own Web of Trust principles, that will be exposed later.</p> + +<p>1.2. Proof-of-Work mining : a power race</p> + +<p>In Bitcoin Model, the calculation and incentive principles cause a power race : new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. This leads to a power race an places the control over the currency in the hands of the richest hardware owners. We want to make Duniter blockchain validation much less energy and hardware consuming while keeping a strong level of security. This will be further explained later. A consequence of this choice is the participation of low-end hardware in the Duniter network, leading to a better decentralization of blockchain validation.</p> + +<p>1.2.1 What about Proof of Stake ?</p> + +<p>Proof of stake consensus algorythm was first introduced in 2012<sup>5</sup>. The basic principle is to allow the richest wallets to issue blocks, putting their coin balance as a “stake” they would lose in case of cheat.</p> + +<p>At the time of conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. We did not chose this consensus principle. Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead to placing power over the currency in the richests hands : this is contrary to the symmetical principles of a libre currency.</p> + +<p>2. Duniters Blockchain</p> + +<p>Duniters Blockchain follows the basic principles of Bitcoins. This is essential for synchronization between peers, as to prevent double-spend attacks. However, Duniters Blockchain will store different informations than Bitcoins.</p> + +<p>The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no generation transaction exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either:</p> + +<p>a former transaction (as in Bitcoin)</p> + +<p>a Universal Dividend (specific to Duniter).</p> + +<p>Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactions are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where “space” are members of the WoT and “time” the basic blockchain units : the blocks. On each point of time, one can determine which account is legitimate to create the UD, only with a blockchain analysis.</p> + +<p>2.1. Spam countermeasures</p> + +<p>An issue of most cryptocurrency projects is to prevent the common ledger from growing too much. This would require nodes to have a lot of storage and computing power to be usable. In particular, we don’t want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don’t want to introduce this mean since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented.</p> + +<p>2.1.1. Minimum output amount</p> + +<p>Fixing a minimal output amount reduces the power of an attack. Duniter deals with cents of Ğ1 or 1/1000 of the first UD. An attacker could create thousand accounts with only 1 UD. To prevent this, a valid transaction must have output amounts of minimum 1Ğ1. This reduces the power an attack by 100.</p> + +<p>2.1.2. Limited block size and chainability</p> + +<p>The block size is always limited. While the protocol allows this limit to evolve to address scaling issues, an attacker cannot register as many transaction as they wish.</p> + +<p>With the same goal to prevent too many transactions to get registered, while transactions can be “chained” (refer to another transaction in the same block), the chainability of transactions is limited to 5.</p> + +<p>2.2. Scaling</p> + +<p>Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons :</p> + +<p>Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don’t want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT should limit its size to around 16 million members.</p> + +<p>Duniter’s aim is to be used to create multiple libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community.</p> + +<p>However, Duniter has assets that will help if the number of users and transactions grow.</p> + +<p>2.2.1 Dynamic block size</p> + +<p>While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks(see “personalised difficulty” part for more information). This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. The block size (in bytes) is limited as so :</p> + +<p>block_size < max(500 ; CEIL(1.10 * (average block size))</p> + +<p>2.2.2. Lightning Networks</p> + +<p>The Lightning Networks<sup>6</sup> allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed.</p> + +<p>2.2.3. Unit base</p> + +<p>As the Universal Dividend grows exponentially, with time Duniter nodes would have had to deal with always largest amounts, eventually reaching the BIGINT limit. To avoid this, the amounts are expressed with a unit base in base 10. We want the UD amount to always fit in 4 digits. To manage it, the unitbase is updated each time the UD value reaches 100.00 : it goes from 99.99*10^(unitbase) to 10.00*10^(unitbase+1). All the unit amounts are thus divided by 10. While this might seem strange, this process has already hapened in state currencies. Moreover, the amounts expressed in UD will not change.</p> + +<p>With a monetary growth of 10% each year and a stable population, such a change of unit base would happen each 25 years.</p> + +<p>3. Duniter Web of Trust</p> + +<p>3.1. Basic Principles</p> + +<p>In order to identify “members” accounts - which create monetary units - and other accounts, Duniter uses a Web of Trust. This can be summarized into few principles:</p> + +<p>Each account becomes a member if it received a minimal number of certifications - 5 for Ğ1 currency.</p> + +<p>Only members accounts can send certifications. Certifications have a limited lifespan.</p> + +<p>A certification indicates that the sender accepts the receiver as a legitimate identity.</p> + +<p>The aim of the WoT is to identify a blockchain account to a living human. According to Lauterbach et.al<sup>7</sup>, the strengh of a relationship should be considered when building a vouch system. For this reason, the Ğ1 Web of Trust rules are expressed in a licence stating what WoT certifications are. A certification represents a strong human relationship : one may certify a close relative, not an acquaintance. Each member has to accept this licence before being included in the WoT. Thus, if a member is part of an attack on the currency, they can be found by mutual relatives. Additional security rules occur to prevent cheat and attacks on a large scale.</p> + +<p>Note that non-members accounts can use the currency, but cannot create money. Non-members accounts can be used by individuals as secondary wallets, or by institutions.</p> + +<p>We were inspired by the OpenPGP Trust system<sup>8</sup>. However, the OpenPGP trust principles aim at defining trust from a particular point of view while Duniter needs to identify humans for the whole community. To achieve this goal, while OpenPGP allows each user to tweak its trust parameters individually, Duniter sets rules in the “genesis” block for the whole community.</p> + +<p>3.2. Why do we need a Web of Trust ?</p> + +<p>There are two reasons we need it :</p> + +<p>To make sure that only one Universal Dividend is produced per member at each specified creation interval. In the Ğ1’s case this interval is set as daily 86 400 seconds, it is the <emphasis>monetary parameter</emphasis> known as dt.</p> + +<p>To identify the nodes hashing the blocks and assign each a personalised difficulty. This custom difficulty proof of work is there to avoid the blockchain’s validation mechanism becoming too centralised as is the case with many 'non-libre’ cryptocurrencies.</p><empty-line /><p>Monetary parameter : Each currency that use Duniter has its own blockchain whose behaviour is dictated by a set of ‘parameters’ defined in block zero - the so-called genesis block - that can be tweaked to achieve the desired results. At the time of writing the Whitepaper, the Duniter Blockchain Protocol (DUBP) has a total of 21 parameters of which 10 are for the WoT alone. We’ll focus on these 10.</p> + +<p>Suffice to say that in the Ğ1’s case, the DU is created every 24 hours - 86 400 seconds. This interval is set through the time derivative dt parameter and can have a different value in other implementations of the protocol.</p> + +<p>We want to make sure that each member can only have one account. As we all know, achieving zero-risk isn’t possible<sup>9</sup>. Our goal is therefore not to create a WoT within which fraud would be absolutely impossible, but instead to discourage it. Here is a rewording of our goal in 4 smaller ones :</p> + +<p>Make the certification process lengthy enough that all members exercise due diligence and are wary of risks.</p> + +<p>Make fraudulent acts as hard as we can to the extent that they become pointless.</p> + +<p>Ensure that any Sybil attacks have a negligible impact on the currency by ensuring that illegitimate double Universal Dividends have no significant bearing on the legitimate monetary mass</p> + +<p>Slow the growth of ‘Sybil regions’ to give enough time for the community to react and isolate the threat.</p><empty-line /><p>Sybil attack : A Sybil attack is an attack perpetrated on a reputation system through the creation of fake identities. A Web of Trust is a specific instance of a Reputation System.</p> + +<p>There are plenty of Sybil attack scenarios we can think of and just as many reasons why their perpetrators would want to carry them out. Our objective is that the configuration of the WoT protects both users and its IT backbone infrastructure against these attacks.</p> + +<p>This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web’s role isn’t to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing your tap water and electricity but isn’t responsible for any burglaries, etc. Much in the same way, Duniter’s WoT guarantees us all a functional currency, but do not detect small fraud.</p> + +<p>3.3. The importance of having our own certification system</p> + +<p>Centralized identification systems can achieve the goal we want. State Identification is an example. However, this has many drawbacks :</p> + +<p>The authority may have arbitrary criteria for identification, for example preventing people without an official state-provided identity or homeless people to be included in the WoT.</p> + +<p>Payment might be required to get identified, thus making the monetary creation not “free”.</p> + +<p>The authority is a point of failure for any attacker.</p> + +<p>It is of the utmost importance that we remain free from any state or corporation. The WoT is an answer to this criterium. To this day we depend only on the Internet and yet, were it to fail, there are already alternatives being tested around the world for a decentralised communication network.</p> + +<p>3.4. A few foundational concepts on graph theory : a bit of vocabulary</p><empty-line /><p>Graph: set of points -called ‘vertices’- joined by edges -called paths/walks-.</p> + +<p>Simple graph: a graph with no loops and with no multiple edges. That is, each edge connects two distinct endpoints and no two edges have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise.</p> + +<p>Directed graph: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. Arrow A –> B is therefore different from arrow B –> A.</p> + +<p>Endpoints: the edge with vertex A –> B has A and B as endpoints, respectively as start and end of the path/walk.</p> + +<p>Isolated vertex: a vertex whose degree is zero, that is, a vertex with no incident edges.</p> + +<p>Degree of a vertex: number of its incident edges -in and out-.</p> + +<p>Out-degree of vertex A: number of outbound edges / tail ends from A.</p> + +<p>In-degree of vertex A: number of incoming edges / head ends to A.</p><empty-line /><p><emphasis>degrees of a vertex diagram</emphasis></p><empty-line /><p>Path: -aka “walk”- path to follow to get from vertex A to vertex B.</p> + +<p>3.5. Definition of the Duniter Web of Trust</p> + +<p>The Duniter WoTs -one per currency- are simple directed graphs without isolated vertices. The vertices are the members and the edges are the certifications given and received.</p> + +<p><emphasis>Directed</emphasis> means that the responsibility of issuing a certification is unique and personal to the certifier. The trust they place in the receiver cannot be imposed in the other direction although in most circumstances both parties equally trust each other.</p> + +<p>In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific ‘deactivated state’ and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered ‘pending’ to avoid a collapse of the WoT. If these old members don’t come back into the WoT, their pending certifications will eventually expire and they will switch from ‘deactivated’ to ‘isolated’ vertices.</p> + +<p>To wrap up with old members, after a certain period of time - set in the currency’s parameters - their deactivated vertex is removed from the web and the associated identity is ‘revoked’. The person who owned the account can no longer use this identity but is free to join the web with another one.</p> + +<p>Identity : An identity is a set of three pieces of information: a public key, a name and a blockstamp. A blockstamp points to a specific block in the chain. Its main use is to freeze the point in time at which an identity was created and to link this identity to a specific chain and a currency - each currency having its own blockchain.</p> + +<p>An identity can be in any one of 5 different status: pending, member, old member, revoked or excluded.</p> + +<p>Let’s take a simple example:</p> + +<p> A -> B -> C + | + \--> D</p> + +<p>If, for whatever reason, A were to lose its member status, the web would crumble and all other members would be excluded as a consequence. To avoid this, the certification from A –> B will remain valid until its expiry date, leaving enough time for B to receive certifications from C or D.</p> + +<p>Because our WoT doesn’t have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications it has received, all in the same block. This calls for a temporary ‘buffer’ storage space for pending identities and the certifications they have received. This storage space is called ‘the pool’ of Duniter nodes, which we could also have called the ‘sandbox’ as that’s the name used in Duniter’s code. Duniter nodes inclued other ‘pools’ for other documents and metadata not mentioned here.</p> + +<p>3.6. Exploring the rules behind a Duniter Web of Trust</p> + +<p>The Duniter WoTs - one per currency - works with a set of eight fundamental rules enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - msPeriod- having being hard-coded in the Ğ1’s code subsequently.</p> + +<p>3.6.1. Distance rule and referent members (</p> + +<p>stepMax</p> + +<p> and</p> + +<p>xPercent</p> + +<p>)</p> + +<p>These two parameters are closely linked and together define the ‘distance rule’. The ‘distance rule’ can only be described after defining what a ‘referent member’ is:</p> + +<p>Referent member: member A is said to be ‘referent’ if and only if the total of their degrees are greater than or equal to CEIL-N^-1/stepMax where N is the total number of members. As the size of the web will grow this number will grow too, meaning it will take more certification issuances to become a referent member. The number of certifications needed to become a member shouldn’t change.</p> + +<p>Let’s now define the distance rule:</p> + +<p>Distance rule: member A is said to observe this rule if and only if for a subset xPercent % of referent members R there exists a path of length less than or equal to stepMax between R and A.</p> + +<p>Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect web, that is one in which each member has certified all members they legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time t who haven’t yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would effectively stop growing.</p> + +<p>Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets confirmed into the web or an existing member gets renewed. There is an exception to this rule: the distance rule is not observed in the genesis block -when the web is first implemented.</p> + +<p>3.6.2. Rule of the minimum number of certifications needed (</p> + +<p>sigQty</p> + +<p>)</p> + +<p>This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least sigQty active certifications. If, for whatever reason, member A were to have less than sigQty active certifications in a given block, they would cease to be a member and be required to publish a request for identity renewal.</p> + +<p>3.6.3. The membership renewal rule (</p> + +<p>msValidity</p> + +<p>,</p> + +<p>msPeriod</p> + +<p> and</p> + +<p>msWindow</p> + +<p>)</p> + +<p>Bear in mind that a membership doesn’t last a lifetime but instead has a lifespan set to msValidity seconds.</p> + +<p>Every single member -or old member who hasn’t revoked his identity or been excluded- can request a membership renewal so long as the last request was made more than msPeriod seconds ago. If a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the ‘pool’ for a maximum of msWindow seconds before it’s included in the blockchain. Once again, this can only happen once/if the member meets both the siqQty rule and the distance rule -if these criterion are already matched it’s just a case of waiting for a new block to be mined-.</p> + +<p>If a member hasn’t requested a renewal for longer than msValidity seconds, they automatically cease to be a member. From this moment on, the ex-member has another msValidity window to renew their membership. When this period of 2 × msValidity runs out, the membership will expire and this identity will never be available for use again in the web. If the person so desires, they will have to publish new identity and membership documents and find enough certifiers, as any newcomer.</p> + +<p>3.6.4. Rule of certification lifespan (</p> + +<p>sigValidity</p> + +<p>)</p> + +<p>All certifications included in the blockchain expire sigValidity seconds after they were issued.</p> + +<p>/!\ The issuance and the inclusion of a certification in the blockchain occur at different times. When member A issues a certification at time t1, it gets stored in the pool starting at t1 and only finds its way into the blockchain at t2 when all of the web’s rules are observed. Several weeks can thus go by between t1 and t2!!!</p> + +<p>3.6.5. Rule of limited supply of active certifications (</p> + +<p>sigStock</p> + +<p>)</p> + +<p>By ‘active certifications’ we refer to certifications included in the blockchain and that haven’t yet expired.</p> + +<p>The total of active certifications issued by any member at any single time must be less than or equal to sigStock. When this threshold is reached the member will have to wait for one of his active certifications to expire before he/she can issue a new one.</p> + +<p>3.6.6. Rule of the time period between two certification issuances. (</p> + +<p>sigPeriod</p> + +<p>)</p> + +<p>As soon as a certification issued by member A gets included in the blockchain, they will be unable to issue a new one before another sigPeriod seconds.</p> + +<p>3.6.7. Expiry of a certification issuance (</p> + +<p>sigWindow</p> + +<p>)</p> + +<p>When a certification is issued by member A, it will be stored in the ‘pool’ for a maximum of sigWindow seconds. If the certification hasn’t been included in the blockchain by then, it will be cancelled and the member’s sigStock will be repleted by one.</p> + +<p>3.6.8. Lifespan of a ‘pending’ identity (</p> + +<p>idtyWindow</p> + +<p>)</p> + +<p>When a new identity is created, it is stored in the ‘pool’ for a maximum of idtyWindow seconds. If the person hasn’t achieved member status by then, the certification will simply be cancelled.</p> + +<p>3.7. Details on some of the WoT’s peculiarities at the genesis block</p> + +<p>The aforementioned rules can only be enforced with an existing web. They cannot be observed when first creating the web, that is when defining the genesis block.</p> + +<p>Only rules 2 and 5 can be observed at the genesis block.</p> + +<p>The genesis block has to be manually created by the founding members. In practice this means that there must be a choice on which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities.</p> + +<p>As soon as the genesis block has been created, the other identities can start mining the blockchain and the member who created block #0 effectively looses the decision power he had at creation.</p> + +<p>3.8. Why these rules and application cases in the Ğ1</p> + +<p>3.8.1. Distance and maximum size</p> + +<p>The distance rule is there to curb the maximum size of a Sybil region as well as that of the monetary community as a whole. The xpercent parameter prevents the creation of a ‘faction’ that could take hold of the blockchain.</p><empty-line /><p><emphasis>Sybil region</emphasis></p> + +<p>The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned Sybil members. As a consequence, the shortest edge/path between a legitimate member and a Sybil one has to have the attack’s author as an endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as stepAttackers. The maximum size of a Sybil region created by sigQty members depends on the L parameter, defined as L = sigQty/sigStock:</p> + +<p>MaxSybilSize= (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L)</p> + +<p>The maximum size of the Web of Trust is given by the following formula:</p> + +<p>WoTmax = (sigStock)*L^(stepMax-1)</p> + +<p>However we know for a fact that members will never use all of their available certifications. According to Dunbar<sup>10</sup>, on average, one is able to maintain relationships to around 150 people. Being conservative, we will consider that on average, each person will certify 50 accounts. We can calculate the size of the average web of trust WoTavg :</p> + +<p>WoTavg= (50)*(sigQty/50)^(stepMax-1)</p> + +<p>Our goal with the Ğ1 is to create a community of about one million members to test the consequences of a libre monetary system. Let’s see how we can tweak the pair of sigQty and stepMax- to reach this size:</p><empty-line /><p><emphasis>Average WoT size graph as a function of sigQty and stepMax</emphasis></p> + +<p>The maximum size of a Sybil region grows linearly with sigQty but exponentially with stepMax. Logic has it that we need to keep stepMax as low as possible to ensure sufficient strength to the web. The above graph shows that the lowest value of stepMax for a web of a million members is of 5. This is an order of magnitude and is likely to be much higher in reality, we cannot measure it for sure.</p> + +<p>For sigQty we can choose a value of 4 for a web of 1.5 million members or 5 for half a million members. Bear in mind these are gross figures and could be significantly higher, we are talking anywhere between 1 and 10 million in reality. Calculating WOTavg gives us a pretty good idea of how the web would scale bearing in mind that it considers all members are referent members too -which isn’t the case as explained previously-. Hence the maximum size of the web is likely larger, a ballpark figure of half a million is enough for now especially knowing that the smaller sigQty is, the easier it is to launch a Sybil attack -it’s easier to find four accomplices than five-. For security reasons we have settled on five:</p> + +<p>stepMax = 5 +sigQty = 5 +sigStock \>= 50</p> + +<p>The maximum size of a Sybil region therefore is:</p> + +<p>(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))</p> + +<p>with sigStock = 50 we have a Sybil region of:</p> + +<p>45*(1-10^(5-stepAttackers))/(-9)</p> + +<p>A good practice for protecting the web is to maximise stepAttackers. That’s why we decided that referent members in the genesis block had to be at least four steps away from each other.</p> + +<p>Another way to keep a Sybil attack at bay, were it slow enough for members to notice it, would be for referent members to ‘stretch’ the web intentionally to limit the growth of the region by ensuring that the attackers’ legitimate certifications received in the first place aren’t renewed. But what if bot accounts were created and certified each other super fast and following all rules, how would we counter that? By introducing a minimum length of time between two certifications!</p> + +<p>3.8.2. Time is our friend</p> + +<p>To help us deter a Sybil attack, we’ve decided to impose a minimum period of time between any two certifications issued from a single account. This parameter called sigPeriod affords us a greater chance to detect the formation of a ‘hostile’ faction.</p> + +<p>Here is a graph showing the evolution of a Sybil region with the variation of sigPeriod. The simulation considers that honest members and attackers both issue a certification each sigPeriod interval, in days:</p><empty-line /><p><emphasis>size of the WoT according to sigPeriod and stepAttackers</emphasis></p> + +<p>As we see, there is a strong link between the growth speed of the region and sigPeriod. As evidenced here, we need a sigPeriod high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher sigPeriod is, the more members will exercise their certification power gingerly, the action coming at a higher ‘cost’.</p> + +<p>There are numerous advantages to giving sigPeriod a high value and no technical barriers to it, hence our choice of five days.</p> + +<p>We could have also gone for one week for the sake of simplicity. However there is an underlying idea behind our choice which was quite simply the pace of today’s life. Certifying someone can be a lengthy process as one needs to make sure they are correctly applying the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea to allow one to certify at the end of every working week -five days- instead of a whole calendar one.</p> + +<p>3.8.3. Trust me now, trust me forever ? (</p> + +<p>sigValidity</p> + +<p>,</p> + +<p>msValidity</p> + +<p>)</p> + +<p>There would be two main drawbacks to a lifetime membership in the Ğ1’s Web of Trust:</p> + +<p>First of all, some members will pass and those accounts should no longer produce the Universal Dividend.</p> + +<p>Secondly it is of the utmost importance that ‘rogue’ accounts can be excluded from the web at some point.</p> + +<p>To achieve this, certifications have a limited lifespan. Members need to seek renewal from their peers after sigValidity time. On the other hand, this time can’t be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, a certification with too short a lifespan would foster careless certifying behaviours. The act of certifying must have a high-enough ‘perceived’ cost to make it feel like an important act. Lastly, we also wanted this lifespan to be easy to remember. Historically speaking, we first settled on the values of sigPeriod and sigStock, meant one could issue all of their certifications in 495 days, one year was therefore not long enough. We deemed three years to be too much and that’s how we agreed on two years in the end.</p> + +<p>Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we needed to address. We chose a value of one year for msValidity. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to ‘prune’ the web of past or inactive members who don’t renew their membership.</p> + +<p>3.8.4. Keeping the pools free of information glut (</p> + +<p>idtyWindow</p> + +<p>,</p> + +<p>sigWindow</p> + +<p>,</p> + +<p>msWindow</p> + +<p>)</p> + +<p>The pools need to be cleaned up on a regular basis to avoid them clogging up with information and to ensure that machines with less calculating power can still run a Duniter node.</p> + +<p>To achieve this, identities with pending membership approval and the corresponding certifications have to remain the shortest time possible in the pool while still having a chance of making it into the blockchain.</p> + +<p>For the Ğ1, our opinion was that two months would be enough for all potential certifiers to agree on a specific identity to certify. We also wanted a time period that would be easy enough to remember by all. We settled on two months, and gave this value to all three parameters idtyWindow, sigWindow and msWindow.</p> + +<p>3.8.5. Avoiding single members from ‘knowing too many people’ (</p> + +<p>sigStock</p> + +<p>)</p> + +<p>We considered that on average, each person will certify 50 people. However, we know for a fact that some members will use more than 50 certifications. The maximum social network of one individual is around 150 people<sup>11</sup>. Being conservative, we settled on a maximum certification number sigstock of 100.</p><empty-line /><p> +Since sigStock’s impact on the size of a Sybil region is fairly limited, we did not investigate further this parameter.</p> + +<p>3.8.6. Avoiding locking minorities (</p> + +<p>xpercent</p> + +<p>)</p> + +<p>It’s easy enough to become a referent member, one of the Sybil strategies could therefore be to create a region of referent members. Such a region would grow slower than otherwise but could confer a locking power to its members by using the distance rule. That’s why the distance rule cannot be calculated on 100% of the referent members. Hence the introduction of the xpercent parameter which defines the percentage of referent members needing to be less than five edges -steps- from each other.</p> + +<p>This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance rule. The xpercent parameter was one of the hardest to define, therefore we might decide to change its value during the Ğ1 experiment.</p> + +<p>We were inspired by the Pareto principle<sup>12</sup>: if at least 20% of members give good density to the web, 80% of the referent members will be five or less steps from any other member -referent or not-. The maximum value for xpercent is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%.</p> + +<p>3.8.7. Spam protection with (</p> + +<p>msPeriod</p> + +<p>)</p> + +<p>This parameter stands out a bit on its own, as it was added after the genesis block. It is there to protect the Duniter P2P infrastructure against ‘spam’ attacks. We had to think of a strategy against attacks such as high-frequency membership renewal requests -i.e: in every block, every five minutes- or worse still, hundreds of these requests per minute to flood the Duniter nodes. Without such limits, nodes are supposed to address all renewal requests, even in cases where they were last published five minutes ago! The msPeriod parameter was given the same value as idtyWindow, sigWindow and msWindow, i.e. two months.</p> + +<p>4. Proof of Work with personal difficulty</p> + +<p>As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human.</p> + +<p>This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each “winning” member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. A view of the whole network is not needed.</p> + +<p>Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power.</p> + +<p>One could say that Duniter uses a PoW that needs very low energy consumption compared to BitCoin : an “ecological” PoW ?</p> + +<p>4.1. Why do we need Proof of Work ?</p> + +<p>Duniter nodes share a database as part of a p2p environment. The proof of work (PoW) allows machines to synchronize with each other. In Duniter’s case, the blockchain is our database, and acts as a ledger keeping a trace of all transactions, status of the WoT and more. How can we let several machines add data (ie: a transaction) at the same time? In addition, how do we settle on how much time has gone by since the blockchain was last updated? Agreement on time is of the utmost importance as we want to create Universal Dividends on a regular basis, and keep track of membership status, both in human time.</p> + +<p>Proof-of-work provides a clever solution to both problems:</p><empty-line /><p>Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, ensuring the unicity of a block’s creator.</p> + +<p>Solving this challenge takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and Duniter adapts the challenge difficulty to get an average duration corresponding to this block time.</p> + +<p>4.2. Only members can “mine”</p> + +<p>One of Duniter’s major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member’s private key, allowing the algorithm to determine a personalised difficulty.</p> + +<p>This personalised difficulty eliminates the rat-race for the most sophisticated and powerful mining equipment. Another benefit is the fact that no “supercomputer” can take control of the blockchain. Lastly, Duniter implements a rotation in forging members thanks to this personalized difficulty.</p> + +<p>This lightweight PoW is much less energy-consuming than other PoW cryptocurrencies. Members can mine with anything from a raspberry pi to a privacy-first internet cube.</p> + +<p>4.3. How does it work ?</p> + +<p>4.3.1. The hash (aka digest)</p> + +<p>Example of a valid hash:</p> + +<p>00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653</p> + +<p>As you can see this hash starts with five zeros which was very hard to achieve and took a lot of work for someone’s computer. Hence the term “proof of work”.</p> + +<p>4.3.2. The common difficulty</p> + +<p>A common difficulty is needed to settle on a yardstick for our time reference. Its role is to make sure the blockchain moves forward at a steady pace - one block every avgGenTime seconds, avgGenTime being one of the 20 parameters behind the Duniter protocol-.</p> + +<p>This difficulty’s initial value can be set to any arbitrary value (70 in Duniter v1.5.x) and then acts as a spring, regulating blocktime creation by increasing itself if the creation interval drops under avgGenTime and vice-versa.</p> + +<p>4.3.2.1. How is difficulty applied ?</p> + +<p>The numeric value of difficulty is taken from an array of possible hashes out of all possible hashes. In DUBPv13 the hash of a block is its sha256 hexadecimal hash.</p> + +<p>To understand the difficulty, we make a euclidiean division of the difficulty by 16.</p> + +<p>Here’s an example with a difficulty value of 70 :</p> + +<p>70 // 16 = 4 with a remainder of 6.</p> + +<p>The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : 0000[0-9]. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes.</p> + +<p>4.3.2.2. The Nonce</p> + +<p>When a member is forging a new block, his computer freezes the block’s content and changes the Nonce until the hash reaches the required number of zeroes.</p> + +<p>The nonce allows us to mine a new block by finding a hash. The hash value allows us to determine the difficulty level of the proof-of-work performed. Examples of possible Nonce values:</p> + +<p>10100000112275</p> + +<p>10300000288743</p> + +<p>10400000008538</p> + +<p>10700000079653</p> + +<p>10300000070919</p> + +<p>In reality the Nonce value follows a pre-determined format akin to XYY00000000000. The Nonce’s value isn’t the number of attempts but rather a value within a set of possible ones. This is how the Nonce is built:</p><empty-line /><p>X is a number assigned to a specific peer. Let’s assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with different nodes. Each <strikethrough>block</strikethrough> node ? will therefore have its own unique X to prevent this from happening.</p> + +<p>Y is the number of cores of the processor. The Nonce starting with 107[…] belongs to a seven cores processor, while 199[...] could be the proof generated by a 99 cores processor.</p> + +<p>The rest of the Nonce, the part that follows after the XYY, is the numerical space for this individual node and is unique to each of the CPU’s core. This space is comprised of eleven digits (00000000000). For the sake of accuracy, we use the term CPU in the wider sense, it can be understood as a bi-CPU for example. We take into consideration the number of cores for the resulting PoW.</p> + +<p>4.4. Personalised difficulty</p> + +<p>Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other PoW-based cryptocurrencies.</p> + +<p>Here is how this personalised difficulty is calculated and assigned:</p> + +<p>It is determined by a combination of two different constraints with complimentary roles: the exclusion factor and the handicap.</p> + +<p>Let powMin be the common difficulty, exFact a member’s exclusion factor and handicap their handicap. This member’s personalised difficulty diff is:</p> + +<p>diff = powMin*exFact + handicap</p> + +<p>4.4.1. Understanding</p> + +<p>exFact</p> + +<p>, the exclusion factor</p> + +<p>Members who have never produced blocks or haven’t for quite some time are assigned an exclusion factor of 1. Their personalised difficulty is therefore simply the sum of powMin + handicap.</p> + +<p>Before reading on, let’s precise the role of this exclusion factor. When a member adds a block to the chain, his exFact jumps up from one to a very high value, to prevent them from forging other blocks immediately after and taking control of the blockchain.</p> + +<p>The exclusion factor will then rapidly return to one. This delay is expressed as a number of blocks. It is calculated as a proportion of the number of members forging. In the Ğ1’s case, this proportion is 1/3, meaning that if there are fifteen members currently forging, the member’s exclusion factor will drop down to one after five blocks.</p> + +<p>4.4.1.1. What is intended by “the number of members forging” ?</p> + +<p>We mean the number of members trying to create the next block. In reality, there is no way to precisely know how many members are calculating at any given time, because it is impossible to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block in the last blocks in the current window, minus the very last one.</p> + +<p>4.4.1.2. Current window</p> + +<p>We use the concept of current window. The current window is the number of blocks we look back at to determine how many members are forging. Let’s see how it works:</p><empty-line /><p>issuersFrame is the size of the current window in blocks.</p> + +<p>issuersCount the number of members who have calculated at least one block during the current window.</p> + +<p>Both issuersFrame and issuersCount are block fields. When first starting a blockchain, the very first block has an issuersFrame=1 and an issuersCount=0. The genesis block is excluded as there are no members in the current window!</p> + +<p>From the second block onwards (block #1) we track the variation of issuersCount. The member having mined block #0 enters the current window and in block #1 we will therefore mention issuersCount=1.</p> + +<p>issuersFrame then varies as follows:</p> + +<p>if issuersCount increases by N (with a maximum step of N = 1), then issuersFrame will increase by one unit over a period of 5N blocks.</p> + +<p>Conversely, if issuersCount decreases by Y (with a maximum step of Y = 2 = current window inching forward + loss of one calculating member), then issuersFrame will decrease by one unit during 5Y blocks.</p> + +<p>When such events overlap, issuersFrame evolves as so :</p><empty-line /><p><strong>bloc</strong></p> + +<p><strong>event</strong></p> + +<p><strong>issuersFrame</strong></p><empty-line /><p>T</p> + +<p>Babar writes a block and enters issuersCount</p> + +<p>160</p><empty-line /><p>T+1</p> + +<p>Celeste leaves issuersCount</p> + +<p>160 +1 = 161</p><empty-line /><p>T+2</p> + +<p>N/a</p> + +<p>161 +1 -1 = 161</p><empty-line /><p>T+3/4/5</p> + +<p>N/a</p> + +<p>161 +1 -1 = 161</p><empty-line /><p>T+6</p> + +<p>N/a</p> + +<p>161 -1 = 160</p><empty-line /><p>The calculation can be found under rules BR_G05 and BR_G06 of the DUP protocol.</p> + +<p>4.4.1.3. exFact and the personalised difficulty</p> + +<p>We explained that exFact spikes immediately after the member has found a block. It decreases then rapidly to 1 after a number of blocks equal to 1/3 * issuersCount. Let’s see precisely how we calculate exFact:</p><empty-line /><p>nbPreviousIssuers is the value of issuersCount at the last block N found by the member.</p> + +<p>nbBlocksSince is the number of blocks found by the rest of the network since block N.</p> + +<p>percentRot is the number of <emphasis>not excluded</emphasis> peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency.</p> + +<p>a = FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) +exFact = MAX [ 1 ; a ]</p> + +<p>The FLOOR is a simple truncate function. For exFact to exclude the member, we need :</p> + +<p>(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2</p> + +<p>We can see that the member is not excluded if nbBlocksSince is greater than 1/3 of the calculating members. Take as an example nbPreviousIssuers = 6 and nbBlocksSince = 3:</p> + +<p>(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1</p> + +<p>However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded:</p> + +<p>(0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2</p> + +<p>Moreover if the last block was authored by the said member, then:</p> + +<p>nbBlocksSince=0 and +exFact = 0.67 * nbPreviousIssuers</p> + +<p>ExFact value increases according to the number of members calculating. Thus, if there is enough members calculating, even mining farms would be excluded. We have therefore succeeded in our intent to deter attempts to seize the blockchain and its currency.</p> + +<p>However, at any time t, the two-thirds of calculating members all have an exclusion factor of 1, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then only the members with the highest computational power from the remaining third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn’t stand a chance…</p> + +<p>4.4.2. The handicap</p> + +<p>The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. A higher handicap is assigned to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW.</p> + +<p>The aim is to handicap the half that has authored most blocks (the most powerful half) to favour the other one. So, the handicap formula will use the median number of blocks authored by peers within the current window.</p><empty-line /><p>nbPersonalBlocksInFrame is the number of blocks authored by a single member within the current window.</p> + +<p>medianOfBlocksInFrame is the median number of blocks written by the calculating members during the same timeframe.</p> + +<p>a = (nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame +handicap = FLOOR(LN(MAX( 1 ; a )) / LN(1.189))</p> + +<p>Let’s unwrap the formula:</p> + +<p>(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)</p> + +<p>is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored 9 blocks in the current window and the median is 5, then the ratio will be (9+1)/5 = 2. The MAX function allows us to ensure that the handicap has a value at least equal to 1.</p> + +<p>The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers.</p> + +<p>If we wanted the handicap to be applied as soon as the median is reached, we would divide it by LN(1). The problem is that we have already set a minimum value of 1 with the MAX function. If we were to divide the ratio by LN(1) all calculating peers would have a handicap \>= 1. In addition, is it really fair to handicap a member who is right on the median?</p> + +<p>That’s why we went for 1.189 rather than 1. A member has to be at least 18.9% above the median to be assigned a handicap. 18.9% is actually 16^(1/16), the difficulty factor between two levels of the proof work (hexadecimal hash).</p> + +<p>To conclude, you have to remember that :</p> + +<p>The handicap is indexed on the logarithm of the ratio to the median,</p> + +<p>Handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work’s difficulty.</p> + +<p>Conclusion</p> + +<p>Duniter’s Blockchain can be compared to Bitcoin’s : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend.</p> + +<p>More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers, maintaining a good security and helping decentralization of calculation.</p> + +<p>The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties :</p> + +<p>The freedom to choose your currency system: because money should not be imposed.</p> + +<p>The freedom to access resources: because we all should have access to economic & monetary resources.</p> + +<p>The freedom to estimate and produce value: because value is a purely relative to each individual.</p> + +<p>The freedom to trade with the money: because we should not be limited by the avaible money supply.</p> + +<p>Those 4 economic freedoms should be understood together, not exclusively. Plus, “freedom” has to be understood as “non-nuisance”. So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency.</p> + +<p>Sources :</p> + +<p>Relative Theory of Money, S.Laborde, 2010: en.trm.creationmonetaire.info/</p> + +<p>Bitcoin Whitepaper, S.Nakamoto, 2008: bitcoin.org/bitcoin.pdf</p> + +<p>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : lightning.network/lightning-network-paper.pdf</p> + +<p>The GNU Privacy Handbook, M.Ashley, 1999 : www.gnupg.org/gph/en/manual.html#AEN335</p> + +<p>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. cr.yp.to/papers.html#ed25519.</p> + +<p>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : archive.org/details/PPCoinPaper</p> + +<p>Duniter Blockchain Protocol, v13, draft by Elois : git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md</p> + +<p>The Sibyl Attack, J.R.Douceur: www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</p> + +<p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992</p><empty-line /><empty-line /><empty-line /><p>Bitcoin Whitepaper, S.Nakamoto, 2008: bitcoin.org/bitcoin.pdf↩</p> + +<p>Relative Theory of Money, S.Laborde, 2010: en.trm.creationmonetaire.info/↩</p> + +<p>OpenPGP protocol defines standard formats for encrypted messages, signatures, private keys, and certificates for exchanging public keys. The GNU Privacy Handbook, M.Ashley, 1999 : www.gnupg.org/gph/en/manual.html#AEN335↩</p> + +<p>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. cr.yp.to/papers.html#ed25519.↩</p> + +<p>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : archive.org/details/PPCoinPaper↩</p> + +<p>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : lightning.network/lightning-network-paper.pdf↩</p> + +<p>Surfing a Web of Trust, Reputation and Reciprocity on CouchSurfing.com, D.Lauterbach, H.Truong, T.Shah, L.Adamic: snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf↩</p> + +<p>Public key validation on GnuPG manual, M.Ashley, 1999 : www.gnupg.org/gph/en/manual.html#AEN335↩</p> + +<p>The Sibyl Attack, J.R.Douceur: www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf↩</p> + +<p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992↩</p> + +<p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992↩</p> + +<p>Pareto principle : en.wikipedia.org/wiki/Pareto_principle↩</p><empty-line /> +</section> + +</body> +</FictionBook> \ No newline at end of file diff --git a/build/whitepaper_en.html b/build/whitepaper_en.html index 7232bd365c6e1d38a63eaafed41125c0ad141e6b..28876029826eea8f675f6084ec5cf08445eef2b7 100644 --- a/build/whitepaper_en.html +++ b/build/whitepaper_en.html @@ -10,26 +10,61 @@ Duniter Whitepaper href='bulma.css' > <link rel='stylesheet' href='main.css' > -<script src='js/jquery.js' ></script > -<script src='js/toc.js' ></script > -<script type='javascript' > - if ($) { - $('#whitepaper').tableofcontents({ id: '#toc' }); - } +<script type='text/javascript' > + /** + * Generates a table of contents for your document based on the headings + * present. Anchors are injected into the document and the + * entries in the table of contents are linked to them. The table of + * contents will be generated inside of the first element with the id `toc`. + * @param {HTMLDOMDocument} documentRef Optional A reference to the document + * object. Defaults to `document`. + * @author Matthew Christopher Kastor-Inare III + * @version 20130726 + * @example + * // call this after the page has loaded + * htmlTableOfContents(); + */ + function htmlTableOfContents(documentRef) { + var documentRef = documentRef || document; + var toc = documentRef.getElementById('table_of_contents'); + var headings = [].slice.call(documentRef.body.querySelectorAll('h1, h2, h3, h4, h5, h6')); + headings.forEach(function (heading, index) { + var anchor = documentRef.createElement('a'); + anchor.setAttribute('name', 'toc' + index); + anchor.setAttribute('id', 'toc' + index); + + var link = documentRef.createElement('a'); + link.setAttribute('href', '#toc' + index); + link.textContent = heading.textContent; + + var div = documentRef.createElement('div'); + div.setAttribute('class', heading.tagName.toLowerCase()); + + div.appendChild(link); + toc.appendChild(div); + heading.parentNode.insertBefore(anchor, heading); + }); + } + + try { + module.exports = htmlTableOfContents; + } catch (e) { + // module.exports is not defined + console.error('e', e) + } </script > </head > -<body> +<body onload="htmlTableOfContents();"> <main> -<div id="toc"> - -</div> +<nav id='table_of_contents' ></nav > <article id="whitepaper" class="content"> -<h1 id="duniter-a-libre-currency-blockchain-generator">Duniter : A libre currency blockchain generator !</h1> -<h2 id="abstract-todo">Abstract (TODO)</h2> +<h1 id="duniter-a-libre-currency-blockchain-generator.">Duniter: A libre currency blockchain generator.</h1> +<h2 id="abstract">Abstract</h2> +<p>Many currency principles involve non-equal rights to monetary creation between humans. We propose a monetary creation based on the Relative Theory of Money, which guarantee equal monetary creation for each willing human. This type of currency can be centralised, however, this could lead to censorship and arbitrary choices of the central institution. Thus, strongly inspired by Bitcoin example, we want the currency to be as decentralised as possible, in the transaction network as in the human identification process. We use a Web of Trust between living humans for identification. This web of trust allows us to impose personalised difficulty for transaction validation, keeping the calculation accessible to low-end hardware and allowing all competent members to secure the currency.</p> <h2 id="introduction">Introduction</h2> <p>Duniter is a software to create and manage “libre currencies”. Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question :</p> <blockquote> -<p>How should a currency be created to match the principle of equality between all humans ?</p> +<p>How should a currency be created to match the principle of equality between all humans, now and between generations ?</p> </blockquote> <p>The results of this demonstration implies a monetary creation :</p> <ul> @@ -38,752 +73,267 @@ Duniter Whitepaper <li>which amount has to be reassessed on fixed intervals according to a fixed formula.</li> </ul> <p>Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula :</p> -<blockquote> -<p>UD(t+1) = UD(t) + c² * ( M(t) / N(t) )</p> -</blockquote> +<p><br /><span class="math display">$$ UD(t+1) = UD(t) + c²*( {M(t) \over N(t) }) $$</span><br /></p> <p>Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin.</p> -<p>The first currency created through Duniter is Ğ1 (say “June”). It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software.</p> -<h2 id="state-of-the-art-bitcoin-case">State of the art : Bitcoin case</h2> +<p>The first currency created through Duniter is Ğ1, pronounced “June”. It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software.</p> +<h2 id="state-of-the-art-bitcoin-case">1. State of the art : Bitcoin case</h2> <!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniter uses the crypto-currency concept introduced by Bitcoin, which is to use cryptographic tools such as <em>signatures</em> to create digital currencies. Duniter fits this definition, but it has completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects.</p> -<h3 id="monetary-creation-of-bitcoin-a-space-time-asymmetry">Monetary creation of Bitcoin : a space-time asymmetry</h3> -<p>Space-time asymmetry refers to the relative access of individuals to newly created money (Relative Theory of Money, S.Laborde, 2010). Concretely, all existing currencies (c. 2015) are both spatially and temporally asymmetrical for their users. Let's take Bitcoin as an example to understand why.</p> -<h4 id="spatial-asymmetry">Spatial asymmetry</h4> -<p>When new Bitcoins are created, <em>only some Bitcoin users</em> (the miners) are given new Bitcoins, while everyone else get nothing. <strong>We believe this is the <em>first</em> injustice.</strong> However, some might say:</p> -<blockquote> -<p>"Miners used their <em>electricity and time</em> to get it!"</p> -</blockquote> -<p>... we would answer that this work <em>shouldn't have been rewarded by newly created Bitcoins</em>. New Bitcoins should be distributed to the whole Bitcoin community. Miners should be rewared another way, but not by money issuance. Of course, Bitcoin can't create money through Basic Income since <em>Bitcoin users are not strongly identified</em>, and one might benefit from money creation multiple times if he owned several wallets. Duniter gets rid of this problem completely by identifying its users and giving <em>the same amount of Basic Income to everyone</em>.</p> -<h4 id="temporal-asymmetry">Temporal-asymmetry</h4> -<p>Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, how will future joiners get Bitcoins? Just like Euros or Dollars: to get money, they will have to work for the ones who already own it. <strong>We believe this is the <em>second</em> injustice.</strong> Every member of a monetary community should be equal concerning monetary creation, and get the same relative amount of money over time, <em>even if they are a late adopter</em>. Duniter aims to fix this by making the Universal Dividend (a.k.a. <em>UD</em>) <em>grow by the time</em> (S.Laborde, 2010) according to precise rules, thus making members equal toward money issuance on a half-lifespan.</p> -<h4 id="a-solution">A solution</h4> -<p>Bitcoin has taught us that <em>it is possible</em> to create a currency system allowing one to both create digital money and to exchange it without a central authority. What we need to change is <em>the way money is issued</em> so we finally have a symmetrical system. We need Bitcoin <em>+ Universal Dividend</em>. But Universal Dividend <em>implies</em> that the community consists of only identified people. This is where the Web of Trust (WoT) comes into place. This concept, introduced by cryptography with the <a href="https://www.wikiwand.com/en/Pretty_Good_Privacy">OpenPGP</a> format, allows us to identify people in a <em>decentralized</em> manner. It works as follows: each person creates <em>a personal identity</em> that is linked to its cyptographic certificate. The identity must be confirmed by others members who use their own cryptographic key. It is that simple: <strong>people choose who is part of the community and who is not, not a central authority.</strong></p> -<blockquote> -<p>Duniter however won't use OpenPGP for its cryptographic features: Elliptic Curves will be used instead for the conciseness of its generated keys and its pratical advantages. Duniter has its own Web of Trust principles, that shall be exposed later.</p> -</blockquote> -<h3 id="proof-of-work-mining-a-power-race-todo">Proof-of-Work mining : a power race (TODO)</h3> -<p>In Bitcoin Model, the calculation and incentive principles cause a power race : new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. The goal of Duniter is to make blockchain validation much less energy and hardware consuming while keeping a strong level of security. As a consequence, even low-power hardware can secure Duniter Blockchain, which leads to a better decentralization of forging operations.</p> -<h3 id="other-projects">Other projects ?</h3> -<h4 id="what-about-pos">What about PoS ?</h4> -<p>When conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead to placing power over the currency in the richests hands : this is contrary to the symmetical principles of Duniter.</p> -<p>Now that PoS is well-tested, one could try to use Duniter’s WoT to create a PoS-like algorithm with equal chances among members. But this is not our aim for now.</p> -<h4 id="what-about-directed-acyclic-graph">What about Directed Acyclic Graph ?</h4> -<p>The Circles project uses DAG in a basic income cryptocurrency. However, in this project, one peer cannot know the whole monetary mass and the exact number of other peers. The calculation of Universal Dividend <code>UD = c * M/N</code> seems impossible, since we know neither M nor N.</p> -<h2 id="duniters-blockchain">Duniters Blockchain</h2> +<p>Duniter uses the crypto-currency concept introduced by Bitcoin<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a>, which is to use cryptographic tools such as signatures to create trustless digital currencies. Duniter fits this definition, but it has two completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects.</p> +<h3 id="monetary-creation-a-space-time-asymmetry">1.1. Monetary creation of Bitcoin : a space-time asymmetry</h3> +<p>Space-time asymmetry refers to the relative access of individuals to newly created money<a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a>. Concretely, most existing currencies (c. 2020) are both spatially and temporally asymmetrical for their users. Let's take Bitcoin as an example to understand why.</p> +<h4 id="spatial-asymmetry">1.1.1. Spatial asymmetry</h4> +<p>When new Bitcoins are created, only some Bitcoin users (the miners) are given new Bitcoins, while everyone else get nothing. We believe this is the first injustice. However, some might say:</p> +<blockquote> +<p>"Miners used their electricity and time to get it!"</p> +</blockquote> +<p>... we would answer that this work should not have been rewarded by newly created Bitcoins. New units should be distributed to the whole community. Miners should be rewared another way, but not by money issuance. Of course, Bitcoin cannot create money through Basic Income since Bitcoin users are not strongly identified, and one might benefit from money creation multiple times if they owned several wallets. Duniter gets rid of this problem by identifying its users and creating the same amount of Basic Income to everyone.</p> +<h4 id="temporal-asymmetry">1.1.2. Temporal-asymmetry</h4> +<p>Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, how will future joiners get Bitcoins? Just like most of us do for Euros or Dollars: to get money, they will have to work for the ones who already own it.</p> +<p>We believe this is the second injustice. Every member of a monetary community should be equal concerning monetary creation, and get the same relative amount of money over time, even if they are a late adopter. Duniter aims to fix this by making the Universal Dividend (a.k.a. UD) grow by the time according to precise rules, thus making members equal toward money issuance on a half-lifespan.</p> +<p>Most currencies present one of these two asymmetries, including metal currencies and mutual credit, as exposed in the RTM.</p> +<h4 id="a-solution">1.1.3. A solution</h4> +<p>Bitcoin has taught us that it is possible to create a currency system allowing one to both create digital money and to exchange it without a central authority. What we need to change is the way money is issued so we finally have a symmetrical system. We need <strong>Bitcoin + Universal Dividend</strong>. But Universal Dividend implies that the community consists of only identified people. This is where the Web of Trust (WoT) comes into place.</p> +<p>This concept, introduced by cryptography with the OpenPGP format<a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a>, allows us to identify people in a decentralized manner. It works as follows: each person creates a personal identity that is linked to its cyptographic certificate. The identity must be confirmed by others members who use their own cryptographic key. It is that simple: people choose who is part of the community and who is not, not a central authority.</p> +<p>However, Duniter will not use OpenPGP for its cryptographic features: Elliptic Curves<a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a> will be used instead for the conciseness of its generated keys and its pratical advantages. Duniter has its own Web of Trust principles, that will be exposed later.</p> +<h3 id="proof-of-work-mining-a-power-race">1.2. Proof-of-Work mining : a power race</h3> +<p>In Bitcoin Model, the calculation and incentive principles cause a power race : new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. This leads to a power race an places the control over the currency in the hands of the richest hardware owners. We want to make Duniter blockchain validation much less energy and hardware consuming while keeping a strong level of security. This will be further explained later. A consequence of this choice is the participation of low-end hardware in the Duniter network, leading to a better decentralization of blockchain validation.</p> +<h4 id="what-about-proof-of-stake">1.2.1 What about Proof of Stake ?</h4> +<p>Proof of stake consensus algorythm was first introduced in 2012<a href="#fn5" class="footnote-ref" id="fnref5"><sup>5</sup></a>. The basic principle is to allow the richest wallets to issue blocks, putting their coin balance as a “stake” they would lose in case of cheat.</p> +<p>At the time of conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. We did not chose this consensus principle. Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead to placing power over the currency in the richests hands : this is contrary to the symmetical principles of a libre currency.</p> +<h2 id="duniters-blockchain">2. Duniters Blockchain</h2> <!-- source : https://duniter.org/en/theoretical/ --> <p>Duniters Blockchain follows the basic principles of Bitcoins. This is essential for synchronization between peers, as to prevent double-spend attacks. However, Duniters Blockchain will store different informations than Bitcoins.</p> -<p>The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no <em>generation transaction</em> exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either:</p> +<p>The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no generation transaction exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either:</p> <ul> <li>a former transaction (as in Bitcoin)</li> <li>a Universal Dividend (specific to Duniter).</li> </ul> -<p>Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactinos are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where “space” are members of the WoT and “time” the basci blockchain units : the blocks. On each point of time, one can determain whick account is legitimate to create the UD, only with a blockchain analysis.</p> -<h3 id="spam-countermeasures-todo">Spam countermeasures (TODO)</h3> -<p>An issue of most cryptocurrency projects is to prevent the common ledger from growing too much and require lot of storage and computing power to be usable. In particular, we don’t want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don’t want to do this since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented.</p> +<p>Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactions are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where “space” are members of the WoT and “time” the basic blockchain units : the blocks. On each point of time, one can determine which account is legitimate to create the UD, only with a blockchain analysis.</p> +<h3 id="spam-countermeasures">2.1. Spam countermeasures</h3> +<p>An issue of most cryptocurrency projects is to prevent the common ledger from growing too much. This would require nodes to have a lot of storage and computing power to be usable. In particular, we don’t want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don’t want to introduce this mean since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented.</p> <!-- see : https://forum.duniter.org/t/sans-frais-de-transaction-comment-resister-aux-attaques/3846/25 (implemented ?)--> -<ul> -<li>output minimal de 100*Unitbase / 1 unité -> empêche un attaquant de faire grossir la BC et les index trop vite (DUBP v12)</li> -<li>chaînage maximal des tx</li> -<li>seuils de dépense (implémentés ? en tout et par issuer ?)</li> -</ul> -<h3 id="scaling">Scaling</h3> +<h4 id="minimum-output-amount">2.1.1. Minimum output amount</h4> +<!-- This has to be implemented in DUBPv13. --> +<p>Fixing a minimal output amount reduces the power of an attack. Duniter deals with cents of Ğ1 or 1/1000 of the first UD. An attacker could create thousand accounts with only 1 UD. To prevent this, a valid transaction must have output amounts of minimum 1Ğ1. This reduces the power an attack by 100.</p> +<h4 id="limited-block-size-and-chainability">2.1.2. Limited block size and chainability</h4> +<p>The block size is always limited. While the protocol allows this limit to evolve to address scaling issues, an attacker cannot register as many transaction as they wish.</p> +<p>With the same goal to prevent too many transactions to get registered, while transactions can be “chained” (refer to another transaction in the same block), the chainability of transactions is limited to 5.</p> +<h3 id="scaling">2.2. Scaling</h3> <p>Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons :</p> <ul> -<li>Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don’t want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT limits its size to around 16 million members.</li> -<li>Duniter’s aim is to be used to create <em>multiple</em> libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community.</li> -</ul> -<p>However, Duniter has two assets that might be used if the number of users grow.</p> -<h4 id="dynamic-block-size">Dynamic block size</h4> -<p>While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks( <em>current window</em> will be described in the PoW part). This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it.</p> -<div class="{highlight}"> -<p>block_size < max(500 ; CEIL(1.10 * (average block size))</p> -</div> -<h4 id="lightning-networks">Lightning Networks</h4> -<p>The Lightning Networks allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed.</p> -<h2 id="duniter-web-of-trust">Duniter Web of Trust</h2> -<!-- source : https://duniter.org/en/deep-dive-into-the-web-of-trust --> -<h3 id="basic-principles">Basic Principles</h3> -<p>In order to identify “members” account - which create monetary units - from other accounts, Duniter uses a Web of Trust. This can be summarized into few principles:</p> -<ul> -<li>Each account becomes a member if it received a minimal number of certifications (5 for Ğ1 currency)</li> +<li>Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don’t want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT should limit its size to around 16 million members.</li> +<li>Duniter’s aim is to be used to create multiple libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community.</li> +</ul> +<p>However, Duniter has assets that will help if the number of users and transactions grow.</p> +<h4 id="dynamic-block-size">2.2.1 Dynamic block size</h4> +<p>While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks(see “personalised difficulty” part for more information). This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. The block size (in bytes) is limited as so :</p> +<pre><code>block_size < max(500 ; CEIL(1.10 * (average block size))</code></pre> +<h4 id="lightning-networks">2.2.2. Lightning Networks</h4> +<p>The Lightning Networks<a href="#fn6" class="footnote-ref" id="fnref6"><sup>6</sup></a> allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed.</p> +<h4 id="unit-base">2.2.3. Unit base</h4> +<p>As the Universal Dividend grows exponentially, with time Duniter nodes would have had to deal with always largest amounts, eventually reaching the BIGINT limit. To avoid this, the amounts are expressed with a unit base in base 10. We want the UD amount to always fit in 4 digits. To manage it, the <code>unitbase</code> is updated each time the UD value reaches 100.00 : it goes from <code>99.99*10^(unitbase)</code> to <code>10.00*10^(unitbase+1)</code>. All the unit amounts are thus divided by 10. While this might seem strange, this process has already hapened in state currencies. Moreover, the amounts expressed in UD will not change.</p> +<p>With a monetary growth of 10% each year and a stable population, such a change of unit base would happen each 25 years.</p> +<h2 id="duniter-web-of-trust">3. Duniter Web of Trust</h2> +<h3 id="duniter-wot-basic-principles">3.1. Basic Principles</h3> +<p>In order to identify “members” accounts - which create monetary units - and other accounts, Duniter uses a Web of Trust. This can be summarized into few principles:</p> +<ul> +<li>Each account becomes a member if it received a minimal number of certifications - 5 for Ğ1 currency.</li> <li>Only members accounts can send certifications. Certifications have a limited lifespan.</li> <li>A certification indicates that the sender accepts the receiver as a legitimate identity.</li> </ul> -<p>The aim of the WoT is to identify a blockchain account to a living human. Each member of the Ğ1 currency signs a licence stating that they will only certify humans they know well (among other rules). Thus, if a member is part of an attack on the currency, they can be found by mutual friends. The security of Ğ1 currency stands on:</p> -<ul> -<li>Corroborating informations on members (5 certifications)</li> -<li>Peer pressure by close relatives</li> -<li>Law if the licence has not been respected.</li> -</ul> -<p>Note that non-members accounts can use the currency, but cannot create money. They can be used by individuals as secondary wallets, or by institutions.</p> -<p>However, the WoT does not rely only on trust betwenn people. Rules have been added to increase the security, and we will present them.</p> -<h3 id="why-do-we-need-a-web-of-trust">Why do we need a Web of Trust?</h3> +<p>The aim of the WoT is to identify a blockchain account to a living human. According to Lauterbach et.al<a href="#fn7" class="footnote-ref" id="fnref7"><sup>7</sup></a>, the strengh of a relationship should be considered when building a vouch system. For this reason, the Ğ1 Web of Trust rules are expressed in a licence stating what WoT certifications are. A certification represents a strong human relationship : one may certify a close relative, not an acquaintance. Each member has to accept this licence before being included in the WoT. Thus, if a member is part of an attack on the currency, they can be found by mutual relatives. Additional security rules occur to prevent cheat and attacks on a large scale.</p> +<p>Note that non-members accounts can use the currency, but cannot create money. Non-members accounts can be used by individuals as secondary wallets, or by institutions.</p> +<p>We were inspired by the OpenPGP Trust system<a href="#fn8" class="footnote-ref" id="fnref8"><sup>8</sup></a>. However, the OpenPGP trust principles aim at defining trust from a particular point of view while Duniter needs to identify humans for the whole community. To achieve this goal, while OpenPGP allows each user to tweak its trust parameters individually, Duniter sets rules in the “genesis” block for the whole community.</p> +<h3 id="why-do-we-need-a-web-of-trust">3.2. Why do we need a Web of Trust ?</h3> <p>There are two reasons we need it :</p> <ol type="1"> -<li>To make sure that only one Universal Dividend is produced per member at each specified creation interval -in the Ğ1’s case this interval is set as daily <code>86 400</code> seconds-, it is the <em>monetary parameter</em> known as <code>dt</code>-.</li> -<li><p>To identify the nodes hashing the blocks and assign them each a personalised difficulty. This custom difficulty <a href="https://en.wikipedia.org/wiki/Proof-of-work_system">proof of work</a> is there to avoid the blockchain’s validation mechanism becoming too centralised as is the case with many 'non-libre’ cryptocurrencies.</p> -<blockquote> -<p>Wait, what’s a ‘monetary parameter’ ?</p> -</blockquote></li> +<li>To make sure that only one Universal Dividend is produced per member at each specified creation interval. In the Ğ1’s case this interval is set as daily <code>86 400</code> seconds, it is the <em>monetary parameter</em> known as <code>dt</code>.</li> +<li>To identify the nodes hashing the blocks and assign each a personalised difficulty. This custom difficulty proof of work is there to avoid the blockchain’s validation mechanism becoming too centralised as is the case with many 'non-libre’ cryptocurrencies.</li> </ol> -<p>Every currency implementing Duniter has its own blockchain whose behaviour is dictated by a set of ‘parameters’ -defined in block zero, the so-called genesis block- that can be tweaked to achieve the desired results. At the time of writing this article, the Duniter protocol -aka DUP- has a total of 21 parameters of which 10 are for the WoT alone. We’ll focus on these 10.</p> -<p>Suffice to say that in the Ğ1’s case, the DU is created every 24 hours -86 400 seconds- but this interval -set through the time derivative <code>dt</code> parameter- can have a different value in an other implementation of the protocol.</p> -<p>I won’t write about the second parameter having to do with the proof of work, it’s outside our scope here, just know that the Web of Trust allows us to <strong>identify</strong> the members providing hashing power, which we couldn’t do without it. This crucial feature means we can impose a rotation between the members hashing the blocks so that no single rich individual or group invests in a giant ‘hash farm’ and takes a hold of the blockchain, paralysing the community!</p> -<p>Let’s go back to the first objective: to make sure that each member can only have one account. As we all know, achieving zero-risk isn’t possible, our goal is therefore not to create a WoT within which fraud would be absolutely impossible but instead to discourage it. Here is a rewording of our goal in 4 smaller ones :</p> -<ol type="1"> -<li>To make the certification process lengthy enough that all members exercise due diligence and are wary of risks.</li> -<li>To make fraudulent acts as hard as we can to the extent that they become pointless.</li> -<li>To ensure that any Sybil attacks have a negligible impact on the currency -<em>by ensuring that illegitimate double Universal Dividends have no significant bearing on the legitimate monetary mass</em>-</li> -<li>To slow the growth of ‘Sybil regions’ to give enough time for the community to react and isolate the threat.</li> -</ol> -<blockquote> -<p><strong>Wait, a Sybil what ?</strong></p> -</blockquote> -<p>A <a href="https://en.wikipedia.org/wiki/Sybil_attack"><strong>Sybil attack</strong></a>, is the name given to attacks perpetrated on a reputation system through the creation of fake identities. A Web of Trust is a specific instance of a <a href="https://en.wikipedia.org/wiki/Reputation_system"><strong>Reputation System</strong></a>.</p> -<p>There are plenty of Sybil attack scenarios we can think of and just as many reasons why their perpetrators would want to carry them out. Our objective is that the configuration of the WoT protects both users and its IT backbone infrastructure against these attacks.</p> -<p>This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web’s role isn’t to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing your tap water and electricity but isn’t responsible for any burglaries etc. Much in the same way, Duniter’s WoT guarantees us all a functional currency and that’s quite a feat in itself!</p> -<h3 id="the-importance-of-having-our-own-certification-system">The importance of having our own certification system</h3> -<p>We are regularly offered to switch over to third-party or state-owned authentication systems but these are centralised and go against the principles of our community. We feel that we would lose our independence and universality by adopting a state-controlled system. People without an official state-provided identity or homeless people would also run the risk of being excluded from the WoT. It is of the utmost importance that we remain free from any state or corporation. To this day we depend only on the Internet and yet, were it to fail, there are already alternatives being tested around the world for a decentralised network.</p> -<h3 id="a-few-foundational-concepts-on-graph-theory-a-bit-of-vocabulary">A few foundational concepts on graph theory : a bit of vocabulary</h3> -<ul> -<li><p><strong>Graph</strong>: set of points -called ‘vertices’- joined by edges -called paths/walks-.</p></li> -<li><p><strong>Simple graph</strong>: a graph with no loops and with no multiple edges. That is, each edge connects two distinct endpoints and no two edges have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a></p></li> -<li><p><strong>Directed graph</strong>: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a> Arrow A –> B is therefore different from arrow B –> A.</p></li> -<li><p><strong>Endpoints</strong>: the edge with vertex A –> B has A and B as endpoints, respectively as start and end of the path/walk.</p></li> -<li><p><strong>Isolated vertex</strong>: a vertex whose degree is zero, that is, a vertex with no incident edges. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a></p></li> -<li><p><strong>Degree of a vertex</strong>: number of its incident edges -in and out-.</p></li> -<li><p><strong>Out-degree of vertex A</strong>: number of outbound edges / tail ends from A.</p></li> -<li><p><strong>In-degree of vertex A</strong>: number of incoming edges / head ends to A.</p></li> -</ul> -<figure> -<img src="https://duniter.org/en/images/wiki/degrees.jpg" alt="degress of a vertex diagram" /><figcaption>degress of a vertex diagram</figcaption> -</figure> -<ul> -<li><strong>Path</strong>: -aka “walk”- path to follow to get from vertex A to vertex B.</li> -</ul> -<h3 id="definition-of-the-duniter-web-of-trust">Definition of the Duniter Web of Trust</h3> -<p>The Duniter WoTs -one per currency- are simple directed graphs without isolated vertices. The vertices are the members and the edges are the certifications given and received.</p> -<p>Directed, what does that mean?</p> -<p>The responsibility of issuing a certification is unique and personal to the certifier. The trust he/she places in the receiver cannot be imposed in the other direction although in most circumstances both parties equally trust each other.</p> -<p>In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific ‘deactivated state’ and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered ‘pending’ to avoid the web collapsing like a house of cards.</p> -<p>If these old members don’t come back into the web, their pending certifications will eventually expire and they will switch from ‘deactivated’ to ‘isolated’ vertices.</p> -<p>To wrap up with old members, after a certain period of time -set in the currency’s parameters - their deactivated vertex is removed from the web and the associated identity is ‘revoked’. The person who owned the account can no longer use this identity but is free to join the web with another one. :-)</p> -<blockquote> -<p>What do you mean by ‘identity’?</p> -</blockquote> -<p>An identity is a set of three pieces of information: a public key, a name and a blockstamp. A blockstamp points to a specific block in the chain. Its main use is to freeze the point in time at which an identity was created and to link this identity to a specific chain and of course, a currency -each currency having its own blockchain-.</p> -<p>An identity can be in any one of 5 different status: pending, member, old member, revoked or excluded.</p> -<p>Let’s take a simple example:</p> -<div class="highlight"> -<pre><code>A -> B -> C - | - \--> D</code></pre> -</div> -<p>If, for whatever reason, A were to lose its member status, the web would crumble and all other members would be excluded as a consequence. To avoid this, the certification from A –> B will remain valid until its expiry date, leaving enough time for B to receive certifications from C or D.</p> -<p>Because our WoT doesn’t have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications it has received -in the same block-. This calls for a temporary ‘buffer’ storage space for <strong>pending</strong> identities and the certifications they’ve received. This storage space is called ‘the pool’ -of Duniter nodes- which we could also have called the ‘sandbox’ as that’s the name used in Duniter’s code. I might add that these ‘pools’ also include other documents and metadata not mentioned here.</p> -<h3 id="exploring-the-rules-behind-a-duniter-web-of-trust">Exploring the rules behind a Duniter Web of Trust</h3> -<p>The Duniter WoTs -one per currency- work with a set of eight fundamental rules, themselves enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - <code>msPeriod</code>- having being hard-coded in the Ğ1’s code subsequently.</p> -<h4 id="distance-rule-and-referent-members-stepmax-and-xpercent-1distance-rule-and-referent-members-stepmax-and-xpercent">1.Distance rule and referent members (<code>stepMax</code> and <code>xPercent</code>) {#1distance-rule-and-referent-members-stepmax-and-xpercent}</h4> -<p>These two parameters are closely linked and together define the ‘distance rule’. The ‘distance rule’ can only be described after defining what a ‘referent member’ is:</p> -<blockquote> -<p><strong>Referent member</strong>: member A is said to be ‘referent’ if and only if the total of his/her degrees are greater than or equal to <code>CEIl-N^-1/stepMax--</code> where N is the total number of members.** As the size of the web will grow this number will grow too, meaning it will take more certification issuances to become a referent member as the number of certifications needed to become a member shouldn’t change.</p> -</blockquote> -<p>Let’s now define the distance rule:</p> -<blockquote> -<p><strong>Distance rule</strong>: member A is said to observe this rule if and only if for a subset xPercent % of referent members R there exists a path of length less than or equal to <code>stepMax</code> between R and A.**</p> -</blockquote> -<p>Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect web, that is one in which each member has certified all members he/she legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time <code>t</code> who haven’t yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would effectively stop growing. -You can see what would happen if the notion of ‘referent member’ didn’t exist by going to the ‘gaussianWotQuality’ page on <a href="https://g1-monit.librelois.fr/gaussianWotQuality?lg=en&unit=quality">currency-monit</a> and activating ‘if the concept of referent members didn’t exist’-.</p> <blockquote> -<p><strong>When is the distance rule applied?</strong></p> +<p><strong>Monetary parameter</strong> : Each currency that use Duniter has its own blockchain whose behaviour is dictated by a set of ‘parameters’ defined in block zero - the so-called genesis block - that can be tweaked to achieve the desired results. At the time of writing the Whitepaper, the Duniter Blockchain Protocol (DUBP) has a total of 21 parameters of which 10 are for the WoT alone. We’ll focus on these 10.</p> +<p>Suffice to say that in the Ğ1’s case, the DU is created every 24 hours - 86 400 seconds. This interval is set through the time derivative <code>dt</code> parameter and can have a different value in other implementations of the protocol.</p> </blockquote> -<p>Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets confirmed into the web or an existing member gets renewed. <em>Exception to the rule: the distance rule is not observed in the genesis block -when the web is first implemented-.</em></p> -<h4 id="rule-of-the-minimum-number-of-certifications-needed-sigqty-2-rule-of-the-minimum-number-of-certifications-needed-sigqty">2. Rule of the minimum number of certifications needed (<code>sigQty</code>) {#2-rule-of-the-minimum-number-of-certifications-needed-sigqty}</h4> -<p>This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least <code>sigQty</code> active certifications. If, for whatever reason, member A were to have less than <code>sigQty</code> active certifications in a given block, he/she would cease being a member and be required to publish a request for identity renewal.</p> -<h4 id="the-membership-renewal-rule-msvalidity-msperiod-and-mswindow-3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow">3. The membership renewal rule (<code>msValidity</code>, <code>msPeriod</code> and <code>msWindow</code>) {#3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow}</h4> -<p>Bear in mind that a membership doesn’t last a lifetime but instead has a lifespan set to <code>msValidity</code> seconds.</p> -<p>Every single member -or old member who hasn’t revoked his identity or been excluded- can request a membership renewal so long as the last request was made more than <code>msPeriod</code> seconds ago -if a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the ‘pool’ for a maximum of <code>msWindow</code> seconds before it’s included in the blockchain. Once again, this can only happen once/if the member meets both the <code>siqQty</code> rule and the distance rule -if these criterion are already matched it’s just a case of waiting for a new block to be mined-.</p> -<p>If a member hasn’t requested a renewal for longer than <code>msValidity</code> seconds, he/she automatically ceases being a member. From this moment on, the ex-member has another <code>msValidity</code> window to renew his/her membership. When this period of `2 × msValidity’ runs out, the membership will expire and this identity will never be available for use again in the web. If the person so desires, he/she will have to start from zero to regain access to the WoT.</p> -<h4 id="rule-of-certification-lifespan-sigvalidity-4-rule-of-certification-lifespan-sigvalidity">4. Rule of certification lifespan (<code>sigValidity</code>) {#4-rule-of-certification-lifespan-sigvalidity}</h4> -<p>All certifications included in the blockchain expire <strong>sigValidity</strong> seconds after they were <strong>issued</strong>.</p> -<p>/!\ The issuance and the inclusion of a certification in the blockchain occur at different times. When member A issues a certification at time t1, it gets stored in the pool starting at t1 and only finds its way into the blockchain at t2 when all of the web’s rules are observed. Several weeks can thus go by between t1 and t2!!!</p> -<h4 id="rule-of-limited-supply-of-active-certifications-sigstock-5-rule-of-limited-supply-of-active-certifications-sigstock">5. Rule of limited supply of active certifications (<code>sigStock</code>) {#5-rule-of-limited-supply-of-active-certifications-sigstock}</h4> -<p>By ‘active certifications’ we refer to certifications included in the blockchain and that haven’t yet expired.</p> -<p>The total of active certifications issued by any member at any single time must be less than or equal to <code>sigStock</code>. When this threshold is reached the member will have to wait for one of his active certifications to expire before he/she can issue a new one.</p> -<h4 id="rule-of-the-time-period-between-two-certification-issuances.-sigperiod-6-rule-of-the-time-period-between-two-certification-issuances-sigperiod">6. Rule of the time period between two certification issuances. (<code>sigPeriod</code>) {#6-rule-of-the-time-period-between-two-certification-issuances-sigperiod}</h4> -<p>As soon as a certification issued by member A gets included in the blockchain, he/she will be unable to issue a new one before another <code>sigPeriod</code> seconds.</p> -<h4 id="expiry-of-a-certification-issuance-sigwindow-7-expiry-of-a-certification-issuance-sigwindow">7. Expiry of a certification issuance (<code>sigWindow</code>) {#7-expiry-of-a-certification-issuance-sigwindow}</h4> -<p>When a certification is issued by member A, it will be stored in the ‘pool’ for a maximum of <code>sigWindow</code> seconds. If the certification hasn’t been included in the blockchain by then, it will be cancelled and the member’s <code>sigStock</code> will be repleted by one.</p> -<h4 id="lifespan-of-a-pending-active-certification-idtywindow-8-lifespan-of-a-pending-active-certification-idtywindow">8. Lifespan of a ‘pending’ active certification (<code>idtyWindow</code>) {#8-lifespan-of-a-pending-active-certification-idtywindow}</h4> -<p>When a new identity is created, it is stored in the ‘pool’ for a maximum of <code>idtyWindow</code> seconds. If the person hasn’t achieved member status by then, the certification will simply be cancelled.</p> -<h3 id="details-on-some-of-the-wots-peculiarities-at-the-genesis-block">Details on some of the WoT’s peculiarities at the genesis block.</h3> -<p>The aforementioned rules can only be enforced with an existing web. They cannot be observed when first creating the web, that is when defining the genesis block.</p> -<p>Only rules 2 and 5 can be observed at the genesis block.</p> -<p>The genesis block has to be manually created by the founding members. In practice this means that there must be a choice of which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities.</p> -<p>As soon as the genesis block has been created, the other identities can start mining the blockchain and the member who begat block #0 effectively looses the decision power he had at creation.</p> -<h3 id="why-these-rules-and-application-cases-in-the-g1">Why these rules and application cases in the Ğ1</h3> -<h4 id="distance-and-maximum-size-1-distance-and-maximum-size">1. Distance and maximum size {#1-distance-and-maximum-size}</h4> -<p>The distance rule is there to curb the maximum size of a Sybil region as well as that of the monetary community as a whole. The <code>xpercent</code> parameter prevents the creation of a ‘faction’ that could take hold of the blockchain.</p> -<figure> -<img src="https://duniter.org/en/images/wiki/wot-sybil.jpg" alt="Sybil region" /><figcaption>Sybil region</figcaption> -</figure> -<p>The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned Sybil members. As a consequence, the shortest edge/path between a legitimate member and a Sybil one has to have the attack’s author as an endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as <code>stepAttackers</code>. The maximum size of a Sybil region created by <code>sigQty</code> members depends on the L parameter, defined as L = sigQty/sigStock:</p> -<div class="highlight"> -<pre><code>Maximum Sybil region size = (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L)</code></pre> -</div> -<p>The maximum size of the Web of Trust is given by the following formula:</p> -<div class="highlight"> -<pre><code>WoTmax = (sigStock)*L^(stepMax-1)</code></pre> -</div> -<p>However we know for a fact that members will never use all of their available certifications. Many studies have proven that we all know a maximum average of fifty people, let’s then replace sigStock by fifty:</p> -<div class="highlight"> -<pre><code>WoTavg= (50)*(sigQty/50)^(stepMax-1)</code></pre> -</div> -<p>Our goal with the Ğ1 is to create a community of about one million members enjoying the world’s first true <a href="https://en.wikipedia.org/wiki/Catallaxy">catallaxy</a> -free economy with a spontaneous order of things-. Let’s see how we can tweak the pair of sigQty and stepMax- to reach this size:</p> -<figure> -<img src="https://duniter.org/en/images/wiki/graph-WoTmoy.png" alt="graphe WoTmoy en fonction de sigQty et stepMax" /><figcaption>graphe WoTmoy en fonction de sigQty et stepMax</figcaption> -</figure> -<p>The maximum size of a Sybil region grows linearly with <code>sigQty</code> but exponentially with <code>stepMax</code>. Logic has it that we need to keep <code>stepMax</code> as low as possible to ensure sufficient strength to the web. The above graph shows that the lowest value of <code>stepMax</code> for a web of a million members is of 5. This is an order of magnitude and is likely to be much higher in reality, we cannot measure it for sure.</p> -<p>For <code>sigQty</code> we can choose a value of <strong>4</strong> for a web of <strong>1.5 million members</strong> or <strong>5</strong> for <strong>half a million members</strong>. Bear in mind these are gross figures and could be significantly higher, we are talking anywhere between 1 and 10 million in reality. Calculating WOTavg gives us a pretty good idea of how the web would scale bearing in mind that it considers all members are referent members too -which isn’t the case as explained previously-. Hence the maximum size of the web is likely larger, a ballpark figure of half a million is enough for now especially knowing that the smaller <code>sigQty</code> is, the easier it is to launch a Sybil attack -it’s easier to find four accomplices than five-. For security reasons we have settled on five:</p> -<p>stepMax = 5 sigQty = 5 sigStock >= 50</p> -<p>The maximum size of a Sybil region therefore is: <code>(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))</code></p> -<p>with sigStock = 50 we have a Sybil region of: <code>45*(1-10^(5-stepAttackers))/(-9)</code></p> -<p>A good practice for protecting the web is to maximise <code>stepAttackers</code>. That’s why we decided that referent members in the genesis block had to be at least four steps away from each other.</p> -<p>Another way to keep a Sybil attack at bay, were it slow enough for members to notice it, would be for referent members to ‘stretch’ the web intentionally to limit the growth of the region by ensuring that the attackers’ legitimate certifications received in the first place aren’t renewed. But what if bot accounts were created and certified each other super fast and following all rules, how would we counter that? By introducing a minimum length of time between two certifications!</p> -<h4 id="time-is-our-friend-2-time-is-our-friend">2. Time is our friend {#2-time-is-our-friend}</h4> -<p>To help us deter a Sybil attack, we’ve decided to impose a minimum period of time between any two certifications issued from a single account. This parameter called <code>sigPeriod</code> affords us a greater chance to detect the formation of a ‘hostile’ faction.</p> -<p>Here is a graph showing the evolution of a Sybil region with the variation of <code>sigPeriod</code>:</p> -<figure> -<img src="https://duniter.org/en/images/wiki/impact_sig_period.png" alt="graph of the WoT's size according to sigPeriod and stepAttackers" /><figcaption>graph of the WoT's size according to sigPeriod and stepAttackers</figcaption> -</figure> -<p>As you’ll easily be able to tell, there is a strong link between the growth speed of the region and <code>sigPeriod</code>. As evidenced here, we need a <code>sigPeriod</code> high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher <code>sigPeriod</code> is, the more members will exercise their certification power gingerly, the action coming at a higher ‘cost’.</p> -<p>There are numerous advantages to giving <code>sigPeriod</code> a high value and no technical barriers to it, hence our choice of five days.</p> -<p>We could have also gone for days days -one week- for the sake of simplicity however there was an underlying idea behind our choice which was quite simply the pace of today’s life. Certifying someone can be a lengthy process as one needs to make sure he/she is correctly applying the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea to allow one to certify at the end of every working week -five days- instead of a whole calendar one.</p> -<h4 id="trust-me-now-trust-me-forever-sigvalidity-msvalidity-3-trust-me-now-trust-me-forever-sigvalidity-msvalidity">3. Trust me now, trust me forever? (<code>sigValidity</code>, <code>msValidity</code>) {#3-trust-me-now-trust-me-forever-sigvalidity-msvalidity}</h4> -<p>There would be two main drawbacks to a lifetime membership in the Ğ1’s Web of Trust:</p> -<blockquote> -<p>First of all we need to take into account that some members will pass and those accounts should no longer produce the Universal Dividend. Secondly it is of the utmost importance that ‘rogue’ accounts can be excluded from the web at some point.</p> -</blockquote> -<p>To achieve this, certifications have a limited lifetime and members need to seek renewal from their peers after <code>sigValidity</code> time. On the other hand, this time can’t be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, a certification with too short a lifetime would foster careless certifying behaviours. The act of certifying must have a ‘perceived’ cost high-enough to make it feel like an important act. Lastly, we also wanted this lifetime to be easy enough to remember. Historically speaking, we first settled on the values of <code>sigPeriod</code> and <code>sigStock</code>, meant one could issue all of his/her certifications in 495 days, one year was therefore not long enough. We deemed three years to bee much and that’s how we agreed on two years in the end.</p> -<p>Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we needed to address. We choose a value of one year for <strong>msValidity</strong>. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to ‘prune’ the web of past or inactive members who don’t renew their membership.</p> -<h4 id="keeping-the-pools-free-of-information-glut--idtywindow-sigwindow-mswindow-4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow">4. Keeping the pools free of information glut -(<code>idtyWindow</code>, <code>sigWindow</code>, <code>msWindow</code>) {#4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow}</h4> -<p>The pools need to be cleaned up on a regular basis to avoid them clogging up with information and to ensure that machines with less calculating power can still run a Duniter node.</p> -<p>To achieve this, identities with pending membership approval and the corresponding certifications have to remain the shortest time possible in the pool while still having a chance of making it into the blockchain.</p> -<p>For the Ğ1, our opinion was that two months would be enough for all potential certifiers to agree on a specific identity to certify. We also wanted a time period that would be easy enough to remember by all. We settled on two months, and gave this value to all three parameters <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>.</p> -<h4 id="avoiding-single-members-from-knowing-too-many-people-sigstock-5-avoiding-single-members-from-knowing-too-many-people-sigstock">5. Avoiding single members from ‘knowing too many people’ (<code>sigStock</code>) {#5-avoiding-single-members-from-knowing-too-many-people-sigstock}</h4> -<p>Many sociology studies have shown that we all know an average of fifty people. This of course is an average, some of us know more than fifty people, others much less. Once again we went for a number that would be easy to remember. Although <code>sigStock</code>’s impact on the size of a Sybil region is fairly limited, its value nonetheless has to be kept reasonable. We settled on hundred.</p> -<h4 id="avoiding-locking-minorities-xpercent-6-avoiding-locking-minorities-xpercent">6. Avoiding locking minorities (<code>xpercent</code>) {#6-avoiding-locking-minorities-xpercent}</h4> -<p>It’s easy enough to become a referent member, one of the Sybil strategies could therefore be to create a region of referent members. Such a region would grow slower than otherwise but could confer a locking power to its members by using the distance rule. That’s why the distance rule cannot be calculated on 100% of the referent members. Hence the introduction of the <code>xpercent</code> parameter which defines the percentage of referent members needing to be less than five edges -steps- from each other.</p> -<p>This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance rule. The <code>xpercent</code> parameter was one of the hardest to define, we therefore reserve ourselves the right of modifying its value during the Ğ1 experiment.</p> -<p>We were inspired by the <a href="https://en.wikipedia.org/wiki/Pareto_principle">Pareto principle</a>: if at least 20% of members give good density to the web, 80% of the referent members will be five or less steps from any other member -referent or non-. The maximum value for <code>xpercent</code> is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%.</p> -<h4 id="spam-protection-with-msperiod-7-spam-protection-with-msperiod">7. Spam protection with (<code>msPeriod</code>) {#7-spam-protection-with-msperiod}</h4> -<p>This parameter stands out a bit on its own, as it was added after the genesis block. It is there to protect the Duniter P2P infrastructure against ‘spam’ attacks. We had to think of a strategy against attacks such as high-frequency membership renewal requests -i.e: in every block, every five minutes- or worse still, hundreds of these requests per minute to flood the Duniter nodes. Without such limits, nodes are supposed to address all renewal requests, even in cases where they were last published five minutes ago! The <code>msPeriod</code> parameter was given the same value as <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>, i.e. two months.</p> -<h2 id="proof-of-work-with-personal-difficulty">Proof of Work with personal difficulty</h2> -<p>As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human.</p> -<p>This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each “winning” member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. The knowledge of the whole network is not needed.</p> -<p>Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power.</p> -<p>One could say that Duniter uses a PoW that needs very low energy consumption compared to BitCoin : an “ecological” PoW ?</p> -<!-- source : https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ --> -<h3 id="why-do-we-need-proof-of-work">Why do we need Proof of Work ?</h3> -<p>Duniter nodes share a database as part of a p2p environment. The proof of work (PoW) allows machines to synchronize with each other. In Duniter’s case, the blockchain is our database, and acts as a ledger keeping a trace of all transactions, status of the WoT and more. How can we let several machines add data (ie: a transaction) at the same time? In addition, how do we settle on how much time has gone by since the blockchain was last updated? Agreement on time is of the utmost importance as we want to create Universal Dividends on a regular basis, and keep track of membership status, both in human time.</p> -<p>Proof-of-work provides a clever solution to both problems: 1. Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, ensuring the unicity of a block’s creator.</p> -<ol start="2" type="1"> -<li>Solving this challenge takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and Duniter adapts the challenge difficulty to get an <em>average</em> duration corresponding to this block time.</li> -</ol> -<h3 id="only-members-can-mine">Only members can “mine”</h3> -<p>One of Duniter’s major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member’s private key, allowing the algorithm to determine a <em>personalised difficulty</em>.</p> -<p>This personalised difficulty eliminates the rat-race for the most sophisticated and powerful mining equipment. Another benefit is the fact that no “supercomputer” can take control of the blockchain. Lastly, Duniter implements a rotation in forging members thanks to this personalized difficulty.</p> -<p>This lightweight PoW is much less energy-consuming than other PoW cryptocurrencies. Members can mine with anything from a raspberry pi to a privacy-first internet cube.</p> -<h3 id="how-does-it-work">How does it work?</h3> -<h4 id="the-hash-aka-digest">The hash (aka digest)</h4> -<p>Example of a valid hash:</p> -<div class="highlight"> -<pre><code>00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653</code></pre> -</div> -<p>As you can see this hash starts with five zeros which was very hard to achieve and took a lot of <em>work</em> for someone’s computer. Hence the term “proof of work”.</p> -<h4 id="the-common-difficulty">The common difficulty</h4> -<p>A common difficulty is needed to settle on a yardstick for our time reference. Its role is to make sure the blockchain moves forward at a steady pace - one block every <code>avgGenTime</code> seconds, <code>avgGenTime</code> being one of the 20 parameters behind the Duniter protocol-.</p> -<p>This difficulty’s initial value can be set to any arbitrary value (<code>70</code> in Duniter <code>v1.5.x</code>) and then acts as a spring, regulating blocktime creation by increasing itself if the creation interval drops under <code>avgGenTime</code> and vice-versa.</p> -<h5 id="how-is-difficulty-applied">How is difficulty applied?</h5> -<p>The numeric value of difficulty is taken from an array of possible hashes out of all possible hashes. In duniter v1.5.x the hash of a block is its sha256 hexadecimal hash.</p> -<p>To understand the difficulty, we make a euclidiean division of the difficulty by 16.</p> -<p>Here’s an example with a difficulty value of <code>70</code> : 70 // 16 = <strong>4</strong> with a remainder of <strong>6</strong>. The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : <code>0000[0-9]</code>. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes.</p> -<blockquote> -<p>Fine, but the hash of a mined block will never change and there’s no reason it should start with a given sequence of numbers. So how then can we make sure a block hash starts with exactly the sequence needed?</p> -</blockquote> -<p>Enter the nonce, short for “number once”. When a member is forging a new block, his computer freezes the block’s content and changes the Nonce until the hash reaches the required number of zeroes.</p> -<h5 id="the-nonce">The Nonce</h5> -<p>The nonce allows us to mine a new block by finding a hash. The hash value allows us to determine the difficulty level of the proof-of-work performed. Examples of possible Nonce values:</p> -<ul> -<li>10100000112275</li> -<li>10300000288743</li> -<li>10400000008538</li> -<li>10700000079653</li> -<li>10300000070919</li> -</ul> -<p>In reality the <code>Nonce</code> value follows a pre-determined format akin to <code>XYY00000000000</code>. The Nonce’s value isn’t the number of attempts but rather a value within a set of possible ones. This is how the Nonce is built:</p> -<ul> -<li><p>X is a number assigned to a specific peer. Let’s assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with different nodes. Each block will therefore have its own unique X to prevent this from happening.</p></li> -<li><p>Y is the number of cores of the processor. The Nonce starting with <code>107[…]</code> belongs to a seven cores processor, while <code>199[...]</code> could be the proof generated by a 99 cores processor.</p></li> -</ul> -<p>The rest of the Nonce, the part that follows after the XYY, is the numerical space for this individual node and is unique to each of the CPU’s core. This space is comprised of eleven digits (<code>00000000000</code>). For the sake of accuracy, we use the term CPU in the wider sense, it can be understood as a bi-CPU for example. We take into consideration the number of cores for the resulting PoW.</p> -<h3 id="personalised-difficulty">Personalised difficulty</h3> -<p>Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other <em>PoW-based</em> cryptocurrencies such as Bitcoin.</p> -<p>Here is how this personalised difficulty is calculated and assigned:</p> -<p>It is determined by a combination of two different constraints with complimentary roles: the <strong>exclusion factor</strong> and the <strong>handicap</strong>.</p> -<p>Let <code>powMin</code> be the common difficulty, <code>exFact</code> a member’s exclusion factor and <code>handicap</code> their handicap. This member’s personalised difficulty <code>diff</code> is:</p> -<div class="highlight"> -<pre><code>diff = powMin*exFact + handicap</code></pre> -</div> -<h4 id="understanding-exfact-the-exclusion-factor">Understanding <code>exFact</code>, the exclusion factor</h4> -<p>Members who have never produced blocks or haven’t for quite some time are assigned an exclusion factor of <code>1</code>. Their personalised difficulty is therefore simply the sum of <code>powMin + handicap</code>.</p> -<p>Before reading on, let’s precise the role of this exclusion factor. When a member adds a block to the chain, his <code>exFact</code> jumps up from one to a very high value, to prevent them from forging other blocks immediately after and taking control of the blockchain.</p> -<p>The exclusion factor will then rapidly return to one. This delay is expressed as a number of blocks. It is calculated as a proportion of the number of members forging. In the Ğ1’s case, this proportion is 1/3, meaning that if there are fifteen members currently forging, the member’s exclusion factor will drop down to one after five blocks.</p> -<blockquote> -<p>What is intended by “the number of members forging”?</p> -</blockquote> -<p>We mean the number of members trying to create the next block. In reality, there is no way to precisely know how many members are calculating at any given time, because it is impossible to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block in the last X blocks, minus the very last one.</p> -<blockquote> -<p>Hox is X determined?</p> -</blockquote> -<p>We use the concept of <strong>current window</strong>. X’s value is equal to the size of this window. Let’s see how it works:</p> -<ul> -<li><p><code>issuersFrame</code> is the size of the current window in blocks.</p></li> -<li><p><code>issuersCount</code> the number of members who have calculated at least one block during the current window.</p></li> -</ul> -<p>Both <code>issuersFrame</code> and <code>issuersCount</code> are block fields. When first starting a blockchain, the very first block has an <code>issuersFrame=1</code> and an <code>issuersCount=0</code>. The genesis block is excluded as there are no members in the current window!</p> -<p>From the second block onwards (block #1) we track the variation of <code>issuersCount</code>. The member having mined block #0 enters the current window and in block #1 we will therefore mention <code>issuersCount=1</code>.</p> -<p><code>issuersFrame</code> then varies as follows:</p> -<ul> -<li>if <code>issuersCount</code> increases by N (with a maximum step of N = 1), then <code>issuersFrame</code> will increase by one unit over a period of 5N blocks.</li> -<li>Conversely, if <code>issuersCount</code> decreases by Y (with a maximum step of Y = 2 = current window inching forward + loss of one calculating member), then <code>issuersFrame</code> will decrease by one unit during 5Y blocks.</li> -<li>When such events overlap, <code>issuersFrame</code> evolves as so :</li> -</ul> -<table> -<thead> -<tr class="header"> -<th>bloc</th> -<th>event</th> -<th>issuersFrame</th> -</tr> -</thead> -<tbody> -<tr class="odd"> -<td>T</td> -<td>Babar writes a block and enters issuersCount</td> -<td>160</td> -</tr> -<tr class="even"> -<td>T+1</td> -<td>Celeste leaves issuersCount</td> -<td>160 +1 = 161</td> -</tr> -<tr class="odd"> -<td>T+2</td> -<td>N/a</td> -<td>161 +1 -1 = 161</td> -</tr> -<tr class="even"> -<td>T+3/4/5</td> -<td>N/a</td> -<td>161 +1 -1 = 161</td> -</tr> -<tr class="odd"> -<td>T+6</td> -<td>N/a</td> -<td>161 -1 = 160</td> -</tr> -</tbody> -</table> -<p>The calculation can be found under rules <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g05-headissuersframe">BR_G05</a> and <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g06-headissuersframevar">BR_G06</a> of the DUP protocol.</p> -<blockquote> -<p>Let’s go back to the personalised difficulty.</p> -</blockquote> -<p>We explained that <code>exFact</code> spikes immediately after the member has found a block. It decreases then rapidly to <code>1</code> after a number of blocks <code>X = 1/3 * issuersCount</code>. Let’s see precisely how we calculate <code>exFact</code>:</p> -<ul> -<li><p><code>nbPreviousIssuers</code> is the value of issuersCount at the last block <code>N</code> found by the member.</p></li> -<li><p><code>nbBlocksSince</code> is the number of blocks found by the rest of the network since block <code>N</code>.</p></li> -<li><p><code>percentRot</code> is the number of <em>not excluded</em> peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency.</p></li> -</ul> -<div class="highlight"> -<pre><code>exFact = MAX [ 1 ; FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) ]</code></pre> -</div> -<p>The FLOOR is a simple truncate function. For <code>exFact</code> to exclude the member, we need :</p> -<blockquote> -<p>(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2</p> -</blockquote> -<p>We can see that the member is not excluded if <code>nbBlocksSince</code> is greater than 1/3 of the calculating members. Take as an example nbPreviousIssuers = 6 and nbBlocksSince = 3:</p> -<blockquote> -<p>(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1</p> -</blockquote> -<p>However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded: > (0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2</p> -<p>Moreover if the last block was authored by the said member, then: > <code>nbBlocksSince=0</code> and > <code>exFact</code> = <code>0.67 * nbPreviousIssuers</code></p> -<p>ExFact value increases according to the number of members calculating. Thus, if there is enough members calculating, even mining farms would be excluded. We have therefore succeeded in our intent to deter attempts to seize the blockchain and its currency.</p> -<p>However, at any time t, the two-thirds of calculating members all have an exclusion factor of <code>1</code>, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then only the members with the highest computational power from the remaining third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn’t stand a chance…</p> -<h4 id="the-handicap">The handicap</h4> -<p>The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. A higher handicap is assined to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW.</p> -<p>The aim is to handicap the half that has authored most blocks (the most powerful half) to favour the other one. So, the handicap formula will use the median number of blocks authored by peers within the current window.</p> -<ul> -<li><p><code>nbPersonalBlocksInFrame</code> is the number of blocks authored by a single member within the current window.</p></li> -<li><p><code>medianOfBlocksInFrame</code> is the median number of blocks written by the calculating members during the same timeframe.</p></li> -</ul> -<div class="highlight"> -<pre><code>handicap = FLOOR(LN(MAX(1;(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)) / LN(1.189))</code></pre> -</div> -<p>Let’s unwrap the formula: <code>(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)</code> is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored <code>9</code> blocks in the current window and the median is <code>5</code>, then the ratio will be <code>(9+1)/5 = 2</code>. The MAX function allows us to ensure that the handicap has a value at least equal to <code>1</code>.</p> -<p>The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers.</p> -<p>If we want the handicap to be applied as soon as the median is reached, we’d have to divide it by <code>LN(1)</code>, the problem is that we’ve already set a minimum value of <code>1</code> with the MAX function, so if we were to divide the ratio by <code>LN(1)</code> all calculating peers would have a handicap >= <code>1</code>. In addition, is it really fair to handicap a member who’s right on the median?</p> -<p>That’s why we went for <code>1.189</code> rather than <code>1</code>. A member has to be at least <code>18.9%</code> above the median to be assigned a handicap. 18.9% is actually 16^(1/16), the difficulty factor between two levels of the proof work (hexadecimal hash).</p> -<p>To conclude, you have to remember that :</p> -<ul> -<li>the handicap is indexed on the logarithm of the ratio to the median,</li> -<li>handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work’s difficulty.</li> -</ul> -<h2 id="conclusion">Conclusion</h2> -<!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniter’s Blockchain can be compared to Bitcoin’s : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend.</p> -<p>More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers while maintaining a good security on the network.</p> -<p>The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties :</p> -<ul> -<li>The freedom to choose your currency system: because money should not be imposed</li> -<li>The freedom to access resources: because we all should have access to economic & monetary resources</li> -<li>The freedom to estimate and produce value: because value is a purely relative to each individual</li> -<li>The freedom to trade with the money: because we should not be limited by the avaible money supply</li> -</ul> -<p>Those 4 economic freedoms should be understood together, not exclusively. Plus, “freedom” has to be understood as “non-nuisance”. So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency.</p> -<h2 id="duniter-projects-sources">Duniter project’s sources :</h2> -<ul> -<li>Theoretical, by Cgeek: https://duniter.org/en/theoretical/</li> -<li>Lock conditions, by Inso: https://duniter.org/en/transactions-0-2-overview/</li> -<li>Individualised Proof of Work, by Elois: https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/</li> -<li>Deep dive into the Web of Trust, by Elois: https://duniter.org/en/deep-dive-into-the-web-of-trust/</li> -<li>Whitepaper sources: https://git.duniter.org/communication/duniter-whitepaper</li> -</ul> -<h2 id="other-sources">Other sources :</h2> -<ul> -<li>Relative Theory of Money, S.Laborde, 2010: http://en.trm.creationmonetaire.info/</li> -<li>Bitcoin Whitepaper, S.Nakamoto, 2008: https://bitcoin.org/bitcoin.pdf</li> -<li>Circles Whitepaper, A.Milenius, 2018: https://github.com/CirclesUBI/docs/blob/master/Circles.md</li> -<li>The Sibyl Attack, J.R.Douceur: https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</li> -</ul> -<!-- travaux en theorie des graphes pourla TdC --> -</article> -</main> -</body> -</html> -<!--doctype html--> -<html lang='en' > -<head > -<title> -Duniter Whitepaper -</title > -<meta charset='UTF-8' /> -<link - rel='stylesheet' - href='bulma.css' > <link - rel='stylesheet' - href='main.css' > -<script src='js/jquery.js' ></script > -<script src='js/toc.js' ></script > -<script type='javascript' > - if ($) { - $('#whitepaper').tableofcontents({ id: '#toc' }); - } - </script > -</head > -<body> -<main> -<div id="toc"> - -</div> -<article id="whitepaper" class="content"> -<h1 id="duniter-a-libre-currency-blockchain-generator-1">Duniter : A libre currency blockchain generator !</h1> -<h2 id="abstract-todo-1">Abstract (TODO)</h2> -<h2 id="introduction-1">Introduction</h2> -<p>Duniter is a software to create and manage “libre currencies”. Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question :</p> -<blockquote> -<p>How should a currency be created to match the principle of equality between all humans ?</p> -</blockquote> -<p>The results of this demonstration implies a monetary creation :</p> -<ul> -<li>on a regular basis</li> -<li>for each human being</li> -<li>which amount has to be reassessed on fixed intervals according to a fixed formula.</li> -</ul> -<p>Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula :</p> -<blockquote> -<p>UD(t+1) = UD(t) + c² * ( M(t) / N(t) )</p> -</blockquote> -<p>Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin.</p> -<p>The first currency created through Duniter is Ğ1 (say “June”). It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software.</p> -<h2 id="state-of-the-art-bitcoin-case-1">State of the art : Bitcoin case</h2> -<!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniter uses the crypto-currency concept introduced by Bitcoin, which is to use cryptographic tools such as <em>signatures</em> to create digital currencies. Duniter fits this definition, but it has completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects.</p> -<h3 id="monetary-creation-of-bitcoin-a-space-time-asymmetry-1">Monetary creation of Bitcoin : a space-time asymmetry</h3> -<p>Space-time asymmetry refers to the relative access of individuals to newly created money (Relative Theory of Money, S.Laborde, 2010). Concretely, all existing currencies (c. 2015) are both spatially and temporally asymmetrical for their users. Let's take Bitcoin as an example to understand why.</p> -<h4 id="spatial-asymmetry-1">Spatial asymmetry</h4> -<p>When new Bitcoins are created, <em>only some Bitcoin users</em> (the miners) are given new Bitcoins, while everyone else get nothing. <strong>We believe this is the <em>first</em> injustice.</strong> However, some might say:</p> -<blockquote> -<p>"Miners used their <em>electricity and time</em> to get it!"</p> -</blockquote> -<p>... we would answer that this work <em>shouldn't have been rewarded by newly created Bitcoins</em>. New Bitcoins should be distributed to the whole Bitcoin community. Miners should be rewared another way, but not by money issuance. Of course, Bitcoin can't create money through Basic Income since <em>Bitcoin users are not strongly identified</em>, and one might benefit from money creation multiple times if he owned several wallets. Duniter gets rid of this problem completely by identifying its users and giving <em>the same amount of Basic Income to everyone</em>.</p> -<h4 id="temporal-asymmetry-1">Temporal-asymmetry</h4> -<p>Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, how will future joiners get Bitcoins? Just like Euros or Dollars: to get money, they will have to work for the ones who already own it. <strong>We believe this is the <em>second</em> injustice.</strong> Every member of a monetary community should be equal concerning monetary creation, and get the same relative amount of money over time, <em>even if they are a late adopter</em>. Duniter aims to fix this by making the Universal Dividend (a.k.a. <em>UD</em>) <em>grow by the time</em> (S.Laborde, 2010) according to precise rules, thus making members equal toward money issuance on a half-lifespan.</p> -<h4 id="a-solution-1">A solution</h4> -<p>Bitcoin has taught us that <em>it is possible</em> to create a currency system allowing one to both create digital money and to exchange it without a central authority. What we need to change is <em>the way money is issued</em> so we finally have a symmetrical system. We need Bitcoin <em>+ Universal Dividend</em>. But Universal Dividend <em>implies</em> that the community consists of only identified people. This is where the Web of Trust (WoT) comes into place. This concept, introduced by cryptography with the <a href="https://www.wikiwand.com/en/Pretty_Good_Privacy">OpenPGP</a> format, allows us to identify people in a <em>decentralized</em> manner. It works as follows: each person creates <em>a personal identity</em> that is linked to its cyptographic certificate. The identity must be confirmed by others members who use their own cryptographic key. It is that simple: <strong>people choose who is part of the community and who is not, not a central authority.</strong></p> -<blockquote> -<p>Duniter however won't use OpenPGP for its cryptographic features: Elliptic Curves will be used instead for the conciseness of its generated keys and its pratical advantages. Duniter has its own Web of Trust principles, that shall be exposed later.</p> -</blockquote> -<h3 id="proof-of-work-mining-a-power-race-todo-1">Proof-of-Work mining : a power race (TODO)</h3> -<p>In Bitcoin Model, the calculation and incentive principles cause a power race : new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. The goal of Duniter is to make blockchain validation much less energy and hardware consuming while keeping a strong level of security. As a consequence, even low-power hardware can secure Duniter Blockchain, which leads to a better decentralization of forging operations.</p> -<h3 id="other-projects-1">Other projects ?</h3> -<h4 id="what-about-pos-1">What about PoS ?</h4> -<p>When conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead to placing power over the currency in the richests hands : this is contrary to the symmetical principles of Duniter.</p> -<p>Now that PoS is well-tested, one could try to use Duniter’s WoT to create a PoS-like algorithm with equal chances among members. But this is not our aim for now.</p> -<h4 id="what-about-directed-acyclic-graph-1">What about Directed Acyclic Graph ?</h4> -<p>The Circles project uses DAG in a basic income cryptocurrency. However, in this project, one peer cannot know the whole monetary mass and the exact number of other peers. The calculation of Universal Dividend <code>UD = c * M/N</code> seems impossible, since we know neither M nor N.</p> -<h2 id="duniters-blockchain-1">Duniters Blockchain</h2> -<!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniters Blockchain follows the basic principles of Bitcoins. This is essential for synchronization between peers, as to prevent double-spend attacks. However, Duniters Blockchain will store different informations than Bitcoins.</p> -<p>The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no <em>generation transaction</em> exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either:</p> -<ul> -<li>a former transaction (as in Bitcoin)</li> -<li>a Universal Dividend (specific to Duniter).</li> -</ul> -<p>Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactinos are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where “space” are members of the WoT and “time” the basci blockchain units : the blocks. On each point of time, one can determain whick account is legitimate to create the UD, only with a blockchain analysis.</p> -<h3 id="spam-countermeasures-todo-1">Spam countermeasures (TODO)</h3> -<p>An issue of most cryptocurrency projects is to prevent the common ledger from growing too much and require lot of storage and computing power to be usable. In particular, we don’t want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don’t want to do this since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented.</p> -<!-- see : https://forum.duniter.org/t/sans-frais-de-transaction-comment-resister-aux-attaques/3846/25 (implemented ?)--> -<ul> -<li>output minimal de 100*Unitbase / 1 unité -> empêche un attaquant de faire grossir la BC et les index trop vite (DUBP v12)</li> -<li>chaînage maximal des tx</li> -<li>seuils de dépense (implémentés ? en tout et par issuer ?)</li> -</ul> -<h3 id="scaling-1">Scaling</h3> -<p>Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons :</p> -<ul> -<li>Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don’t want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT limits its size to around 16 million members.</li> -<li>Duniter’s aim is to be used to create <em>multiple</em> libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community.</li> -</ul> -<p>However, Duniter has two assets that might be used if the number of users grow.</p> -<h4 id="dynamic-block-size-1">Dynamic block size</h4> -<p>While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks( <em>current window</em> will be described in the PoW part). This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it.</p> -<div class="{highlight}"> -<p>block_size < max(500 ; CEIL(1.10 * (average block size))</p> -</div> -<h4 id="lightning-networks-1">Lightning Networks</h4> -<p>The Lightning Networks allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed.</p> -<h2 id="duniter-web-of-trust-1">Duniter Web of Trust</h2> -<!-- source : https://duniter.org/en/deep-dive-into-the-web-of-trust --> -<h3 id="basic-principles-1">Basic Principles</h3> -<p>In order to identify “members” account - which create monetary units - from other accounts, Duniter uses a Web of Trust. This can be summarized into few principles:</p> -<ul> -<li>Each account becomes a member if it received a minimal number of certifications (5 for Ğ1 currency)</li> -<li>Only members accounts can send certifications. Certifications have a limited lifespan.</li> -<li>A certification indicates that the sender accepts the receiver as a legitimate identity.</li> -</ul> -<p>The aim of the WoT is to identify a blockchain account to a living human. Each member of the Ğ1 currency signs a licence stating that they will only certify humans they know well (among other rules). Thus, if a member is part of an attack on the currency, they can be found by mutual friends. The security of Ğ1 currency stands on:</p> -<ul> -<li>Corroborating informations on members (5 certifications)</li> -<li>Peer pressure by close relatives</li> -<li>Law if the licence has not been respected.</li> -</ul> -<p>Note that non-members accounts can use the currency, but cannot create money. They can be used by individuals as secondary wallets, or by institutions.</p> -<p>However, the WoT does not rely only on trust betwenn people. Rules have been added to increase the security, and we will present them.</p> -<h3 id="why-do-we-need-a-web-of-trust-1">Why do we need a Web of Trust?</h3> -<p>There are two reasons we need it :</p> +<p>We want to make sure that each member can only have one account. As we all know, achieving zero-risk isn’t possible<a href="#fn9" class="footnote-ref" id="fnref9"><sup>9</sup></a>. Our goal is therefore not to create a WoT within which fraud would be absolutely impossible, but instead to discourage it. Here is a rewording of our goal in 4 smaller ones :</p> <ol type="1"> -<li>To make sure that only one Universal Dividend is produced per member at each specified creation interval -in the Ğ1’s case this interval is set as daily <code>86 400</code> seconds-, it is the <em>monetary parameter</em> known as <code>dt</code>-.</li> -<li><p>To identify the nodes hashing the blocks and assign them each a personalised difficulty. This custom difficulty <a href="https://en.wikipedia.org/wiki/Proof-of-work_system">proof of work</a> is there to avoid the blockchain’s validation mechanism becoming too centralised as is the case with many 'non-libre’ cryptocurrencies.</p> -<blockquote> -<p>Wait, what’s a ‘monetary parameter’ ?</p> -</blockquote></li> -</ol> -<p>Every currency implementing Duniter has its own blockchain whose behaviour is dictated by a set of ‘parameters’ -defined in block zero, the so-called genesis block- that can be tweaked to achieve the desired results. At the time of writing this article, the Duniter protocol -aka DUP- has a total of 21 parameters of which 10 are for the WoT alone. We’ll focus on these 10.</p> -<p>Suffice to say that in the Ğ1’s case, the DU is created every 24 hours -86 400 seconds- but this interval -set through the time derivative <code>dt</code> parameter- can have a different value in an other implementation of the protocol.</p> -<p>I won’t write about the second parameter having to do with the proof of work, it’s outside our scope here, just know that the Web of Trust allows us to <strong>identify</strong> the members providing hashing power, which we couldn’t do without it. This crucial feature means we can impose a rotation between the members hashing the blocks so that no single rich individual or group invests in a giant ‘hash farm’ and takes a hold of the blockchain, paralysing the community!</p> -<p>Let’s go back to the first objective: to make sure that each member can only have one account. As we all know, achieving zero-risk isn’t possible, our goal is therefore not to create a WoT within which fraud would be absolutely impossible but instead to discourage it. Here is a rewording of our goal in 4 smaller ones :</p> -<ol type="1"> -<li>To make the certification process lengthy enough that all members exercise due diligence and are wary of risks.</li> -<li>To make fraudulent acts as hard as we can to the extent that they become pointless.</li> -<li>To ensure that any Sybil attacks have a negligible impact on the currency -<em>by ensuring that illegitimate double Universal Dividends have no significant bearing on the legitimate monetary mass</em>-</li> -<li>To slow the growth of ‘Sybil regions’ to give enough time for the community to react and isolate the threat.</li> +<li>Make the certification process lengthy enough that all members exercise due diligence and are wary of risks.</li> +<li>Make fraudulent acts as hard as we can to the extent that they become pointless.</li> +<li>Ensure that any Sybil attacks have a negligible impact on the currency by ensuring that illegitimate double Universal Dividends have no significant bearing on the legitimate monetary mass</li> +<li>Slow the growth of ‘Sybil regions’ to give enough time for the community to react and isolate the threat.</li> </ol> <blockquote> -<p><strong>Wait, a Sybil what ?</strong></p> +<p><strong>Sybil attack</strong> : A Sybil attack is an attack perpetrated on a reputation system through the creation of fake identities. A Web of Trust is a specific instance of a Reputation System.</p> </blockquote> -<p>A <a href="https://en.wikipedia.org/wiki/Sybil_attack"><strong>Sybil attack</strong></a>, is the name given to attacks perpetrated on a reputation system through the creation of fake identities. A Web of Trust is a specific instance of a <a href="https://en.wikipedia.org/wiki/Reputation_system"><strong>Reputation System</strong></a>.</p> <p>There are plenty of Sybil attack scenarios we can think of and just as many reasons why their perpetrators would want to carry them out. Our objective is that the configuration of the WoT protects both users and its IT backbone infrastructure against these attacks.</p> -<p>This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web’s role isn’t to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing your tap water and electricity but isn’t responsible for any burglaries etc. Much in the same way, Duniter’s WoT guarantees us all a functional currency and that’s quite a feat in itself!</p> -<h3 id="the-importance-of-having-our-own-certification-system-1">The importance of having our own certification system</h3> -<p>We are regularly offered to switch over to third-party or state-owned authentication systems but these are centralised and go against the principles of our community. We feel that we would lose our independence and universality by adopting a state-controlled system. People without an official state-provided identity or homeless people would also run the risk of being excluded from the WoT. It is of the utmost importance that we remain free from any state or corporation. To this day we depend only on the Internet and yet, were it to fail, there are already alternatives being tested around the world for a decentralised network.</p> -<h3 id="a-few-foundational-concepts-on-graph-theory-a-bit-of-vocabulary-1">A few foundational concepts on graph theory : a bit of vocabulary</h3> +<p>This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web’s role isn’t to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing your tap water and electricity but isn’t responsible for any burglaries, etc. Much in the same way, Duniter’s WoT guarantees us all a functional currency, but do not detect small fraud.</p> +<h3 id="own-certification-system">3.3. The importance of having our own certification system</h3> +<p>Centralized identification systems can achieve the goal we want. State Identification is an example. However, this has many drawbacks :</p> +<ul> +<li>The authority may have arbitrary criteria for identification, for example preventing people without an official state-provided identity or homeless people to be included in the WoT.</li> +<li>Payment might be required to get identified, thus making the monetary creation not “free”.</li> +<li>The authority is a point of failure for any attacker.</li> +</ul> +<p>It is of the utmost importance that we remain free from any state or corporation. The WoT is an answer to this criterium. To this day we depend only on the Internet and yet, were it to fail, there are already alternatives being tested around the world for a decentralised communication network.</p> +<h3 id="graph-theory-vocabulary">3.4. A few foundational concepts on graph theory : a bit of vocabulary</h3> <ul> <li><p><strong>Graph</strong>: set of points -called ‘vertices’- joined by edges -called paths/walks-.</p></li> -<li><p><strong>Simple graph</strong>: a graph with no loops and with no multiple edges. That is, each edge connects two distinct endpoints and no two edges have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a></p></li> -<li><p><strong>Directed graph</strong>: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a> Arrow A –> B is therefore different from arrow B –> A.</p></li> +<li><p><strong>Simple graph</strong>: a graph with no loops and with no multiple edges. That is, each edge connects two distinct endpoints and no two edges have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise.</p></li> +<li><p><strong>Directed graph</strong>: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. Arrow A –> B is therefore different from arrow B –> A.</p></li> <li><p><strong>Endpoints</strong>: the edge with vertex A –> B has A and B as endpoints, respectively as start and end of the path/walk.</p></li> -<li><p><strong>Isolated vertex</strong>: a vertex whose degree is zero, that is, a vertex with no incident edges. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a></p></li> +<li><p><strong>Isolated vertex</strong>: a vertex whose degree is zero, that is, a vertex with no incident edges.</p></li> <li><p><strong>Degree of a vertex</strong>: number of its incident edges -in and out-.</p></li> <li><p><strong>Out-degree of vertex A</strong>: number of outbound edges / tail ends from A.</p></li> <li><p><strong>In-degree of vertex A</strong>: number of incoming edges / head ends to A.</p></li> </ul> <figure> -<img src="https://duniter.org/en/images/wiki/degrees.jpg" alt="degress of a vertex diagram" /><figcaption>degress of a vertex diagram</figcaption> +<img src="./images/degres.jpg" alt="degrees of a vertex diagram" /><figcaption>degrees of a vertex diagram</figcaption> </figure> <ul> <li><strong>Path</strong>: -aka “walk”- path to follow to get from vertex A to vertex B.</li> </ul> -<h3 id="definition-of-the-duniter-web-of-trust-1">Definition of the Duniter Web of Trust</h3> +<h3 id="definition-of-the-duniter-web-of-trust">3.5. Definition of the Duniter Web of Trust</h3> <p>The Duniter WoTs -one per currency- are simple directed graphs without isolated vertices. The vertices are the members and the edges are the certifications given and received.</p> -<p>Directed, what does that mean?</p> -<p>The responsibility of issuing a certification is unique and personal to the certifier. The trust he/she places in the receiver cannot be imposed in the other direction although in most circumstances both parties equally trust each other.</p> -<p>In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific ‘deactivated state’ and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered ‘pending’ to avoid the web collapsing like a house of cards.</p> -<p>If these old members don’t come back into the web, their pending certifications will eventually expire and they will switch from ‘deactivated’ to ‘isolated’ vertices.</p> -<p>To wrap up with old members, after a certain period of time -set in the currency’s parameters - their deactivated vertex is removed from the web and the associated identity is ‘revoked’. The person who owned the account can no longer use this identity but is free to join the web with another one. :-)</p> +<p><em>Directed</em> means that the responsibility of issuing a certification is unique and personal to the certifier. The trust they place in the receiver cannot be imposed in the other direction although in most circumstances both parties equally trust each other.</p> +<p>In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific ‘deactivated state’ and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered ‘pending’ to avoid a collapse of the WoT. If these old members don’t come back into the WoT, their pending certifications will eventually expire and they will switch from ‘deactivated’ to ‘isolated’ vertices.</p> +<p>To wrap up with old members, after a certain period of time - set in the currency’s parameters - their deactivated vertex is removed from the web and the associated identity is ‘revoked’. The person who owned the account can no longer use this identity but is free to join the web with another one.</p> <blockquote> -<p>What do you mean by ‘identity’?</p> -</blockquote> -<p>An identity is a set of three pieces of information: a public key, a name and a blockstamp. A blockstamp points to a specific block in the chain. Its main use is to freeze the point in time at which an identity was created and to link this identity to a specific chain and of course, a currency -each currency having its own blockchain-.</p> +<p><strong>Identity</strong> : An identity is a set of three pieces of information: a public key, a name and a blockstamp. A blockstamp points to a specific block in the chain. Its main use is to freeze the point in time at which an identity was created and to link this identity to a specific chain and a currency - each currency having its own blockchain.</p> <p>An identity can be in any one of 5 different status: pending, member, old member, revoked or excluded.</p> +</blockquote> <p>Let’s take a simple example:</p> -<div class="highlight"> -<pre><code>A -> B -> C - | - \--> D</code></pre> -</div> +<pre><code> A -> B -> C + | + \--> D</code></pre> <p>If, for whatever reason, A were to lose its member status, the web would crumble and all other members would be excluded as a consequence. To avoid this, the certification from A –> B will remain valid until its expiry date, leaving enough time for B to receive certifications from C or D.</p> -<p>Because our WoT doesn’t have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications it has received -in the same block-. This calls for a temporary ‘buffer’ storage space for <strong>pending</strong> identities and the certifications they’ve received. This storage space is called ‘the pool’ -of Duniter nodes- which we could also have called the ‘sandbox’ as that’s the name used in Duniter’s code. I might add that these ‘pools’ also include other documents and metadata not mentioned here.</p> -<h3 id="exploring-the-rules-behind-a-duniter-web-of-trust-1">Exploring the rules behind a Duniter Web of Trust</h3> -<p>The Duniter WoTs -one per currency- work with a set of eight fundamental rules, themselves enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - <code>msPeriod</code>- having being hard-coded in the Ğ1’s code subsequently.</p> -<h4 id="distance-rule-and-referent-members-stepmax-and-xpercent-1distance-rule-and-referent-members-stepmax-and-xpercent-1">1.Distance rule and referent members (<code>stepMax</code> and <code>xPercent</code>) {#1distance-rule-and-referent-members-stepmax-and-xpercent}</h4> +<p>Because our WoT doesn’t have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications it has received, all in the same block. This calls for a temporary ‘buffer’ storage space for <strong>pending</strong> identities and the certifications they have received. This storage space is called ‘the pool’ of Duniter nodes, which we could also have called the ‘sandbox’ as that’s the name used in Duniter’s code. Duniter nodes inclued other ‘pools’ for other documents and metadata not mentioned here.</p> +<h3 id="exploring-the-rules-behind-duniter-wot">3.6. Exploring the rules behind a Duniter Web of Trust</h3> +<p>The Duniter WoTs - one per currency - works with a set of eight fundamental rules enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - <code>msPeriod</code>- having being hard-coded in the Ğ1’s code subsequently.</p> +<h4 id="distance-rule-and-referent-members-stepmax-and-xpercent">3.6.1. Distance rule and referent members (<code>stepMax</code> and <code>xPercent</code>)</h4> <p>These two parameters are closely linked and together define the ‘distance rule’. The ‘distance rule’ can only be described after defining what a ‘referent member’ is:</p> <blockquote> -<p><strong>Referent member</strong>: member A is said to be ‘referent’ if and only if the total of his/her degrees are greater than or equal to <code>CEIl-N^-1/stepMax--</code> where N is the total number of members.** As the size of the web will grow this number will grow too, meaning it will take more certification issuances to become a referent member as the number of certifications needed to become a member shouldn’t change.</p> +<p><strong>Referent member</strong>: member A is said to be ‘referent’ if and only if the total of their degrees are greater than or equal to <code>CEIL-N^-1/stepMax</code> where N is the total number of members. As the size of the web will grow this number will grow too, meaning it will take more certification issuances to become a referent member. The number of certifications needed to become a member shouldn’t change.</p> </blockquote> <p>Let’s now define the distance rule:</p> <blockquote> -<p><strong>Distance rule</strong>: member A is said to observe this rule if and only if for a subset xPercent % of referent members R there exists a path of length less than or equal to <code>stepMax</code> between R and A.**</p> -</blockquote> -<p>Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect web, that is one in which each member has certified all members he/she legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time <code>t</code> who haven’t yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would effectively stop growing. -You can see what would happen if the notion of ‘referent member’ didn’t exist by going to the ‘gaussianWotQuality’ page on <a href="https://g1-monit.librelois.fr/gaussianWotQuality?lg=en&unit=quality">currency-monit</a> and activating ‘if the concept of referent members didn’t exist’-.</p> -<blockquote> -<p><strong>When is the distance rule applied?</strong></p> +<p><strong>Distance rule</strong>: member A is said to observe this rule if and only if for a subset xPercent % of referent members R there exists a path of length less than or equal to <code>stepMax</code> between R and A.</p> </blockquote> -<p>Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets confirmed into the web or an existing member gets renewed. <em>Exception to the rule: the distance rule is not observed in the genesis block -when the web is first implemented-.</em></p> -<h4 id="rule-of-the-minimum-number-of-certifications-needed-sigqty-2-rule-of-the-minimum-number-of-certifications-needed-sigqty-1">2. Rule of the minimum number of certifications needed (<code>sigQty</code>) {#2-rule-of-the-minimum-number-of-certifications-needed-sigqty}</h4> -<p>This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least <code>sigQty</code> active certifications. If, for whatever reason, member A were to have less than <code>sigQty</code> active certifications in a given block, he/she would cease being a member and be required to publish a request for identity renewal.</p> -<h4 id="the-membership-renewal-rule-msvalidity-msperiod-and-mswindow-3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow-1">3. The membership renewal rule (<code>msValidity</code>, <code>msPeriod</code> and <code>msWindow</code>) {#3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow}</h4> +<p>Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect web, that is one in which each member has certified all members they legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time <code>t</code> who haven’t yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would effectively stop growing.</p> +<p>Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets confirmed into the web or an existing member gets renewed. There is an exception to this rule: the distance rule is not observed in the genesis block -when the web is first implemented.</p> +<h4 id="rule-of-the-minimum-number-of-certifications-needed-sigqty">3.6.2. Rule of the minimum number of certifications needed (<code>sigQty</code>)</h4> +<p>This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least <code>sigQty</code> active certifications. If, for whatever reason, member A were to have less than <code>sigQty</code> active certifications in a given block, they would cease to be a member and be required to publish a request for identity renewal.</p> +<h4 id="the-membership-renewal-rule-msvalidity-msperiod-and-mswindow">3.6.3. The membership renewal rule (<code>msValidity</code>, <code>msPeriod</code> and <code>msWindow</code>)</h4> <p>Bear in mind that a membership doesn’t last a lifetime but instead has a lifespan set to <code>msValidity</code> seconds.</p> -<p>Every single member -or old member who hasn’t revoked his identity or been excluded- can request a membership renewal so long as the last request was made more than <code>msPeriod</code> seconds ago -if a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the ‘pool’ for a maximum of <code>msWindow</code> seconds before it’s included in the blockchain. Once again, this can only happen once/if the member meets both the <code>siqQty</code> rule and the distance rule -if these criterion are already matched it’s just a case of waiting for a new block to be mined-.</p> -<p>If a member hasn’t requested a renewal for longer than <code>msValidity</code> seconds, he/she automatically ceases being a member. From this moment on, the ex-member has another <code>msValidity</code> window to renew his/her membership. When this period of `2 × msValidity’ runs out, the membership will expire and this identity will never be available for use again in the web. If the person so desires, he/she will have to start from zero to regain access to the WoT.</p> -<h4 id="rule-of-certification-lifespan-sigvalidity-4-rule-of-certification-lifespan-sigvalidity-1">4. Rule of certification lifespan (<code>sigValidity</code>) {#4-rule-of-certification-lifespan-sigvalidity}</h4> +<p>Every single member -or old member who hasn’t revoked his identity or been excluded- can request a membership renewal so long as the last request was made more than <code>msPeriod</code> seconds ago. If a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the ‘pool’ for a maximum of <code>msWindow</code> seconds before it’s included in the blockchain. Once again, this can only happen once/if the member meets both the <code>siqQty</code> rule and the distance rule -if these criterion are already matched it’s just a case of waiting for a new block to be mined-.</p> +<p>If a member hasn’t requested a renewal for longer than <code>msValidity</code> seconds, they automatically cease to be a member. From this moment on, the ex-member has another <code>msValidity</code> window to renew their membership. When this period of <code>2 × msValidity</code> runs out, the membership will expire and this identity will never be available for use again in the web. If the person so desires, they will have to publish new identity and membership documents and find enough certifiers, as any newcomer.</p> +<h4 id="rule-of-certification-lifespan-sigvalidity">3.6.4. Rule of certification lifespan (<code>sigValidity</code>)</h4> <p>All certifications included in the blockchain expire <strong>sigValidity</strong> seconds after they were <strong>issued</strong>.</p> +<blockquote> <p>/!\ The issuance and the inclusion of a certification in the blockchain occur at different times. When member A issues a certification at time t1, it gets stored in the pool starting at t1 and only finds its way into the blockchain at t2 when all of the web’s rules are observed. Several weeks can thus go by between t1 and t2!!!</p> -<h4 id="rule-of-limited-supply-of-active-certifications-sigstock-5-rule-of-limited-supply-of-active-certifications-sigstock-1">5. Rule of limited supply of active certifications (<code>sigStock</code>) {#5-rule-of-limited-supply-of-active-certifications-sigstock}</h4> +</blockquote> +<h4 id="rule-of-limited-supply-of-active-certifications-sigstock">3.6.5. Rule of limited supply of active certifications (<code>sigStock</code>)</h4> <p>By ‘active certifications’ we refer to certifications included in the blockchain and that haven’t yet expired.</p> <p>The total of active certifications issued by any member at any single time must be less than or equal to <code>sigStock</code>. When this threshold is reached the member will have to wait for one of his active certifications to expire before he/she can issue a new one.</p> -<h4 id="rule-of-the-time-period-between-two-certification-issuances.-sigperiod-6-rule-of-the-time-period-between-two-certification-issuances-sigperiod-1">6. Rule of the time period between two certification issuances. (<code>sigPeriod</code>) {#6-rule-of-the-time-period-between-two-certification-issuances-sigperiod}</h4> -<p>As soon as a certification issued by member A gets included in the blockchain, he/she will be unable to issue a new one before another <code>sigPeriod</code> seconds.</p> -<h4 id="expiry-of-a-certification-issuance-sigwindow-7-expiry-of-a-certification-issuance-sigwindow-1">7. Expiry of a certification issuance (<code>sigWindow</code>) {#7-expiry-of-a-certification-issuance-sigwindow}</h4> +<h4 id="rule-of-the-time-period-between-two-certification-issuances-sigperiod">3.6.6. Rule of the time period between two certification issuances. (<code>sigPeriod</code>)</h4> +<p>As soon as a certification issued by member A gets included in the blockchain, they will be unable to issue a new one before another <code>sigPeriod</code> seconds.</p> +<h4 id="expiry-of-a-certification-issuance-sigwindow">3.6.7. Expiry of a certification issuance (<code>sigWindow</code>)</h4> <p>When a certification is issued by member A, it will be stored in the ‘pool’ for a maximum of <code>sigWindow</code> seconds. If the certification hasn’t been included in the blockchain by then, it will be cancelled and the member’s <code>sigStock</code> will be repleted by one.</p> -<h4 id="lifespan-of-a-pending-active-certification-idtywindow-8-lifespan-of-a-pending-active-certification-idtywindow-1">8. Lifespan of a ‘pending’ active certification (<code>idtyWindow</code>) {#8-lifespan-of-a-pending-active-certification-idtywindow}</h4> +<h4 id="lifespan-of-a-pending-identity-idtywindow">3.6.8. Lifespan of a ‘pending’ identity (<code>idtyWindow</code>)</h4> <p>When a new identity is created, it is stored in the ‘pool’ for a maximum of <code>idtyWindow</code> seconds. If the person hasn’t achieved member status by then, the certification will simply be cancelled.</p> -<h3 id="details-on-some-of-the-wots-peculiarities-at-the-genesis-block">Details on some of the WoT’s peculiarities at the genesis block.</h3> +<h3 id="details-on-some-of-the-wots-peculiarities-at-the-genesis-block">3.7. Details on some of the WoT’s peculiarities at the genesis block</h3> <p>The aforementioned rules can only be enforced with an existing web. They cannot be observed when first creating the web, that is when defining the genesis block.</p> <p>Only rules 2 and 5 can be observed at the genesis block.</p> -<p>The genesis block has to be manually created by the founding members. In practice this means that there must be a choice of which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities.</p> -<p>As soon as the genesis block has been created, the other identities can start mining the blockchain and the member who begat block #0 effectively looses the decision power he had at creation.</p> -<h3 id="why-these-rules-and-application-cases-in-the-g1">Why these rules and application cases in the Ğ1</h3> -<h4 id="distance-and-maximum-size-1-distance-and-maximum-size-1">1. Distance and maximum size {#1-distance-and-maximum-size}</h4> +<p>The genesis block has to be manually created by the founding members. In practice this means that there must be a choice on which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities.</p> +<p>As soon as the genesis block has been created, the other identities can start mining the blockchain and the member who created block #0 effectively looses the decision power he had at creation.</p> +<h3 id="why-these-rules-and-application-cases-in-the-g1">3.8. Why these rules and application cases in the Ğ1</h3> +<h4 id="distance-and-maximum-size">3.8.1. Distance and maximum size</h4> <p>The distance rule is there to curb the maximum size of a Sybil region as well as that of the monetary community as a whole. The <code>xpercent</code> parameter prevents the creation of a ‘faction’ that could take hold of the blockchain.</p> <figure> -<img src="https://duniter.org/en/images/wiki/wot-sybil.jpg" alt="Sybil region" /><figcaption>Sybil region</figcaption> +<img src="./images/wot-sybil.jpg" alt="Sybil region" /><figcaption>Sybil region</figcaption> </figure> -<p>The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned Sybil members. As a consequence, the shortest edge/path between a legitimate member and a Sybil one has to have the attack’s author as an endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as <code>stepAttackers</code>. The maximum size of a Sybil region created by <code>sigQty</code> members depends on the L parameter, defined as L = sigQty/sigStock:</p> -<div class="highlight"> -<pre><code>Maximum Sybil region size = (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L)</code></pre> -</div> +<p>The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned Sybil members. As a consequence, the shortest edge/path between a legitimate member and a Sybil one has to have the attack’s author as an endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as <code>stepAttackers</code>. The maximum size of a Sybil region created by <code>sigQty</code> members depends on the L parameter, defined as <code>L = sigQty/sigStock</code>:</p> +<pre><code>MaxSybilSize= (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L)</code></pre> <p>The maximum size of the Web of Trust is given by the following formula:</p> -<div class="highlight"> <pre><code>WoTmax = (sigStock)*L^(stepMax-1)</code></pre> -</div> -<p>However we know for a fact that members will never use all of their available certifications. Many studies have proven that we all know a maximum average of fifty people, let’s then replace sigStock by fifty:</p> -<div class="highlight"> +<p>However we know for a fact that members will never use all of their available certifications. According to Dunbar<a href="#fn10" class="footnote-ref" id="fnref10"><sup>10</sup></a>, on average, one is able to maintain relationships to around 150 people. Being conservative, we will consider that on average, each person will certify 50 accounts. We can calculate the size of the average web of trust <code>WoTavg</code> :</p> <pre><code>WoTavg= (50)*(sigQty/50)^(stepMax-1)</code></pre> -</div> -<p>Our goal with the Ğ1 is to create a community of about one million members enjoying the world’s first true <a href="https://en.wikipedia.org/wiki/Catallaxy">catallaxy</a> -free economy with a spontaneous order of things-. Let’s see how we can tweak the pair of sigQty and stepMax- to reach this size:</p> +<p>Our goal with the Ğ1 is to create a community of about one million members to test the consequences of a libre monetary system. Let’s see how we can tweak the pair of sigQty and stepMax- to reach this size:</p> <figure> -<img src="https://duniter.org/en/images/wiki/graph-WoTmoy.png" alt="graphe WoTmoy en fonction de sigQty et stepMax" /><figcaption>graphe WoTmoy en fonction de sigQty et stepMax</figcaption> +<img src="./images/wot-moy.png" alt="Average WoT size graph as a function of sigQty and stepMax" /><figcaption>Average WoT size graph as a function of sigQty and stepMax</figcaption> </figure> <p>The maximum size of a Sybil region grows linearly with <code>sigQty</code> but exponentially with <code>stepMax</code>. Logic has it that we need to keep <code>stepMax</code> as low as possible to ensure sufficient strength to the web. The above graph shows that the lowest value of <code>stepMax</code> for a web of a million members is of 5. This is an order of magnitude and is likely to be much higher in reality, we cannot measure it for sure.</p> <p>For <code>sigQty</code> we can choose a value of <strong>4</strong> for a web of <strong>1.5 million members</strong> or <strong>5</strong> for <strong>half a million members</strong>. Bear in mind these are gross figures and could be significantly higher, we are talking anywhere between 1 and 10 million in reality. Calculating WOTavg gives us a pretty good idea of how the web would scale bearing in mind that it considers all members are referent members too -which isn’t the case as explained previously-. Hence the maximum size of the web is likely larger, a ballpark figure of half a million is enough for now especially knowing that the smaller <code>sigQty</code> is, the easier it is to launch a Sybil attack -it’s easier to find four accomplices than five-. For security reasons we have settled on five:</p> -<p>stepMax = 5 sigQty = 5 sigStock >= 50</p> -<p>The maximum size of a Sybil region therefore is: <code>(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))</code></p> -<p>with sigStock = 50 we have a Sybil region of: <code>45*(1-10^(5-stepAttackers))/(-9)</code></p> +<pre><code>stepMax = 5 +sigQty = 5 +sigStock \>= 50</code></pre> +<p>The maximum size of a Sybil region therefore is:</p> +<pre><code>(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))</code></pre> +<p>with sigStock = 50 we have a Sybil region of:</p> +<pre><code>45*(1-10^(5-stepAttackers))/(-9)</code></pre> <p>A good practice for protecting the web is to maximise <code>stepAttackers</code>. That’s why we decided that referent members in the genesis block had to be at least four steps away from each other.</p> <p>Another way to keep a Sybil attack at bay, were it slow enough for members to notice it, would be for referent members to ‘stretch’ the web intentionally to limit the growth of the region by ensuring that the attackers’ legitimate certifications received in the first place aren’t renewed. But what if bot accounts were created and certified each other super fast and following all rules, how would we counter that? By introducing a minimum length of time between two certifications!</p> -<h4 id="time-is-our-friend-2-time-is-our-friend-1">2. Time is our friend {#2-time-is-our-friend}</h4> +<h4 id="time-is-our-friend">3.8.2. Time is our friend</h4> <p>To help us deter a Sybil attack, we’ve decided to impose a minimum period of time between any two certifications issued from a single account. This parameter called <code>sigPeriod</code> affords us a greater chance to detect the formation of a ‘hostile’ faction.</p> -<p>Here is a graph showing the evolution of a Sybil region with the variation of <code>sigPeriod</code>:</p> +<p>Here is a graph showing the evolution of a Sybil region with the variation of <code>sigPeriod</code>. The simulation considers that honest members and attackers both issue a certification each <code>sigPeriod</code> interval, in days:</p> <figure> -<img src="https://duniter.org/en/images/wiki/impact_sig_period.png" alt="graph of the WoT's size according to sigPeriod and stepAttackers" /><figcaption>graph of the WoT's size according to sigPeriod and stepAttackers</figcaption> +<img src="./images/impact_sig_period.png" alt="size of the WoT according to sigPeriod and stepAttackers" /><figcaption>size of the WoT according to sigPeriod and stepAttackers</figcaption> </figure> -<p>As you’ll easily be able to tell, there is a strong link between the growth speed of the region and <code>sigPeriod</code>. As evidenced here, we need a <code>sigPeriod</code> high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher <code>sigPeriod</code> is, the more members will exercise their certification power gingerly, the action coming at a higher ‘cost’.</p> +<p>As we see, there is a strong link between the growth speed of the region and <code>sigPeriod</code>. As evidenced here, we need a <code>sigPeriod</code> high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher <code>sigPeriod</code> is, the more members will exercise their certification power gingerly, the action coming at a higher ‘cost’.</p> <p>There are numerous advantages to giving <code>sigPeriod</code> a high value and no technical barriers to it, hence our choice of five days.</p> -<p>We could have also gone for days days -one week- for the sake of simplicity however there was an underlying idea behind our choice which was quite simply the pace of today’s life. Certifying someone can be a lengthy process as one needs to make sure he/she is correctly applying the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea to allow one to certify at the end of every working week -five days- instead of a whole calendar one.</p> -<h4 id="trust-me-now-trust-me-forever-sigvalidity-msvalidity-3-trust-me-now-trust-me-forever-sigvalidity-msvalidity-1">3. Trust me now, trust me forever? (<code>sigValidity</code>, <code>msValidity</code>) {#3-trust-me-now-trust-me-forever-sigvalidity-msvalidity}</h4> +<p>We could have also gone for one week for the sake of simplicity. However there is an underlying idea behind our choice which was quite simply the pace of today’s life. Certifying someone can be a lengthy process as one needs to make sure they are correctly applying the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea to allow one to certify at the end of every working week -five days- instead of a whole calendar one.</p> +<h4 id="trust-me-now-trust-me-forever-sigvalidity-msvalidity">3.8.3. Trust me now, trust me forever ? (<code>sigValidity</code>, <code>msValidity</code>)</h4> <p>There would be two main drawbacks to a lifetime membership in the Ğ1’s Web of Trust:</p> -<blockquote> -<p>First of all we need to take into account that some members will pass and those accounts should no longer produce the Universal Dividend. Secondly it is of the utmost importance that ‘rogue’ accounts can be excluded from the web at some point.</p> -</blockquote> -<p>To achieve this, certifications have a limited lifetime and members need to seek renewal from their peers after <code>sigValidity</code> time. On the other hand, this time can’t be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, a certification with too short a lifetime would foster careless certifying behaviours. The act of certifying must have a ‘perceived’ cost high-enough to make it feel like an important act. Lastly, we also wanted this lifetime to be easy enough to remember. Historically speaking, we first settled on the values of <code>sigPeriod</code> and <code>sigStock</code>, meant one could issue all of his/her certifications in 495 days, one year was therefore not long enough. We deemed three years to bee much and that’s how we agreed on two years in the end.</p> -<p>Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we needed to address. We choose a value of one year for <strong>msValidity</strong>. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to ‘prune’ the web of past or inactive members who don’t renew their membership.</p> -<h4 id="keeping-the-pools-free-of-information-glut--idtywindow-sigwindow-mswindow-4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow-1">4. Keeping the pools free of information glut -(<code>idtyWindow</code>, <code>sigWindow</code>, <code>msWindow</code>) {#4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow}</h4> +<ul> +<li>First of all, some members will pass and those accounts should no longer produce the Universal Dividend.</li> +<li>Secondly it is of the utmost importance that ‘rogue’ accounts can be excluded from the web at some point.</li> +</ul> +<p>To achieve this, certifications have a limited lifespan. Members need to seek renewal from their peers after <code>sigValidity</code> time. On the other hand, this time can’t be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, a certification with too short a lifespan would foster careless certifying behaviours. The act of certifying must have a high-enough ‘perceived’ cost to make it feel like an important act. Lastly, we also wanted this lifespan to be easy to remember. Historically speaking, we first settled on the values of <code>sigPeriod</code> and <code>sigStock</code>, meant one could issue all of their certifications in 495 days, one year was therefore not long enough. We deemed three years to be too much and that’s how we agreed on two years in the end.</p> +<p>Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we needed to address. We chose a value of one year for <strong>msValidity</strong>. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to ‘prune’ the web of past or inactive members who don’t renew their membership.</p> +<h4 id="keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow">3.8.4. Keeping the pools free of information glut (<code>idtyWindow</code>, <code>sigWindow</code>, <code>msWindow</code>)</h4> <p>The pools need to be cleaned up on a regular basis to avoid them clogging up with information and to ensure that machines with less calculating power can still run a Duniter node.</p> <p>To achieve this, identities with pending membership approval and the corresponding certifications have to remain the shortest time possible in the pool while still having a chance of making it into the blockchain.</p> <p>For the Ğ1, our opinion was that two months would be enough for all potential certifiers to agree on a specific identity to certify. We also wanted a time period that would be easy enough to remember by all. We settled on two months, and gave this value to all three parameters <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>.</p> -<h4 id="avoiding-single-members-from-knowing-too-many-people-sigstock-5-avoiding-single-members-from-knowing-too-many-people-sigstock-1">5. Avoiding single members from ‘knowing too many people’ (<code>sigStock</code>) {#5-avoiding-single-members-from-knowing-too-many-people-sigstock}</h4> -<p>Many sociology studies have shown that we all know an average of fifty people. This of course is an average, some of us know more than fifty people, others much less. Once again we went for a number that would be easy to remember. Although <code>sigStock</code>’s impact on the size of a Sybil region is fairly limited, its value nonetheless has to be kept reasonable. We settled on hundred.</p> -<h4 id="avoiding-locking-minorities-xpercent-6-avoiding-locking-minorities-xpercent-1">6. Avoiding locking minorities (<code>xpercent</code>) {#6-avoiding-locking-minorities-xpercent}</h4> +<h4 id="avoiding-single-members-from-knowing-too-many-people-sigstock">3.8.5. Avoiding single members from ‘knowing too many people’ (<code>sigStock</code>)</h4> +<p>We considered that on average, each person will certify 50 people. However, we know for a fact that some members will use more than 50 certifications. The maximum social network of one individual is around 150 people<a href="#fn11" class="footnote-ref" id="fnref11"><sup>11</sup></a>. Being conservative, we settled on a maximum certification number <code>sigstock</code> of 100.<br /> +Since <code>sigStock</code>’s impact on the size of a Sybil region is fairly limited, we did not investigate further this parameter.</p> +<h4 id="avoiding-locking-minorities-xpercent">3.8.6. Avoiding locking minorities (<code>xpercent</code>)</h4> <p>It’s easy enough to become a referent member, one of the Sybil strategies could therefore be to create a region of referent members. Such a region would grow slower than otherwise but could confer a locking power to its members by using the distance rule. That’s why the distance rule cannot be calculated on 100% of the referent members. Hence the introduction of the <code>xpercent</code> parameter which defines the percentage of referent members needing to be less than five edges -steps- from each other.</p> -<p>This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance rule. The <code>xpercent</code> parameter was one of the hardest to define, we therefore reserve ourselves the right of modifying its value during the Ğ1 experiment.</p> -<p>We were inspired by the <a href="https://en.wikipedia.org/wiki/Pareto_principle">Pareto principle</a>: if at least 20% of members give good density to the web, 80% of the referent members will be five or less steps from any other member -referent or non-. The maximum value for <code>xpercent</code> is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%.</p> -<h4 id="spam-protection-with-msperiod-7-spam-protection-with-msperiod-1">7. Spam protection with (<code>msPeriod</code>) {#7-spam-protection-with-msperiod}</h4> +<p>This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance rule. The <code>xpercent</code> parameter was one of the hardest to define, therefore we might decide to change its value during the Ğ1 experiment.</p> +<p>We were inspired by the Pareto principle<a href="#fn12" class="footnote-ref" id="fnref12"><sup>12</sup></a>: if at least 20% of members give good density to the web, 80% of the referent members will be five or less steps from any other member -referent or not-. The maximum value for <code>xpercent</code> is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%.</p> +<h4 id="spam-protection-with-msperiod">3.8.7. Spam protection with (<code>msPeriod</code>)</h4> <p>This parameter stands out a bit on its own, as it was added after the genesis block. It is there to protect the Duniter P2P infrastructure against ‘spam’ attacks. We had to think of a strategy against attacks such as high-frequency membership renewal requests -i.e: in every block, every five minutes- or worse still, hundreds of these requests per minute to flood the Duniter nodes. Without such limits, nodes are supposed to address all renewal requests, even in cases where they were last published five minutes ago! The <code>msPeriod</code> parameter was given the same value as <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>, i.e. two months.</p> -<h2 id="proof-of-work-with-personal-difficulty-1">Proof of Work with personal difficulty</h2> +<h2 id="proof-of-work-with-personalized-difficulty">4. Proof of Work with personal difficulty</h2> <p>As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human.</p> -<p>This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each “winning” member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. The knowledge of the whole network is not needed.</p> +<p>This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each “winning” member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. A view of the whole network is not needed.</p> <p>Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power.</p> <p>One could say that Duniter uses a PoW that needs very low energy consumption compared to BitCoin : an “ecological” PoW ?</p> <!-- source : https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ --> -<h3 id="why-do-we-need-proof-of-work-1">Why do we need Proof of Work ?</h3> +<h3 id="why-proof-of-work">4.1. Why do we need Proof of Work ?</h3> <p>Duniter nodes share a database as part of a p2p environment. The proof of work (PoW) allows machines to synchronize with each other. In Duniter’s case, the blockchain is our database, and acts as a ledger keeping a trace of all transactions, status of the WoT and more. How can we let several machines add data (ie: a transaction) at the same time? In addition, how do we settle on how much time has gone by since the blockchain was last updated? Agreement on time is of the utmost importance as we want to create Universal Dividends on a regular basis, and keep track of membership status, both in human time.</p> -<p>Proof-of-work provides a clever solution to both problems: 1. Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, ensuring the unicity of a block’s creator.</p> -<ol start="2" type="1"> -<li>Solving this challenge takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and Duniter adapts the challenge difficulty to get an <em>average</em> duration corresponding to this block time.</li> +<p>Proof-of-work provides a clever solution to both problems:</p> +<ol type="1"> +<li><p>Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, ensuring the unicity of a block’s creator.</p></li> +<li><p>Solving this challenge takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and Duniter adapts the challenge difficulty to get an average duration corresponding to this block time.</p></li> </ol> -<h3 id="only-members-can-mine-1">Only members can “mine”</h3> -<p>One of Duniter’s major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member’s private key, allowing the algorithm to determine a <em>personalised difficulty</em>.</p> +<h3 id="only-members-can-mine">4.2. Only members can “mine”</h3> +<p>One of Duniter’s major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member’s private key, allowing the algorithm to determine a personalised difficulty.</p> <p>This personalised difficulty eliminates the rat-race for the most sophisticated and powerful mining equipment. Another benefit is the fact that no “supercomputer” can take control of the blockchain. Lastly, Duniter implements a rotation in forging members thanks to this personalized difficulty.</p> <p>This lightweight PoW is much less energy-consuming than other PoW cryptocurrencies. Members can mine with anything from a raspberry pi to a privacy-first internet cube.</p> -<h3 id="how-does-it-work-1">How does it work?</h3> -<h4 id="the-hash-aka-digest-1">The hash (aka digest)</h4> +<h3 id="how-does-duniter-pow-work">4.3. How does it work ?</h3> +<h4 id="the-hash">4.3.1. The hash (aka digest)</h4> <p>Example of a valid hash:</p> -<div class="highlight"> <pre><code>00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653</code></pre> -</div> -<p>As you can see this hash starts with five zeros which was very hard to achieve and took a lot of <em>work</em> for someone’s computer. Hence the term “proof of work”.</p> -<h4 id="the-common-difficulty-1">The common difficulty</h4> +<p>As you can see this hash starts with five zeros which was very hard to achieve and took a lot of work for someone’s computer. Hence the term “proof of work”.</p> +<h4 id="common-difficulty">4.3.2. The common difficulty</h4> <p>A common difficulty is needed to settle on a yardstick for our time reference. Its role is to make sure the blockchain moves forward at a steady pace - one block every <code>avgGenTime</code> seconds, <code>avgGenTime</code> being one of the 20 parameters behind the Duniter protocol-.</p> <p>This difficulty’s initial value can be set to any arbitrary value (<code>70</code> in Duniter <code>v1.5.x</code>) and then acts as a spring, regulating blocktime creation by increasing itself if the creation interval drops under <code>avgGenTime</code> and vice-versa.</p> -<h5 id="how-is-difficulty-applied-1">How is difficulty applied?</h5> -<p>The numeric value of difficulty is taken from an array of possible hashes out of all possible hashes. In duniter v1.5.x the hash of a block is its sha256 hexadecimal hash.</p> +<h5 id="how-is-difficulty-applied">4.3.2.1. How is difficulty applied ?</h5> +<p>The numeric value of difficulty is taken from an array of possible hashes out of all possible hashes. In DUBPv13 the hash of a block is its sha256 hexadecimal hash.</p> <p>To understand the difficulty, we make a euclidiean division of the difficulty by 16.</p> -<p>Here’s an example with a difficulty value of <code>70</code> : 70 // 16 = <strong>4</strong> with a remainder of <strong>6</strong>. The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : <code>0000[0-9]</code>. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes.</p> -<blockquote> -<p>Fine, but the hash of a mined block will never change and there’s no reason it should start with a given sequence of numbers. So how then can we make sure a block hash starts with exactly the sequence needed?</p> -</blockquote> -<p>Enter the nonce, short for “number once”. When a member is forging a new block, his computer freezes the block’s content and changes the Nonce until the hash reaches the required number of zeroes.</p> -<h5 id="the-nonce-1">The Nonce</h5> +<p>Here’s an example with a difficulty value of 70 :</p> +<pre><code>70 // 16 = 4 with a remainder of 6. </code></pre> +<p>The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : <code>0000[0-9]</code>. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes.</p> +<h5 id="the-nonce">4.3.2.2. The Nonce</h5> +<p>When a member is forging a new block, his computer freezes the block’s content and changes the Nonce until the hash reaches the required number of zeroes.</p> <p>The nonce allows us to mine a new block by finding a hash. The hash value allows us to determine the difficulty level of the proof-of-work performed. Examples of possible Nonce values:</p> <ul> <li>10100000112275</li> @@ -794,30 +344,24 @@ Duniter Whitepaper </ul> <p>In reality the <code>Nonce</code> value follows a pre-determined format akin to <code>XYY00000000000</code>. The Nonce’s value isn’t the number of attempts but rather a value within a set of possible ones. This is how the Nonce is built:</p> <ul> -<li><p>X is a number assigned to a specific peer. Let’s assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with different nodes. Each block will therefore have its own unique X to prevent this from happening.</p></li> +<li><p>X is a number assigned to a specific peer. Let’s assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with different nodes. Each <del>block</del> <strong>node ?</strong> will therefore have its own unique X to prevent this from happening.</p></li> <li><p>Y is the number of cores of the processor. The Nonce starting with <code>107[…]</code> belongs to a seven cores processor, while <code>199[...]</code> could be the proof generated by a 99 cores processor.</p></li> </ul> <p>The rest of the Nonce, the part that follows after the XYY, is the numerical space for this individual node and is unique to each of the CPU’s core. This space is comprised of eleven digits (<code>00000000000</code>). For the sake of accuracy, we use the term CPU in the wider sense, it can be understood as a bi-CPU for example. We take into consideration the number of cores for the resulting PoW.</p> -<h3 id="personalised-difficulty-1">Personalised difficulty</h3> -<p>Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other <em>PoW-based</em> cryptocurrencies such as Bitcoin.</p> +<h3 id="personalised-difficulty">4.4. Personalised difficulty</h3> +<p>Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other PoW-based cryptocurrencies.</p> <p>Here is how this personalised difficulty is calculated and assigned:</p> <p>It is determined by a combination of two different constraints with complimentary roles: the <strong>exclusion factor</strong> and the <strong>handicap</strong>.</p> <p>Let <code>powMin</code> be the common difficulty, <code>exFact</code> a member’s exclusion factor and <code>handicap</code> their handicap. This member’s personalised difficulty <code>diff</code> is:</p> -<div class="highlight"> <pre><code>diff = powMin*exFact + handicap</code></pre> -</div> -<h4 id="understanding-exfact-the-exclusion-factor-1">Understanding <code>exFact</code>, the exclusion factor</h4> +<h4 id="the-exclusion-factor">4.4.1. Understanding <code>exFact</code>, the exclusion factor</h4> <p>Members who have never produced blocks or haven’t for quite some time are assigned an exclusion factor of <code>1</code>. Their personalised difficulty is therefore simply the sum of <code>powMin + handicap</code>.</p> <p>Before reading on, let’s precise the role of this exclusion factor. When a member adds a block to the chain, his <code>exFact</code> jumps up from one to a very high value, to prevent them from forging other blocks immediately after and taking control of the blockchain.</p> <p>The exclusion factor will then rapidly return to one. This delay is expressed as a number of blocks. It is calculated as a proportion of the number of members forging. In the Ğ1’s case, this proportion is 1/3, meaning that if there are fifteen members currently forging, the member’s exclusion factor will drop down to one after five blocks.</p> -<blockquote> -<p>What is intended by “the number of members forging”?</p> -</blockquote> -<p>We mean the number of members trying to create the next block. In reality, there is no way to precisely know how many members are calculating at any given time, because it is impossible to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block in the last X blocks, minus the very last one.</p> -<blockquote> -<p>Hox is X determined?</p> -</blockquote> -<p>We use the concept of <strong>current window</strong>. X’s value is equal to the size of this window. Let’s see how it works:</p> +<h5 id="what-is-intended-by-the-number-of-members-forging">4.4.1.1. What is intended by “the number of members forging” ?</h5> +<p>We mean the number of members trying to create the next block. In reality, there is no way to precisely know how many members are calculating at any given time, because it is impossible to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block in the last blocks in the current window, minus the very last one.</p> +<h5 id="current-window">4.4.1.2. Current window</h5> +<p>We use the concept of <strong>current window</strong>. The current window is the number of blocks we look back at to determine how many members are forging. Let’s see how it works:</p> <ul> <li><p><code>issuersFrame</code> is the size of the current window in blocks.</p></li> <li><p><code>issuersCount</code> the number of members who have calculated at least one block during the current window.</p></li> @@ -867,78 +411,88 @@ Duniter Whitepaper </tbody> </table> <p>The calculation can be found under rules <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g05-headissuersframe">BR_G05</a> and <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g06-headissuersframevar">BR_G06</a> of the DUP protocol.</p> -<blockquote> -<p>Let’s go back to the personalised difficulty.</p> -</blockquote> -<p>We explained that <code>exFact</code> spikes immediately after the member has found a block. It decreases then rapidly to <code>1</code> after a number of blocks <code>X = 1/3 * issuersCount</code>. Let’s see precisely how we calculate <code>exFact</code>:</p> +<h5 id="exfact-and-the-personalised-difficulty">4.4.1.3. exFact and the personalised difficulty</h5> +<p>We explained that <code>exFact</code> spikes immediately after the member has found a block. It decreases then rapidly to <code>1</code> after a number of blocks equal to <code>1/3 * issuersCount</code>. Let’s see precisely how we calculate <code>exFact</code>:</p> <ul> <li><p><code>nbPreviousIssuers</code> is the value of issuersCount at the last block <code>N</code> found by the member.</p></li> <li><p><code>nbBlocksSince</code> is the number of blocks found by the rest of the network since block <code>N</code>.</p></li> <li><p><code>percentRot</code> is the number of <em>not excluded</em> peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency.</p></li> </ul> -<div class="highlight"> -<pre><code>exFact = MAX [ 1 ; FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) ]</code></pre> -</div> +<pre><code>a = FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) +exFact = MAX [ 1 ; a ]</code></pre> <p>The FLOOR is a simple truncate function. For <code>exFact</code> to exclude the member, we need :</p> -<blockquote> -<p>(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2</p> -</blockquote> -<p>We can see that the member is not excluded if <code>nbBlocksSince</code> is greater than 1/3 of the calculating members. Take as an example nbPreviousIssuers = 6 and nbBlocksSince = 3:</p> -<blockquote> -<p>(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1</p> -</blockquote> -<p>However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded: > (0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2</p> -<p>Moreover if the last block was authored by the said member, then: > <code>nbBlocksSince=0</code> and > <code>exFact</code> = <code>0.67 * nbPreviousIssuers</code></p> +<pre><code>(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2</code></pre> +<p>We can see that the member is not excluded if <code>nbBlocksSince</code> is greater than 1/3 of the calculating members. Take as an example <code>nbPreviousIssuers = 6</code> and <code>nbBlocksSince = 3</code>:</p> +<pre><code>(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1</code></pre> +<p>However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded:</p> +<pre><code>(0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2</code></pre> +<p>Moreover if the last block was authored by the said member, then:</p> +<pre><code>nbBlocksSince=0 and +exFact = 0.67 * nbPreviousIssuers</code></pre> <p>ExFact value increases according to the number of members calculating. Thus, if there is enough members calculating, even mining farms would be excluded. We have therefore succeeded in our intent to deter attempts to seize the blockchain and its currency.</p> -<p>However, at any time t, the two-thirds of calculating members all have an exclusion factor of <code>1</code>, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then only the members with the highest computational power from the remaining third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn’t stand a chance…</p> -<h4 id="the-handicap-1">The handicap</h4> -<p>The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. A higher handicap is assined to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW.</p> +<p>However, at any time <code>t</code>, the two-thirds of calculating members all have an exclusion factor of <code>1</code>, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then only the members with the highest computational power from the remaining third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn’t stand a chance…</p> +<h4 id="the-handicap">4.4.2. The handicap</h4> +<p>The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. A higher handicap is assigned to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW.</p> <p>The aim is to handicap the half that has authored most blocks (the most powerful half) to favour the other one. So, the handicap formula will use the median number of blocks authored by peers within the current window.</p> <ul> <li><p><code>nbPersonalBlocksInFrame</code> is the number of blocks authored by a single member within the current window.</p></li> <li><p><code>medianOfBlocksInFrame</code> is the median number of blocks written by the calculating members during the same timeframe.</p></li> </ul> -<div class="highlight"> -<pre><code>handicap = FLOOR(LN(MAX(1;(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)) / LN(1.189))</code></pre> -</div> -<p>Let’s unwrap the formula: <code>(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)</code> is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored <code>9</code> blocks in the current window and the median is <code>5</code>, then the ratio will be <code>(9+1)/5 = 2</code>. The MAX function allows us to ensure that the handicap has a value at least equal to <code>1</code>.</p> +<pre><code>a = (nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame +handicap = FLOOR(LN(MAX( 1 ; a )) / LN(1.189))</code></pre> +<p>Let’s unwrap the formula:</p> +<pre><code>(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)</code></pre> +<p>is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored <code>9</code> blocks in the current window and the median is <code>5</code>, then the ratio will be <code>(9+1)/5 = 2</code>. The MAX function allows us to ensure that the handicap has a value at least equal to <code>1</code>.</p> <p>The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers.</p> -<p>If we want the handicap to be applied as soon as the median is reached, we’d have to divide it by <code>LN(1)</code>, the problem is that we’ve already set a minimum value of <code>1</code> with the MAX function, so if we were to divide the ratio by <code>LN(1)</code> all calculating peers would have a handicap >= <code>1</code>. In addition, is it really fair to handicap a member who’s right on the median?</p> +<p>If we wanted the handicap to be applied as soon as the median is reached, we would divide it by <code>LN(1)</code>. The problem is that we have already set a minimum value of <code>1</code> with the MAX function. If we were to divide the ratio by <code>LN(1)</code> all calculating peers would have a handicap <code>\>= 1</code>. In addition, is it really fair to handicap a member who is right on the median?</p> <p>That’s why we went for <code>1.189</code> rather than <code>1</code>. A member has to be at least <code>18.9%</code> above the median to be assigned a handicap. 18.9% is actually 16^(1/16), the difficulty factor between two levels of the proof work (hexadecimal hash).</p> <p>To conclude, you have to remember that :</p> <ul> -<li>the handicap is indexed on the logarithm of the ratio to the median,</li> -<li>handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work’s difficulty.</li> +<li>The handicap is indexed on the logarithm of the ratio to the median,</li> +<li>Handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work’s difficulty.</li> </ul> -<h2 id="conclusion-1">Conclusion</h2> +<h2 id="conclusion">Conclusion</h2> <!-- source : https://duniter.org/en/theoretical/ --> <p>Duniter’s Blockchain can be compared to Bitcoin’s : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend.</p> -<p>More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers while maintaining a good security on the network.</p> +<p>More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers, maintaining a good security and helping decentralization of calculation.</p> <p>The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties :</p> <ul> -<li>The freedom to choose your currency system: because money should not be imposed</li> -<li>The freedom to access resources: because we all should have access to economic & monetary resources</li> -<li>The freedom to estimate and produce value: because value is a purely relative to each individual</li> -<li>The freedom to trade with the money: because we should not be limited by the avaible money supply</li> +<li>The freedom to choose your currency system: because money should not be imposed.</li> +<li>The freedom to access resources: because we all should have access to economic & monetary resources.</li> +<li>The freedom to estimate and produce value: because value is a purely relative to each individual.</li> +<li>The freedom to trade with the money: because we should not be limited by the avaible money supply.</li> </ul> <p>Those 4 economic freedoms should be understood together, not exclusively. Plus, “freedom” has to be understood as “non-nuisance”. So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency.</p> -<h2 id="duniter-projects-sources-1">Duniter project’s sources :</h2> -<ul> -<li>Theoretical, by Cgeek: https://duniter.org/en/theoretical/</li> -<li>Lock conditions, by Inso: https://duniter.org/en/transactions-0-2-overview/</li> -<li>Individualised Proof of Work, by Elois: https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/</li> -<li>Deep dive into the Web of Trust, by Elois: https://duniter.org/en/deep-dive-into-the-web-of-trust/</li> -<li>Whitepaper sources: https://git.duniter.org/communication/duniter-whitepaper</li> -</ul> -<h2 id="other-sources-1">Other sources :</h2> -<ul> -<li>Relative Theory of Money, S.Laborde, 2010: http://en.trm.creationmonetaire.info/</li> -<li>Bitcoin Whitepaper, S.Nakamoto, 2008: https://bitcoin.org/bitcoin.pdf</li> -<li>Circles Whitepaper, A.Milenius, 2018: https://github.com/CirclesUBI/docs/blob/master/Circles.md</li> -<li>The Sibyl Attack, J.R.Douceur: https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</li> +<h2 id="sources">Sources :</h2> +<ul> +<li>Relative Theory of Money, S.Laborde, 2010: <a href="http://en.trm.creationmonetaire.info/">en.trm.creationmonetaire.info/</a></li> +<li>Bitcoin Whitepaper, S.Nakamoto, 2008: <a href="https://bitcoin.org/bitcoin.pdf">bitcoin.org/bitcoin.pdf</a></li> +<li>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : <a href="http://lightning.network/lightning-network-paper.pdf">lightning.network/lightning-network-paper.pdf</a></li> +<li>The GNU Privacy Handbook, M.Ashley, 1999 : <a href="https://www.gnupg.org/gph/en/manual.html#AEN335">www.gnupg.org/gph/en/manual.html#AEN335</a></li> +<li>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. <a href="https://cr.yp.to/papers.html#ed25519">cr.yp.to/papers.html#ed25519</a>.</li> +<li>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : <a href="https://archive.org/details/PPCoinPaper">archive.org/details/PPCoinPaper</a></li> +<li>Duniter Blockchain Protocol, v13, draft by Elois : <a href="https://git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md">git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md</a></li> +<li>The Sibyl Attack, J.R.Douceur: <a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf">www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</a></li> +<li>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992</li> </ul> -<!-- travaux en theorie des graphes pourla TdC --> </article> </main> </body> </html> +<section class="footnotes"> +<hr /> +<ol> +<li id="fn1"><p>Bitcoin Whitepaper, S.Nakamoto, 2008: <a href="https://bitcoin.org/bitcoin.pdf">bitcoin.org/bitcoin.pdf</a><a href="#fnref1" class="footnote-back">↩</a></p></li> +<li id="fn2"><p>Relative Theory of Money, S.Laborde, 2010: <a href="http://en.trm.creationmonetaire.info/">en.trm.creationmonetaire.info/</a><a href="#fnref2" class="footnote-back">↩</a></p></li> +<li id="fn3"><p>OpenPGP protocol defines standard formats for encrypted messages, signatures, private keys, and certificates for exchanging public keys. The GNU Privacy Handbook, M.Ashley, 1999 : <a href="https://www.gnupg.org/gph/en/manual.html#AEN335">www.gnupg.org/gph/en/manual.html#AEN335</a><a href="#fnref3" class="footnote-back">↩</a></p></li> +<li id="fn4"><p>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. <a href="https://cr.yp.to/papers.html#ed25519">cr.yp.to/papers.html#ed25519</a>.<a href="#fnref4" class="footnote-back">↩</a></p></li> +<li id="fn5"><p>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : <a href="https://archive.org/details/PPCoinPaper">archive.org/details/PPCoinPaper</a><a href="#fnref5" class="footnote-back">↩</a></p></li> +<li id="fn6"><p>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : <a href="http://lightning.network/lightning-network-paper.pdf">lightning.network/lightning-network-paper.pdf</a><a href="#fnref6" class="footnote-back">↩</a></p></li> +<li id="fn7"><p>Surfing a Web of Trust, Reputation and Reciprocity on CouchSurfing.com, D.Lauterbach, H.Truong, T.Shah, L.Adamic: <a href="http://snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf">snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf</a><a href="#fnref7" class="footnote-back">↩</a></p></li> +<li id="fn8"><p>Public key validation on GnuPG manual, M.Ashley, 1999 : <a href="https://www.gnupg.org/gph/en/manual.html#AEN335">www.gnupg.org/gph/en/manual.html#AEN335</a><a href="#fnref8" class="footnote-back">↩</a></p></li> +<li id="fn9"><p>The Sibyl Attack, J.R.Douceur: <a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf">www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</a><a href="#fnref9" class="footnote-back">↩</a></p></li> +<li id="fn10"><p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992<a href="#fnref10" class="footnote-back">↩</a></p></li> +<li id="fn11"><p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992<a href="#fnref11" class="footnote-back">↩</a></p></li> +<li id="fn12"><p>Pareto principle : <a href="https://en.wikipedia.org/wiki/Pareto_principle">en.wikipedia.org/wiki/Pareto_principle</a><a href="#fnref12" class="footnote-back">↩</a></p></li> +</ol> +</section> diff --git a/build/whitepaper_en.md b/build/whitepaper_en.md index a459ae656f4a3a9d2a6ab9d85e294399a935949e..a73c873832445b1546c4eea5abb7272cdaca8674 100644 --- a/build/whitepaper_en.md +++ b/build/whitepaper_en.md @@ -1,13 +1,22 @@ -Duniter : A libre currency blockchain generator ! +Duniter: A libre currency blockchain generator. ======================================= -## Abstract (TODO) +## Abstract {#abstract} -## Introduction +Many currency principles involve non-equal rights to monetary creation between humans. +We propose a monetary creation based on the Relative Theory of Money, which guarantee equal monetary creation for each willing human. +This type of currency can be centralised, however, this could lead to censorship and arbitrary choices of the central institution. +Thus, strongly inspired by Bitcoin example, we want the currency to be as decentralised as possible, in the transaction network as in the human identification process. +We use a Web of Trust between living humans for identification. +This web of trust allows us to impose personalised difficulty for transaction validation, keeping the calculation accessible to low-end hardware and allowing all competent members to secure the currency. + + + +## Introduction {#introduction} Duniter is a software to create and manage "libre currencies". Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question : -> How should a currency be created to match the principle of equality between all humans ? +> How should a currency be created to match the principle of equality between all humans, now and between generations ? The results of this demonstration implies a monetary creation : @@ -17,111 +26,118 @@ The results of this demonstration implies a monetary creation : Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula : -> UD(t+1) = UD(t) + c² * ( M(t) / N(t) ) +$$ UD(t+1) = UD(t) + c²*( {M(t) \over N(t) }) $$ + Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin. -The first currency created through Duniter is Ğ1 (say "June"). It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software. +The first currency created through Duniter is Ğ1, pronounced "June". It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software. -## State of the art : Bitcoin case + +## 1. State of the art : Bitcoin case {#state-of-the-art-bitcoin-case} <!-- source : https://duniter.org/en/theoretical/ --> -Duniter uses the crypto-currency concept introduced by Bitcoin, which is -to use cryptographic tools such as *signatures* to create digital -currencies. Duniter fits this definition, but it has completely +Duniter uses the crypto-currency concept introduced by Bitcoin[^BTC_whitepaper], which is +to use cryptographic tools such as signatures to create trustless digital +currencies. Duniter fits this definition, but it has two completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects. -### Monetary creation of Bitcoin : a space-time asymmetry +[^BTC_whitepaper]: Bitcoin Whitepaper, S.Nakamoto, 2008: [bitcoin.org/bitcoin.pdf](https://bitcoin.org/bitcoin.pdf) + +### 1.1. Monetary creation of Bitcoin : a space-time asymmetry {#monetary-creation-a-space-time-asymmetry} Space-time asymmetry refers to the relative access of individuals to -newly created money (Relative Theory of Money, S.Laborde, 2010). Concretely, all existing currencies (c. 2015) are +newly created money[^RTM]. Concretely, most existing currencies (c. 2020) are both spatially and temporally asymmetrical for their users. Let\'s take Bitcoin as an example to understand why. -#### Spatial asymmetry +[^RTM]: Relative Theory of Money, S.Laborde, 2010: [en.trm.creationmonetaire.info/](http://en.trm.creationmonetaire.info/) + +#### 1.1.1. Spatial asymmetry {#spatial-asymmetry} -When new Bitcoins are created, *only some Bitcoin users* (the miners) -are given new Bitcoins, while everyone else get nothing. **We believe -this is the *first* injustice.** However, some might say: +When new Bitcoins are created, only some Bitcoin users (the miners) +are given new Bitcoins, while everyone else get nothing. We believe +this is the first injustice. However, some might say: -> \"Miners used their *electricity and time* to get it!\" +> \"Miners used their electricity and time to get it!\" -\... we would answer that this work *shouldn\'t have been rewarded by -newly created Bitcoins*. New Bitcoins should be distributed to the whole -Bitcoin community. Miners should be rewared another way, but not by -money issuance. Of course, Bitcoin can\'t create money through Basic -Income since *Bitcoin users are not strongly identified*, and one might -benefit from money creation multiple times if he owned several wallets. -Duniter gets rid of this problem completely by identifying its users and -giving *the same amount of Basic Income to everyone*. +\... we would answer that this work should not have been rewarded by +newly created Bitcoins. New units should be distributed to the whole +community. Miners should be rewared another way, but not by +money issuance. Of course, Bitcoin cannot create money through Basic +Income since Bitcoin users are not strongly identified, and one might +benefit from money creation multiple times if they owned several wallets. +Duniter gets rid of this problem by identifying its users and +creating the same amount of Basic Income to everyone. -#### Temporal-asymmetry +#### 1.1.2. Temporal-asymmetry {#temporal-asymmetry} Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, -how will future joiners get Bitcoins? Just like Euros or +how will future joiners get Bitcoins? Just like most of us do for Euros or Dollars: to get money, they will have to work for the ones who already own it. -**We believe this is the *second* injustice.** Every member of a + +We believe this is the second injustice. Every member of a monetary community should be equal concerning monetary creation, and get -the same relative amount of money over time, *even if they are a late -adopter*. Duniter aims to fix this by making the Universal Dividend -(a.k.a. *UD*) *grow by the time* (S.Laborde, 2010) according to precise rules, thus making +the same relative amount of money over time, even if they are a late +adopter. Duniter aims to fix this by making the Universal Dividend +(a.k.a. UD) grow by the time according to precise rules, thus making members equal toward money issuance on a half-lifespan. +Most currencies present one of these two asymmetries, including metal currencies +and mutual credit, as exposed in the RTM. +#### 1.1.3. A solution {#a-solution} - -#### A solution - -Bitcoin has taught us that *it is possible* to create a currency system +Bitcoin has taught us that it is possible to create a currency system allowing one to both create digital money and to exchange it without a -central authority. What we need to change is *the way money is issued* -so we finally have a symmetrical system. We need Bitcoin *+ Universal -Dividend*. But Universal Dividend *implies* that the community consists +central authority. What we need to change is the way money is issued +so we finally have a symmetrical system. We need **Bitcoin + Universal +Dividend**. But Universal Dividend implies that the community consists of only identified people. This is where the Web of Trust (WoT) comes -into place. This concept, introduced by cryptography with the -[OpenPGP](https://www.wikiwand.com/en/Pretty_Good_Privacy) format, -allows us to identify people in a *decentralized* manner. It works as -follows: each person creates *a personal identity* that is linked to its +into place. + +This concept, introduced by cryptography with the OpenPGP format[^OpenPGP], +allows us to identify people in a decentralized manner. It works as +follows: each person creates a personal identity that is linked to its cyptographic certificate. The identity must be confirmed by others -members who use their own cryptographic key. It is that simple: **people +members who use their own cryptographic key. It is that simple: people choose who is part of the community and who is not, not a central -authority.** +authority. -> Duniter however won\'t use OpenPGP for its cryptographic features: -> Elliptic Curves will be used instead for the conciseness of its -> generated keys and its pratical advantages. Duniter has its own Web -> of Trust principles, that shall be exposed later. +[^OpenPGP]: OpenPGP protocol defines standard formats for encrypted messages, signatures, private keys, and certificates for exchanging public keys. The GNU Privacy Handbook, M.Ashley, 1999 : [www.gnupg.org/gph/en/manual.html#AEN335](https://www.gnupg.org/gph/en/manual.html#AEN335) -### Proof-of-Work mining : a power race (TODO) +However, Duniter will not use OpenPGP for its cryptographic features: +Elliptic Curves[^Elliptic] will be used instead for the conciseness of its +generated keys and its pratical advantages. Duniter has its own Web +of Trust principles, that will be exposed later. -In Bitcoin Model, the calculation and incentive principles cause a power race : -new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. -The goal of Duniter is to make blockchain validation much less energy and hardware consuming while -keeping a strong level of security. As a consequence, even low-power hardware can secure Duniter Blockchain, -which leads to a better decentralization of forging operations. +[^Elliptic]: High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. [cr.yp.to/papers.html#ed25519](https://cr.yp.to/papers.html#ed25519). -### Other projects ? +### 1.2. Proof-of-Work mining : a power race {#proof-of-work-mining-a-power-race} -#### What about PoS ? +In Bitcoin Model, the calculation and incentive principles cause a power race : +new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. +This leads to a power race an places the control over the currency in the hands of the richest hardware owners. +We want to make Duniter blockchain validation much less energy and hardware consuming while +keeping a strong level of security. This will be further explained later. A consequence of +this choice is the participation of low-end hardware in the Duniter network, +leading to a better decentralization of blockchain validation. -When conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. -Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead -to placing power over the currency in the richests hands : this is contrary to the symmetical principles of Duniter. +#### 1.2.1 What about Proof of Stake ? {#what-about-proof-of-stake} -Now that PoS is well-tested, one could try to use Duniter's WoT to create a PoS-like algorithm with equal chances among members. -But this is not our aim for now. +Proof of stake consensus algorythm was first introduced in 2012[^PPCoin]. The basic principle is to allow the richest wallets to issue blocks, putting their coin balance as a "stake" they would lose in case of cheat. -#### What about Directed Acyclic Graph ? +[^PPCoin]: PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : [archive.org/details/PPCoinPaper](https://archive.org/details/PPCoinPaper) -The Circles project uses DAG in a basic income cryptocurrency. However, in this project, -one peer cannot know the whole monetary mass and the exact number of other peers. -The calculation of Universal Dividend `UD = c * M/N` seems impossible, since we know neither M nor N. +At the time of conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. We did not chose this consensus principle. +Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead +to placing power over the currency in the richests hands : this is contrary to the symmetical principles of a libre currency. -## Duniters Blockchain +## 2. Duniters Blockchain {#duniters-blockchain} <!-- source : https://duniter.org/en/theoretical/ --> @@ -130,138 +146,165 @@ Duniters Blockchain follows the basic principles of Bitcoins. This is essential for synchronization between peers, as to prevent double-spend attacks. However, Duniters Blockchain will store different informations than Bitcoins. -The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no *generation transaction* exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either: +The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no generation transaction exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either: * a former transaction (as in Bitcoin) * a Universal Dividend (specific to Duniter). -Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactinos are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where "space" are members of the WoT and "time" the basci blockchain units : the blocks. On each point of time, one can determain whick account is legitimate to create the UD, only with a blockchain analysis. +Duniters Web of Trust is also written in the Blockchain. The identity of each +member gets registered much like transactions are, with a strong link to the +time reference. Thus, the Blockchain is a representation of a space-time frame +of reference, where "space" are members of the WoT and "time" the basic blockchain +units : the blocks. On each point of time, one can determine which account is +legitimate to create the UD, only with a blockchain analysis. +### 2.1. Spam countermeasures {#spam-countermeasures} -### Spam countermeasures (TODO) -An issue of most cryptocurrency projects is to prevent the common ledger from growing too much and require lot of storage and computing power to be usable. In particular, we don't want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don't want to do this since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented. +An issue of most cryptocurrency projects is to prevent the common ledger from +growing too much. This would require nodes to have a lot of storage and computing +power to be usable. In particular, we don't want an attacker to be able to make the +Blockchain grow too fast. Most projects implement transaction fees as a way to prevent +this, making the attacker lose money. We don't want to introduce this mean since a +currency with automatic fees on transactions is no more neutral. Several +countermeasuers against such spam attacks are implemented. <!-- see : https://forum.duniter.org/t/sans-frais-de-transaction-comment-resister-aux-attaques/3846/25 (implemented ?)--> -* output minimal de 100*Unitbase / 1 unité -> empêche un attaquant de faire grossir la BC et les index trop vite (DUBP v12) -* chaînage maximal des tx -* seuils de dépense (implémentés ? en tout et par issuer ?) +#### 2.1.1. Minimum output amount {#minimum-output-amount} + +<!-- This has to be implemented in DUBPv13. --> + +Fixing a minimal output amount reduces the power of an attack. Duniter deals with cents of Ğ1 or 1/1000 of the first UD. An attacker could create thousand accounts with only 1 UD. To prevent this, a valid transaction must have output amounts of minimum 1Ğ1. This reduces the power an attack by 100. + +#### 2.1.2. Limited block size and chainability {#limited-block-size-and-chainability} + +The block size is always limited. While the protocol allows this limit to evolve to address scaling issues, an attacker cannot register as many transaction as they wish. -### Scaling +With the same goal to prevent too many transactions to get registered, while transactions can be "chained" (refer to another transaction in the same block), the chainability of transactions is limited to 5. + + +### 2.2. Scaling {#scaling} Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons : -* Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don't want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT limits its size to around 16 million members. -* Duniter's aim is to be used to create *multiple* libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community. +* Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don't want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT should limit its size to around 16 million members. +* Duniter's aim is to be used to create multiple libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community. -However, Duniter has two assets that might be used if the number of users grow. +However, Duniter has assets that will help if the number of users and transactions grow. -#### Dynamic block size +#### 2.2.1 Dynamic block size {#dynamic-block-size} While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. -On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks( *current window* will be described in the PoW part). -This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. +On high use of the blockchain, the maximal block size would be 110% of the +average size of the current window blocks(see "personalised difficulty" part for more information). +This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. The block size (in bytes) is limited as so : -:::{highlight} +``` block_size < max(500 ; CEIL(1.10 * (average block size)) -::: - +``` -#### Lightning Networks +#### 2.2.2. Lightning Networks {#lightning-networks} -The Lightning Networks allow almost instant and off-chain transactions. +The Lightning Networks[^Lightning] allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed. +[^Lightning]: The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : [lightning.network/lightning-network-paper.pdf](http://lightning.network/lightning-network-paper.pdf) + +#### 2.2.3. Unit base {#unit-base} + +As the Universal Dividend grows exponentially, with time Duniter nodes would have had to deal with always largest amounts, eventually reaching the BIGINT limit. To avoid this, the amounts are expressed with a unit base in base 10. We want the UD amount to always fit in 4 digits. To manage it, the `unitbase` is updated each time the UD value reaches 100.00 : it goes from `99.99*10^(unitbase)` to `10.00*10^(unitbase+1)`. All the unit amounts are thus divided by 10. While this might seem strange, this process has already hapened in state currencies. Moreover, the amounts expressed in UD will not change. + +With a monetary growth of 10% each year and a stable population, such a change of unit base would happen each 25 years. -## Duniter Web of Trust +## 3. Duniter Web of Trust -<!-- source : https://duniter.org/en/deep-dive-into-the-web-of-trust --> -### Basic Principles +### 3.1. Basic Principles {#duniter-wot-basic-principles} -In order to identify "members" account - which create monetary units - from other accounts, Duniter uses a Web of Trust. This can be summarized into few principles: +In order to identify "members" accounts - which create monetary units - +and other accounts, Duniter uses a Web of Trust. This can be summarized +into few principles: -* Each account becomes a member if it received a minimal number of certifications (5 for Ğ1 currency) -* Only members accounts can send certifications. Certifications have a limited lifespan. -* A certification indicates that the sender accepts the receiver as a legitimate identity. +- Each account becomes a member if it received a minimal number of + certifications - 5 for Ğ1 currency. +- Only members accounts can send certifications. Certifications have a + limited lifespan. +- A certification indicates that the sender accepts the receiver as a + legitimate identity. -The aim of the WoT is to identify a blockchain account to a living human. Each member of the Ğ1 currency signs a licence stating that they will only certify humans they know well (among other rules). -Thus, if a member is part of an attack on the currency, they can be found by mutual friends. The security of Ğ1 currency stands on: +The aim of the WoT is to identify a blockchain account to a living +human. According to Lauterbach et.al[^Couchsurf], the strengh of a relationship should be considered when building a vouch system. +For this reason, the Ğ1 Web of Trust rules are expressed in a licence stating what WoT certifications are. +A certification represents a strong human relationship : one may certify a close relative, not an acquaintance. +Each member has to accept this licence before being included in the WoT. +Thus, if a member is part of an attack on the currency, they can be found by mutual relatives. +Additional security rules occur to prevent cheat and attacks on a large scale. -* Corroborating informations on members (5 certifications) -* Peer pressure by close relatives -* Law if the licence has not been respected. +[^Couchsurf]: Surfing a Web of Trust, Reputation and Reciprocity on CouchSurfing.com, D.Lauterbach, H.Truong, T.Shah, L.Adamic: [snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf](http://snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf) -Note that non-members accounts can use the currency, but cannot create money. They can be used by individuals as secondary wallets, or by institutions. +Note that non-members accounts can use the currency, but cannot create +money. Non-members accounts can be used by individuals as secondary wallets, or by +institutions. -However, the WoT does not rely only on trust betwenn people. Rules have been added to increase the security, and we will present them. +We were inspired by the OpenPGP Trust system[^OpenPGP_Trust]. However, the OpenPGP +trust principles aim at defining trust from a particular point of view while Duniter needs to +identify humans for the whole community. To achieve this goal, while OpenPGP allows each +user to tweak its trust parameters individually, Duniter sets rules in the "genesis" block for the whole community. +[^OpenPGP_Trust]: Public key validation on GnuPG manual, M.Ashley, 1999 : [www.gnupg.org/gph/en/manual.html#AEN335](https://www.gnupg.org/gph/en/manual.html#AEN335) -### Why do we need a Web of Trust? +### 3.2. Why do we need a Web of Trust ? {#why-do-we-need-a-web-of-trust} There are two reasons we need it : 1. To make sure that only one Universal Dividend is produced per member - at each specified creation interval -in the Ğ1's case this interval - is set as daily `86 400` seconds-, it is the *monetary parameter* - known as `dt`-. -2. To identify the nodes hashing the blocks and assign them each a - personalised difficulty. This custom difficulty [proof of - work](https://en.wikipedia.org/wiki/Proof-of-work_system) is there - to avoid the blockchain's validation mechanism becoming too + at each specified creation interval. In the Ğ1's case this interval + is set as daily `86 400` seconds, it is the *monetary parameter* + known as `dt`. +2. To identify the nodes hashing the blocks and assign each a + personalised difficulty. This custom difficulty proof of work is + there to avoid the blockchain's validation mechanism becoming too centralised as is the case with many \'non-libre' cryptocurrencies. - > Wait, what's a 'monetary parameter' ? - -Every currency implementing Duniter has its own blockchain whose -behaviour is dictated by a set of 'parameters' -defined in block zero, -the so-called genesis block- that can be tweaked to achieve the desired -results. At the time of writing this article, the Duniter protocol -aka -DUP- has a total of 21 parameters of which 10 are for the WoT alone. -We'll focus on these 10. - -Suffice to say that in the Ğ1's case, the DU is created every 24 hours --86 400 seconds- but this interval -set through the time derivative `dt` -parameter- can have a different value in an other implementation of the -protocol. - -I won't write about the second parameter having to do with the proof of -work, it's outside our scope here, just know that the Web of Trust -allows us to **identify** the members providing hashing power, which we -couldn't do without it. This crucial feature means we can impose a -rotation between the members hashing the blocks so that no single rich -individual or group invests in a giant 'hash farm' and takes a hold of -the blockchain, paralysing the community! - -Let's go back to the first objective: to make sure that each member can -only have one account. As we all know, achieving zero-risk isn't -possible, our goal is therefore not to create a WoT within which fraud -would be absolutely impossible but instead to discourage it. Here is a +> **Monetary parameter** : Each currency that use Duniter has its own blockchain whose behaviour is +> dictated by a set of 'parameters' defined in block zero - the so-called +> genesis block - that can be tweaked to achieve the desired results. At +> the time of writing the Whitepaper, the Duniter Blockchain Protocol +> (DUBP) has a total of 21 parameters of which 10 are for the WoT alone. +> We'll focus on these 10. +> +> Suffice to say that in the Ğ1's case, the DU is created every 24 hours - +> 86 400 seconds. This interval is set through the time derivative `dt` +> parameter and can have a different value in other implementations of the +> protocol. + +We want to make sure that each member can only have one account. As we +all know, achieving zero-risk isn't possible[^Sybil_Attack]. +Our goal is therefore not to create a WoT within which fraud +would be absolutely impossible, but instead to discourage it. Here is a rewording of our goal in 4 smaller ones : -1. To make the certification process lengthy enough that all members +1. Make the certification process lengthy enough that all members exercise due diligence and are wary of risks. -2. To make fraudulent acts as hard as we can to the extent that they +2. Make fraudulent acts as hard as we can to the extent that they become pointless. -3. To ensure that any Sybil attacks have a negligible impact on the - currency -*by ensuring that illegitimate double Universal Dividends - have no significant bearing on the legitimate monetary mass*- -4. To slow the growth of 'Sybil regions' to give enough time for the +3. Ensure that any Sybil attacks have a negligible impact on the + currency by ensuring that illegitimate double Universal Dividends + have no significant bearing on the legitimate monetary mass +4. Slow the growth of 'Sybil regions' to give enough time for the community to react and isolate the threat. + +[^Sybil_Attack]: The Sibyl Attack, J.R.Douceur: [www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf](https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf) -> **Wait, a Sybil what ?** - -A [**Sybil attack**](https://en.wikipedia.org/wiki/Sybil_attack), is the -name given to attacks perpetrated on a reputation system through the -creation of fake identities. A Web of Trust is a specific instance of a -[**Reputation -System**](https://en.wikipedia.org/wiki/Reputation_system). +> **Sybil attack** : A Sybil attack is an attack perpetrated on a +> reputation system through the creation of fake identities. A Web of +> Trust is a specific instance of a Reputation System. There are plenty of Sybil attack scenarios we can think of and just as many reasons why their perpetrators would want to carry them out. Our @@ -272,23 +315,28 @@ This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web's role isn't to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing -your tap water and electricity but isn't responsible for any burglaries +your tap water and electricity but isn't responsible for any burglaries, etc. Much in the same way, Duniter's WoT guarantees us all a functional -currency and that's quite a feat in itself! +currency, but do not detect small fraud. + +### 3.3. The importance of having our own certification system {#own-certification-system} -### The importance of having our own certification system +Centralized identification systems can achieve the goal we want. State +Identification is an example. However, this has many drawbacks : -We are regularly offered to switch over to third-party or state-owned -authentication systems but these are centralised and go against the -principles of our community. We feel that we would lose our independence -and universality by adopting a state-controlled system. People without -an official state-provided identity or homeless people would also run -the risk of being excluded from the WoT. It is of the utmost importance -that we remain free from any state or corporation. To this day we depend -only on the Internet and yet, were it to fail, there are already -alternatives being tested around the world for a decentralised network. +* The authority may have arbitrary criteria for identification, for example +preventing people without an official state-provided identity or +homeless people to be included in the WoT. +* Payment might be required +to get identified, thus making the monetary creation not "free". +* The authority is a point of failure for any attacker. -### A few foundational concepts on graph theory : a bit of vocabulary +It is of the utmost importance that we remain free from any state or +corporation. The WoT is an answer to this criterium. To this day we +depend only on the Internet and yet, were it to fail, there are already +alternatives being tested around the world for a decentralised communication network. + +### 3.4. A few foundational concepts on graph theory : a bit of vocabulary {#graph-theory-vocabulary} - **Graph**: set of points -called 'vertices'- joined by edges -called paths/walks-. @@ -298,12 +346,10 @@ alternatives being tested around the world for a decentralised network. have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise. - [Wikipedia](https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms) - + - **Directed graph**: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. - [Wikipedia](https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms) Arrow A --\> B is therefore different from arrow B --\> A. - **Endpoints**: the edge with vertex A --\> B has A and B as @@ -311,7 +357,6 @@ alternatives being tested around the world for a decentralised network. - **Isolated vertex**: a vertex whose degree is zero, that is, a vertex with no incident edges. - [Wikipedia](https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms) - **Degree of a vertex**: number of its incident edges -in and out-. @@ -321,59 +366,52 @@ alternatives being tested around the world for a decentralised network. - **In-degree of vertex A**: number of incoming edges / head ends to A. - + - **Path**: -aka "walk"- path to follow to get from vertex A to vertex B. -### Definition of the Duniter Web of Trust +### 3.5. Definition of the Duniter Web of Trust {#definition-of-the-duniter-web-of-trust} The Duniter WoTs -one per currency- are simple directed graphs without isolated vertices. The vertices are the members and the edges are the certifications given and received. -Directed, what does that mean? - -The responsibility of issuing a certification is unique and personal to -the certifier. The trust he/she places in the receiver cannot be imposed -in the other direction although in most circumstances both parties -equally trust each other. +*Directed* means that the responsibility of issuing a certification is +unique and personal to the certifier. The trust they place in the +receiver cannot be imposed in the other direction although in most +circumstances both parties equally trust each other. In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific 'deactivated state' and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered -'pending' to avoid the web collapsing like a house of cards. - -If these old members don't come back into the web, their pending -certifications will eventually expire and they will switch from -'deactivated' to 'isolated' vertices. +'pending' to avoid a collapse of the WoT. If these old members don't +come back into the WoT, their pending certifications will eventually +expire and they will switch from 'deactivated' to 'isolated' vertices. -To wrap up with old members, after a certain period of time -set in the +To wrap up with old members, after a certain period of time - set in the currency's parameters - their deactivated vertex is removed from the web and the associated identity is 'revoked'. The person who owned the account can no longer use this identity but is free to join the web with -another one. :-) - -> What do you mean by 'identity'? +another one. -An identity is a set of three pieces of information: a public key, a -name and a blockstamp. A blockstamp points to a specific block in the -chain. Its main use is to freeze the point in time at which an identity -was created and to link this identity to a specific chain and of course, -a currency -each currency having its own blockchain-. - -An identity can be in any one of 5 different status: pending, member, -old member, revoked or excluded. +> **Identity** : An identity is a set of three pieces of information: a public key, a +> name and a blockstamp. A blockstamp points to a specific block in the +> chain. Its main use is to freeze the point in time at which an identity +> was created and to link this identity to a specific chain and a currency +> - each currency having its own blockchain. +> +> An identity can be in any one of 5 different status: pending, member, +> old member, revoked or excluded. Let's take a simple example: -::: {.highlight} +``` A -> B -> C | \--> D -::: +``` If, for whatever reason, A were to lose its member status, the web would crumble and all other members would be excluded as a consequence. To @@ -383,80 +421,73 @@ or D. Because our WoT doesn't have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications -it has received -in the same block-. This calls for a temporary 'buffer' -storage space for **pending** identities and the certifications they've -received. This storage space is called 'the pool' -of Duniter nodes- -which we could also have called the 'sandbox' as that's the name used in -Duniter's code. I might add that these 'pools' also include other +it has received, all in the same block. This calls for a temporary +'buffer' storage space for **pending** identities and the certifications +they have received. This storage space is called 'the pool' of Duniter +nodes, which we could also have called the 'sandbox' as that's the name +used in Duniter's code. Duniter nodes inclued other 'pools' for other documents and metadata not mentioned here. -### Exploring the rules behind a Duniter Web of Trust +### 3.6. Exploring the rules behind a Duniter Web of Trust {#exploring-the-rules-behind-duniter-wot} -The Duniter WoTs -one per currency- work with a set of eight fundamental -rules, themselves enforced through eleven different parameters. Ten of +The Duniter WoTs - one per currency - works with a set of eight +fundamental rules enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - `msPeriod`- having being hard-coded in the Ğ1's code subsequently. -#### 1.Distance rule and referent members (`stepMax` and `xPercent`) {#1distance-rule-and-referent-members-stepmax-and-xpercent} +#### 3.6.1. Distance rule and referent members (`stepMax` and `xPercent`) {#distance-rule-and-referent-members-stepmax-and-xpercent} These two parameters are closely linked and together define the 'distance rule'. The 'distance rule' can only be described after defining what a 'referent member' is: > **Referent member**: member A is said to be 'referent' if and only if -> the total of his/her degrees are greater than or equal to -> `CEIl-N^-1/stepMax--` where N is the total number of members.\*\* As -> the size of the web will grow this number will grow too, meaning it -> will take more certification issuances to become a referent member as -> the number of certifications needed to become a member shouldn't -> change. +> the total of their degrees are greater than or equal to +> `CEIL-N^-1/stepMax` where N is the total number of members. As the +> size of the web will grow this number will grow too, meaning it will +> take more certification issuances to become a referent member. The +> number of certifications needed to become a member shouldn't change. Let's now define the distance rule: > **Distance rule**: member A is said to observe this rule if and only > if for a subset xPercent % of referent members R there exists a path -> of length less than or equal to `stepMax` between R and A.\*\* +> of length less than or equal to `stepMax` between R and A. Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect -web, that is one in which each member has certified all members he/she +web, that is one in which each member has certified all members they legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time `t` who haven't yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would -effectively stop growing. -You can see what would happen if the notion -of 'referent member' didn't exist by going to the 'gaussianWotQuality' -page on -[currency-monit](https://g1-monit.librelois.fr/gaussianWotQuality?lg=en&unit=quality) -and activating 'if the concept of referent members didn't exist'-. - -> **When is the distance rule applied?** +effectively stop growing. Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets -confirmed into the web or an existing member gets renewed. *Exception to -the rule: the distance rule is not observed in the genesis block -when -the web is first implemented-.* +confirmed into the web or an existing member gets renewed. There is an +exception to this rule: the distance rule is not observed in the genesis +block -when the web is first implemented. -#### 2. Rule of the minimum number of certifications needed (`sigQty`) {#2-rule-of-the-minimum-number-of-certifications-needed-sigqty} +#### 3.6.2. Rule of the minimum number of certifications needed (`sigQty`) {#rule-of-the-minimum-number-of-certifications-needed-sigqty} This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least `sigQty` active certifications. If, for whatever reason, member A were -to have less than `sigQty` active certifications in a given block, -he/she would cease being a member and be required to publish a request -for identity renewal. +to have less than `sigQty` active certifications in a given block, they +would cease to be a member and be required to publish a request for +identity renewal. -#### 3. The membership renewal rule (`msValidity`, `msPeriod` and `msWindow`) {#3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow} +#### 3.6.3. The membership renewal rule (`msValidity`, `msPeriod` and `msWindow`) {#the-membership-renewal-rule-msvalidity-msperiod-and-mswindow} Bear in mind that a membership doesn't last a lifetime but instead has a lifespan set to `msValidity` seconds. Every single member -or old member who hasn't revoked his identity or been excluded- can request a membership renewal so long as the last -request was made more than `msPeriod` seconds ago -if a member has never +request was made more than `msPeriod` seconds ago. If a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the 'pool' for a maximum of `msWindow` seconds before it's included @@ -466,25 +497,25 @@ are already matched it's just a case of waiting for a new block to be mined-. If a member hasn't requested a renewal for longer than `msValidity` -seconds, he/she automatically ceases being a member. From this moment -on, the ex-member has another `msValidity` window to renew his/her -membership. When this period of \`2 × msValidity' runs out, the -membership will expire and this identity will never be available for use -again in the web. If the person so desires, he/she will have to start -from zero to regain access to the WoT. +seconds, they automatically cease to be a member. From this moment on, +the ex-member has another `msValidity` window to renew their membership. +When this period of `2 × msValidity` runs out, the membership will +expire and this identity will never be available for use again in the +web. If the person so desires, they will have to publish new identity +and membership documents and find enough certifiers, as any newcomer. -#### 4. Rule of certification lifespan (`sigValidity`) {#4-rule-of-certification-lifespan-sigvalidity} +#### 3.6.4. Rule of certification lifespan (`sigValidity`) {#rule-of-certification-lifespan-sigvalidity} All certifications included in the blockchain expire **sigValidity** seconds after they were **issued**. -/!\\ The issuance and the inclusion of a certification in the blockchain -occur at different times. When member A issues a certification at time -t1, it gets stored in the pool starting at t1 and only finds its way -into the blockchain at t2 when all of the web's rules are observed. -Several weeks can thus go by between t1 and t2!!! +> /!\\ The issuance and the inclusion of a certification in the +> blockchain occur at different times. When member A issues a +> certification at time t1, it gets stored in the pool starting at t1 +> and only finds its way into the blockchain at t2 when all of the web's +> rules are observed. Several weeks can thus go by between t1 and t2!!! -#### 5. Rule of limited supply of active certifications (`sigStock`) {#5-rule-of-limited-supply-of-active-certifications-sigstock} +#### 3.6.5. Rule of limited supply of active certifications (`sigStock`) {#rule-of-limited-supply-of-active-certifications-sigstock} By 'active certifications' we refer to certifications included in the blockchain and that haven't yet expired. @@ -494,26 +525,26 @@ time must be less than or equal to `sigStock`. When this threshold is reached the member will have to wait for one of his active certifications to expire before he/she can issue a new one. -#### 6. Rule of the time period between two certification issuances. (`sigPeriod`) {#6-rule-of-the-time-period-between-two-certification-issuances-sigperiod} +#### 3.6.6. Rule of the time period between two certification issuances. (`sigPeriod`) {#rule-of-the-time-period-between-two-certification-issuances-sigperiod} As soon as a certification issued by member A gets included in the -blockchain, he/she will be unable to issue a new one before another +blockchain, they will be unable to issue a new one before another `sigPeriod` seconds. -#### 7. Expiry of a certification issuance (`sigWindow`) {#7-expiry-of-a-certification-issuance-sigwindow} +#### 3.6.7. Expiry of a certification issuance (`sigWindow`) {#expiry-of-a-certification-issuance-sigwindow} When a certification is issued by member A, it will be stored in the 'pool' for a maximum of `sigWindow` seconds. If the certification hasn't been included in the blockchain by then, it will be cancelled and the member's `sigStock` will be repleted by one. -#### 8. Lifespan of a 'pending' active certification (`idtyWindow`) {#8-lifespan-of-a-pending-active-certification-idtywindow} +#### 3.6.8. Lifespan of a 'pending' identity (`idtyWindow`) {#lifespan-of-a-pending-identity-idtywindow} When a new identity is created, it is stored in the 'pool' for a maximum of `idtyWindow` seconds. If the person hasn't achieved member status by then, the certification will simply be cancelled. -### Details on some of the WoT's peculiarities at the genesis block. {#details-on-some-of-the-wots-peculiarities-at-the-genesis-block} +### 3.7. Details on some of the WoT's peculiarities at the genesis block {#details-on-some-of-the-wots-peculiarities-at-the-genesis-block} The aforementioned rules can only be enforced with an existing web. They cannot be observed when first creating the web, that is when defining @@ -522,25 +553,25 @@ the genesis block. Only rules 2 and 5 can be observed at the genesis block. The genesis block has to be manually created by the founding members. In -practice this means that there must be a choice of which identities to +practice this means that there must be a choice on which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities. As soon as the genesis block has been created, the other identities can -start mining the blockchain and the member who begat block \#0 +start mining the blockchain and the member who created block \#0 effectively looses the decision power he had at creation. -### Why these rules and application cases in the Ğ1 {#why-these-rules-and-application-cases-in-the-g1} +### 3.8. Why these rules and application cases in the Ğ1 {#why-these-rules-and-application-cases-in-the-g1} -#### 1. Distance and maximum size {#1-distance-and-maximum-size} +#### 3.8.1. Distance and maximum size {#distance-and-maximum-size} The distance rule is there to curb the maximum size of a Sybil region as well as that of the monetary community as a whole. The `xpercent` parameter prevents the creation of a 'faction' that could take hold of the blockchain. - + The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned @@ -550,34 +581,36 @@ endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as `stepAttackers`. The maximum size of a Sybil region created by `sigQty` -members depends on the L parameter, defined as L = sigQty/sigStock: +members depends on the L parameter, defined as `L = sigQty/sigStock`: -::: {.highlight} - Maximum Sybil region size = (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L) -::: +``` +MaxSybilSize= (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L) +``` The maximum size of the Web of Trust is given by the following formula: -::: {.highlight} - WoTmax = (sigStock)*L^(stepMax-1) -::: +``` +WoTmax = (sigStock)*L^(stepMax-1) +``` However we know for a fact that members will never use all of their -available certifications. Many studies have proven that we all know a -maximum average of fifty people, let's then replace sigStock by fifty: +available certifications. +According to Dunbar[^Dunbar], on average, one is able to maintain relationships to around 150 people. +Being conservative, we will consider that on average, each person will certify 50 accounts. +We can calculate the size of the average web of trust `WoTavg` : + +``` +WoTavg= (50)*(sigQty/50)^(stepMax-1) +``` + +[^Dunbar]: Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992 -::: {.highlight} - WoTavg= (50)*(sigQty/50)^(stepMax-1) -::: Our goal with the Ğ1 is to create a community of about one million -members enjoying the world's first true -[catallaxy](https://en.wikipedia.org/wiki/Catallaxy) -free economy with -a spontaneous order of things-. Let's see how we can tweak the pair of -sigQty and stepMax- to reach this size: +members to test the consequences of a libre monetary system. Let's see +how we can tweak the pair of sigQty and stepMax- to reach this size: - + The maximum size of a Sybil region grows linearly with `sigQty` but exponentially with `stepMax`. Logic has it that we need to keep @@ -598,13 +631,23 @@ knowing that the smaller `sigQty` is, the easier it is to launch a Sybil attack -it's easier to find four accomplices than five-. For security reasons we have settled on five: -stepMax = 5 sigQty = 5 sigStock \>= 50 +``` +stepMax = 5 +sigQty = 5 +sigStock \>= 50 +``` The maximum size of a Sybil region therefore is: -`(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))` + +``` +(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5)) +``` with sigStock = 50 we have a Sybil region of: -`45*(1-10^(5-stepAttackers))/(-9)` + +``` +45*(1-10^(5-stepAttackers))/(-9) +``` A good practice for protecting the web is to maximise `stepAttackers`. That's why we decided that referent members in the genesis block had to @@ -618,7 +661,7 @@ renewed. But what if bot accounts were created and certified each other super fast and following all rules, how would we counter that? By introducing a minimum length of time between two certifications! -#### 2. Time is our friend {#2-time-is-our-friend} +#### 3.8.2. Time is our friend {#time-is-our-friend} To help us deter a Sybil attack, we've decided to impose a minimum period of time between any two certifications issued from a single @@ -626,12 +669,12 @@ account. This parameter called `sigPeriod` affords us a greater chance to detect the formation of a 'hostile' faction. Here is a graph showing the evolution of a Sybil region with the -variation of `sigPeriod`: +variation of `sigPeriod`. The simulation considers that honest members +and attackers both issue a certification each `sigPeriod` interval, in days: - + -As you'll easily be able to tell, there is a strong link between the +As we see, there is a strong link between the growth speed of the region and `sigPeriod`. As evidenced here, we need a `sigPeriod` high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher @@ -641,47 +684,47 @@ gingerly, the action coming at a higher 'cost'. There are numerous advantages to giving `sigPeriod` a high value and no technical barriers to it, hence our choice of five days. -We could have also gone for days days -one week- for the sake of -simplicity however there was an underlying idea behind our choice which -was quite simply the pace of today's life. Certifying someone can be a -lengthy process as one needs to make sure he/she is correctly applying -the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit -of free-time. Thus the idea to allow one to certify at the end of every -working week -five days- instead of a whole calendar one. +We could have also gone for one week for the sake of simplicity. However +there is an underlying idea behind our choice which was quite simply the +pace of today's life. Certifying someone can be a lengthy process as one +needs to make sure they are correctly applying the Ğ1 licence and people +nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea +to allow one to certify at the end of every working week -five days- +instead of a whole calendar one. -#### 3. Trust me now, trust me forever? (`sigValidity`, `msValidity`) {#3-trust-me-now-trust-me-forever-sigvalidity-msvalidity} +#### 3.8.3. Trust me now, trust me forever ? (`sigValidity`, `msValidity`) {#trust-me-now-trust-me-forever-sigvalidity-msvalidity} There would be two main drawbacks to a lifetime membership in the Ğ1's Web of Trust: -> First of all we need to take into account that some members will pass -> and those accounts should no longer produce the Universal Dividend. -> Secondly it is of the utmost importance that 'rogue' accounts can be -> excluded from the web at some point. +- First of all, some members will pass and those accounts should no + longer produce the Universal Dividend. +- Secondly it is of the utmost importance that 'rogue' accounts can be + excluded from the web at some point. -To achieve this, certifications have a limited lifetime and members need -to seek renewal from their peers after `sigValidity` time. On the other +To achieve this, certifications have a limited lifespan. Members need to +seek renewal from their peers after `sigValidity` time. On the other hand, this time can't be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, -a certification with too short a lifetime would foster careless -certifying behaviours. The act of certifying must have a 'perceived' -cost high-enough to make it feel like an important act. Lastly, we also -wanted this lifetime to be easy enough to remember. Historically -speaking, we first settled on the values of `sigPeriod` and `sigStock`, -meant one could issue all of his/her certifications in 495 days, one -year was therefore not long enough. We deemed three years to bee much -and that's how we agreed on two years in the end. +a certification with too short a lifespan would foster careless +certifying behaviours. The act of certifying must have a high-enough +'perceived' cost to make it feel like an important act. Lastly, we also +wanted this lifespan to be easy to remember. Historically speaking, we +first settled on the values of `sigPeriod` and `sigStock`, meant one +could issue all of their certifications in 495 days, one year was +therefore not long enough. We deemed three years to be too much and +that's how we agreed on two years in the end. Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we -needed to address. We choose a value of one year for **msValidity**. The +needed to address. We chose a value of one year for **msValidity**. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to 'prune' the web of past or inactive members who don't renew their membership. -#### 4. Keeping the pools free of information glut -(`idtyWindow`, `sigWindow`, `msWindow`) {#4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow} +#### 3.8.4. Keeping the pools free of information glut (`idtyWindow`, `sigWindow`, `msWindow`) {#keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow} The pools need to be cleaned up on a regular basis to avoid them clogging up with information and to ensure that machines with less @@ -698,16 +741,15 @@ wanted a time period that would be easy enough to remember by all. We settled on two months, and gave this value to all three parameters `idtyWindow`, `sigWindow` and `msWindow`. -#### 5. Avoiding single members from 'knowing too many people' (`sigStock`) {#5-avoiding-single-members-from-knowing-too-many-people-sigstock} +#### 3.8.5. Avoiding single members from 'knowing too many people' (`sigStock`) {#avoiding-single-members-from-knowing-too-many-people-sigstock} -Many sociology studies have shown that we all know an average of fifty -people. This of course is an average, some of us know more than fifty -people, others much less. Once again we went for a number that would be -easy to remember. Although `sigStock`'s impact on the size of a Sybil -region is fairly limited, its value nonetheless has to be kept -reasonable. We settled on hundred. +We considered that on average, each person will certify 50 people. +However, we know for a fact that some members will use more than 50 certifications. +The maximum social network of one individual is around 150 people[^Dunbar]. +Being conservative, we settled on a maximum certification number `sigstock` of 100. +Since `sigStock`'s impact on the size of a Sybil region is fairly limited, we did not investigate further this parameter. -#### 6. Avoiding locking minorities (`xpercent`) {#6-avoiding-locking-minorities-xpercent} +#### 3.8.6. Avoiding locking minorities (`xpercent`) {#avoiding-locking-minorities-xpercent} It's easy enough to become a referent member, one of the Sybil strategies could therefore be to create a region of referent members. @@ -722,19 +764,20 @@ This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance -rule. The `xpercent` parameter was one of the hardest to define, we -therefore reserve ourselves the right of modifying its value during the -Ğ1 experiment. +rule. The `xpercent` parameter was one of the hardest to define, +therefore we might decide to change its value during the Ğ1 experiment. -We were inspired by the [Pareto -principle](https://en.wikipedia.org/wiki/Pareto_principle): if at least +We were inspired by the Pareto +principle[^Pareto]: if at least 20% of members give good density to the web, 80% of the referent members -will be five or less steps from any other member -referent or non-. The +will be five or less steps from any other member -referent or not-. The maximum value for `xpercent` is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%. -#### 7. Spam protection with (`msPeriod`) {#7-spam-protection-with-msperiod} +[^Pareto]: Pareto principle : [en.wikipedia.org/wiki/Pareto_principle](https://en.wikipedia.org/wiki/Pareto_principle) + +#### 3.8.7. Spam protection with (`msPeriod`) {#spam-protection-with-msperiod} This parameter stands out a bit on its own, as it was added after the genesis block. It is there to protect the Duniter P2P infrastructure @@ -744,13 +787,14 @@ every five minutes- or worse still, hundreds of these requests per minute to flood the Duniter nodes. Without such limits, nodes are supposed to address all renewal requests, even in cases where they were last published five minutes ago! The `msPeriod` parameter was given the -same value as `idtyWindow`, `sigWindow` and `msWindow`, i.e. two months. +same value as `idtyWindow`, `sigWindow` and `msWindow`, i.e. two months. + -## Proof of Work with personal difficulty +## 4. Proof of Work with personal difficulty {#proof-of-work-with-personalized-difficulty} As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human. -This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each "winning" member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. The knowledge of the whole network is not needed. +This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each "winning" member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. A view of the whole network is not needed. Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power. @@ -760,7 +804,7 @@ One could say that Duniter uses a PoW that needs very low energy consumption com <!-- source : https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ --> -### Why do we need Proof of Work ? +### 4.1. Why do we need Proof of Work ? {#why-proof-of-work} Duniter nodes share a database as part of a p2p environment. The proof of work (PoW) allows machines to synchronize with each other. In Duniter's case, the blockchain is @@ -773,9 +817,9 @@ as we want to create Universal Dividends on a regular basis, and keep track of membership status, both in human time. -Proof-of-work provides a clever solution to both problems: -1. Any -machine can write into the blockchain (create a new block) but is only +Proof-of-work provides a clever solution to both problems: + +1. Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, @@ -785,15 +829,15 @@ ensuring the unicity of a block's creator. takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and -Duniter adapts the challenge difficulty to get an *average* duration +Duniter adapts the challenge difficulty to get an average duration corresponding to this block time. -### Only members can "mine" +### 4.2. Only members can "mine" {#only-members-can-mine} One of Duniter's major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member's private key, allowing the algorithm to determine a -*personalised difficulty*. +personalised difficulty. This personalised difficulty eliminates the rat-race for the most sophisticated and powerful mining equipment. Another benefit is the fact @@ -804,21 +848,21 @@ This lightweight PoW is much less energy-consuming than other PoW cryptocurrenci Members can mine with anything from a raspberry pi to a privacy-first internet cube. -### How does it work? +### 4.3. How does it work ? {#how-does-duniter-pow-work} -#### The hash (aka digest) +#### 4.3.1. The hash (aka digest) {#the-hash} Example of a valid hash: -::: {.highlight} - 00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653 -::: +``` +00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653 +``` As you can see this hash starts with five zeros which was very hard to -achieve and took a lot of *work* for someone's computer. Hence the term +achieve and took a lot of work for someone's computer. Hence the term "proof of work". -#### The common difficulty +#### 4.3.2. The common difficulty {#common-difficulty} A common difficulty is needed to settle on a yardstick for our time reference. Its role is to make sure the blockchain moves forward @@ -830,32 +874,32 @@ Duniter `v1.5.x`) and then acts as a spring, regulating blocktime creation by increasing itself if the creation interval drops under `avgGenTime` and vice-versa. -##### How is difficulty applied? +##### 4.3.2.1. How is difficulty applied ? {#how-is-difficulty-applied} The numeric value of difficulty is taken from an array of possible -hashes out of all possible hashes. In duniter v1.5.x the hash +hashes out of all possible hashes. In DUBPv13 the hash of a block is its sha256 hexadecimal hash. To understand the difficulty, we make a euclidiean division of the difficulty by 16. -Here's an example with a difficulty value of `70` : 70 // 16 = **4** with a -remainder of **6**. The valid hashes are the ones starting with four +Here's an example with a difficulty value of 70 : + +``` +70 // 16 = 4 with a remainder of 6. +``` + +The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : `0000[0-9]`. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes. -> Fine, but the hash of a mined block will never change and there's no -> reason it should start with a given sequence of numbers. So how then -> can we make sure a block hash starts with exactly the sequence -> needed? +##### 4.3.2.2. The Nonce {#the-nonce} -Enter the nonce, short for "number once". When a member is forging a new +When a member is forging a new block, his computer freezes the block's content and changes the Nonce -until the hash reaches the required number of zeroes. - -##### The Nonce +until the hash reaches the required number of zeroes. The nonce allows us to mine a new block by finding a hash. The hash value allows us to determine the difficulty level of the @@ -875,7 +919,7 @@ built: - X is a number assigned to a specific peer. Let's assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with - different nodes. Each block will therefore have its own unique X to + different nodes. Each ~~block~~ **node ?** will therefore have its own unique X to prevent this from happening. - Y is the number of cores of the processor. The Nonce starting with @@ -889,11 +933,11 @@ For the sake of accuracy, we use the term CPU in the wider sense, it can be understood as a bi-CPU for example. We take into consideration the number of cores for the resulting PoW. -### Personalised difficulty +### 4.4. Personalised difficulty {#personalised-difficulty} Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other -*PoW-based* cryptocurrencies such as Bitcoin. +PoW-based cryptocurrencies. Here is how this personalised difficulty is calculated and assigned: @@ -904,11 +948,11 @@ Let `powMin` be the common difficulty, `exFact` a member's exclusion factor and `handicap` their handicap. This member's personalised difficulty `diff` is: -::: {.highlight} - diff = powMin*exFact + handicap -::: +``` +diff = powMin*exFact + handicap +``` -#### Understanding `exFact`, the exclusion factor +#### 4.4.1. Understanding `exFact`, the exclusion factor {#the-exclusion-factor} Members who have never produced blocks or haven't for quite some time are assigned an exclusion factor of `1`. Their personalised difficulty @@ -926,7 +970,7 @@ proportion is 1/3, meaning that if there are fifteen members currently forging, the member's exclusion factor will drop down to one after five blocks. -> What is intended by "the number of members forging"? +##### 4.4.1.1. What is intended by "the number of members forging" ? We mean the number of members trying to create the next block. In reality, there is no way to precisely know how @@ -935,12 +979,12 @@ to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block -in the last X blocks, minus the very last one. +in the last blocks in the current window, minus the very last one. -> Hox is X determined? +##### 4.4.1.2. Current window -We use the concept of **current window**. X's value is equal to the size of -this window. Let's see how it works: +We use the concept of **current window**. The current window is the number of blocks we look back at to determine how many members are forging. +Let's see how it works: * `issuersFrame` is the size of the current window in blocks. @@ -979,11 +1023,11 @@ and [BR\_G06](https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g06-headissuersframevar) of the DUP protocol. -> Let's go back to the personalised difficulty. +##### 4.4.1.3. exFact and the personalised difficulty {#exfact-and-the-personalised-difficulty} We explained that `exFact` spikes immediately after the member has found a block. It decreases then rapidly to `1` after a number of -blocks `X = 1/3 * issuersCount`. Let's see precisely +blocks equal to `1/3 * issuersCount`. Let's see precisely how we calculate `exFact`: * `nbPreviousIssuers` is the value of issuersCount at the @@ -994,27 +1038,36 @@ found by the rest of the network since block `N`. * `percentRot` is the number of *not excluded* peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency. -::: {.highlight} - exFact = MAX [ 1 ; FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) ] -::: +``` +a = FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) +exFact = MAX [ 1 ; a ] +``` The FLOOR is a simple truncate function. For `exFact` to exclude the member, we need : -> (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2 +``` +(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2 +``` We can see that the member is not excluded if `nbBlocksSince` is greater than 1/3 of -the calculating members. Take as an example nbPreviousIssuers = 6 and nbBlocksSince = 3: +the calculating members. Take as an example `nbPreviousIssuers = 6` and `nbBlocksSince = 3`: -> (0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1 +``` +(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1 +``` However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded: -> (0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2 +``` +(0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2 +``` Moreover if the last block was authored by the said member, then: -> `nbBlocksSince=0` and -> `exFact` = `0.67 * nbPreviousIssuers` +``` +nbBlocksSince=0 and +exFact = 0.67 * nbPreviousIssuers +``` ExFact value increases according to the number of members calculating. Thus, if there is enough members calculating, even @@ -1023,7 +1076,7 @@ succeeded in our intent to deter attempts to seize the blockchain and its currency. -However, at any time t, the two-thirds of +However, at any time `t`, the two-thirds of calculating members all have an exclusion factor of `1`, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then @@ -1032,11 +1085,11 @@ third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn't stand a chance... -#### The handicap +#### 4.4.2. The handicap {#the-handicap} The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. -A higher handicap is assined to members with higher calculating +A higher handicap is assigned to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW. @@ -1052,12 +1105,18 @@ single member within the current window. median number of blocks written by the calculating members during the same timeframe. -::: {.highlight} - handicap = FLOOR(LN(MAX(1;(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)) / LN(1.189)) -::: +``` +a = (nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame +handicap = FLOOR(LN(MAX( 1 ; a )) / LN(1.189)) +``` Let's unwrap the formula: -`(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)` is simply the + +``` +(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame) +``` + +is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored `9` blocks in the current window and the median is `5`, then the ratio @@ -1067,11 +1126,11 @@ the handicap has a value at least equal to `1`. The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers. -If we want the handicap to be applied as soon as the median is reached, -we'd have to divide it by `LN(1)`, the problem is that we've already set -a minimum value of `1` with the MAX function, so if we were to divide -the ratio by `LN(1)` all calculating peers would have a handicap \>= -`1`. In addition, is it really fair to handicap a member who's right on +If we wanted the handicap to be applied as soon as the median is reached, +we would divide it by `LN(1)`. The problem is that we have already set +a minimum value of `1` with the MAX function. If we were to divide +the ratio by `LN(1)` all calculating peers would have a handicap `\>= +1`. In addition, is it really fair to handicap a member who is right on the median? That's why we went for `1.189` rather than `1`. A member has to @@ -1081,43 +1140,39 @@ factor between two levels of the proof work (hexadecimal hash). To conclude, you have to remember that : -* the handicap is indexed on the logarithm of the ratio to the median, -* handicap is only applied on members whose ratio to the median is greater than the ratio between two +* The handicap is indexed on the logarithm of the ratio to the median, +* Handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work's difficulty. -## Conclusion + +## Conclusion {#conclusion} <!-- source : https://duniter.org/en/theoretical/ --> Duniter's Blockchain can be compared to Bitcoin's : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend. -More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers while maintaining a good security on the network. +More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers, maintaining a good security and helping decentralization of calculation. The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties : -* The freedom to choose your currency system: because money should not be imposed -* The freedom to access resources: because we all should have access to economic & monetary resources -* The freedom to estimate and produce value: because value is a purely relative to each individual -* The freedom to trade with the money: because we should not be limited by the avaible money supply +* The freedom to choose your currency system: because money should not be imposed. +* The freedom to access resources: because we all should have access to economic & monetary resources. +* The freedom to estimate and produce value: because value is a purely relative to each individual. +* The freedom to trade with the money: because we should not be limited by the avaible money supply. Those 4 economic freedoms should be understood together, not exclusively. Plus, "freedom" has to be understood as "non-nuisance". So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency. -## Duniter project's sources : - -* Theoretical, by Cgeek: https://duniter.org/en/theoretical/ -* Lock conditions, by Inso: https://duniter.org/en/transactions-0-2-overview/ -* Individualised Proof of Work, by Elois: https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ -* Deep dive into the Web of Trust, by Elois: https://duniter.org/en/deep-dive-into-the-web-of-trust/ -* Whitepaper sources: https://git.duniter.org/communication/duniter-whitepaper - -## Other sources : - -* Relative Theory of Money, S.Laborde, 2010: http://en.trm.creationmonetaire.info/ -* Bitcoin Whitepaper, S.Nakamoto, 2008: https://bitcoin.org/bitcoin.pdf -* Circles Whitepaper, A.Milenius, 2018: https://github.com/CirclesUBI/docs/blob/master/Circles.md -* The Sibyl Attack, J.R.Douceur: https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf - -<!-- travaux en theorie des graphes pourla TdC --> +## Sources : {#sources} + +* Relative Theory of Money, S.Laborde, 2010: [en.trm.creationmonetaire.info/](http://en.trm.creationmonetaire.info/) +* Bitcoin Whitepaper, S.Nakamoto, 2008: [bitcoin.org/bitcoin.pdf](https://bitcoin.org/bitcoin.pdf) +* The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : [lightning.network/lightning-network-paper.pdf](http://lightning.network/lightning-network-paper.pdf) +* The GNU Privacy Handbook, M.Ashley, 1999 : [www.gnupg.org/gph/en/manual.html#AEN335](https://www.gnupg.org/gph/en/manual.html#AEN335) +* High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. [cr.yp.to/papers.html#ed25519](https://cr.yp.to/papers.html#ed25519). +* PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : [archive.org/details/PPCoinPaper](https://archive.org/details/PPCoinPaper) +* Duniter Blockchain Protocol, v13, draft by Elois : [git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md](https://git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md) +* The Sibyl Attack, J.R.Douceur: [www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf](https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf) +* Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992 diff --git a/build/whitepaper_en.mobi b/build/whitepaper_en.mobi new file mode 100644 index 0000000000000000000000000000000000000000..9c136aa1c73dd60d6341483c1e50adf9bbe47eb5 Binary files /dev/null and b/build/whitepaper_en.mobi differ diff --git a/build/whitepaper_fr.epub b/build/whitepaper_fr.epub new file mode 100644 index 0000000000000000000000000000000000000000..757507f6e7510c050ec501d34e11d6be49e18404 Binary files /dev/null and b/build/whitepaper_fr.epub differ diff --git a/build/whitepaper_fr.fb2 b/build/whitepaper_fr.fb2 new file mode 100644 index 0000000000000000000000000000000000000000..5b804e8054a98731f9c7b0e4c339f5ee4efab7a1 --- /dev/null +++ b/build/whitepaper_fr.fb2 @@ -0,0 +1,742 @@ +<?xml version="1.0" encoding="UTF-8"?> +<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:xlink="http://www.w3.org/1999/xlink"> + <description> + <title-info> + <genre>antique</genre> + <author><first-name></first-name><last-name>Inconnu(e)</last-name></author> + <book-title>whitepaper fr</book-title> + + <lang>fr</lang> + + + + </title-info> + <document-info> + <author><first-name></first-name><last-name>Inconnu(e)</last-name></author> + <program-used>calibre 3.46.0</program-used> + <date>5.5.2020</date> + <id>e13c9ea4-7536-44c5-8117-25f915c2e2da</id> + <version>1.0</version> + </document-info> + <publish-info> + + + + </publish-info> + </description> +<body> +<section> +<empty-line /><p>Duniter: A libre currency blockchain generator.</p> + +<p>Abstract</p> + +<p>Many currency principles involve non-equal rights to monetary creation between humans. We propose a monetary creation based on the Relative Theory of Money, which guarantee equal monetary creation for each willing human. This type of currency can be centralised, however, this could lead to censorship and arbitrary choices of the central institution. Thus, strongly inspired by Bitcoin example, we want the currency to be as decentralised as possible, in the transaction network as in the human identification process. We use a Web of Trust between living humans for identification. This web of trust allows us to impose personalised difficulty for transaction validation, keeping the calculation accessible to low-end hardware and allowing all competent members to secure the currency.</p> + +<p>Introduction</p> + +<p>Duniter is a software to create and manage “libre currencies”. Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question :</p> + +<p>How should a currency be created to match the principle of equality between all humans, now and between generations ?</p> + +<p>The results of this demonstration implies a monetary creation :</p> + +<p>on a regular basis</p> + +<p>for each human being</p> + +<p>which amount has to be reassessed on fixed intervals according to a fixed formula.</p> + +<p>Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula :</p> + +<p>$$ UD(t+1) = UD(t) + c²*( {M(t) \over N(t) }) $$</p> + +<p>Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin.</p> + +<p>The first currency created through Duniter is Ğ1, pronounced “June”. It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software.</p> + +<p>1. State of the art : Bitcoin case</p> + +<p>Duniter uses the crypto-currency concept introduced by Bitcoin<sup>1</sup>, which is to use cryptographic tools such as signatures to create trustless digital currencies. Duniter fits this definition, but it has two completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects.</p> + +<p>1.1. Monetary creation of Bitcoin : a space-time asymmetry</p> + +<p>Space-time asymmetry refers to the relative access of individuals to newly created money<sup>2</sup>. Concretely, most existing currencies (c. 2020) are both spatially and temporally asymmetrical for their users. Let's take Bitcoin as an example to understand why.</p> + +<p>1.1.1. Spatial asymmetry</p> + +<p>When new Bitcoins are created, only some Bitcoin users (the miners) are given new Bitcoins, while everyone else get nothing. We believe this is the first injustice. However, some might say:</p> + +<p>"Miners used their electricity and time to get it!"</p> + +<p>... we would answer that this work should not have been rewarded by newly created Bitcoins. New units should be distributed to the whole community. Miners should be rewared another way, but not by money issuance. Of course, Bitcoin cannot create money through Basic Income since Bitcoin users are not strongly identified, and one might benefit from money creation multiple times if they owned several wallets. Duniter gets rid of this problem by identifying its users and creating the same amount of Basic Income to everyone.</p> + +<p>1.1.2. Temporal-asymmetry</p> + +<p>Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, how will future joiners get Bitcoins? Just like most of us do for Euros or Dollars: to get money, they will have to work for the ones who already own it.</p> + +<p>We believe this is the second injustice. Every member of a monetary community should be equal concerning monetary creation, and get the same relative amount of money over time, even if they are a late adopter. Duniter aims to fix this by making the Universal Dividend (a.k.a. UD) grow by the time according to precise rules, thus making members equal toward money issuance on a half-lifespan.</p> + +<p>Most currencies present one of these two asymmetries, including metal currencies and mutual credit, as exposed in the RTM.</p> + +<p>1.1.3. A solution</p> + +<p>Bitcoin has taught us that it is possible to create a currency system allowing one to both create digital money and to exchange it without a central authority. What we need to change is the way money is issued so we finally have a symmetrical system. We need Bitcoin + Universal Dividend. But Universal Dividend implies that the community consists of only identified people. This is where the Web of Trust (WoT) comes into place.</p> + +<p>This concept, introduced by cryptography with the OpenPGP format<sup>3</sup>, allows us to identify people in a decentralized manner. It works as follows: each person creates a personal identity that is linked to its cyptographic certificate. The identity must be confirmed by others members who use their own cryptographic key. It is that simple: people choose who is part of the community and who is not, not a central authority.</p> + +<p>However, Duniter will not use OpenPGP for its cryptographic features: Elliptic Curves<sup>4</sup> will be used instead for the conciseness of its generated keys and its pratical advantages. Duniter has its own Web of Trust principles, that will be exposed later.</p> + +<p>1.2. Proof-of-Work mining : a power race</p> + +<p>In Bitcoin Model, the calculation and incentive principles cause a power race : new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. This leads to a power race an places the control over the currency in the hands of the richest hardware owners. We want to make Duniter blockchain validation much less energy and hardware consuming while keeping a strong level of security. This will be further explained later. A consequence of this choice is the participation of low-end hardware in the Duniter network, leading to a better decentralization of blockchain validation.</p> + +<p>1.2.1 What about Proof of Stake ?</p> + +<p>Proof of stake consensus algorythm was first introduced in 2012<sup>5</sup>. The basic principle is to allow the richest wallets to issue blocks, putting their coin balance as a “stake” they would lose in case of cheat.</p> + +<p>At the time of conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. We did not chose this consensus principle. Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead to placing power over the currency in the richests hands : this is contrary to the symmetical principles of a libre currency.</p> + +<p>2. Duniters Blockchain</p> + +<p>Duniters Blockchain follows the basic principles of Bitcoins. This is essential for synchronization between peers, as to prevent double-spend attacks. However, Duniters Blockchain will store different informations than Bitcoins.</p> + +<p>The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no generation transaction exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either:</p> + +<p>a former transaction (as in Bitcoin)</p> + +<p>a Universal Dividend (specific to Duniter).</p> + +<p>Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactions are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where “space” are members of the WoT and “time” the basic blockchain units : the blocks. On each point of time, one can determine which account is legitimate to create the UD, only with a blockchain analysis.</p> + +<p>2.1. Spam countermeasures</p> + +<p>An issue of most cryptocurrency projects is to prevent the common ledger from growing too much. This would require nodes to have a lot of storage and computing power to be usable. In particular, we don’t want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don’t want to introduce this mean since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented.</p> + +<p>2.1.1. Minimum output amount</p> + +<p>Fixing a minimal output amount reduces the power of an attack. Duniter deals with cents of Ğ1 or 1/1000 of the first UD. An attacker could create thousand accounts with only 1 UD. To prevent this, a valid transaction must have output amounts of minimum 1Ğ1. This reduces the power an attack by 100.</p> + +<p>2.1.2. Limited block size and chainability</p> + +<p>The block size is always limited. While the protocol allows this limit to evolve to address scaling issues, an attacker cannot register as many transaction as they wish.</p> + +<p>With the same goal to prevent too many transactions to get registered, while transactions can be “chained” (refer to another transaction in the same block), the chainability of transactions is limited to 5.</p> + +<p>2.2. Scaling</p> + +<p>Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons :</p> + +<p>Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don’t want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT should limit its size to around 16 million members.</p> + +<p>Duniter’s aim is to be used to create multiple libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community.</p> + +<p>However, Duniter has assets that will help if the number of users and transactions grow.</p> + +<p>2.2.1 Dynamic block size</p> + +<p>While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks(see “personalised difficulty” part for more information). This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. The block size (in bytes) is limited as so :</p> + +<p>block_size < max(500 ; CEIL(1.10 * (average block size))</p> + +<p>2.2.2. Lightning Networks</p> + +<p>The Lightning Networks<sup>6</sup> allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed.</p> + +<p>2.2.3. Unit base</p> + +<p>As the Universal Dividend grows exponentially, with time Duniter nodes would have had to deal with always largest amounts, eventually reaching the BIGINT limit. To avoid this, the amounts are expressed with a unit base in base 10. We want the UD amount to always fit in 4 digits. To manage it, the unitbase is updated each time the UD value reaches 100.00 : it goes from 99.99*10^(unitbase) to 10.00*10^(unitbase+1). All the unit amounts are thus divided by 10. While this might seem strange, this process has already hapened in state currencies. Moreover, the amounts expressed in UD will not change.</p> + +<p>With a monetary growth of 10% each year and a stable population, such a change of unit base would happen each 25 years.</p> + +<p>3. Duniter Web of Trust</p> + +<p>3.1. Basic Principles</p> + +<p>In order to identify “members” accounts - which create monetary units - and other accounts, Duniter uses a Web of Trust. This can be summarized into few principles:</p> + +<p>Each account becomes a member if it received a minimal number of certifications - 5 for Ğ1 currency.</p> + +<p>Only members accounts can send certifications. Certifications have a limited lifespan.</p> + +<p>A certification indicates that the sender accepts the receiver as a legitimate identity.</p> + +<p>The aim of the WoT is to identify a blockchain account to a living human. According to Lauterbach et.al<sup>7</sup>, the strengh of a relationship should be considered when building a vouch system. For this reason, the Ğ1 Web of Trust rules are expressed in a licence stating what WoT certifications are. A certification represents a strong human relationship : one may certify a close relative, not an acquaintance. Each member has to accept this licence before being included in the WoT. Thus, if a member is part of an attack on the currency, they can be found by mutual relatives. Additional security rules occur to prevent cheat and attacks on a large scale.</p> + +<p>Note that non-members accounts can use the currency, but cannot create money. Non-members accounts can be used by individuals as secondary wallets, or by institutions.</p> + +<p>We were inspired by the OpenPGP Trust system<sup>8</sup>. However, the OpenPGP trust principles aim at defining trust from a particular point of view while Duniter needs to identify humans for the whole community. To achieve this goal, while OpenPGP allows each user to tweak its trust parameters individually, Duniter sets rules in the “genesis” block for the whole community.</p> + +<p>3.2. Why do we need a Web of Trust ?</p> + +<p>There are two reasons we need it :</p> + +<p>To make sure that only one Universal Dividend is produced per member at each specified creation interval. In the Ğ1’s case this interval is set as daily 86 400 seconds, it is the <emphasis>monetary parameter</emphasis> known as dt.</p> + +<p>To identify the nodes hashing the blocks and assign each a personalised difficulty. This custom difficulty proof of work is there to avoid the blockchain’s validation mechanism becoming too centralised as is the case with many 'non-libre’ cryptocurrencies.</p><empty-line /><p>Monetary parameter : Each currency that use Duniter has its own blockchain whose behaviour is dictated by a set of ‘parameters’ defined in block zero - the so-called genesis block - that can be tweaked to achieve the desired results. At the time of writing the Whitepaper, the Duniter Blockchain Protocol (DUBP) has a total of 21 parameters of which 10 are for the WoT alone. We’ll focus on these 10.</p> + +<p>Suffice to say that in the Ğ1’s case, the DU is created every 24 hours - 86 400 seconds. This interval is set through the time derivative dt parameter and can have a different value in other implementations of the protocol.</p> + +<p>We want to make sure that each member can only have one account. As we all know, achieving zero-risk isn’t possible<sup>9</sup>. Our goal is therefore not to create a WoT within which fraud would be absolutely impossible, but instead to discourage it. Here is a rewording of our goal in 4 smaller ones :</p> + +<p>Make the certification process lengthy enough that all members exercise due diligence and are wary of risks.</p> + +<p>Make fraudulent acts as hard as we can to the extent that they become pointless.</p> + +<p>Ensure that any Sybil attacks have a negligible impact on the currency by ensuring that illegitimate double Universal Dividends have no significant bearing on the legitimate monetary mass</p> + +<p>Slow the growth of ‘Sybil regions’ to give enough time for the community to react and isolate the threat.</p><empty-line /><p>Sybil attack : A Sybil attack is an attack perpetrated on a reputation system through the creation of fake identities. A Web of Trust is a specific instance of a Reputation System.</p> + +<p>There are plenty of Sybil attack scenarios we can think of and just as many reasons why their perpetrators would want to carry them out. Our objective is that the configuration of the WoT protects both users and its IT backbone infrastructure against these attacks.</p> + +<p>This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web’s role isn’t to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing your tap water and electricity but isn’t responsible for any burglaries, etc. Much in the same way, Duniter’s WoT guarantees us all a functional currency, but do not detect small fraud.</p> + +<p>3.3. The importance of having our own certification system</p> + +<p>Centralized identification systems can achieve the goal we want. State Identification is an example. However, this has many drawbacks :</p> + +<p>The authority may have arbitrary criteria for identification, for example preventing people without an official state-provided identity or homeless people to be included in the WoT.</p> + +<p>Payment might be required to get identified, thus making the monetary creation not “free”.</p> + +<p>The authority is a point of failure for any attacker.</p> + +<p>It is of the utmost importance that we remain free from any state or corporation. The WoT is an answer to this criterium. To this day we depend only on the Internet and yet, were it to fail, there are already alternatives being tested around the world for a decentralised communication network.</p> + +<p>3.4. A few foundational concepts on graph theory : a bit of vocabulary</p><empty-line /><p>Graph: set of points -called ‘vertices’- joined by edges -called paths/walks-.</p> + +<p>Simple graph: a graph with no loops and with no multiple edges. That is, each edge connects two distinct endpoints and no two edges have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise.</p> + +<p>Directed graph: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. Arrow A –> B is therefore different from arrow B –> A.</p> + +<p>Endpoints: the edge with vertex A –> B has A and B as endpoints, respectively as start and end of the path/walk.</p> + +<p>Isolated vertex: a vertex whose degree is zero, that is, a vertex with no incident edges.</p> + +<p>Degree of a vertex: number of its incident edges -in and out-.</p> + +<p>Out-degree of vertex A: number of outbound edges / tail ends from A.</p> + +<p>In-degree of vertex A: number of incoming edges / head ends to A.</p><empty-line /><p><emphasis>degrees of a vertex diagram</emphasis></p><empty-line /><p>Path: -aka “walk”- path to follow to get from vertex A to vertex B.</p> + +<p>3.5. Definition of the Duniter Web of Trust</p> + +<p>The Duniter WoTs -one per currency- are simple directed graphs without isolated vertices. The vertices are the members and the edges are the certifications given and received.</p> + +<p><emphasis>Directed</emphasis> means that the responsibility of issuing a certification is unique and personal to the certifier. The trust they place in the receiver cannot be imposed in the other direction although in most circumstances both parties equally trust each other.</p> + +<p>In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific ‘deactivated state’ and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered ‘pending’ to avoid a collapse of the WoT. If these old members don’t come back into the WoT, their pending certifications will eventually expire and they will switch from ‘deactivated’ to ‘isolated’ vertices.</p> + +<p>To wrap up with old members, after a certain period of time - set in the currency’s parameters - their deactivated vertex is removed from the web and the associated identity is ‘revoked’. The person who owned the account can no longer use this identity but is free to join the web with another one.</p> + +<p>Identity : An identity is a set of three pieces of information: a public key, a name and a blockstamp. A blockstamp points to a specific block in the chain. Its main use is to freeze the point in time at which an identity was created and to link this identity to a specific chain and a currency - each currency having its own blockchain.</p> + +<p>An identity can be in any one of 5 different status: pending, member, old member, revoked or excluded.</p> + +<p>Let’s take a simple example:</p> + +<p> A -> B -> C + | + \--> D</p> + +<p>If, for whatever reason, A were to lose its member status, the web would crumble and all other members would be excluded as a consequence. To avoid this, the certification from A –> B will remain valid until its expiry date, leaving enough time for B to receive certifications from C or D.</p> + +<p>Because our WoT doesn’t have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications it has received, all in the same block. This calls for a temporary ‘buffer’ storage space for pending identities and the certifications they have received. This storage space is called ‘the pool’ of Duniter nodes, which we could also have called the ‘sandbox’ as that’s the name used in Duniter’s code. Duniter nodes inclued other ‘pools’ for other documents and metadata not mentioned here.</p> + +<p>3.6. Exploring the rules behind a Duniter Web of Trust</p> + +<p>The Duniter WoTs - one per currency - works with a set of eight fundamental rules enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - msPeriod- having being hard-coded in the Ğ1’s code subsequently.</p> + +<p>3.6.1. Distance rule and referent members (</p> + +<p>stepMax</p> + +<p> and</p> + +<p>xPercent</p> + +<p>)</p> + +<p>These two parameters are closely linked and together define the ‘distance rule’. The ‘distance rule’ can only be described after defining what a ‘referent member’ is:</p> + +<p>Referent member: member A is said to be ‘referent’ if and only if the total of their degrees are greater than or equal to CEIL-N^-1/stepMax where N is the total number of members. As the size of the web will grow this number will grow too, meaning it will take more certification issuances to become a referent member. The number of certifications needed to become a member shouldn’t change.</p> + +<p>Let’s now define the distance rule:</p> + +<p>Distance rule: member A is said to observe this rule if and only if for a subset xPercent % of referent members R there exists a path of length less than or equal to stepMax between R and A.</p> + +<p>Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect web, that is one in which each member has certified all members they legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time t who haven’t yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would effectively stop growing.</p> + +<p>Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets confirmed into the web or an existing member gets renewed. There is an exception to this rule: the distance rule is not observed in the genesis block -when the web is first implemented.</p> + +<p>3.6.2. Rule of the minimum number of certifications needed (</p> + +<p>sigQty</p> + +<p>)</p> + +<p>This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least sigQty active certifications. If, for whatever reason, member A were to have less than sigQty active certifications in a given block, they would cease to be a member and be required to publish a request for identity renewal.</p> + +<p>3.6.3. The membership renewal rule (</p> + +<p>msValidity</p> + +<p>,</p> + +<p>msPeriod</p> + +<p> and</p> + +<p>msWindow</p> + +<p>)</p> + +<p>Bear in mind that a membership doesn’t last a lifetime but instead has a lifespan set to msValidity seconds.</p> + +<p>Every single member -or old member who hasn’t revoked his identity or been excluded- can request a membership renewal so long as the last request was made more than msPeriod seconds ago. If a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the ‘pool’ for a maximum of msWindow seconds before it’s included in the blockchain. Once again, this can only happen once/if the member meets both the siqQty rule and the distance rule -if these criterion are already matched it’s just a case of waiting for a new block to be mined-.</p> + +<p>If a member hasn’t requested a renewal for longer than msValidity seconds, they automatically cease to be a member. From this moment on, the ex-member has another msValidity window to renew their membership. When this period of 2 × msValidity runs out, the membership will expire and this identity will never be available for use again in the web. If the person so desires, they will have to publish new identity and membership documents and find enough certifiers, as any newcomer.</p> + +<p>3.6.4. Rule of certification lifespan (</p> + +<p>sigValidity</p> + +<p>)</p> + +<p>All certifications included in the blockchain expire sigValidity seconds after they were issued.</p> + +<p>/!\ The issuance and the inclusion of a certification in the blockchain occur at different times. When member A issues a certification at time t1, it gets stored in the pool starting at t1 and only finds its way into the blockchain at t2 when all of the web’s rules are observed. Several weeks can thus go by between t1 and t2!!!</p> + +<p>3.6.5. Rule of limited supply of active certifications (</p> + +<p>sigStock</p> + +<p>)</p> + +<p>By ‘active certifications’ we refer to certifications included in the blockchain and that haven’t yet expired.</p> + +<p>The total of active certifications issued by any member at any single time must be less than or equal to sigStock. When this threshold is reached the member will have to wait for one of his active certifications to expire before he/she can issue a new one.</p> + +<p>3.6.6. Rule of the time period between two certification issuances. (</p> + +<p>sigPeriod</p> + +<p>)</p> + +<p>As soon as a certification issued by member A gets included in the blockchain, they will be unable to issue a new one before another sigPeriod seconds.</p> + +<p>3.6.7. Expiry of a certification issuance (</p> + +<p>sigWindow</p> + +<p>)</p> + +<p>When a certification is issued by member A, it will be stored in the ‘pool’ for a maximum of sigWindow seconds. If the certification hasn’t been included in the blockchain by then, it will be cancelled and the member’s sigStock will be repleted by one.</p> + +<p>3.6.8. Lifespan of a ‘pending’ identity (</p> + +<p>idtyWindow</p> + +<p>)</p> + +<p>When a new identity is created, it is stored in the ‘pool’ for a maximum of idtyWindow seconds. If the person hasn’t achieved member status by then, the certification will simply be cancelled.</p> + +<p>3.7. Details on some of the WoT’s peculiarities at the genesis block</p> + +<p>The aforementioned rules can only be enforced with an existing web. They cannot be observed when first creating the web, that is when defining the genesis block.</p> + +<p>Only rules 2 and 5 can be observed at the genesis block.</p> + +<p>The genesis block has to be manually created by the founding members. In practice this means that there must be a choice on which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities.</p> + +<p>As soon as the genesis block has been created, the other identities can start mining the blockchain and the member who created block #0 effectively looses the decision power he had at creation.</p> + +<p>3.8. Why these rules and application cases in the Ğ1</p> + +<p>3.8.1. Distance and maximum size</p> + +<p>The distance rule is there to curb the maximum size of a Sybil region as well as that of the monetary community as a whole. The xpercent parameter prevents the creation of a ‘faction’ that could take hold of the blockchain.</p><empty-line /><p><emphasis>Sybil region</emphasis></p> + +<p>The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned Sybil members. As a consequence, the shortest edge/path between a legitimate member and a Sybil one has to have the attack’s author as an endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as stepAttackers. The maximum size of a Sybil region created by sigQty members depends on the L parameter, defined as L = sigQty/sigStock:</p> + +<p>MaxSybilSize= (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L)</p> + +<p>The maximum size of the Web of Trust is given by the following formula:</p> + +<p>WoTmax = (sigStock)*L^(stepMax-1)</p> + +<p>However we know for a fact that members will never use all of their available certifications. According to Dunbar<sup>10</sup>, on average, one is able to maintain relationships to around 150 people. Being conservative, we will consider that on average, each person will certify 50 accounts. We can calculate the size of the average web of trust WoTavg :</p> + +<p>WoTavg= (50)*(sigQty/50)^(stepMax-1)</p> + +<p>Our goal with the Ğ1 is to create a community of about one million members to test the consequences of a libre monetary system. Let’s see how we can tweak the pair of sigQty and stepMax- to reach this size:</p><empty-line /><p><emphasis>Average WoT size graph as a function of sigQty and stepMax</emphasis></p> + +<p>The maximum size of a Sybil region grows linearly with sigQty but exponentially with stepMax. Logic has it that we need to keep stepMax as low as possible to ensure sufficient strength to the web. The above graph shows that the lowest value of stepMax for a web of a million members is of 5. This is an order of magnitude and is likely to be much higher in reality, we cannot measure it for sure.</p> + +<p>For sigQty we can choose a value of 4 for a web of 1.5 million members or 5 for half a million members. Bear in mind these are gross figures and could be significantly higher, we are talking anywhere between 1 and 10 million in reality. Calculating WOTavg gives us a pretty good idea of how the web would scale bearing in mind that it considers all members are referent members too -which isn’t the case as explained previously-. Hence the maximum size of the web is likely larger, a ballpark figure of half a million is enough for now especially knowing that the smaller sigQty is, the easier it is to launch a Sybil attack -it’s easier to find four accomplices than five-. For security reasons we have settled on five:</p> + +<p>stepMax = 5 +sigQty = 5 +sigStock \>= 50</p> + +<p>The maximum size of a Sybil region therefore is:</p> + +<p>(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))</p> + +<p>with sigStock = 50 we have a Sybil region of:</p> + +<p>45*(1-10^(5-stepAttackers))/(-9)</p> + +<p>A good practice for protecting the web is to maximise stepAttackers. That’s why we decided that referent members in the genesis block had to be at least four steps away from each other.</p> + +<p>Another way to keep a Sybil attack at bay, were it slow enough for members to notice it, would be for referent members to ‘stretch’ the web intentionally to limit the growth of the region by ensuring that the attackers’ legitimate certifications received in the first place aren’t renewed. But what if bot accounts were created and certified each other super fast and following all rules, how would we counter that? By introducing a minimum length of time between two certifications!</p> + +<p>3.8.2. Time is our friend</p> + +<p>To help us deter a Sybil attack, we’ve decided to impose a minimum period of time between any two certifications issued from a single account. This parameter called sigPeriod affords us a greater chance to detect the formation of a ‘hostile’ faction.</p> + +<p>Here is a graph showing the evolution of a Sybil region with the variation of sigPeriod. The simulation considers that honest members and attackers both issue a certification each sigPeriod interval, in days:</p><empty-line /><p><emphasis>size of the WoT according to sigPeriod and stepAttackers</emphasis></p> + +<p>As we see, there is a strong link between the growth speed of the region and sigPeriod. As evidenced here, we need a sigPeriod high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher sigPeriod is, the more members will exercise their certification power gingerly, the action coming at a higher ‘cost’.</p> + +<p>There are numerous advantages to giving sigPeriod a high value and no technical barriers to it, hence our choice of five days.</p> + +<p>We could have also gone for one week for the sake of simplicity. However there is an underlying idea behind our choice which was quite simply the pace of today’s life. Certifying someone can be a lengthy process as one needs to make sure they are correctly applying the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea to allow one to certify at the end of every working week -five days- instead of a whole calendar one.</p> + +<p>3.8.3. Trust me now, trust me forever ? (</p> + +<p>sigValidity</p> + +<p>,</p> + +<p>msValidity</p> + +<p>)</p> + +<p>There would be two main drawbacks to a lifetime membership in the Ğ1’s Web of Trust:</p> + +<p>First of all, some members will pass and those accounts should no longer produce the Universal Dividend.</p> + +<p>Secondly it is of the utmost importance that ‘rogue’ accounts can be excluded from the web at some point.</p> + +<p>To achieve this, certifications have a limited lifespan. Members need to seek renewal from their peers after sigValidity time. On the other hand, this time can’t be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, a certification with too short a lifespan would foster careless certifying behaviours. The act of certifying must have a high-enough ‘perceived’ cost to make it feel like an important act. Lastly, we also wanted this lifespan to be easy to remember. Historically speaking, we first settled on the values of sigPeriod and sigStock, meant one could issue all of their certifications in 495 days, one year was therefore not long enough. We deemed three years to be too much and that’s how we agreed on two years in the end.</p> + +<p>Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we needed to address. We chose a value of one year for msValidity. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to ‘prune’ the web of past or inactive members who don’t renew their membership.</p> + +<p>3.8.4. Keeping the pools free of information glut (</p> + +<p>idtyWindow</p> + +<p>,</p> + +<p>sigWindow</p> + +<p>,</p> + +<p>msWindow</p> + +<p>)</p> + +<p>The pools need to be cleaned up on a regular basis to avoid them clogging up with information and to ensure that machines with less calculating power can still run a Duniter node.</p> + +<p>To achieve this, identities with pending membership approval and the corresponding certifications have to remain the shortest time possible in the pool while still having a chance of making it into the blockchain.</p> + +<p>For the Ğ1, our opinion was that two months would be enough for all potential certifiers to agree on a specific identity to certify. We also wanted a time period that would be easy enough to remember by all. We settled on two months, and gave this value to all three parameters idtyWindow, sigWindow and msWindow.</p> + +<p>3.8.5. Avoiding single members from ‘knowing too many people’ (</p> + +<p>sigStock</p> + +<p>)</p> + +<p>We considered that on average, each person will certify 50 people. However, we know for a fact that some members will use more than 50 certifications. The maximum social network of one individual is around 150 people<sup>11</sup>. Being conservative, we settled on a maximum certification number sigstock of 100. Since sigStock’s impact on the size of a Sybil region is fairly limited, we did not investigate further this parameter.</p> + +<p>3.8.6. Avoiding locking minorities (</p> + +<p>xpercent</p> + +<p>)</p> + +<p>It’s easy enough to become a referent member, one of the Sybil strategies could therefore be to create a region of referent members. Such a region would grow slower than otherwise but could confer a locking power to its members by using the distance rule. That’s why the distance rule cannot be calculated on 100% of the referent members. Hence the introduction of the xpercent parameter which defines the percentage of referent members needing to be less than five edges -steps- from each other.</p> + +<p>This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance rule. The xpercent parameter was one of the hardest to define, therefore we might decide to change its value during the Ğ1 experiment.</p> + +<p>We were inspired by the Pareto principle<sup>12</sup>: if at least 20% of members give good density to the web, 80% of the referent members will be five or less steps from any other member -referent or not-. The maximum value for xpercent is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%.</p> + +<p>3.8.7. Spam protection with (</p> + +<p>msPeriod</p> + +<p>)</p> + +<p>This parameter stands out a bit on its own, as it was added after the genesis block. It is there to protect the Duniter P2P infrastructure against ‘spam’ attacks. We had to think of a strategy against attacks such as high-frequency membership renewal requests -i.e: in every block, every five minutes- or worse still, hundreds of these requests per minute to flood the Duniter nodes. Without such limits, nodes are supposed to address all renewal requests, even in cases where they were last published five minutes ago! The msPeriod parameter was given the same value as idtyWindow, sigWindow and msWindow, i.e. two months.</p> + +<p>4. Proof of Work with personal difficulty</p> + +<p>As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human.</p> + +<p>This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each “winning” member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. A view of the whole network is not needed.</p> + +<p>Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power.</p> + +<p>One could say that Duniter uses a PoW that needs very low energy consumption compared to BitCoin : an “ecological” PoW ?</p> + +<p>4.1. Why do we need Proof of Work ?</p> + +<p>Duniter nodes share a database as part of a p2p environment. The proof of work (PoW) allows machines to synchronize with each other. In Duniter’s case, the blockchain is our database, and acts as a ledger keeping a trace of all transactions, status of the WoT and more. How can we let several machines add data (ie: a transaction) at the same time? In addition, how do we settle on how much time has gone by since the blockchain was last updated? Agreement on time is of the utmost importance as we want to create Universal Dividends on a regular basis, and keep track of membership status, both in human time.</p> + +<p>Proof-of-work provides a clever solution to both problems:</p><empty-line /><p>Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, ensuring the unicity of a block’s creator.</p> + +<p>Solving this challenge takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and Duniter adapts the challenge difficulty to get an average duration corresponding to this block time.</p> + +<p>4.2. Only members can “mine”</p> + +<p>One of Duniter’s major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member’s private key, allowing the algorithm to determine a personalised difficulty.</p> + +<p>This personalised difficulty eliminates the rat-race for the most sophisticated and powerful mining equipment. Another benefit is the fact that no “supercomputer” can take control of the blockchain. Lastly, Duniter implements a rotation in forging members thanks to this personalized difficulty.</p> + +<p>This lightweight PoW is much less energy-consuming than other PoW cryptocurrencies. Members can mine with anything from a raspberry pi to a privacy-first internet cube.</p> + +<p>4.3. How does it work ?</p> + +<p>4.3.1. The hash (aka digest)</p> + +<p>Example of a valid hash:</p> + +<p>00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653</p> + +<p>As you can see this hash starts with five zeros which was very hard to achieve and took a lot of work for someone’s computer. Hence the term “proof of work”.</p> + +<p>4.3.2. The common difficulty</p> + +<p>A common difficulty is needed to settle on a yardstick for our time reference. Its role is to make sure the blockchain moves forward at a steady pace - one block every avgGenTime seconds, avgGenTime being one of the 20 parameters behind the Duniter protocol-.</p> + +<p>This difficulty’s initial value can be set to any arbitrary value (70 in Duniter v1.5.x) and then acts as a spring, regulating blocktime creation by increasing itself if the creation interval drops under avgGenTime and vice-versa.</p> + +<p>4.3.2.1. How is difficulty applied ?</p> + +<p>The numeric value of difficulty is taken from an array of possible hashes out of all possible hashes. In DUBPv13 the hash of a block is its sha256 hexadecimal hash.</p> + +<p>To understand the difficulty, we make a euclidiean division of the difficulty by 16.</p> + +<p>Here’s an example with a difficulty value of 70 :</p> + +<p>70 // 16 = 4 with a remainder of 6.</p> + +<p>The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : 0000[0-9]. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes.</p> + +<p>4.3.2.2. The Nonce</p> + +<p>When a member is forging a new block, his computer freezes the block’s content and changes the Nonce until the hash reaches the required number of zeroes.</p> + +<p>The nonce allows us to mine a new block by finding a hash. The hash value allows us to determine the difficulty level of the proof-of-work performed. Examples of possible Nonce values:</p> + +<p>10100000112275</p> + +<p>10300000288743</p> + +<p>10400000008538</p> + +<p>10700000079653</p> + +<p>10300000070919</p> + +<p>In reality the Nonce value follows a pre-determined format akin to XYY00000000000. The Nonce’s value isn’t the number of attempts but rather a value within a set of possible ones. This is how the Nonce is built:</p><empty-line /><p>X is a number assigned to a specific peer. Let’s assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with different nodes. Each <strikethrough>block</strikethrough> node ? will therefore have its own unique X to prevent this from happening.</p> + +<p>Y is the number of cores of the processor. The Nonce starting with 107[…] belongs to a seven cores processor, while 199[...] could be the proof generated by a 99 cores processor.</p> + +<p>The rest of the Nonce, the part that follows after the XYY, is the numerical space for this individual node and is unique to each of the CPU’s core. This space is comprised of eleven digits (00000000000). For the sake of accuracy, we use the term CPU in the wider sense, it can be understood as a bi-CPU for example. We take into consideration the number of cores for the resulting PoW.</p> + +<p>4.4. Personalised difficulty</p> + +<p>Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other PoW-based cryptocurrencies.</p> + +<p>Here is how this personalised difficulty is calculated and assigned:</p> + +<p>It is determined by a combination of two different constraints with complimentary roles: the exclusion factor and the handicap.</p> + +<p>Let powMin be the common difficulty, exFact a member’s exclusion factor and handicap their handicap. This member’s personalised difficulty diff is:</p> + +<p>diff = powMin*exFact + handicap</p> + +<p>4.4.1. Understanding</p> + +<p>exFact</p> + +<p>, the exclusion factor</p> + +<p>Members who have never produced blocks or haven’t for quite some time are assigned an exclusion factor of 1. Their personalised difficulty is therefore simply the sum of powMin + handicap.</p> + +<p>Before reading on, let’s precise the role of this exclusion factor. When a member adds a block to the chain, his exFact jumps up from one to a very high value, to prevent them from forging other blocks immediately after and taking control of the blockchain.</p> + +<p>The exclusion factor will then rapidly return to one. This delay is expressed as a number of blocks. It is calculated as a proportion of the number of members forging. In the Ğ1’s case, this proportion is 1/3, meaning that if there are fifteen members currently forging, the member’s exclusion factor will drop down to one after five blocks.</p> + +<p>4.4.1.1. What is intended by “the number of members forging” ?</p> + +<p>We mean the number of members trying to create the next block. In reality, there is no way to precisely know how many members are calculating at any given time, because it is impossible to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block in the last blocks in the current window, minus the very last one.</p> + +<p>4.4.1.2. Current window</p> + +<p>We use the concept of current window. The current window is the number of blocks we look back at to determine how many members are forging. Let’s see how it works:</p><empty-line /><p>issuersFrame is the size of the current window in blocks.</p> + +<p>issuersCount the number of members who have calculated at least one block during the current window.</p> + +<p>Both issuersFrame and issuersCount are block fields. When first starting a blockchain, the very first block has an issuersFrame=1 and an issuersCount=0. The genesis block is excluded as there are no members in the current window!</p> + +<p>From the second block onwards (block #1) we track the variation of issuersCount. The member having mined block #0 enters the current window and in block #1 we will therefore mention issuersCount=1.</p> + +<p>issuersFrame then varies as follows:</p> + +<p>if issuersCount increases by N (with a maximum step of N = 1), then issuersFrame will increase by one unit over a period of 5N blocks.</p> + +<p>Conversely, if issuersCount decreases by Y (with a maximum step of Y = 2 = current window inching forward + loss of one calculating member), then issuersFrame will decrease by one unit during 5Y blocks.</p> + +<p>When such events overlap, issuersFrame evolves as so :</p><empty-line /><p><strong>bloc</strong></p> + +<p><strong>event</strong></p> + +<p><strong>issuersFrame</strong></p><empty-line /><p>T</p> + +<p>Babar writes a block and enters issuersCount</p> + +<p>160</p><empty-line /><p>T+1</p> + +<p>Celeste leaves issuersCount</p> + +<p>160 +1 = 161</p><empty-line /><p>T+2</p> + +<p>N/a</p> + +<p>161 +1 -1 = 161</p><empty-line /><p>T+3/4/5</p> + +<p>N/a</p> + +<p>161 +1 -1 = 161</p><empty-line /><p>T+6</p> + +<p>N/a</p> + +<p>161 -1 = 160</p><empty-line /><p>The calculation can be found under rules BR_G05 and BR_G06 of the DUP protocol.</p> + +<p>4.4.1.3. exFact and the personalised difficulty</p> + +<p>We explained that exFact spikes immediately after the member has found a block. It decreases then rapidly to 1 after a number of blocks equal to 1/3 * issuersCount. Let’s see precisely how we calculate exFact:</p><empty-line /><p>nbPreviousIssuers is the value of issuersCount at the last block N found by the member.</p> + +<p>nbBlocksSince is the number of blocks found by the rest of the network since block N.</p> + +<p>percentRot is the number of <emphasis>not excluded</emphasis> peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency.</p> + +<p>a = FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) +exFact = MAX [ 1 ; a ]</p> + +<p>The FLOOR is a simple truncate function. For exFact to exclude the member, we need :</p> + +<p>(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2</p> + +<p>We can see that the member is not excluded if nbBlocksSince is greater than 1/3 of the calculating members. Take as an example nbPreviousIssuers = 6 and nbBlocksSince = 3:</p> + +<p>(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1</p> + +<p>However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded:</p> + +<p>(0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2</p> + +<p>Moreover if the last block was authored by the said member, then:</p> + +<p>nbBlocksSince=0 and +exFact = 0.67 * nbPreviousIssuers</p> + +<p>ExFact value increases according to the number of members calculating. Thus, if there is enough members calculating, even mining farms would be excluded. We have therefore succeeded in our intent to deter attempts to seize the blockchain and its currency.</p> + +<p>However, at any time t, the two-thirds of calculating members all have an exclusion factor of 1, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then only the members with the highest computational power from the remaining third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn’t stand a chance…</p> + +<p>4.4.2. The handicap</p> + +<p>The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. A higher handicap is assigned to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW.</p> + +<p>The aim is to handicap the half that has authored most blocks (the most powerful half) to favour the other one. So, the handicap formula will use the median number of blocks authored by peers within the current window.</p><empty-line /><p>nbPersonalBlocksInFrame is the number of blocks authored by a single member within the current window.</p> + +<p>medianOfBlocksInFrame is the median number of blocks written by the calculating members during the same timeframe.</p> + +<p>a = (nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame +handicap = FLOOR(LN(MAX( 1 ; a )) / LN(1.189))</p> + +<p>Let’s unwrap the formula:</p> + +<p>(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)</p> + +<p>is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored 9 blocks in the current window and the median is 5, then the ratio will be (9+1)/5 = 2. The MAX function allows us to ensure that the handicap has a value at least equal to 1.</p> + +<p>The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers.</p> + +<p>If we wanted the handicap to be applied as soon as the median is reached, we would divide it by LN(1). The problem is that we have already set a minimum value of 1 with the MAX function. If we were to divide the ratio by LN(1) all calculating peers would have a handicap \>= 1. In addition, is it really fair to handicap a member who is right on the median?</p> + +<p>That’s why we went for 1.189 rather than 1. A member has to be at least 18.9% above the median to be assigned a handicap. 18.9% is actually 16^(1/16), the difficulty factor between two levels of the proof work (hexadecimal hash).</p> + +<p>To conclude, you have to remember that :</p> + +<p>The handicap is indexed on the logarithm of the ratio to the median,</p> + +<p>Handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work’s difficulty.</p> + +<p>Conclusion</p> + +<p>Duniter’s Blockchain can be compared to Bitcoin’s : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend.</p> + +<p>More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers, maintaining a good security and helping decentralization of calculation.</p> + +<p>The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties :</p> + +<p>The freedom to choose your currency system: because money should not be imposed.</p> + +<p>The freedom to access resources: because we all should have access to economic & monetary resources.</p> + +<p>The freedom to estimate and produce value: because value is a purely relative to each individual.</p> + +<p>The freedom to trade with the money: because we should not be limited by the avaible money supply.</p> + +<p>Those 4 economic freedoms should be understood together, not exclusively. Plus, “freedom” has to be understood as “non-nuisance”. So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency.</p> + +<p>Sources :</p> + +<p>Relative Theory of Money, S.Laborde, 2010: en.trm.creationmonetaire.info/</p> + +<p>Bitcoin Whitepaper, S.Nakamoto, 2008: bitcoin.org/bitcoin.pdf</p> + +<p>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : lightning.network/lightning-network-paper.pdf</p> + +<p>The GNU Privacy Handbook, M.Ashley, 1999 : www.gnupg.org/gph/en/manual.html#AEN335</p> + +<p>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. cr.yp.to/papers.html#ed25519.</p> + +<p>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : archive.org/details/PPCoinPaper</p> + +<p>Duniter Blockchain Protocol, v13, draft by Elois : git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md</p> + +<p>The Sibyl Attack, J.R.Douceur: www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</p> + +<p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992</p><empty-line /><empty-line /><empty-line /><p>Bitcoin Whitepaper, S.Nakamoto, 2008: bitcoin.org/bitcoin.pdf↩</p> + +<p>Relative Theory of Money, S.Laborde, 2010: en.trm.creationmonetaire.info/↩</p> + +<p>OpenPGP protocol defines standard formats for encrypted messages, signatures, private keys, and certificates for exchanging public keys. The GNU Privacy Handbook, M.Ashley, 1999 : www.gnupg.org/gph/en/manual.html#AEN335↩</p> + +<p>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. cr.yp.to/papers.html#ed25519.↩</p> + +<p>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : archive.org/details/PPCoinPaper↩</p> + +<p>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : lightning.network/lightning-network-paper.pdf↩</p> + +<p>Surfing a Web of Trust, Reputation and Reciprocity on CouchSurfing.com, D.Lauterbach, H.Truong, T.Shah, L.Adamic: snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf↩</p> + +<p>Public key validation on GnuPG manual, M.Ashley, 1999 : www.gnupg.org/gph/en/manual.html#AEN335↩</p> + +<p>The Sibyl Attack, J.R.Douceur: www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf↩</p> + +<p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992↩</p> + +<p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992↩</p> + +<p>Pareto principle : en.wikipedia.org/wiki/Pareto_principle↩</p><empty-line /> +</section> + +</body> +</FictionBook> \ No newline at end of file diff --git a/build/whitepaper_fr.html b/build/whitepaper_fr.html index 7232bd365c6e1d38a63eaafed41125c0ad141e6b..aa82115d9a653dfb76b3874a4f26f1552753e9a9 100644 --- a/build/whitepaper_fr.html +++ b/build/whitepaper_fr.html @@ -10,26 +10,61 @@ Duniter Whitepaper href='bulma.css' > <link rel='stylesheet' href='main.css' > -<script src='js/jquery.js' ></script > -<script src='js/toc.js' ></script > -<script type='javascript' > - if ($) { - $('#whitepaper').tableofcontents({ id: '#toc' }); - } +<script type='text/javascript' > + /** + * Generates a table of contents for your document based on the headings + * present. Anchors are injected into the document and the + * entries in the table of contents are linked to them. The table of + * contents will be generated inside of the first element with the id `toc`. + * @param {HTMLDOMDocument} documentRef Optional A reference to the document + * object. Defaults to `document`. + * @author Matthew Christopher Kastor-Inare III + * @version 20130726 + * @example + * // call this after the page has loaded + * htmlTableOfContents(); + */ + function htmlTableOfContents(documentRef) { + var documentRef = documentRef || document; + var toc = documentRef.getElementById('table_of_contents'); + var headings = [].slice.call(documentRef.body.querySelectorAll('h1, h2, h3, h4, h5, h6')); + headings.forEach(function (heading, index) { + var anchor = documentRef.createElement('a'); + anchor.setAttribute('name', 'toc' + index); + anchor.setAttribute('id', 'toc' + index); + + var link = documentRef.createElement('a'); + link.setAttribute('href', '#toc' + index); + link.textContent = heading.textContent; + + var div = documentRef.createElement('div'); + div.setAttribute('class', heading.tagName.toLowerCase()); + + div.appendChild(link); + toc.appendChild(div); + heading.parentNode.insertBefore(anchor, heading); + }); + } + + try { + module.exports = htmlTableOfContents; + } catch (e) { + // module.exports is not defined + console.error('e', e) + } </script > </head > -<body> +<body onload="htmlTableOfContents();"> <main> -<div id="toc"> - -</div> +<nav id='table_of_contents' ></nav > <article id="whitepaper" class="content"> -<h1 id="duniter-a-libre-currency-blockchain-generator">Duniter : A libre currency blockchain generator !</h1> -<h2 id="abstract-todo">Abstract (TODO)</h2> +<h1 id="duniter-a-libre-currency-blockchain-generator.">Duniter: A libre currency blockchain generator.</h1> +<h2 id="abstract">Abstract</h2> +<p>Many currency principles involve non-equal rights to monetary creation between humans. We propose a monetary creation based on the Relative Theory of Money, which guarantee equal monetary creation for each willing human. This type of currency can be centralised, however, this could lead to censorship and arbitrary choices of the central institution. Thus, strongly inspired by Bitcoin example, we want the currency to be as decentralised as possible, in the transaction network as in the human identification process. We use a Web of Trust between living humans for identification. This web of trust allows us to impose personalised difficulty for transaction validation, keeping the calculation accessible to low-end hardware and allowing all competent members to secure the currency.</p> <h2 id="introduction">Introduction</h2> <p>Duniter is a software to create and manage “libre currencies”. Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question :</p> <blockquote> -<p>How should a currency be created to match the principle of equality between all humans ?</p> +<p>How should a currency be created to match the principle of equality between all humans, now and between generations ?</p> </blockquote> <p>The results of this demonstration implies a monetary creation :</p> <ul> @@ -38,752 +73,266 @@ Duniter Whitepaper <li>which amount has to be reassessed on fixed intervals according to a fixed formula.</li> </ul> <p>Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula :</p> -<blockquote> -<p>UD(t+1) = UD(t) + c² * ( M(t) / N(t) )</p> -</blockquote> +<pre><code>$$ UD(t+1) = UD(t) + c²*( {M(t) \over N(t) }) $$</code></pre> <p>Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin.</p> -<p>The first currency created through Duniter is Ğ1 (say “June”). It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software.</p> -<h2 id="state-of-the-art-bitcoin-case">State of the art : Bitcoin case</h2> +<p>The first currency created through Duniter is Ğ1, pronounced “June”. It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software.</p> +<h2 id="state-of-the-art-bitcoin-case">1. State of the art : Bitcoin case</h2> <!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniter uses the crypto-currency concept introduced by Bitcoin, which is to use cryptographic tools such as <em>signatures</em> to create digital currencies. Duniter fits this definition, but it has completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects.</p> -<h3 id="monetary-creation-of-bitcoin-a-space-time-asymmetry">Monetary creation of Bitcoin : a space-time asymmetry</h3> -<p>Space-time asymmetry refers to the relative access of individuals to newly created money (Relative Theory of Money, S.Laborde, 2010). Concretely, all existing currencies (c. 2015) are both spatially and temporally asymmetrical for their users. Let's take Bitcoin as an example to understand why.</p> -<h4 id="spatial-asymmetry">Spatial asymmetry</h4> -<p>When new Bitcoins are created, <em>only some Bitcoin users</em> (the miners) are given new Bitcoins, while everyone else get nothing. <strong>We believe this is the <em>first</em> injustice.</strong> However, some might say:</p> -<blockquote> -<p>"Miners used their <em>electricity and time</em> to get it!"</p> -</blockquote> -<p>... we would answer that this work <em>shouldn't have been rewarded by newly created Bitcoins</em>. New Bitcoins should be distributed to the whole Bitcoin community. Miners should be rewared another way, but not by money issuance. Of course, Bitcoin can't create money through Basic Income since <em>Bitcoin users are not strongly identified</em>, and one might benefit from money creation multiple times if he owned several wallets. Duniter gets rid of this problem completely by identifying its users and giving <em>the same amount of Basic Income to everyone</em>.</p> -<h4 id="temporal-asymmetry">Temporal-asymmetry</h4> -<p>Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, how will future joiners get Bitcoins? Just like Euros or Dollars: to get money, they will have to work for the ones who already own it. <strong>We believe this is the <em>second</em> injustice.</strong> Every member of a monetary community should be equal concerning monetary creation, and get the same relative amount of money over time, <em>even if they are a late adopter</em>. Duniter aims to fix this by making the Universal Dividend (a.k.a. <em>UD</em>) <em>grow by the time</em> (S.Laborde, 2010) according to precise rules, thus making members equal toward money issuance on a half-lifespan.</p> -<h4 id="a-solution">A solution</h4> -<p>Bitcoin has taught us that <em>it is possible</em> to create a currency system allowing one to both create digital money and to exchange it without a central authority. What we need to change is <em>the way money is issued</em> so we finally have a symmetrical system. We need Bitcoin <em>+ Universal Dividend</em>. But Universal Dividend <em>implies</em> that the community consists of only identified people. This is where the Web of Trust (WoT) comes into place. This concept, introduced by cryptography with the <a href="https://www.wikiwand.com/en/Pretty_Good_Privacy">OpenPGP</a> format, allows us to identify people in a <em>decentralized</em> manner. It works as follows: each person creates <em>a personal identity</em> that is linked to its cyptographic certificate. The identity must be confirmed by others members who use their own cryptographic key. It is that simple: <strong>people choose who is part of the community and who is not, not a central authority.</strong></p> -<blockquote> -<p>Duniter however won't use OpenPGP for its cryptographic features: Elliptic Curves will be used instead for the conciseness of its generated keys and its pratical advantages. Duniter has its own Web of Trust principles, that shall be exposed later.</p> -</blockquote> -<h3 id="proof-of-work-mining-a-power-race-todo">Proof-of-Work mining : a power race (TODO)</h3> -<p>In Bitcoin Model, the calculation and incentive principles cause a power race : new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. The goal of Duniter is to make blockchain validation much less energy and hardware consuming while keeping a strong level of security. As a consequence, even low-power hardware can secure Duniter Blockchain, which leads to a better decentralization of forging operations.</p> -<h3 id="other-projects">Other projects ?</h3> -<h4 id="what-about-pos">What about PoS ?</h4> -<p>When conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead to placing power over the currency in the richests hands : this is contrary to the symmetical principles of Duniter.</p> -<p>Now that PoS is well-tested, one could try to use Duniter’s WoT to create a PoS-like algorithm with equal chances among members. But this is not our aim for now.</p> -<h4 id="what-about-directed-acyclic-graph">What about Directed Acyclic Graph ?</h4> -<p>The Circles project uses DAG in a basic income cryptocurrency. However, in this project, one peer cannot know the whole monetary mass and the exact number of other peers. The calculation of Universal Dividend <code>UD = c * M/N</code> seems impossible, since we know neither M nor N.</p> -<h2 id="duniters-blockchain">Duniters Blockchain</h2> +<p>Duniter uses the crypto-currency concept introduced by Bitcoin<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a>, which is to use cryptographic tools such as signatures to create trustless digital currencies. Duniter fits this definition, but it has two completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects.</p> +<h3 id="monetary-creation-a-space-time-asymmetry">1.1. Monetary creation of Bitcoin : a space-time asymmetry</h3> +<p>Space-time asymmetry refers to the relative access of individuals to newly created money<a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a>. Concretely, most existing currencies (c. 2020) are both spatially and temporally asymmetrical for their users. Let's take Bitcoin as an example to understand why.</p> +<h4 id="spatial-asymmetry">1.1.1. Spatial asymmetry</h4> +<p>When new Bitcoins are created, only some Bitcoin users (the miners) are given new Bitcoins, while everyone else get nothing. We believe this is the first injustice. However, some might say:</p> +<blockquote> +<p>"Miners used their electricity and time to get it!"</p> +</blockquote> +<p>... we would answer that this work should not have been rewarded by newly created Bitcoins. New units should be distributed to the whole community. Miners should be rewared another way, but not by money issuance. Of course, Bitcoin cannot create money through Basic Income since Bitcoin users are not strongly identified, and one might benefit from money creation multiple times if they owned several wallets. Duniter gets rid of this problem by identifying its users and creating the same amount of Basic Income to everyone.</p> +<h4 id="temporal-asymmetry">1.1.2. Temporal-asymmetry</h4> +<p>Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, how will future joiners get Bitcoins? Just like most of us do for Euros or Dollars: to get money, they will have to work for the ones who already own it.</p> +<p>We believe this is the second injustice. Every member of a monetary community should be equal concerning monetary creation, and get the same relative amount of money over time, even if they are a late adopter. Duniter aims to fix this by making the Universal Dividend (a.k.a. UD) grow by the time according to precise rules, thus making members equal toward money issuance on a half-lifespan.</p> +<p>Most currencies present one of these two asymmetries, including metal currencies and mutual credit, as exposed in the RTM.</p> +<h4 id="a-solution">1.1.3. A solution</h4> +<p>Bitcoin has taught us that it is possible to create a currency system allowing one to both create digital money and to exchange it without a central authority. What we need to change is the way money is issued so we finally have a symmetrical system. We need <strong>Bitcoin + Universal Dividend</strong>. But Universal Dividend implies that the community consists of only identified people. This is where the Web of Trust (WoT) comes into place.</p> +<p>This concept, introduced by cryptography with the OpenPGP format<a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a>, allows us to identify people in a decentralized manner. It works as follows: each person creates a personal identity that is linked to its cyptographic certificate. The identity must be confirmed by others members who use their own cryptographic key. It is that simple: people choose who is part of the community and who is not, not a central authority.</p> +<p>However, Duniter will not use OpenPGP for its cryptographic features: Elliptic Curves<a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a> will be used instead for the conciseness of its generated keys and its pratical advantages. Duniter has its own Web of Trust principles, that will be exposed later.</p> +<h3 id="proof-of-work-mining-a-power-race">1.2. Proof-of-Work mining : a power race</h3> +<p>In Bitcoin Model, the calculation and incentive principles cause a power race : new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. This leads to a power race an places the control over the currency in the hands of the richest hardware owners. We want to make Duniter blockchain validation much less energy and hardware consuming while keeping a strong level of security. This will be further explained later. A consequence of this choice is the participation of low-end hardware in the Duniter network, leading to a better decentralization of blockchain validation.</p> +<h4 id="what-about-proof-of-stake">1.2.1 What about Proof of Stake ?</h4> +<p>Proof of stake consensus algorythm was first introduced in 2012<a href="#fn5" class="footnote-ref" id="fnref5"><sup>5</sup></a>. The basic principle is to allow the richest wallets to issue blocks, putting their coin balance as a “stake” they would lose in case of cheat.</p> +<p>At the time of conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. We did not chose this consensus principle. Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead to placing power over the currency in the richests hands : this is contrary to the symmetical principles of a libre currency.</p> +<h2 id="duniters-blockchain">2. Duniters Blockchain</h2> <!-- source : https://duniter.org/en/theoretical/ --> <p>Duniters Blockchain follows the basic principles of Bitcoins. This is essential for synchronization between peers, as to prevent double-spend attacks. However, Duniters Blockchain will store different informations than Bitcoins.</p> -<p>The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no <em>generation transaction</em> exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either:</p> +<p>The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no generation transaction exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either:</p> <ul> <li>a former transaction (as in Bitcoin)</li> <li>a Universal Dividend (specific to Duniter).</li> </ul> -<p>Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactinos are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where “space” are members of the WoT and “time” the basci blockchain units : the blocks. On each point of time, one can determain whick account is legitimate to create the UD, only with a blockchain analysis.</p> -<h3 id="spam-countermeasures-todo">Spam countermeasures (TODO)</h3> -<p>An issue of most cryptocurrency projects is to prevent the common ledger from growing too much and require lot of storage and computing power to be usable. In particular, we don’t want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don’t want to do this since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented.</p> +<p>Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactions are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where “space” are members of the WoT and “time” the basic blockchain units : the blocks. On each point of time, one can determine which account is legitimate to create the UD, only with a blockchain analysis.</p> +<h3 id="spam-countermeasures">2.1. Spam countermeasures</h3> +<p>An issue of most cryptocurrency projects is to prevent the common ledger from growing too much. This would require nodes to have a lot of storage and computing power to be usable. In particular, we don’t want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don’t want to introduce this mean since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented.</p> <!-- see : https://forum.duniter.org/t/sans-frais-de-transaction-comment-resister-aux-attaques/3846/25 (implemented ?)--> -<ul> -<li>output minimal de 100*Unitbase / 1 unité -> empêche un attaquant de faire grossir la BC et les index trop vite (DUBP v12)</li> -<li>chaînage maximal des tx</li> -<li>seuils de dépense (implémentés ? en tout et par issuer ?)</li> -</ul> -<h3 id="scaling">Scaling</h3> +<h4 id="minimum-output-amount">2.1.1. Minimum output amount</h4> +<!-- This has to be implemented in DUBPv13. --> +<p>Fixing a minimal output amount reduces the power of an attack. Duniter deals with cents of Ğ1 or 1/1000 of the first UD. An attacker could create thousand accounts with only 1 UD. To prevent this, a valid transaction must have output amounts of minimum 1Ğ1. This reduces the power an attack by 100.</p> +<h4 id="limited-block-size-and-chainability">2.1.2. Limited block size and chainability</h4> +<p>The block size is always limited. While the protocol allows this limit to evolve to address scaling issues, an attacker cannot register as many transaction as they wish.</p> +<p>With the same goal to prevent too many transactions to get registered, while transactions can be “chained” (refer to another transaction in the same block), the chainability of transactions is limited to 5.</p> +<h3 id="scaling">2.2. Scaling</h3> <p>Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons :</p> <ul> -<li>Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don’t want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT limits its size to around 16 million members.</li> -<li>Duniter’s aim is to be used to create <em>multiple</em> libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community.</li> -</ul> -<p>However, Duniter has two assets that might be used if the number of users grow.</p> -<h4 id="dynamic-block-size">Dynamic block size</h4> -<p>While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks( <em>current window</em> will be described in the PoW part). This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it.</p> -<div class="{highlight}"> -<p>block_size < max(500 ; CEIL(1.10 * (average block size))</p> -</div> -<h4 id="lightning-networks">Lightning Networks</h4> -<p>The Lightning Networks allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed.</p> -<h2 id="duniter-web-of-trust">Duniter Web of Trust</h2> -<!-- source : https://duniter.org/en/deep-dive-into-the-web-of-trust --> -<h3 id="basic-principles">Basic Principles</h3> -<p>In order to identify “members” account - which create monetary units - from other accounts, Duniter uses a Web of Trust. This can be summarized into few principles:</p> -<ul> -<li>Each account becomes a member if it received a minimal number of certifications (5 for Ğ1 currency)</li> +<li>Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don’t want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT should limit its size to around 16 million members.</li> +<li>Duniter’s aim is to be used to create multiple libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community.</li> +</ul> +<p>However, Duniter has assets that will help if the number of users and transactions grow.</p> +<h4 id="dynamic-block-size">2.2.1 Dynamic block size</h4> +<p>While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks(see “personalised difficulty” part for more information). This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. The block size (in bytes) is limited as so :</p> +<pre><code>block_size < max(500 ; CEIL(1.10 * (average block size))</code></pre> +<h4 id="lightning-networks">2.2.2. Lightning Networks</h4> +<p>The Lightning Networks<a href="#fn6" class="footnote-ref" id="fnref6"><sup>6</sup></a> allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed.</p> +<h4 id="unit-base">2.2.3. Unit base</h4> +<p>As the Universal Dividend grows exponentially, with time Duniter nodes would have had to deal with always largest amounts, eventually reaching the BIGINT limit. To avoid this, the amounts are expressed with a unit base in base 10. We want the UD amount to always fit in 4 digits. To manage it, the <code>unitbase</code> is updated each time the UD value reaches 100.00 : it goes from <code>99.99*10^(unitbase)</code> to <code>10.00*10^(unitbase+1)</code>. All the unit amounts are thus divided by 10. While this might seem strange, this process has already hapened in state currencies. Moreover, the amounts expressed in UD will not change.</p> +<p>With a monetary growth of 10% each year and a stable population, such a change of unit base would happen each 25 years.</p> +<h2 id="duniter-web-of-trust">3. Duniter Web of Trust</h2> +<h3 id="duniter-wot-basic-principles">3.1. Basic Principles</h3> +<p>In order to identify “members” accounts - which create monetary units - and other accounts, Duniter uses a Web of Trust. This can be summarized into few principles:</p> +<ul> +<li>Each account becomes a member if it received a minimal number of certifications - 5 for Ğ1 currency.</li> <li>Only members accounts can send certifications. Certifications have a limited lifespan.</li> <li>A certification indicates that the sender accepts the receiver as a legitimate identity.</li> </ul> -<p>The aim of the WoT is to identify a blockchain account to a living human. Each member of the Ğ1 currency signs a licence stating that they will only certify humans they know well (among other rules). Thus, if a member is part of an attack on the currency, they can be found by mutual friends. The security of Ğ1 currency stands on:</p> -<ul> -<li>Corroborating informations on members (5 certifications)</li> -<li>Peer pressure by close relatives</li> -<li>Law if the licence has not been respected.</li> -</ul> -<p>Note that non-members accounts can use the currency, but cannot create money. They can be used by individuals as secondary wallets, or by institutions.</p> -<p>However, the WoT does not rely only on trust betwenn people. Rules have been added to increase the security, and we will present them.</p> -<h3 id="why-do-we-need-a-web-of-trust">Why do we need a Web of Trust?</h3> +<p>The aim of the WoT is to identify a blockchain account to a living human. According to Lauterbach et.al<a href="#fn7" class="footnote-ref" id="fnref7"><sup>7</sup></a>, the strengh of a relationship should be considered when building a vouch system. For this reason, the Ğ1 Web of Trust rules are expressed in a licence stating what WoT certifications are. A certification represents a strong human relationship : one may certify a close relative, not an acquaintance. Each member has to accept this licence before being included in the WoT. Thus, if a member is part of an attack on the currency, they can be found by mutual relatives. Additional security rules occur to prevent cheat and attacks on a large scale.</p> +<p>Note that non-members accounts can use the currency, but cannot create money. Non-members accounts can be used by individuals as secondary wallets, or by institutions.</p> +<p>We were inspired by the OpenPGP Trust system<a href="#fn8" class="footnote-ref" id="fnref8"><sup>8</sup></a>. However, the OpenPGP trust principles aim at defining trust from a particular point of view while Duniter needs to identify humans for the whole community. To achieve this goal, while OpenPGP allows each user to tweak its trust parameters individually, Duniter sets rules in the “genesis” block for the whole community.</p> +<h3 id="why-do-we-need-a-web-of-trust">3.2. Why do we need a Web of Trust ?</h3> <p>There are two reasons we need it :</p> <ol type="1"> -<li>To make sure that only one Universal Dividend is produced per member at each specified creation interval -in the Ğ1’s case this interval is set as daily <code>86 400</code> seconds-, it is the <em>monetary parameter</em> known as <code>dt</code>-.</li> -<li><p>To identify the nodes hashing the blocks and assign them each a personalised difficulty. This custom difficulty <a href="https://en.wikipedia.org/wiki/Proof-of-work_system">proof of work</a> is there to avoid the blockchain’s validation mechanism becoming too centralised as is the case with many 'non-libre’ cryptocurrencies.</p> -<blockquote> -<p>Wait, what’s a ‘monetary parameter’ ?</p> -</blockquote></li> +<li>To make sure that only one Universal Dividend is produced per member at each specified creation interval. In the Ğ1’s case this interval is set as daily <code>86 400</code> seconds, it is the <em>monetary parameter</em> known as <code>dt</code>.</li> +<li>To identify the nodes hashing the blocks and assign each a personalised difficulty. This custom difficulty proof of work is there to avoid the blockchain’s validation mechanism becoming too centralised as is the case with many 'non-libre’ cryptocurrencies.</li> </ol> -<p>Every currency implementing Duniter has its own blockchain whose behaviour is dictated by a set of ‘parameters’ -defined in block zero, the so-called genesis block- that can be tweaked to achieve the desired results. At the time of writing this article, the Duniter protocol -aka DUP- has a total of 21 parameters of which 10 are for the WoT alone. We’ll focus on these 10.</p> -<p>Suffice to say that in the Ğ1’s case, the DU is created every 24 hours -86 400 seconds- but this interval -set through the time derivative <code>dt</code> parameter- can have a different value in an other implementation of the protocol.</p> -<p>I won’t write about the second parameter having to do with the proof of work, it’s outside our scope here, just know that the Web of Trust allows us to <strong>identify</strong> the members providing hashing power, which we couldn’t do without it. This crucial feature means we can impose a rotation between the members hashing the blocks so that no single rich individual or group invests in a giant ‘hash farm’ and takes a hold of the blockchain, paralysing the community!</p> -<p>Let’s go back to the first objective: to make sure that each member can only have one account. As we all know, achieving zero-risk isn’t possible, our goal is therefore not to create a WoT within which fraud would be absolutely impossible but instead to discourage it. Here is a rewording of our goal in 4 smaller ones :</p> -<ol type="1"> -<li>To make the certification process lengthy enough that all members exercise due diligence and are wary of risks.</li> -<li>To make fraudulent acts as hard as we can to the extent that they become pointless.</li> -<li>To ensure that any Sybil attacks have a negligible impact on the currency -<em>by ensuring that illegitimate double Universal Dividends have no significant bearing on the legitimate monetary mass</em>-</li> -<li>To slow the growth of ‘Sybil regions’ to give enough time for the community to react and isolate the threat.</li> -</ol> -<blockquote> -<p><strong>Wait, a Sybil what ?</strong></p> -</blockquote> -<p>A <a href="https://en.wikipedia.org/wiki/Sybil_attack"><strong>Sybil attack</strong></a>, is the name given to attacks perpetrated on a reputation system through the creation of fake identities. A Web of Trust is a specific instance of a <a href="https://en.wikipedia.org/wiki/Reputation_system"><strong>Reputation System</strong></a>.</p> -<p>There are plenty of Sybil attack scenarios we can think of and just as many reasons why their perpetrators would want to carry them out. Our objective is that the configuration of the WoT protects both users and its IT backbone infrastructure against these attacks.</p> -<p>This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web’s role isn’t to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing your tap water and electricity but isn’t responsible for any burglaries etc. Much in the same way, Duniter’s WoT guarantees us all a functional currency and that’s quite a feat in itself!</p> -<h3 id="the-importance-of-having-our-own-certification-system">The importance of having our own certification system</h3> -<p>We are regularly offered to switch over to third-party or state-owned authentication systems but these are centralised and go against the principles of our community. We feel that we would lose our independence and universality by adopting a state-controlled system. People without an official state-provided identity or homeless people would also run the risk of being excluded from the WoT. It is of the utmost importance that we remain free from any state or corporation. To this day we depend only on the Internet and yet, were it to fail, there are already alternatives being tested around the world for a decentralised network.</p> -<h3 id="a-few-foundational-concepts-on-graph-theory-a-bit-of-vocabulary">A few foundational concepts on graph theory : a bit of vocabulary</h3> -<ul> -<li><p><strong>Graph</strong>: set of points -called ‘vertices’- joined by edges -called paths/walks-.</p></li> -<li><p><strong>Simple graph</strong>: a graph with no loops and with no multiple edges. That is, each edge connects two distinct endpoints and no two edges have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a></p></li> -<li><p><strong>Directed graph</strong>: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a> Arrow A –> B is therefore different from arrow B –> A.</p></li> -<li><p><strong>Endpoints</strong>: the edge with vertex A –> B has A and B as endpoints, respectively as start and end of the path/walk.</p></li> -<li><p><strong>Isolated vertex</strong>: a vertex whose degree is zero, that is, a vertex with no incident edges. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a></p></li> -<li><p><strong>Degree of a vertex</strong>: number of its incident edges -in and out-.</p></li> -<li><p><strong>Out-degree of vertex A</strong>: number of outbound edges / tail ends from A.</p></li> -<li><p><strong>In-degree of vertex A</strong>: number of incoming edges / head ends to A.</p></li> -</ul> -<figure> -<img src="https://duniter.org/en/images/wiki/degrees.jpg" alt="degress of a vertex diagram" /><figcaption>degress of a vertex diagram</figcaption> -</figure> -<ul> -<li><strong>Path</strong>: -aka “walk”- path to follow to get from vertex A to vertex B.</li> -</ul> -<h3 id="definition-of-the-duniter-web-of-trust">Definition of the Duniter Web of Trust</h3> -<p>The Duniter WoTs -one per currency- are simple directed graphs without isolated vertices. The vertices are the members and the edges are the certifications given and received.</p> -<p>Directed, what does that mean?</p> -<p>The responsibility of issuing a certification is unique and personal to the certifier. The trust he/she places in the receiver cannot be imposed in the other direction although in most circumstances both parties equally trust each other.</p> -<p>In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific ‘deactivated state’ and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered ‘pending’ to avoid the web collapsing like a house of cards.</p> -<p>If these old members don’t come back into the web, their pending certifications will eventually expire and they will switch from ‘deactivated’ to ‘isolated’ vertices.</p> -<p>To wrap up with old members, after a certain period of time -set in the currency’s parameters - their deactivated vertex is removed from the web and the associated identity is ‘revoked’. The person who owned the account can no longer use this identity but is free to join the web with another one. :-)</p> -<blockquote> -<p>What do you mean by ‘identity’?</p> -</blockquote> -<p>An identity is a set of three pieces of information: a public key, a name and a blockstamp. A blockstamp points to a specific block in the chain. Its main use is to freeze the point in time at which an identity was created and to link this identity to a specific chain and of course, a currency -each currency having its own blockchain-.</p> -<p>An identity can be in any one of 5 different status: pending, member, old member, revoked or excluded.</p> -<p>Let’s take a simple example:</p> -<div class="highlight"> -<pre><code>A -> B -> C - | - \--> D</code></pre> -</div> -<p>If, for whatever reason, A were to lose its member status, the web would crumble and all other members would be excluded as a consequence. To avoid this, the certification from A –> B will remain valid until its expiry date, leaving enough time for B to receive certifications from C or D.</p> -<p>Because our WoT doesn’t have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications it has received -in the same block-. This calls for a temporary ‘buffer’ storage space for <strong>pending</strong> identities and the certifications they’ve received. This storage space is called ‘the pool’ -of Duniter nodes- which we could also have called the ‘sandbox’ as that’s the name used in Duniter’s code. I might add that these ‘pools’ also include other documents and metadata not mentioned here.</p> -<h3 id="exploring-the-rules-behind-a-duniter-web-of-trust">Exploring the rules behind a Duniter Web of Trust</h3> -<p>The Duniter WoTs -one per currency- work with a set of eight fundamental rules, themselves enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - <code>msPeriod</code>- having being hard-coded in the Ğ1’s code subsequently.</p> -<h4 id="distance-rule-and-referent-members-stepmax-and-xpercent-1distance-rule-and-referent-members-stepmax-and-xpercent">1.Distance rule and referent members (<code>stepMax</code> and <code>xPercent</code>) {#1distance-rule-and-referent-members-stepmax-and-xpercent}</h4> -<p>These two parameters are closely linked and together define the ‘distance rule’. The ‘distance rule’ can only be described after defining what a ‘referent member’ is:</p> -<blockquote> -<p><strong>Referent member</strong>: member A is said to be ‘referent’ if and only if the total of his/her degrees are greater than or equal to <code>CEIl-N^-1/stepMax--</code> where N is the total number of members.** As the size of the web will grow this number will grow too, meaning it will take more certification issuances to become a referent member as the number of certifications needed to become a member shouldn’t change.</p> -</blockquote> -<p>Let’s now define the distance rule:</p> -<blockquote> -<p><strong>Distance rule</strong>: member A is said to observe this rule if and only if for a subset xPercent % of referent members R there exists a path of length less than or equal to <code>stepMax</code> between R and A.**</p> -</blockquote> -<p>Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect web, that is one in which each member has certified all members he/she legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time <code>t</code> who haven’t yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would effectively stop growing. -You can see what would happen if the notion of ‘referent member’ didn’t exist by going to the ‘gaussianWotQuality’ page on <a href="https://g1-monit.librelois.fr/gaussianWotQuality?lg=en&unit=quality">currency-monit</a> and activating ‘if the concept of referent members didn’t exist’-.</p> <blockquote> -<p><strong>When is the distance rule applied?</strong></p> +<p><strong>Monetary parameter</strong> : Each currency that use Duniter has its own blockchain whose behaviour is dictated by a set of ‘parameters’ defined in block zero - the so-called genesis block - that can be tweaked to achieve the desired results. At the time of writing the Whitepaper, the Duniter Blockchain Protocol (DUBP) has a total of 21 parameters of which 10 are for the WoT alone. We’ll focus on these 10.</p> +<p>Suffice to say that in the Ğ1’s case, the DU is created every 24 hours - 86 400 seconds. This interval is set through the time derivative <code>dt</code> parameter and can have a different value in other implementations of the protocol.</p> </blockquote> -<p>Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets confirmed into the web or an existing member gets renewed. <em>Exception to the rule: the distance rule is not observed in the genesis block -when the web is first implemented-.</em></p> -<h4 id="rule-of-the-minimum-number-of-certifications-needed-sigqty-2-rule-of-the-minimum-number-of-certifications-needed-sigqty">2. Rule of the minimum number of certifications needed (<code>sigQty</code>) {#2-rule-of-the-minimum-number-of-certifications-needed-sigqty}</h4> -<p>This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least <code>sigQty</code> active certifications. If, for whatever reason, member A were to have less than <code>sigQty</code> active certifications in a given block, he/she would cease being a member and be required to publish a request for identity renewal.</p> -<h4 id="the-membership-renewal-rule-msvalidity-msperiod-and-mswindow-3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow">3. The membership renewal rule (<code>msValidity</code>, <code>msPeriod</code> and <code>msWindow</code>) {#3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow}</h4> -<p>Bear in mind that a membership doesn’t last a lifetime but instead has a lifespan set to <code>msValidity</code> seconds.</p> -<p>Every single member -or old member who hasn’t revoked his identity or been excluded- can request a membership renewal so long as the last request was made more than <code>msPeriod</code> seconds ago -if a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the ‘pool’ for a maximum of <code>msWindow</code> seconds before it’s included in the blockchain. Once again, this can only happen once/if the member meets both the <code>siqQty</code> rule and the distance rule -if these criterion are already matched it’s just a case of waiting for a new block to be mined-.</p> -<p>If a member hasn’t requested a renewal for longer than <code>msValidity</code> seconds, he/she automatically ceases being a member. From this moment on, the ex-member has another <code>msValidity</code> window to renew his/her membership. When this period of `2 × msValidity’ runs out, the membership will expire and this identity will never be available for use again in the web. If the person so desires, he/she will have to start from zero to regain access to the WoT.</p> -<h4 id="rule-of-certification-lifespan-sigvalidity-4-rule-of-certification-lifespan-sigvalidity">4. Rule of certification lifespan (<code>sigValidity</code>) {#4-rule-of-certification-lifespan-sigvalidity}</h4> -<p>All certifications included in the blockchain expire <strong>sigValidity</strong> seconds after they were <strong>issued</strong>.</p> -<p>/!\ The issuance and the inclusion of a certification in the blockchain occur at different times. When member A issues a certification at time t1, it gets stored in the pool starting at t1 and only finds its way into the blockchain at t2 when all of the web’s rules are observed. Several weeks can thus go by between t1 and t2!!!</p> -<h4 id="rule-of-limited-supply-of-active-certifications-sigstock-5-rule-of-limited-supply-of-active-certifications-sigstock">5. Rule of limited supply of active certifications (<code>sigStock</code>) {#5-rule-of-limited-supply-of-active-certifications-sigstock}</h4> -<p>By ‘active certifications’ we refer to certifications included in the blockchain and that haven’t yet expired.</p> -<p>The total of active certifications issued by any member at any single time must be less than or equal to <code>sigStock</code>. When this threshold is reached the member will have to wait for one of his active certifications to expire before he/she can issue a new one.</p> -<h4 id="rule-of-the-time-period-between-two-certification-issuances.-sigperiod-6-rule-of-the-time-period-between-two-certification-issuances-sigperiod">6. Rule of the time period between two certification issuances. (<code>sigPeriod</code>) {#6-rule-of-the-time-period-between-two-certification-issuances-sigperiod}</h4> -<p>As soon as a certification issued by member A gets included in the blockchain, he/she will be unable to issue a new one before another <code>sigPeriod</code> seconds.</p> -<h4 id="expiry-of-a-certification-issuance-sigwindow-7-expiry-of-a-certification-issuance-sigwindow">7. Expiry of a certification issuance (<code>sigWindow</code>) {#7-expiry-of-a-certification-issuance-sigwindow}</h4> -<p>When a certification is issued by member A, it will be stored in the ‘pool’ for a maximum of <code>sigWindow</code> seconds. If the certification hasn’t been included in the blockchain by then, it will be cancelled and the member’s <code>sigStock</code> will be repleted by one.</p> -<h4 id="lifespan-of-a-pending-active-certification-idtywindow-8-lifespan-of-a-pending-active-certification-idtywindow">8. Lifespan of a ‘pending’ active certification (<code>idtyWindow</code>) {#8-lifespan-of-a-pending-active-certification-idtywindow}</h4> -<p>When a new identity is created, it is stored in the ‘pool’ for a maximum of <code>idtyWindow</code> seconds. If the person hasn’t achieved member status by then, the certification will simply be cancelled.</p> -<h3 id="details-on-some-of-the-wots-peculiarities-at-the-genesis-block">Details on some of the WoT’s peculiarities at the genesis block.</h3> -<p>The aforementioned rules can only be enforced with an existing web. They cannot be observed when first creating the web, that is when defining the genesis block.</p> -<p>Only rules 2 and 5 can be observed at the genesis block.</p> -<p>The genesis block has to be manually created by the founding members. In practice this means that there must be a choice of which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities.</p> -<p>As soon as the genesis block has been created, the other identities can start mining the blockchain and the member who begat block #0 effectively looses the decision power he had at creation.</p> -<h3 id="why-these-rules-and-application-cases-in-the-g1">Why these rules and application cases in the Ğ1</h3> -<h4 id="distance-and-maximum-size-1-distance-and-maximum-size">1. Distance and maximum size {#1-distance-and-maximum-size}</h4> -<p>The distance rule is there to curb the maximum size of a Sybil region as well as that of the monetary community as a whole. The <code>xpercent</code> parameter prevents the creation of a ‘faction’ that could take hold of the blockchain.</p> -<figure> -<img src="https://duniter.org/en/images/wiki/wot-sybil.jpg" alt="Sybil region" /><figcaption>Sybil region</figcaption> -</figure> -<p>The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned Sybil members. As a consequence, the shortest edge/path between a legitimate member and a Sybil one has to have the attack’s author as an endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as <code>stepAttackers</code>. The maximum size of a Sybil region created by <code>sigQty</code> members depends on the L parameter, defined as L = sigQty/sigStock:</p> -<div class="highlight"> -<pre><code>Maximum Sybil region size = (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L)</code></pre> -</div> -<p>The maximum size of the Web of Trust is given by the following formula:</p> -<div class="highlight"> -<pre><code>WoTmax = (sigStock)*L^(stepMax-1)</code></pre> -</div> -<p>However we know for a fact that members will never use all of their available certifications. Many studies have proven that we all know a maximum average of fifty people, let’s then replace sigStock by fifty:</p> -<div class="highlight"> -<pre><code>WoTavg= (50)*(sigQty/50)^(stepMax-1)</code></pre> -</div> -<p>Our goal with the Ğ1 is to create a community of about one million members enjoying the world’s first true <a href="https://en.wikipedia.org/wiki/Catallaxy">catallaxy</a> -free economy with a spontaneous order of things-. Let’s see how we can tweak the pair of sigQty and stepMax- to reach this size:</p> -<figure> -<img src="https://duniter.org/en/images/wiki/graph-WoTmoy.png" alt="graphe WoTmoy en fonction de sigQty et stepMax" /><figcaption>graphe WoTmoy en fonction de sigQty et stepMax</figcaption> -</figure> -<p>The maximum size of a Sybil region grows linearly with <code>sigQty</code> but exponentially with <code>stepMax</code>. Logic has it that we need to keep <code>stepMax</code> as low as possible to ensure sufficient strength to the web. The above graph shows that the lowest value of <code>stepMax</code> for a web of a million members is of 5. This is an order of magnitude and is likely to be much higher in reality, we cannot measure it for sure.</p> -<p>For <code>sigQty</code> we can choose a value of <strong>4</strong> for a web of <strong>1.5 million members</strong> or <strong>5</strong> for <strong>half a million members</strong>. Bear in mind these are gross figures and could be significantly higher, we are talking anywhere between 1 and 10 million in reality. Calculating WOTavg gives us a pretty good idea of how the web would scale bearing in mind that it considers all members are referent members too -which isn’t the case as explained previously-. Hence the maximum size of the web is likely larger, a ballpark figure of half a million is enough for now especially knowing that the smaller <code>sigQty</code> is, the easier it is to launch a Sybil attack -it’s easier to find four accomplices than five-. For security reasons we have settled on five:</p> -<p>stepMax = 5 sigQty = 5 sigStock >= 50</p> -<p>The maximum size of a Sybil region therefore is: <code>(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))</code></p> -<p>with sigStock = 50 we have a Sybil region of: <code>45*(1-10^(5-stepAttackers))/(-9)</code></p> -<p>A good practice for protecting the web is to maximise <code>stepAttackers</code>. That’s why we decided that referent members in the genesis block had to be at least four steps away from each other.</p> -<p>Another way to keep a Sybil attack at bay, were it slow enough for members to notice it, would be for referent members to ‘stretch’ the web intentionally to limit the growth of the region by ensuring that the attackers’ legitimate certifications received in the first place aren’t renewed. But what if bot accounts were created and certified each other super fast and following all rules, how would we counter that? By introducing a minimum length of time between two certifications!</p> -<h4 id="time-is-our-friend-2-time-is-our-friend">2. Time is our friend {#2-time-is-our-friend}</h4> -<p>To help us deter a Sybil attack, we’ve decided to impose a minimum period of time between any two certifications issued from a single account. This parameter called <code>sigPeriod</code> affords us a greater chance to detect the formation of a ‘hostile’ faction.</p> -<p>Here is a graph showing the evolution of a Sybil region with the variation of <code>sigPeriod</code>:</p> -<figure> -<img src="https://duniter.org/en/images/wiki/impact_sig_period.png" alt="graph of the WoT's size according to sigPeriod and stepAttackers" /><figcaption>graph of the WoT's size according to sigPeriod and stepAttackers</figcaption> -</figure> -<p>As you’ll easily be able to tell, there is a strong link between the growth speed of the region and <code>sigPeriod</code>. As evidenced here, we need a <code>sigPeriod</code> high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher <code>sigPeriod</code> is, the more members will exercise their certification power gingerly, the action coming at a higher ‘cost’.</p> -<p>There are numerous advantages to giving <code>sigPeriod</code> a high value and no technical barriers to it, hence our choice of five days.</p> -<p>We could have also gone for days days -one week- for the sake of simplicity however there was an underlying idea behind our choice which was quite simply the pace of today’s life. Certifying someone can be a lengthy process as one needs to make sure he/she is correctly applying the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea to allow one to certify at the end of every working week -five days- instead of a whole calendar one.</p> -<h4 id="trust-me-now-trust-me-forever-sigvalidity-msvalidity-3-trust-me-now-trust-me-forever-sigvalidity-msvalidity">3. Trust me now, trust me forever? (<code>sigValidity</code>, <code>msValidity</code>) {#3-trust-me-now-trust-me-forever-sigvalidity-msvalidity}</h4> -<p>There would be two main drawbacks to a lifetime membership in the Ğ1’s Web of Trust:</p> -<blockquote> -<p>First of all we need to take into account that some members will pass and those accounts should no longer produce the Universal Dividend. Secondly it is of the utmost importance that ‘rogue’ accounts can be excluded from the web at some point.</p> -</blockquote> -<p>To achieve this, certifications have a limited lifetime and members need to seek renewal from their peers after <code>sigValidity</code> time. On the other hand, this time can’t be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, a certification with too short a lifetime would foster careless certifying behaviours. The act of certifying must have a ‘perceived’ cost high-enough to make it feel like an important act. Lastly, we also wanted this lifetime to be easy enough to remember. Historically speaking, we first settled on the values of <code>sigPeriod</code> and <code>sigStock</code>, meant one could issue all of his/her certifications in 495 days, one year was therefore not long enough. We deemed three years to bee much and that’s how we agreed on two years in the end.</p> -<p>Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we needed to address. We choose a value of one year for <strong>msValidity</strong>. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to ‘prune’ the web of past or inactive members who don’t renew their membership.</p> -<h4 id="keeping-the-pools-free-of-information-glut--idtywindow-sigwindow-mswindow-4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow">4. Keeping the pools free of information glut -(<code>idtyWindow</code>, <code>sigWindow</code>, <code>msWindow</code>) {#4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow}</h4> -<p>The pools need to be cleaned up on a regular basis to avoid them clogging up with information and to ensure that machines with less calculating power can still run a Duniter node.</p> -<p>To achieve this, identities with pending membership approval and the corresponding certifications have to remain the shortest time possible in the pool while still having a chance of making it into the blockchain.</p> -<p>For the Ğ1, our opinion was that two months would be enough for all potential certifiers to agree on a specific identity to certify. We also wanted a time period that would be easy enough to remember by all. We settled on two months, and gave this value to all three parameters <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>.</p> -<h4 id="avoiding-single-members-from-knowing-too-many-people-sigstock-5-avoiding-single-members-from-knowing-too-many-people-sigstock">5. Avoiding single members from ‘knowing too many people’ (<code>sigStock</code>) {#5-avoiding-single-members-from-knowing-too-many-people-sigstock}</h4> -<p>Many sociology studies have shown that we all know an average of fifty people. This of course is an average, some of us know more than fifty people, others much less. Once again we went for a number that would be easy to remember. Although <code>sigStock</code>’s impact on the size of a Sybil region is fairly limited, its value nonetheless has to be kept reasonable. We settled on hundred.</p> -<h4 id="avoiding-locking-minorities-xpercent-6-avoiding-locking-minorities-xpercent">6. Avoiding locking minorities (<code>xpercent</code>) {#6-avoiding-locking-minorities-xpercent}</h4> -<p>It’s easy enough to become a referent member, one of the Sybil strategies could therefore be to create a region of referent members. Such a region would grow slower than otherwise but could confer a locking power to its members by using the distance rule. That’s why the distance rule cannot be calculated on 100% of the referent members. Hence the introduction of the <code>xpercent</code> parameter which defines the percentage of referent members needing to be less than five edges -steps- from each other.</p> -<p>This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance rule. The <code>xpercent</code> parameter was one of the hardest to define, we therefore reserve ourselves the right of modifying its value during the Ğ1 experiment.</p> -<p>We were inspired by the <a href="https://en.wikipedia.org/wiki/Pareto_principle">Pareto principle</a>: if at least 20% of members give good density to the web, 80% of the referent members will be five or less steps from any other member -referent or non-. The maximum value for <code>xpercent</code> is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%.</p> -<h4 id="spam-protection-with-msperiod-7-spam-protection-with-msperiod">7. Spam protection with (<code>msPeriod</code>) {#7-spam-protection-with-msperiod}</h4> -<p>This parameter stands out a bit on its own, as it was added after the genesis block. It is there to protect the Duniter P2P infrastructure against ‘spam’ attacks. We had to think of a strategy against attacks such as high-frequency membership renewal requests -i.e: in every block, every five minutes- or worse still, hundreds of these requests per minute to flood the Duniter nodes. Without such limits, nodes are supposed to address all renewal requests, even in cases where they were last published five minutes ago! The <code>msPeriod</code> parameter was given the same value as <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>, i.e. two months.</p> -<h2 id="proof-of-work-with-personal-difficulty">Proof of Work with personal difficulty</h2> -<p>As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human.</p> -<p>This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each “winning” member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. The knowledge of the whole network is not needed.</p> -<p>Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power.</p> -<p>One could say that Duniter uses a PoW that needs very low energy consumption compared to BitCoin : an “ecological” PoW ?</p> -<!-- source : https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ --> -<h3 id="why-do-we-need-proof-of-work">Why do we need Proof of Work ?</h3> -<p>Duniter nodes share a database as part of a p2p environment. The proof of work (PoW) allows machines to synchronize with each other. In Duniter’s case, the blockchain is our database, and acts as a ledger keeping a trace of all transactions, status of the WoT and more. How can we let several machines add data (ie: a transaction) at the same time? In addition, how do we settle on how much time has gone by since the blockchain was last updated? Agreement on time is of the utmost importance as we want to create Universal Dividends on a regular basis, and keep track of membership status, both in human time.</p> -<p>Proof-of-work provides a clever solution to both problems: 1. Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, ensuring the unicity of a block’s creator.</p> -<ol start="2" type="1"> -<li>Solving this challenge takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and Duniter adapts the challenge difficulty to get an <em>average</em> duration corresponding to this block time.</li> -</ol> -<h3 id="only-members-can-mine">Only members can “mine”</h3> -<p>One of Duniter’s major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member’s private key, allowing the algorithm to determine a <em>personalised difficulty</em>.</p> -<p>This personalised difficulty eliminates the rat-race for the most sophisticated and powerful mining equipment. Another benefit is the fact that no “supercomputer” can take control of the blockchain. Lastly, Duniter implements a rotation in forging members thanks to this personalized difficulty.</p> -<p>This lightweight PoW is much less energy-consuming than other PoW cryptocurrencies. Members can mine with anything from a raspberry pi to a privacy-first internet cube.</p> -<h3 id="how-does-it-work">How does it work?</h3> -<h4 id="the-hash-aka-digest">The hash (aka digest)</h4> -<p>Example of a valid hash:</p> -<div class="highlight"> -<pre><code>00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653</code></pre> -</div> -<p>As you can see this hash starts with five zeros which was very hard to achieve and took a lot of <em>work</em> for someone’s computer. Hence the term “proof of work”.</p> -<h4 id="the-common-difficulty">The common difficulty</h4> -<p>A common difficulty is needed to settle on a yardstick for our time reference. Its role is to make sure the blockchain moves forward at a steady pace - one block every <code>avgGenTime</code> seconds, <code>avgGenTime</code> being one of the 20 parameters behind the Duniter protocol-.</p> -<p>This difficulty’s initial value can be set to any arbitrary value (<code>70</code> in Duniter <code>v1.5.x</code>) and then acts as a spring, regulating blocktime creation by increasing itself if the creation interval drops under <code>avgGenTime</code> and vice-versa.</p> -<h5 id="how-is-difficulty-applied">How is difficulty applied?</h5> -<p>The numeric value of difficulty is taken from an array of possible hashes out of all possible hashes. In duniter v1.5.x the hash of a block is its sha256 hexadecimal hash.</p> -<p>To understand the difficulty, we make a euclidiean division of the difficulty by 16.</p> -<p>Here’s an example with a difficulty value of <code>70</code> : 70 // 16 = <strong>4</strong> with a remainder of <strong>6</strong>. The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : <code>0000[0-9]</code>. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes.</p> -<blockquote> -<p>Fine, but the hash of a mined block will never change and there’s no reason it should start with a given sequence of numbers. So how then can we make sure a block hash starts with exactly the sequence needed?</p> -</blockquote> -<p>Enter the nonce, short for “number once”. When a member is forging a new block, his computer freezes the block’s content and changes the Nonce until the hash reaches the required number of zeroes.</p> -<h5 id="the-nonce">The Nonce</h5> -<p>The nonce allows us to mine a new block by finding a hash. The hash value allows us to determine the difficulty level of the proof-of-work performed. Examples of possible Nonce values:</p> -<ul> -<li>10100000112275</li> -<li>10300000288743</li> -<li>10400000008538</li> -<li>10700000079653</li> -<li>10300000070919</li> -</ul> -<p>In reality the <code>Nonce</code> value follows a pre-determined format akin to <code>XYY00000000000</code>. The Nonce’s value isn’t the number of attempts but rather a value within a set of possible ones. This is how the Nonce is built:</p> -<ul> -<li><p>X is a number assigned to a specific peer. Let’s assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with different nodes. Each block will therefore have its own unique X to prevent this from happening.</p></li> -<li><p>Y is the number of cores of the processor. The Nonce starting with <code>107[…]</code> belongs to a seven cores processor, while <code>199[...]</code> could be the proof generated by a 99 cores processor.</p></li> -</ul> -<p>The rest of the Nonce, the part that follows after the XYY, is the numerical space for this individual node and is unique to each of the CPU’s core. This space is comprised of eleven digits (<code>00000000000</code>). For the sake of accuracy, we use the term CPU in the wider sense, it can be understood as a bi-CPU for example. We take into consideration the number of cores for the resulting PoW.</p> -<h3 id="personalised-difficulty">Personalised difficulty</h3> -<p>Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other <em>PoW-based</em> cryptocurrencies such as Bitcoin.</p> -<p>Here is how this personalised difficulty is calculated and assigned:</p> -<p>It is determined by a combination of two different constraints with complimentary roles: the <strong>exclusion factor</strong> and the <strong>handicap</strong>.</p> -<p>Let <code>powMin</code> be the common difficulty, <code>exFact</code> a member’s exclusion factor and <code>handicap</code> their handicap. This member’s personalised difficulty <code>diff</code> is:</p> -<div class="highlight"> -<pre><code>diff = powMin*exFact + handicap</code></pre> -</div> -<h4 id="understanding-exfact-the-exclusion-factor">Understanding <code>exFact</code>, the exclusion factor</h4> -<p>Members who have never produced blocks or haven’t for quite some time are assigned an exclusion factor of <code>1</code>. Their personalised difficulty is therefore simply the sum of <code>powMin + handicap</code>.</p> -<p>Before reading on, let’s precise the role of this exclusion factor. When a member adds a block to the chain, his <code>exFact</code> jumps up from one to a very high value, to prevent them from forging other blocks immediately after and taking control of the blockchain.</p> -<p>The exclusion factor will then rapidly return to one. This delay is expressed as a number of blocks. It is calculated as a proportion of the number of members forging. In the Ğ1’s case, this proportion is 1/3, meaning that if there are fifteen members currently forging, the member’s exclusion factor will drop down to one after five blocks.</p> -<blockquote> -<p>What is intended by “the number of members forging”?</p> -</blockquote> -<p>We mean the number of members trying to create the next block. In reality, there is no way to precisely know how many members are calculating at any given time, because it is impossible to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block in the last X blocks, minus the very last one.</p> -<blockquote> -<p>Hox is X determined?</p> -</blockquote> -<p>We use the concept of <strong>current window</strong>. X’s value is equal to the size of this window. Let’s see how it works:</p> -<ul> -<li><p><code>issuersFrame</code> is the size of the current window in blocks.</p></li> -<li><p><code>issuersCount</code> the number of members who have calculated at least one block during the current window.</p></li> -</ul> -<p>Both <code>issuersFrame</code> and <code>issuersCount</code> are block fields. When first starting a blockchain, the very first block has an <code>issuersFrame=1</code> and an <code>issuersCount=0</code>. The genesis block is excluded as there are no members in the current window!</p> -<p>From the second block onwards (block #1) we track the variation of <code>issuersCount</code>. The member having mined block #0 enters the current window and in block #1 we will therefore mention <code>issuersCount=1</code>.</p> -<p><code>issuersFrame</code> then varies as follows:</p> -<ul> -<li>if <code>issuersCount</code> increases by N (with a maximum step of N = 1), then <code>issuersFrame</code> will increase by one unit over a period of 5N blocks.</li> -<li>Conversely, if <code>issuersCount</code> decreases by Y (with a maximum step of Y = 2 = current window inching forward + loss of one calculating member), then <code>issuersFrame</code> will decrease by one unit during 5Y blocks.</li> -<li>When such events overlap, <code>issuersFrame</code> evolves as so :</li> -</ul> -<table> -<thead> -<tr class="header"> -<th>bloc</th> -<th>event</th> -<th>issuersFrame</th> -</tr> -</thead> -<tbody> -<tr class="odd"> -<td>T</td> -<td>Babar writes a block and enters issuersCount</td> -<td>160</td> -</tr> -<tr class="even"> -<td>T+1</td> -<td>Celeste leaves issuersCount</td> -<td>160 +1 = 161</td> -</tr> -<tr class="odd"> -<td>T+2</td> -<td>N/a</td> -<td>161 +1 -1 = 161</td> -</tr> -<tr class="even"> -<td>T+3/4/5</td> -<td>N/a</td> -<td>161 +1 -1 = 161</td> -</tr> -<tr class="odd"> -<td>T+6</td> -<td>N/a</td> -<td>161 -1 = 160</td> -</tr> -</tbody> -</table> -<p>The calculation can be found under rules <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g05-headissuersframe">BR_G05</a> and <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g06-headissuersframevar">BR_G06</a> of the DUP protocol.</p> -<blockquote> -<p>Let’s go back to the personalised difficulty.</p> -</blockquote> -<p>We explained that <code>exFact</code> spikes immediately after the member has found a block. It decreases then rapidly to <code>1</code> after a number of blocks <code>X = 1/3 * issuersCount</code>. Let’s see precisely how we calculate <code>exFact</code>:</p> -<ul> -<li><p><code>nbPreviousIssuers</code> is the value of issuersCount at the last block <code>N</code> found by the member.</p></li> -<li><p><code>nbBlocksSince</code> is the number of blocks found by the rest of the network since block <code>N</code>.</p></li> -<li><p><code>percentRot</code> is the number of <em>not excluded</em> peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency.</p></li> -</ul> -<div class="highlight"> -<pre><code>exFact = MAX [ 1 ; FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) ]</code></pre> -</div> -<p>The FLOOR is a simple truncate function. For <code>exFact</code> to exclude the member, we need :</p> -<blockquote> -<p>(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2</p> -</blockquote> -<p>We can see that the member is not excluded if <code>nbBlocksSince</code> is greater than 1/3 of the calculating members. Take as an example nbPreviousIssuers = 6 and nbBlocksSince = 3:</p> -<blockquote> -<p>(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1</p> -</blockquote> -<p>However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded: > (0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2</p> -<p>Moreover if the last block was authored by the said member, then: > <code>nbBlocksSince=0</code> and > <code>exFact</code> = <code>0.67 * nbPreviousIssuers</code></p> -<p>ExFact value increases according to the number of members calculating. Thus, if there is enough members calculating, even mining farms would be excluded. We have therefore succeeded in our intent to deter attempts to seize the blockchain and its currency.</p> -<p>However, at any time t, the two-thirds of calculating members all have an exclusion factor of <code>1</code>, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then only the members with the highest computational power from the remaining third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn’t stand a chance…</p> -<h4 id="the-handicap">The handicap</h4> -<p>The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. A higher handicap is assined to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW.</p> -<p>The aim is to handicap the half that has authored most blocks (the most powerful half) to favour the other one. So, the handicap formula will use the median number of blocks authored by peers within the current window.</p> -<ul> -<li><p><code>nbPersonalBlocksInFrame</code> is the number of blocks authored by a single member within the current window.</p></li> -<li><p><code>medianOfBlocksInFrame</code> is the median number of blocks written by the calculating members during the same timeframe.</p></li> -</ul> -<div class="highlight"> -<pre><code>handicap = FLOOR(LN(MAX(1;(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)) / LN(1.189))</code></pre> -</div> -<p>Let’s unwrap the formula: <code>(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)</code> is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored <code>9</code> blocks in the current window and the median is <code>5</code>, then the ratio will be <code>(9+1)/5 = 2</code>. The MAX function allows us to ensure that the handicap has a value at least equal to <code>1</code>.</p> -<p>The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers.</p> -<p>If we want the handicap to be applied as soon as the median is reached, we’d have to divide it by <code>LN(1)</code>, the problem is that we’ve already set a minimum value of <code>1</code> with the MAX function, so if we were to divide the ratio by <code>LN(1)</code> all calculating peers would have a handicap >= <code>1</code>. In addition, is it really fair to handicap a member who’s right on the median?</p> -<p>That’s why we went for <code>1.189</code> rather than <code>1</code>. A member has to be at least <code>18.9%</code> above the median to be assigned a handicap. 18.9% is actually 16^(1/16), the difficulty factor between two levels of the proof work (hexadecimal hash).</p> -<p>To conclude, you have to remember that :</p> -<ul> -<li>the handicap is indexed on the logarithm of the ratio to the median,</li> -<li>handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work’s difficulty.</li> -</ul> -<h2 id="conclusion">Conclusion</h2> -<!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniter’s Blockchain can be compared to Bitcoin’s : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend.</p> -<p>More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers while maintaining a good security on the network.</p> -<p>The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties :</p> -<ul> -<li>The freedom to choose your currency system: because money should not be imposed</li> -<li>The freedom to access resources: because we all should have access to economic & monetary resources</li> -<li>The freedom to estimate and produce value: because value is a purely relative to each individual</li> -<li>The freedom to trade with the money: because we should not be limited by the avaible money supply</li> -</ul> -<p>Those 4 economic freedoms should be understood together, not exclusively. Plus, “freedom” has to be understood as “non-nuisance”. So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency.</p> -<h2 id="duniter-projects-sources">Duniter project’s sources :</h2> -<ul> -<li>Theoretical, by Cgeek: https://duniter.org/en/theoretical/</li> -<li>Lock conditions, by Inso: https://duniter.org/en/transactions-0-2-overview/</li> -<li>Individualised Proof of Work, by Elois: https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/</li> -<li>Deep dive into the Web of Trust, by Elois: https://duniter.org/en/deep-dive-into-the-web-of-trust/</li> -<li>Whitepaper sources: https://git.duniter.org/communication/duniter-whitepaper</li> -</ul> -<h2 id="other-sources">Other sources :</h2> -<ul> -<li>Relative Theory of Money, S.Laborde, 2010: http://en.trm.creationmonetaire.info/</li> -<li>Bitcoin Whitepaper, S.Nakamoto, 2008: https://bitcoin.org/bitcoin.pdf</li> -<li>Circles Whitepaper, A.Milenius, 2018: https://github.com/CirclesUBI/docs/blob/master/Circles.md</li> -<li>The Sibyl Attack, J.R.Douceur: https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</li> -</ul> -<!-- travaux en theorie des graphes pourla TdC --> -</article> -</main> -</body> -</html> -<!--doctype html--> -<html lang='en' > -<head > -<title> -Duniter Whitepaper -</title > -<meta charset='UTF-8' /> -<link - rel='stylesheet' - href='bulma.css' > <link - rel='stylesheet' - href='main.css' > -<script src='js/jquery.js' ></script > -<script src='js/toc.js' ></script > -<script type='javascript' > - if ($) { - $('#whitepaper').tableofcontents({ id: '#toc' }); - } - </script > -</head > -<body> -<main> -<div id="toc"> - -</div> -<article id="whitepaper" class="content"> -<h1 id="duniter-a-libre-currency-blockchain-generator-1">Duniter : A libre currency blockchain generator !</h1> -<h2 id="abstract-todo-1">Abstract (TODO)</h2> -<h2 id="introduction-1">Introduction</h2> -<p>Duniter is a software to create and manage “libre currencies”. Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question :</p> -<blockquote> -<p>How should a currency be created to match the principle of equality between all humans ?</p> -</blockquote> -<p>The results of this demonstration implies a monetary creation :</p> -<ul> -<li>on a regular basis</li> -<li>for each human being</li> -<li>which amount has to be reassessed on fixed intervals according to a fixed formula.</li> -</ul> -<p>Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula :</p> -<blockquote> -<p>UD(t+1) = UD(t) + c² * ( M(t) / N(t) )</p> -</blockquote> -<p>Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin.</p> -<p>The first currency created through Duniter is Ğ1 (say “June”). It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software.</p> -<h2 id="state-of-the-art-bitcoin-case-1">State of the art : Bitcoin case</h2> -<!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniter uses the crypto-currency concept introduced by Bitcoin, which is to use cryptographic tools such as <em>signatures</em> to create digital currencies. Duniter fits this definition, but it has completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects.</p> -<h3 id="monetary-creation-of-bitcoin-a-space-time-asymmetry-1">Monetary creation of Bitcoin : a space-time asymmetry</h3> -<p>Space-time asymmetry refers to the relative access of individuals to newly created money (Relative Theory of Money, S.Laborde, 2010). Concretely, all existing currencies (c. 2015) are both spatially and temporally asymmetrical for their users. Let's take Bitcoin as an example to understand why.</p> -<h4 id="spatial-asymmetry-1">Spatial asymmetry</h4> -<p>When new Bitcoins are created, <em>only some Bitcoin users</em> (the miners) are given new Bitcoins, while everyone else get nothing. <strong>We believe this is the <em>first</em> injustice.</strong> However, some might say:</p> -<blockquote> -<p>"Miners used their <em>electricity and time</em> to get it!"</p> -</blockquote> -<p>... we would answer that this work <em>shouldn't have been rewarded by newly created Bitcoins</em>. New Bitcoins should be distributed to the whole Bitcoin community. Miners should be rewared another way, but not by money issuance. Of course, Bitcoin can't create money through Basic Income since <em>Bitcoin users are not strongly identified</em>, and one might benefit from money creation multiple times if he owned several wallets. Duniter gets rid of this problem completely by identifying its users and giving <em>the same amount of Basic Income to everyone</em>.</p> -<h4 id="temporal-asymmetry-1">Temporal-asymmetry</h4> -<p>Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, how will future joiners get Bitcoins? Just like Euros or Dollars: to get money, they will have to work for the ones who already own it. <strong>We believe this is the <em>second</em> injustice.</strong> Every member of a monetary community should be equal concerning monetary creation, and get the same relative amount of money over time, <em>even if they are a late adopter</em>. Duniter aims to fix this by making the Universal Dividend (a.k.a. <em>UD</em>) <em>grow by the time</em> (S.Laborde, 2010) according to precise rules, thus making members equal toward money issuance on a half-lifespan.</p> -<h4 id="a-solution-1">A solution</h4> -<p>Bitcoin has taught us that <em>it is possible</em> to create a currency system allowing one to both create digital money and to exchange it without a central authority. What we need to change is <em>the way money is issued</em> so we finally have a symmetrical system. We need Bitcoin <em>+ Universal Dividend</em>. But Universal Dividend <em>implies</em> that the community consists of only identified people. This is where the Web of Trust (WoT) comes into place. This concept, introduced by cryptography with the <a href="https://www.wikiwand.com/en/Pretty_Good_Privacy">OpenPGP</a> format, allows us to identify people in a <em>decentralized</em> manner. It works as follows: each person creates <em>a personal identity</em> that is linked to its cyptographic certificate. The identity must be confirmed by others members who use their own cryptographic key. It is that simple: <strong>people choose who is part of the community and who is not, not a central authority.</strong></p> -<blockquote> -<p>Duniter however won't use OpenPGP for its cryptographic features: Elliptic Curves will be used instead for the conciseness of its generated keys and its pratical advantages. Duniter has its own Web of Trust principles, that shall be exposed later.</p> -</blockquote> -<h3 id="proof-of-work-mining-a-power-race-todo-1">Proof-of-Work mining : a power race (TODO)</h3> -<p>In Bitcoin Model, the calculation and incentive principles cause a power race : new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. The goal of Duniter is to make blockchain validation much less energy and hardware consuming while keeping a strong level of security. As a consequence, even low-power hardware can secure Duniter Blockchain, which leads to a better decentralization of forging operations.</p> -<h3 id="other-projects-1">Other projects ?</h3> -<h4 id="what-about-pos-1">What about PoS ?</h4> -<p>When conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead to placing power over the currency in the richests hands : this is contrary to the symmetical principles of Duniter.</p> -<p>Now that PoS is well-tested, one could try to use Duniter’s WoT to create a PoS-like algorithm with equal chances among members. But this is not our aim for now.</p> -<h4 id="what-about-directed-acyclic-graph-1">What about Directed Acyclic Graph ?</h4> -<p>The Circles project uses DAG in a basic income cryptocurrency. However, in this project, one peer cannot know the whole monetary mass and the exact number of other peers. The calculation of Universal Dividend <code>UD = c * M/N</code> seems impossible, since we know neither M nor N.</p> -<h2 id="duniters-blockchain-1">Duniters Blockchain</h2> -<!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniters Blockchain follows the basic principles of Bitcoins. This is essential for synchronization between peers, as to prevent double-spend attacks. However, Duniters Blockchain will store different informations than Bitcoins.</p> -<p>The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no <em>generation transaction</em> exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either:</p> -<ul> -<li>a former transaction (as in Bitcoin)</li> -<li>a Universal Dividend (specific to Duniter).</li> -</ul> -<p>Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactinos are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where “space” are members of the WoT and “time” the basci blockchain units : the blocks. On each point of time, one can determain whick account is legitimate to create the UD, only with a blockchain analysis.</p> -<h3 id="spam-countermeasures-todo-1">Spam countermeasures (TODO)</h3> -<p>An issue of most cryptocurrency projects is to prevent the common ledger from growing too much and require lot of storage and computing power to be usable. In particular, we don’t want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don’t want to do this since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented.</p> -<!-- see : https://forum.duniter.org/t/sans-frais-de-transaction-comment-resister-aux-attaques/3846/25 (implemented ?)--> -<ul> -<li>output minimal de 100*Unitbase / 1 unité -> empêche un attaquant de faire grossir la BC et les index trop vite (DUBP v12)</li> -<li>chaînage maximal des tx</li> -<li>seuils de dépense (implémentés ? en tout et par issuer ?)</li> -</ul> -<h3 id="scaling-1">Scaling</h3> -<p>Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons :</p> -<ul> -<li>Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don’t want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT limits its size to around 16 million members.</li> -<li>Duniter’s aim is to be used to create <em>multiple</em> libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community.</li> -</ul> -<p>However, Duniter has two assets that might be used if the number of users grow.</p> -<h4 id="dynamic-block-size-1">Dynamic block size</h4> -<p>While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks( <em>current window</em> will be described in the PoW part). This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it.</p> -<div class="{highlight}"> -<p>block_size < max(500 ; CEIL(1.10 * (average block size))</p> -</div> -<h4 id="lightning-networks-1">Lightning Networks</h4> -<p>The Lightning Networks allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed.</p> -<h2 id="duniter-web-of-trust-1">Duniter Web of Trust</h2> -<!-- source : https://duniter.org/en/deep-dive-into-the-web-of-trust --> -<h3 id="basic-principles-1">Basic Principles</h3> -<p>In order to identify “members” account - which create monetary units - from other accounts, Duniter uses a Web of Trust. This can be summarized into few principles:</p> -<ul> -<li>Each account becomes a member if it received a minimal number of certifications (5 for Ğ1 currency)</li> -<li>Only members accounts can send certifications. Certifications have a limited lifespan.</li> -<li>A certification indicates that the sender accepts the receiver as a legitimate identity.</li> -</ul> -<p>The aim of the WoT is to identify a blockchain account to a living human. Each member of the Ğ1 currency signs a licence stating that they will only certify humans they know well (among other rules). Thus, if a member is part of an attack on the currency, they can be found by mutual friends. The security of Ğ1 currency stands on:</p> -<ul> -<li>Corroborating informations on members (5 certifications)</li> -<li>Peer pressure by close relatives</li> -<li>Law if the licence has not been respected.</li> -</ul> -<p>Note that non-members accounts can use the currency, but cannot create money. They can be used by individuals as secondary wallets, or by institutions.</p> -<p>However, the WoT does not rely only on trust betwenn people. Rules have been added to increase the security, and we will present them.</p> -<h3 id="why-do-we-need-a-web-of-trust-1">Why do we need a Web of Trust?</h3> -<p>There are two reasons we need it :</p> +<p>We want to make sure that each member can only have one account. As we all know, achieving zero-risk isn’t possible<a href="#fn9" class="footnote-ref" id="fnref9"><sup>9</sup></a>. Our goal is therefore not to create a WoT within which fraud would be absolutely impossible, but instead to discourage it. Here is a rewording of our goal in 4 smaller ones :</p> <ol type="1"> -<li>To make sure that only one Universal Dividend is produced per member at each specified creation interval -in the Ğ1’s case this interval is set as daily <code>86 400</code> seconds-, it is the <em>monetary parameter</em> known as <code>dt</code>-.</li> -<li><p>To identify the nodes hashing the blocks and assign them each a personalised difficulty. This custom difficulty <a href="https://en.wikipedia.org/wiki/Proof-of-work_system">proof of work</a> is there to avoid the blockchain’s validation mechanism becoming too centralised as is the case with many 'non-libre’ cryptocurrencies.</p> -<blockquote> -<p>Wait, what’s a ‘monetary parameter’ ?</p> -</blockquote></li> -</ol> -<p>Every currency implementing Duniter has its own blockchain whose behaviour is dictated by a set of ‘parameters’ -defined in block zero, the so-called genesis block- that can be tweaked to achieve the desired results. At the time of writing this article, the Duniter protocol -aka DUP- has a total of 21 parameters of which 10 are for the WoT alone. We’ll focus on these 10.</p> -<p>Suffice to say that in the Ğ1’s case, the DU is created every 24 hours -86 400 seconds- but this interval -set through the time derivative <code>dt</code> parameter- can have a different value in an other implementation of the protocol.</p> -<p>I won’t write about the second parameter having to do with the proof of work, it’s outside our scope here, just know that the Web of Trust allows us to <strong>identify</strong> the members providing hashing power, which we couldn’t do without it. This crucial feature means we can impose a rotation between the members hashing the blocks so that no single rich individual or group invests in a giant ‘hash farm’ and takes a hold of the blockchain, paralysing the community!</p> -<p>Let’s go back to the first objective: to make sure that each member can only have one account. As we all know, achieving zero-risk isn’t possible, our goal is therefore not to create a WoT within which fraud would be absolutely impossible but instead to discourage it. Here is a rewording of our goal in 4 smaller ones :</p> -<ol type="1"> -<li>To make the certification process lengthy enough that all members exercise due diligence and are wary of risks.</li> -<li>To make fraudulent acts as hard as we can to the extent that they become pointless.</li> -<li>To ensure that any Sybil attacks have a negligible impact on the currency -<em>by ensuring that illegitimate double Universal Dividends have no significant bearing on the legitimate monetary mass</em>-</li> -<li>To slow the growth of ‘Sybil regions’ to give enough time for the community to react and isolate the threat.</li> +<li>Make the certification process lengthy enough that all members exercise due diligence and are wary of risks.</li> +<li>Make fraudulent acts as hard as we can to the extent that they become pointless.</li> +<li>Ensure that any Sybil attacks have a negligible impact on the currency by ensuring that illegitimate double Universal Dividends have no significant bearing on the legitimate monetary mass</li> +<li>Slow the growth of ‘Sybil regions’ to give enough time for the community to react and isolate the threat.</li> </ol> <blockquote> -<p><strong>Wait, a Sybil what ?</strong></p> +<p><strong>Sybil attack</strong> : A Sybil attack is an attack perpetrated on a reputation system through the creation of fake identities. A Web of Trust is a specific instance of a Reputation System.</p> </blockquote> -<p>A <a href="https://en.wikipedia.org/wiki/Sybil_attack"><strong>Sybil attack</strong></a>, is the name given to attacks perpetrated on a reputation system through the creation of fake identities. A Web of Trust is a specific instance of a <a href="https://en.wikipedia.org/wiki/Reputation_system"><strong>Reputation System</strong></a>.</p> <p>There are plenty of Sybil attack scenarios we can think of and just as many reasons why their perpetrators would want to carry them out. Our objective is that the configuration of the WoT protects both users and its IT backbone infrastructure against these attacks.</p> -<p>This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web’s role isn’t to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing your tap water and electricity but isn’t responsible for any burglaries etc. Much in the same way, Duniter’s WoT guarantees us all a functional currency and that’s quite a feat in itself!</p> -<h3 id="the-importance-of-having-our-own-certification-system-1">The importance of having our own certification system</h3> -<p>We are regularly offered to switch over to third-party or state-owned authentication systems but these are centralised and go against the principles of our community. We feel that we would lose our independence and universality by adopting a state-controlled system. People without an official state-provided identity or homeless people would also run the risk of being excluded from the WoT. It is of the utmost importance that we remain free from any state or corporation. To this day we depend only on the Internet and yet, were it to fail, there are already alternatives being tested around the world for a decentralised network.</p> -<h3 id="a-few-foundational-concepts-on-graph-theory-a-bit-of-vocabulary-1">A few foundational concepts on graph theory : a bit of vocabulary</h3> +<p>This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web’s role isn’t to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing your tap water and electricity but isn’t responsible for any burglaries, etc. Much in the same way, Duniter’s WoT guarantees us all a functional currency, but do not detect small fraud.</p> +<h3 id="own-certification-system">3.3. The importance of having our own certification system</h3> +<p>Centralized identification systems can achieve the goal we want. State Identification is an example. However, this has many drawbacks :</p> +<ul> +<li>The authority may have arbitrary criteria for identification, for example preventing people without an official state-provided identity or homeless people to be included in the WoT.</li> +<li>Payment might be required to get identified, thus making the monetary creation not “free”.</li> +<li>The authority is a point of failure for any attacker.</li> +</ul> +<p>It is of the utmost importance that we remain free from any state or corporation. The WoT is an answer to this criterium. To this day we depend only on the Internet and yet, were it to fail, there are already alternatives being tested around the world for a decentralised communication network.</p> +<h3 id="graph-theory-vocabulary">3.4. A few foundational concepts on graph theory : a bit of vocabulary</h3> <ul> <li><p><strong>Graph</strong>: set of points -called ‘vertices’- joined by edges -called paths/walks-.</p></li> -<li><p><strong>Simple graph</strong>: a graph with no loops and with no multiple edges. That is, each edge connects two distinct endpoints and no two edges have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a></p></li> -<li><p><strong>Directed graph</strong>: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a> Arrow A –> B is therefore different from arrow B –> A.</p></li> +<li><p><strong>Simple graph</strong>: a graph with no loops and with no multiple edges. That is, each edge connects two distinct endpoints and no two edges have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise.</p></li> +<li><p><strong>Directed graph</strong>: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. Arrow A –> B is therefore different from arrow B –> A.</p></li> <li><p><strong>Endpoints</strong>: the edge with vertex A –> B has A and B as endpoints, respectively as start and end of the path/walk.</p></li> -<li><p><strong>Isolated vertex</strong>: a vertex whose degree is zero, that is, a vertex with no incident edges. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a></p></li> +<li><p><strong>Isolated vertex</strong>: a vertex whose degree is zero, that is, a vertex with no incident edges.</p></li> <li><p><strong>Degree of a vertex</strong>: number of its incident edges -in and out-.</p></li> <li><p><strong>Out-degree of vertex A</strong>: number of outbound edges / tail ends from A.</p></li> <li><p><strong>In-degree of vertex A</strong>: number of incoming edges / head ends to A.</p></li> </ul> <figure> -<img src="https://duniter.org/en/images/wiki/degrees.jpg" alt="degress of a vertex diagram" /><figcaption>degress of a vertex diagram</figcaption> +<img src="./images/degres.jpg" alt="degrees of a vertex diagram" /><figcaption>degrees of a vertex diagram</figcaption> </figure> <ul> <li><strong>Path</strong>: -aka “walk”- path to follow to get from vertex A to vertex B.</li> </ul> -<h3 id="definition-of-the-duniter-web-of-trust-1">Definition of the Duniter Web of Trust</h3> +<h3 id="definition-of-the-duniter-web-of-trust">3.5. Definition of the Duniter Web of Trust</h3> <p>The Duniter WoTs -one per currency- are simple directed graphs without isolated vertices. The vertices are the members and the edges are the certifications given and received.</p> -<p>Directed, what does that mean?</p> -<p>The responsibility of issuing a certification is unique and personal to the certifier. The trust he/she places in the receiver cannot be imposed in the other direction although in most circumstances both parties equally trust each other.</p> -<p>In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific ‘deactivated state’ and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered ‘pending’ to avoid the web collapsing like a house of cards.</p> -<p>If these old members don’t come back into the web, their pending certifications will eventually expire and they will switch from ‘deactivated’ to ‘isolated’ vertices.</p> -<p>To wrap up with old members, after a certain period of time -set in the currency’s parameters - their deactivated vertex is removed from the web and the associated identity is ‘revoked’. The person who owned the account can no longer use this identity but is free to join the web with another one. :-)</p> +<p><em>Directed</em> means that the responsibility of issuing a certification is unique and personal to the certifier. The trust they place in the receiver cannot be imposed in the other direction although in most circumstances both parties equally trust each other.</p> +<p>In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific ‘deactivated state’ and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered ‘pending’ to avoid a collapse of the WoT. If these old members don’t come back into the WoT, their pending certifications will eventually expire and they will switch from ‘deactivated’ to ‘isolated’ vertices.</p> +<p>To wrap up with old members, after a certain period of time - set in the currency’s parameters - their deactivated vertex is removed from the web and the associated identity is ‘revoked’. The person who owned the account can no longer use this identity but is free to join the web with another one.</p> <blockquote> -<p>What do you mean by ‘identity’?</p> -</blockquote> -<p>An identity is a set of three pieces of information: a public key, a name and a blockstamp. A blockstamp points to a specific block in the chain. Its main use is to freeze the point in time at which an identity was created and to link this identity to a specific chain and of course, a currency -each currency having its own blockchain-.</p> +<p><strong>Identity</strong> : An identity is a set of three pieces of information: a public key, a name and a blockstamp. A blockstamp points to a specific block in the chain. Its main use is to freeze the point in time at which an identity was created and to link this identity to a specific chain and a currency - each currency having its own blockchain.</p> <p>An identity can be in any one of 5 different status: pending, member, old member, revoked or excluded.</p> +</blockquote> <p>Let’s take a simple example:</p> -<div class="highlight"> -<pre><code>A -> B -> C - | - \--> D</code></pre> -</div> +<pre><code> A -> B -> C + | + \--> D</code></pre> <p>If, for whatever reason, A were to lose its member status, the web would crumble and all other members would be excluded as a consequence. To avoid this, the certification from A –> B will remain valid until its expiry date, leaving enough time for B to receive certifications from C or D.</p> -<p>Because our WoT doesn’t have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications it has received -in the same block-. This calls for a temporary ‘buffer’ storage space for <strong>pending</strong> identities and the certifications they’ve received. This storage space is called ‘the pool’ -of Duniter nodes- which we could also have called the ‘sandbox’ as that’s the name used in Duniter’s code. I might add that these ‘pools’ also include other documents and metadata not mentioned here.</p> -<h3 id="exploring-the-rules-behind-a-duniter-web-of-trust-1">Exploring the rules behind a Duniter Web of Trust</h3> -<p>The Duniter WoTs -one per currency- work with a set of eight fundamental rules, themselves enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - <code>msPeriod</code>- having being hard-coded in the Ğ1’s code subsequently.</p> -<h4 id="distance-rule-and-referent-members-stepmax-and-xpercent-1distance-rule-and-referent-members-stepmax-and-xpercent-1">1.Distance rule and referent members (<code>stepMax</code> and <code>xPercent</code>) {#1distance-rule-and-referent-members-stepmax-and-xpercent}</h4> +<p>Because our WoT doesn’t have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications it has received, all in the same block. This calls for a temporary ‘buffer’ storage space for <strong>pending</strong> identities and the certifications they have received. This storage space is called ‘the pool’ of Duniter nodes, which we could also have called the ‘sandbox’ as that’s the name used in Duniter’s code. Duniter nodes inclued other ‘pools’ for other documents and metadata not mentioned here.</p> +<h3 id="exploring-the-rules-behind-duniter-wot">3.6. Exploring the rules behind a Duniter Web of Trust</h3> +<p>The Duniter WoTs - one per currency - works with a set of eight fundamental rules enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - <code>msPeriod</code>- having being hard-coded in the Ğ1’s code subsequently.</p> +<h4 id="distance-rule-and-referent-members-stepmax-and-xpercent">3.6.1. Distance rule and referent members (<code>stepMax</code> and <code>xPercent</code>)</h4> <p>These two parameters are closely linked and together define the ‘distance rule’. The ‘distance rule’ can only be described after defining what a ‘referent member’ is:</p> <blockquote> -<p><strong>Referent member</strong>: member A is said to be ‘referent’ if and only if the total of his/her degrees are greater than or equal to <code>CEIl-N^-1/stepMax--</code> where N is the total number of members.** As the size of the web will grow this number will grow too, meaning it will take more certification issuances to become a referent member as the number of certifications needed to become a member shouldn’t change.</p> +<p><strong>Referent member</strong>: member A is said to be ‘referent’ if and only if the total of their degrees are greater than or equal to <code>CEIL-N^-1/stepMax</code> where N is the total number of members. As the size of the web will grow this number will grow too, meaning it will take more certification issuances to become a referent member. The number of certifications needed to become a member shouldn’t change.</p> </blockquote> <p>Let’s now define the distance rule:</p> <blockquote> -<p><strong>Distance rule</strong>: member A is said to observe this rule if and only if for a subset xPercent % of referent members R there exists a path of length less than or equal to <code>stepMax</code> between R and A.**</p> -</blockquote> -<p>Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect web, that is one in which each member has certified all members he/she legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time <code>t</code> who haven’t yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would effectively stop growing. -You can see what would happen if the notion of ‘referent member’ didn’t exist by going to the ‘gaussianWotQuality’ page on <a href="https://g1-monit.librelois.fr/gaussianWotQuality?lg=en&unit=quality">currency-monit</a> and activating ‘if the concept of referent members didn’t exist’-.</p> -<blockquote> -<p><strong>When is the distance rule applied?</strong></p> +<p><strong>Distance rule</strong>: member A is said to observe this rule if and only if for a subset xPercent % of referent members R there exists a path of length less than or equal to <code>stepMax</code> between R and A.</p> </blockquote> -<p>Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets confirmed into the web or an existing member gets renewed. <em>Exception to the rule: the distance rule is not observed in the genesis block -when the web is first implemented-.</em></p> -<h4 id="rule-of-the-minimum-number-of-certifications-needed-sigqty-2-rule-of-the-minimum-number-of-certifications-needed-sigqty-1">2. Rule of the minimum number of certifications needed (<code>sigQty</code>) {#2-rule-of-the-minimum-number-of-certifications-needed-sigqty}</h4> -<p>This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least <code>sigQty</code> active certifications. If, for whatever reason, member A were to have less than <code>sigQty</code> active certifications in a given block, he/she would cease being a member and be required to publish a request for identity renewal.</p> -<h4 id="the-membership-renewal-rule-msvalidity-msperiod-and-mswindow-3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow-1">3. The membership renewal rule (<code>msValidity</code>, <code>msPeriod</code> and <code>msWindow</code>) {#3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow}</h4> +<p>Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect web, that is one in which each member has certified all members they legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time <code>t</code> who haven’t yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would effectively stop growing.</p> +<p>Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets confirmed into the web or an existing member gets renewed. There is an exception to this rule: the distance rule is not observed in the genesis block -when the web is first implemented.</p> +<h4 id="rule-of-the-minimum-number-of-certifications-needed-sigqty">3.6.2. Rule of the minimum number of certifications needed (<code>sigQty</code>)</h4> +<p>This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least <code>sigQty</code> active certifications. If, for whatever reason, member A were to have less than <code>sigQty</code> active certifications in a given block, they would cease to be a member and be required to publish a request for identity renewal.</p> +<h4 id="the-membership-renewal-rule-msvalidity-msperiod-and-mswindow">3.6.3. The membership renewal rule (<code>msValidity</code>, <code>msPeriod</code> and <code>msWindow</code>)</h4> <p>Bear in mind that a membership doesn’t last a lifetime but instead has a lifespan set to <code>msValidity</code> seconds.</p> -<p>Every single member -or old member who hasn’t revoked his identity or been excluded- can request a membership renewal so long as the last request was made more than <code>msPeriod</code> seconds ago -if a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the ‘pool’ for a maximum of <code>msWindow</code> seconds before it’s included in the blockchain. Once again, this can only happen once/if the member meets both the <code>siqQty</code> rule and the distance rule -if these criterion are already matched it’s just a case of waiting for a new block to be mined-.</p> -<p>If a member hasn’t requested a renewal for longer than <code>msValidity</code> seconds, he/she automatically ceases being a member. From this moment on, the ex-member has another <code>msValidity</code> window to renew his/her membership. When this period of `2 × msValidity’ runs out, the membership will expire and this identity will never be available for use again in the web. If the person so desires, he/she will have to start from zero to regain access to the WoT.</p> -<h4 id="rule-of-certification-lifespan-sigvalidity-4-rule-of-certification-lifespan-sigvalidity-1">4. Rule of certification lifespan (<code>sigValidity</code>) {#4-rule-of-certification-lifespan-sigvalidity}</h4> +<p>Every single member -or old member who hasn’t revoked his identity or been excluded- can request a membership renewal so long as the last request was made more than <code>msPeriod</code> seconds ago. If a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the ‘pool’ for a maximum of <code>msWindow</code> seconds before it’s included in the blockchain. Once again, this can only happen once/if the member meets both the <code>siqQty</code> rule and the distance rule -if these criterion are already matched it’s just a case of waiting for a new block to be mined-.</p> +<p>If a member hasn’t requested a renewal for longer than <code>msValidity</code> seconds, they automatically cease to be a member. From this moment on, the ex-member has another <code>msValidity</code> window to renew their membership. When this period of <code>2 × msValidity</code> runs out, the membership will expire and this identity will never be available for use again in the web. If the person so desires, they will have to publish new identity and membership documents and find enough certifiers, as any newcomer.</p> +<h4 id="rule-of-certification-lifespan-sigvalidity">3.6.4. Rule of certification lifespan (<code>sigValidity</code>)</h4> <p>All certifications included in the blockchain expire <strong>sigValidity</strong> seconds after they were <strong>issued</strong>.</p> +<blockquote> <p>/!\ The issuance and the inclusion of a certification in the blockchain occur at different times. When member A issues a certification at time t1, it gets stored in the pool starting at t1 and only finds its way into the blockchain at t2 when all of the web’s rules are observed. Several weeks can thus go by between t1 and t2!!!</p> -<h4 id="rule-of-limited-supply-of-active-certifications-sigstock-5-rule-of-limited-supply-of-active-certifications-sigstock-1">5. Rule of limited supply of active certifications (<code>sigStock</code>) {#5-rule-of-limited-supply-of-active-certifications-sigstock}</h4> +</blockquote> +<h4 id="rule-of-limited-supply-of-active-certifications-sigstock">3.6.5. Rule of limited supply of active certifications (<code>sigStock</code>)</h4> <p>By ‘active certifications’ we refer to certifications included in the blockchain and that haven’t yet expired.</p> <p>The total of active certifications issued by any member at any single time must be less than or equal to <code>sigStock</code>. When this threshold is reached the member will have to wait for one of his active certifications to expire before he/she can issue a new one.</p> -<h4 id="rule-of-the-time-period-between-two-certification-issuances.-sigperiod-6-rule-of-the-time-period-between-two-certification-issuances-sigperiod-1">6. Rule of the time period between two certification issuances. (<code>sigPeriod</code>) {#6-rule-of-the-time-period-between-two-certification-issuances-sigperiod}</h4> -<p>As soon as a certification issued by member A gets included in the blockchain, he/she will be unable to issue a new one before another <code>sigPeriod</code> seconds.</p> -<h4 id="expiry-of-a-certification-issuance-sigwindow-7-expiry-of-a-certification-issuance-sigwindow-1">7. Expiry of a certification issuance (<code>sigWindow</code>) {#7-expiry-of-a-certification-issuance-sigwindow}</h4> +<h4 id="rule-of-the-time-period-between-two-certification-issuances-sigperiod">3.6.6. Rule of the time period between two certification issuances. (<code>sigPeriod</code>)</h4> +<p>As soon as a certification issued by member A gets included in the blockchain, they will be unable to issue a new one before another <code>sigPeriod</code> seconds.</p> +<h4 id="expiry-of-a-certification-issuance-sigwindow">3.6.7. Expiry of a certification issuance (<code>sigWindow</code>)</h4> <p>When a certification is issued by member A, it will be stored in the ‘pool’ for a maximum of <code>sigWindow</code> seconds. If the certification hasn’t been included in the blockchain by then, it will be cancelled and the member’s <code>sigStock</code> will be repleted by one.</p> -<h4 id="lifespan-of-a-pending-active-certification-idtywindow-8-lifespan-of-a-pending-active-certification-idtywindow-1">8. Lifespan of a ‘pending’ active certification (<code>idtyWindow</code>) {#8-lifespan-of-a-pending-active-certification-idtywindow}</h4> +<h4 id="lifespan-of-a-pending-identity-idtywindow">3.6.8. Lifespan of a ‘pending’ identity (<code>idtyWindow</code>)</h4> <p>When a new identity is created, it is stored in the ‘pool’ for a maximum of <code>idtyWindow</code> seconds. If the person hasn’t achieved member status by then, the certification will simply be cancelled.</p> -<h3 id="details-on-some-of-the-wots-peculiarities-at-the-genesis-block">Details on some of the WoT’s peculiarities at the genesis block.</h3> +<h3 id="details-on-some-of-the-wots-peculiarities-at-the-genesis-block">3.7. Details on some of the WoT’s peculiarities at the genesis block</h3> <p>The aforementioned rules can only be enforced with an existing web. They cannot be observed when first creating the web, that is when defining the genesis block.</p> <p>Only rules 2 and 5 can be observed at the genesis block.</p> -<p>The genesis block has to be manually created by the founding members. In practice this means that there must be a choice of which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities.</p> -<p>As soon as the genesis block has been created, the other identities can start mining the blockchain and the member who begat block #0 effectively looses the decision power he had at creation.</p> -<h3 id="why-these-rules-and-application-cases-in-the-g1">Why these rules and application cases in the Ğ1</h3> -<h4 id="distance-and-maximum-size-1-distance-and-maximum-size-1">1. Distance and maximum size {#1-distance-and-maximum-size}</h4> +<p>The genesis block has to be manually created by the founding members. In practice this means that there must be a choice on which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities.</p> +<p>As soon as the genesis block has been created, the other identities can start mining the blockchain and the member who created block #0 effectively looses the decision power he had at creation.</p> +<h3 id="why-these-rules-and-application-cases-in-the-g1">3.8. Why these rules and application cases in the Ğ1</h3> +<h4 id="distance-and-maximum-size">3.8.1. Distance and maximum size</h4> <p>The distance rule is there to curb the maximum size of a Sybil region as well as that of the monetary community as a whole. The <code>xpercent</code> parameter prevents the creation of a ‘faction’ that could take hold of the blockchain.</p> <figure> -<img src="https://duniter.org/en/images/wiki/wot-sybil.jpg" alt="Sybil region" /><figcaption>Sybil region</figcaption> +<img src="./images/wot-sybil.jpg" alt="Sybil region" /><figcaption>Sybil region</figcaption> </figure> -<p>The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned Sybil members. As a consequence, the shortest edge/path between a legitimate member and a Sybil one has to have the attack’s author as an endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as <code>stepAttackers</code>. The maximum size of a Sybil region created by <code>sigQty</code> members depends on the L parameter, defined as L = sigQty/sigStock:</p> -<div class="highlight"> -<pre><code>Maximum Sybil region size = (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L)</code></pre> -</div> +<p>The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned Sybil members. As a consequence, the shortest edge/path between a legitimate member and a Sybil one has to have the attack’s author as an endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as <code>stepAttackers</code>. The maximum size of a Sybil region created by <code>sigQty</code> members depends on the L parameter, defined as <code>L = sigQty/sigStock</code>:</p> +<pre><code>MaxSybilSize= (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L)</code></pre> <p>The maximum size of the Web of Trust is given by the following formula:</p> -<div class="highlight"> <pre><code>WoTmax = (sigStock)*L^(stepMax-1)</code></pre> -</div> -<p>However we know for a fact that members will never use all of their available certifications. Many studies have proven that we all know a maximum average of fifty people, let’s then replace sigStock by fifty:</p> -<div class="highlight"> +<p>However we know for a fact that members will never use all of their available certifications. According to Dunbar<a href="#fn10" class="footnote-ref" id="fnref10"><sup>10</sup></a>, on average, one is able to maintain relationships to around 150 people. Being conservative, we will consider that on average, each person will certify 50 accounts. We can calculate the size of the average web of trust <code>WoTavg</code> :</p> <pre><code>WoTavg= (50)*(sigQty/50)^(stepMax-1)</code></pre> -</div> -<p>Our goal with the Ğ1 is to create a community of about one million members enjoying the world’s first true <a href="https://en.wikipedia.org/wiki/Catallaxy">catallaxy</a> -free economy with a spontaneous order of things-. Let’s see how we can tweak the pair of sigQty and stepMax- to reach this size:</p> +<p>Our goal with the Ğ1 is to create a community of about one million members to test the consequences of a libre monetary system. Let’s see how we can tweak the pair of sigQty and stepMax- to reach this size:</p> <figure> -<img src="https://duniter.org/en/images/wiki/graph-WoTmoy.png" alt="graphe WoTmoy en fonction de sigQty et stepMax" /><figcaption>graphe WoTmoy en fonction de sigQty et stepMax</figcaption> +<img src="./images/wot-moy.png" alt="Average WoT size graph as a function of sigQty and stepMax" /><figcaption>Average WoT size graph as a function of sigQty and stepMax</figcaption> </figure> <p>The maximum size of a Sybil region grows linearly with <code>sigQty</code> but exponentially with <code>stepMax</code>. Logic has it that we need to keep <code>stepMax</code> as low as possible to ensure sufficient strength to the web. The above graph shows that the lowest value of <code>stepMax</code> for a web of a million members is of 5. This is an order of magnitude and is likely to be much higher in reality, we cannot measure it for sure.</p> <p>For <code>sigQty</code> we can choose a value of <strong>4</strong> for a web of <strong>1.5 million members</strong> or <strong>5</strong> for <strong>half a million members</strong>. Bear in mind these are gross figures and could be significantly higher, we are talking anywhere between 1 and 10 million in reality. Calculating WOTavg gives us a pretty good idea of how the web would scale bearing in mind that it considers all members are referent members too -which isn’t the case as explained previously-. Hence the maximum size of the web is likely larger, a ballpark figure of half a million is enough for now especially knowing that the smaller <code>sigQty</code> is, the easier it is to launch a Sybil attack -it’s easier to find four accomplices than five-. For security reasons we have settled on five:</p> -<p>stepMax = 5 sigQty = 5 sigStock >= 50</p> -<p>The maximum size of a Sybil region therefore is: <code>(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))</code></p> -<p>with sigStock = 50 we have a Sybil region of: <code>45*(1-10^(5-stepAttackers))/(-9)</code></p> +<pre><code>stepMax = 5 +sigQty = 5 +sigStock \>= 50</code></pre> +<p>The maximum size of a Sybil region therefore is:</p> +<pre><code>(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))</code></pre> +<p>with sigStock = 50 we have a Sybil region of:</p> +<pre><code>45*(1-10^(5-stepAttackers))/(-9)</code></pre> <p>A good practice for protecting the web is to maximise <code>stepAttackers</code>. That’s why we decided that referent members in the genesis block had to be at least four steps away from each other.</p> <p>Another way to keep a Sybil attack at bay, were it slow enough for members to notice it, would be for referent members to ‘stretch’ the web intentionally to limit the growth of the region by ensuring that the attackers’ legitimate certifications received in the first place aren’t renewed. But what if bot accounts were created and certified each other super fast and following all rules, how would we counter that? By introducing a minimum length of time between two certifications!</p> -<h4 id="time-is-our-friend-2-time-is-our-friend-1">2. Time is our friend {#2-time-is-our-friend}</h4> +<h4 id="time-is-our-friend">3.8.2. Time is our friend</h4> <p>To help us deter a Sybil attack, we’ve decided to impose a minimum period of time between any two certifications issued from a single account. This parameter called <code>sigPeriod</code> affords us a greater chance to detect the formation of a ‘hostile’ faction.</p> -<p>Here is a graph showing the evolution of a Sybil region with the variation of <code>sigPeriod</code>:</p> +<p>Here is a graph showing the evolution of a Sybil region with the variation of <code>sigPeriod</code>. The simulation considers that honest members and attackers both issue a certification each <code>sigPeriod</code> interval, in days:</p> <figure> -<img src="https://duniter.org/en/images/wiki/impact_sig_period.png" alt="graph of the WoT's size according to sigPeriod and stepAttackers" /><figcaption>graph of the WoT's size according to sigPeriod and stepAttackers</figcaption> +<img src="./images/impact_sig_period.png" alt="size of the WoT according to sigPeriod and stepAttackers" /><figcaption>size of the WoT according to sigPeriod and stepAttackers</figcaption> </figure> -<p>As you’ll easily be able to tell, there is a strong link between the growth speed of the region and <code>sigPeriod</code>. As evidenced here, we need a <code>sigPeriod</code> high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher <code>sigPeriod</code> is, the more members will exercise their certification power gingerly, the action coming at a higher ‘cost’.</p> +<p>As we see, there is a strong link between the growth speed of the region and <code>sigPeriod</code>. As evidenced here, we need a <code>sigPeriod</code> high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher <code>sigPeriod</code> is, the more members will exercise their certification power gingerly, the action coming at a higher ‘cost’.</p> <p>There are numerous advantages to giving <code>sigPeriod</code> a high value and no technical barriers to it, hence our choice of five days.</p> -<p>We could have also gone for days days -one week- for the sake of simplicity however there was an underlying idea behind our choice which was quite simply the pace of today’s life. Certifying someone can be a lengthy process as one needs to make sure he/she is correctly applying the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea to allow one to certify at the end of every working week -five days- instead of a whole calendar one.</p> -<h4 id="trust-me-now-trust-me-forever-sigvalidity-msvalidity-3-trust-me-now-trust-me-forever-sigvalidity-msvalidity-1">3. Trust me now, trust me forever? (<code>sigValidity</code>, <code>msValidity</code>) {#3-trust-me-now-trust-me-forever-sigvalidity-msvalidity}</h4> +<p>We could have also gone for one week for the sake of simplicity. However there is an underlying idea behind our choice which was quite simply the pace of today’s life. Certifying someone can be a lengthy process as one needs to make sure they are correctly applying the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea to allow one to certify at the end of every working week -five days- instead of a whole calendar one.</p> +<h4 id="trust-me-now-trust-me-forever-sigvalidity-msvalidity">3.8.3. Trust me now, trust me forever ? (<code>sigValidity</code>, <code>msValidity</code>)</h4> <p>There would be two main drawbacks to a lifetime membership in the Ğ1’s Web of Trust:</p> -<blockquote> -<p>First of all we need to take into account that some members will pass and those accounts should no longer produce the Universal Dividend. Secondly it is of the utmost importance that ‘rogue’ accounts can be excluded from the web at some point.</p> -</blockquote> -<p>To achieve this, certifications have a limited lifetime and members need to seek renewal from their peers after <code>sigValidity</code> time. On the other hand, this time can’t be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, a certification with too short a lifetime would foster careless certifying behaviours. The act of certifying must have a ‘perceived’ cost high-enough to make it feel like an important act. Lastly, we also wanted this lifetime to be easy enough to remember. Historically speaking, we first settled on the values of <code>sigPeriod</code> and <code>sigStock</code>, meant one could issue all of his/her certifications in 495 days, one year was therefore not long enough. We deemed three years to bee much and that’s how we agreed on two years in the end.</p> -<p>Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we needed to address. We choose a value of one year for <strong>msValidity</strong>. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to ‘prune’ the web of past or inactive members who don’t renew their membership.</p> -<h4 id="keeping-the-pools-free-of-information-glut--idtywindow-sigwindow-mswindow-4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow-1">4. Keeping the pools free of information glut -(<code>idtyWindow</code>, <code>sigWindow</code>, <code>msWindow</code>) {#4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow}</h4> +<ul> +<li>First of all, some members will pass and those accounts should no longer produce the Universal Dividend.</li> +<li>Secondly it is of the utmost importance that ‘rogue’ accounts can be excluded from the web at some point.</li> +</ul> +<p>To achieve this, certifications have a limited lifespan. Members need to seek renewal from their peers after <code>sigValidity</code> time. On the other hand, this time can’t be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, a certification with too short a lifespan would foster careless certifying behaviours. The act of certifying must have a high-enough ‘perceived’ cost to make it feel like an important act. Lastly, we also wanted this lifespan to be easy to remember. Historically speaking, we first settled on the values of <code>sigPeriod</code> and <code>sigStock</code>, meant one could issue all of their certifications in 495 days, one year was therefore not long enough. We deemed three years to be too much and that’s how we agreed on two years in the end.</p> +<p>Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we needed to address. We chose a value of one year for <strong>msValidity</strong>. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to ‘prune’ the web of past or inactive members who don’t renew their membership.</p> +<h4 id="keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow">3.8.4. Keeping the pools free of information glut (<code>idtyWindow</code>, <code>sigWindow</code>, <code>msWindow</code>)</h4> <p>The pools need to be cleaned up on a regular basis to avoid them clogging up with information and to ensure that machines with less calculating power can still run a Duniter node.</p> <p>To achieve this, identities with pending membership approval and the corresponding certifications have to remain the shortest time possible in the pool while still having a chance of making it into the blockchain.</p> <p>For the Ğ1, our opinion was that two months would be enough for all potential certifiers to agree on a specific identity to certify. We also wanted a time period that would be easy enough to remember by all. We settled on two months, and gave this value to all three parameters <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>.</p> -<h4 id="avoiding-single-members-from-knowing-too-many-people-sigstock-5-avoiding-single-members-from-knowing-too-many-people-sigstock-1">5. Avoiding single members from ‘knowing too many people’ (<code>sigStock</code>) {#5-avoiding-single-members-from-knowing-too-many-people-sigstock}</h4> -<p>Many sociology studies have shown that we all know an average of fifty people. This of course is an average, some of us know more than fifty people, others much less. Once again we went for a number that would be easy to remember. Although <code>sigStock</code>’s impact on the size of a Sybil region is fairly limited, its value nonetheless has to be kept reasonable. We settled on hundred.</p> -<h4 id="avoiding-locking-minorities-xpercent-6-avoiding-locking-minorities-xpercent-1">6. Avoiding locking minorities (<code>xpercent</code>) {#6-avoiding-locking-minorities-xpercent}</h4> +<h4 id="avoiding-single-members-from-knowing-too-many-people-sigstock">3.8.5. Avoiding single members from ‘knowing too many people’ (<code>sigStock</code>)</h4> +<p>We considered that on average, each person will certify 50 people. However, we know for a fact that some members will use more than 50 certifications. The maximum social network of one individual is around 150 people<a href="#fn11" class="footnote-ref" id="fnref11"><sup>11</sup></a>. Being conservative, we settled on a maximum certification number <code>sigstock</code> of 100. Since <code>sigStock</code>’s impact on the size of a Sybil region is fairly limited, we did not investigate further this parameter.</p> +<h4 id="avoiding-locking-minorities-xpercent">3.8.6. Avoiding locking minorities (<code>xpercent</code>)</h4> <p>It’s easy enough to become a referent member, one of the Sybil strategies could therefore be to create a region of referent members. Such a region would grow slower than otherwise but could confer a locking power to its members by using the distance rule. That’s why the distance rule cannot be calculated on 100% of the referent members. Hence the introduction of the <code>xpercent</code> parameter which defines the percentage of referent members needing to be less than five edges -steps- from each other.</p> -<p>This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance rule. The <code>xpercent</code> parameter was one of the hardest to define, we therefore reserve ourselves the right of modifying its value during the Ğ1 experiment.</p> -<p>We were inspired by the <a href="https://en.wikipedia.org/wiki/Pareto_principle">Pareto principle</a>: if at least 20% of members give good density to the web, 80% of the referent members will be five or less steps from any other member -referent or non-. The maximum value for <code>xpercent</code> is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%.</p> -<h4 id="spam-protection-with-msperiod-7-spam-protection-with-msperiod-1">7. Spam protection with (<code>msPeriod</code>) {#7-spam-protection-with-msperiod}</h4> +<p>This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance rule. The <code>xpercent</code> parameter was one of the hardest to define, therefore we might decide to change its value during the Ğ1 experiment.</p> +<p>We were inspired by the Pareto principle<a href="#fn12" class="footnote-ref" id="fnref12"><sup>12</sup></a>: if at least 20% of members give good density to the web, 80% of the referent members will be five or less steps from any other member -referent or not-. The maximum value for <code>xpercent</code> is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%.</p> +<h4 id="spam-protection-with-msperiod">3.8.7. Spam protection with (<code>msPeriod</code>)</h4> <p>This parameter stands out a bit on its own, as it was added after the genesis block. It is there to protect the Duniter P2P infrastructure against ‘spam’ attacks. We had to think of a strategy against attacks such as high-frequency membership renewal requests -i.e: in every block, every five minutes- or worse still, hundreds of these requests per minute to flood the Duniter nodes. Without such limits, nodes are supposed to address all renewal requests, even in cases where they were last published five minutes ago! The <code>msPeriod</code> parameter was given the same value as <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>, i.e. two months.</p> -<h2 id="proof-of-work-with-personal-difficulty-1">Proof of Work with personal difficulty</h2> +<h2 id="proof-of-work-with-personalized-difficulty">4. Proof of Work with personal difficulty</h2> <p>As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human.</p> -<p>This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each “winning” member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. The knowledge of the whole network is not needed.</p> +<p>This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each “winning” member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. A view of the whole network is not needed.</p> <p>Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power.</p> <p>One could say that Duniter uses a PoW that needs very low energy consumption compared to BitCoin : an “ecological” PoW ?</p> <!-- source : https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ --> -<h3 id="why-do-we-need-proof-of-work-1">Why do we need Proof of Work ?</h3> +<h3 id="why-proof-of-work">4.1. Why do we need Proof of Work ?</h3> <p>Duniter nodes share a database as part of a p2p environment. The proof of work (PoW) allows machines to synchronize with each other. In Duniter’s case, the blockchain is our database, and acts as a ledger keeping a trace of all transactions, status of the WoT and more. How can we let several machines add data (ie: a transaction) at the same time? In addition, how do we settle on how much time has gone by since the blockchain was last updated? Agreement on time is of the utmost importance as we want to create Universal Dividends on a regular basis, and keep track of membership status, both in human time.</p> -<p>Proof-of-work provides a clever solution to both problems: 1. Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, ensuring the unicity of a block’s creator.</p> -<ol start="2" type="1"> -<li>Solving this challenge takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and Duniter adapts the challenge difficulty to get an <em>average</em> duration corresponding to this block time.</li> +<p>Proof-of-work provides a clever solution to both problems:</p> +<ol type="1"> +<li><p>Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, ensuring the unicity of a block’s creator.</p></li> +<li><p>Solving this challenge takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and Duniter adapts the challenge difficulty to get an average duration corresponding to this block time.</p></li> </ol> -<h3 id="only-members-can-mine-1">Only members can “mine”</h3> -<p>One of Duniter’s major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member’s private key, allowing the algorithm to determine a <em>personalised difficulty</em>.</p> +<h3 id="only-members-can-mine">4.2. Only members can “mine”</h3> +<p>One of Duniter’s major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member’s private key, allowing the algorithm to determine a personalised difficulty.</p> <p>This personalised difficulty eliminates the rat-race for the most sophisticated and powerful mining equipment. Another benefit is the fact that no “supercomputer” can take control of the blockchain. Lastly, Duniter implements a rotation in forging members thanks to this personalized difficulty.</p> <p>This lightweight PoW is much less energy-consuming than other PoW cryptocurrencies. Members can mine with anything from a raspberry pi to a privacy-first internet cube.</p> -<h3 id="how-does-it-work-1">How does it work?</h3> -<h4 id="the-hash-aka-digest-1">The hash (aka digest)</h4> +<h3 id="how-does-duniter-pow-work">4.3. How does it work ?</h3> +<h4 id="the-hash">4.3.1. The hash (aka digest)</h4> <p>Example of a valid hash:</p> -<div class="highlight"> <pre><code>00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653</code></pre> -</div> -<p>As you can see this hash starts with five zeros which was very hard to achieve and took a lot of <em>work</em> for someone’s computer. Hence the term “proof of work”.</p> -<h4 id="the-common-difficulty-1">The common difficulty</h4> +<p>As you can see this hash starts with five zeros which was very hard to achieve and took a lot of work for someone’s computer. Hence the term “proof of work”.</p> +<h4 id="common-difficulty">4.3.2. The common difficulty</h4> <p>A common difficulty is needed to settle on a yardstick for our time reference. Its role is to make sure the blockchain moves forward at a steady pace - one block every <code>avgGenTime</code> seconds, <code>avgGenTime</code> being one of the 20 parameters behind the Duniter protocol-.</p> <p>This difficulty’s initial value can be set to any arbitrary value (<code>70</code> in Duniter <code>v1.5.x</code>) and then acts as a spring, regulating blocktime creation by increasing itself if the creation interval drops under <code>avgGenTime</code> and vice-versa.</p> -<h5 id="how-is-difficulty-applied-1">How is difficulty applied?</h5> -<p>The numeric value of difficulty is taken from an array of possible hashes out of all possible hashes. In duniter v1.5.x the hash of a block is its sha256 hexadecimal hash.</p> +<h5 id="how-is-difficulty-applied">4.3.2.1. How is difficulty applied ?</h5> +<p>The numeric value of difficulty is taken from an array of possible hashes out of all possible hashes. In DUBPv13 the hash of a block is its sha256 hexadecimal hash.</p> <p>To understand the difficulty, we make a euclidiean division of the difficulty by 16.</p> -<p>Here’s an example with a difficulty value of <code>70</code> : 70 // 16 = <strong>4</strong> with a remainder of <strong>6</strong>. The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : <code>0000[0-9]</code>. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes.</p> -<blockquote> -<p>Fine, but the hash of a mined block will never change and there’s no reason it should start with a given sequence of numbers. So how then can we make sure a block hash starts with exactly the sequence needed?</p> -</blockquote> -<p>Enter the nonce, short for “number once”. When a member is forging a new block, his computer freezes the block’s content and changes the Nonce until the hash reaches the required number of zeroes.</p> -<h5 id="the-nonce-1">The Nonce</h5> +<p>Here’s an example with a difficulty value of 70 :</p> +<pre><code>70 // 16 = 4 with a remainder of 6. </code></pre> +<p>The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : <code>0000[0-9]</code>. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes.</p> +<h5 id="the-nonce">4.3.2.2. The Nonce</h5> +<p>When a member is forging a new block, his computer freezes the block’s content and changes the Nonce until the hash reaches the required number of zeroes.</p> <p>The nonce allows us to mine a new block by finding a hash. The hash value allows us to determine the difficulty level of the proof-of-work performed. Examples of possible Nonce values:</p> <ul> <li>10100000112275</li> @@ -794,30 +343,24 @@ Duniter Whitepaper </ul> <p>In reality the <code>Nonce</code> value follows a pre-determined format akin to <code>XYY00000000000</code>. The Nonce’s value isn’t the number of attempts but rather a value within a set of possible ones. This is how the Nonce is built:</p> <ul> -<li><p>X is a number assigned to a specific peer. Let’s assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with different nodes. Each block will therefore have its own unique X to prevent this from happening.</p></li> +<li><p>X is a number assigned to a specific peer. Let’s assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with different nodes. Each <del>block</del> <strong>node ?</strong> will therefore have its own unique X to prevent this from happening.</p></li> <li><p>Y is the number of cores of the processor. The Nonce starting with <code>107[…]</code> belongs to a seven cores processor, while <code>199[...]</code> could be the proof generated by a 99 cores processor.</p></li> </ul> <p>The rest of the Nonce, the part that follows after the XYY, is the numerical space for this individual node and is unique to each of the CPU’s core. This space is comprised of eleven digits (<code>00000000000</code>). For the sake of accuracy, we use the term CPU in the wider sense, it can be understood as a bi-CPU for example. We take into consideration the number of cores for the resulting PoW.</p> -<h3 id="personalised-difficulty-1">Personalised difficulty</h3> -<p>Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other <em>PoW-based</em> cryptocurrencies such as Bitcoin.</p> +<h3 id="personalised-difficulty">4.4. Personalised difficulty</h3> +<p>Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other PoW-based cryptocurrencies.</p> <p>Here is how this personalised difficulty is calculated and assigned:</p> <p>It is determined by a combination of two different constraints with complimentary roles: the <strong>exclusion factor</strong> and the <strong>handicap</strong>.</p> <p>Let <code>powMin</code> be the common difficulty, <code>exFact</code> a member’s exclusion factor and <code>handicap</code> their handicap. This member’s personalised difficulty <code>diff</code> is:</p> -<div class="highlight"> <pre><code>diff = powMin*exFact + handicap</code></pre> -</div> -<h4 id="understanding-exfact-the-exclusion-factor-1">Understanding <code>exFact</code>, the exclusion factor</h4> +<h4 id="the-exclusion-factor">4.4.1. Understanding <code>exFact</code>, the exclusion factor</h4> <p>Members who have never produced blocks or haven’t for quite some time are assigned an exclusion factor of <code>1</code>. Their personalised difficulty is therefore simply the sum of <code>powMin + handicap</code>.</p> <p>Before reading on, let’s precise the role of this exclusion factor. When a member adds a block to the chain, his <code>exFact</code> jumps up from one to a very high value, to prevent them from forging other blocks immediately after and taking control of the blockchain.</p> <p>The exclusion factor will then rapidly return to one. This delay is expressed as a number of blocks. It is calculated as a proportion of the number of members forging. In the Ğ1’s case, this proportion is 1/3, meaning that if there are fifteen members currently forging, the member’s exclusion factor will drop down to one after five blocks.</p> -<blockquote> -<p>What is intended by “the number of members forging”?</p> -</blockquote> -<p>We mean the number of members trying to create the next block. In reality, there is no way to precisely know how many members are calculating at any given time, because it is impossible to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block in the last X blocks, minus the very last one.</p> -<blockquote> -<p>Hox is X determined?</p> -</blockquote> -<p>We use the concept of <strong>current window</strong>. X’s value is equal to the size of this window. Let’s see how it works:</p> +<h5 id="what-is-intended-by-the-number-of-members-forging">4.4.1.1. What is intended by “the number of members forging” ?</h5> +<p>We mean the number of members trying to create the next block. In reality, there is no way to precisely know how many members are calculating at any given time, because it is impossible to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block in the last blocks in the current window, minus the very last one.</p> +<h5 id="current-window">4.4.1.2. Current window</h5> +<p>We use the concept of <strong>current window</strong>. The current window is the number of blocks we look back at to determine how many members are forging. Let’s see how it works:</p> <ul> <li><p><code>issuersFrame</code> is the size of the current window in blocks.</p></li> <li><p><code>issuersCount</code> the number of members who have calculated at least one block during the current window.</p></li> @@ -867,78 +410,88 @@ Duniter Whitepaper </tbody> </table> <p>The calculation can be found under rules <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g05-headissuersframe">BR_G05</a> and <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g06-headissuersframevar">BR_G06</a> of the DUP protocol.</p> -<blockquote> -<p>Let’s go back to the personalised difficulty.</p> -</blockquote> -<p>We explained that <code>exFact</code> spikes immediately after the member has found a block. It decreases then rapidly to <code>1</code> after a number of blocks <code>X = 1/3 * issuersCount</code>. Let’s see precisely how we calculate <code>exFact</code>:</p> +<h5 id="exfact-and-the-personalised-difficulty">4.4.1.3. exFact and the personalised difficulty</h5> +<p>We explained that <code>exFact</code> spikes immediately after the member has found a block. It decreases then rapidly to <code>1</code> after a number of blocks equal to <code>1/3 * issuersCount</code>. Let’s see precisely how we calculate <code>exFact</code>:</p> <ul> <li><p><code>nbPreviousIssuers</code> is the value of issuersCount at the last block <code>N</code> found by the member.</p></li> <li><p><code>nbBlocksSince</code> is the number of blocks found by the rest of the network since block <code>N</code>.</p></li> <li><p><code>percentRot</code> is the number of <em>not excluded</em> peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency.</p></li> </ul> -<div class="highlight"> -<pre><code>exFact = MAX [ 1 ; FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) ]</code></pre> -</div> +<pre><code>a = FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) +exFact = MAX [ 1 ; a ]</code></pre> <p>The FLOOR is a simple truncate function. For <code>exFact</code> to exclude the member, we need :</p> -<blockquote> -<p>(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2</p> -</blockquote> -<p>We can see that the member is not excluded if <code>nbBlocksSince</code> is greater than 1/3 of the calculating members. Take as an example nbPreviousIssuers = 6 and nbBlocksSince = 3:</p> -<blockquote> -<p>(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1</p> -</blockquote> -<p>However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded: > (0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2</p> -<p>Moreover if the last block was authored by the said member, then: > <code>nbBlocksSince=0</code> and > <code>exFact</code> = <code>0.67 * nbPreviousIssuers</code></p> +<pre><code>(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2</code></pre> +<p>We can see that the member is not excluded if <code>nbBlocksSince</code> is greater than 1/3 of the calculating members. Take as an example <code>nbPreviousIssuers = 6</code> and <code>nbBlocksSince = 3</code>:</p> +<pre><code>(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1</code></pre> +<p>However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded:</p> +<pre><code>(0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2</code></pre> +<p>Moreover if the last block was authored by the said member, then:</p> +<pre><code>nbBlocksSince=0 and +exFact = 0.67 * nbPreviousIssuers</code></pre> <p>ExFact value increases according to the number of members calculating. Thus, if there is enough members calculating, even mining farms would be excluded. We have therefore succeeded in our intent to deter attempts to seize the blockchain and its currency.</p> -<p>However, at any time t, the two-thirds of calculating members all have an exclusion factor of <code>1</code>, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then only the members with the highest computational power from the remaining third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn’t stand a chance…</p> -<h4 id="the-handicap-1">The handicap</h4> -<p>The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. A higher handicap is assined to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW.</p> +<p>However, at any time <code>t</code>, the two-thirds of calculating members all have an exclusion factor of <code>1</code>, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then only the members with the highest computational power from the remaining third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn’t stand a chance…</p> +<h4 id="the-handicap">4.4.2. The handicap</h4> +<p>The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. A higher handicap is assigned to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW.</p> <p>The aim is to handicap the half that has authored most blocks (the most powerful half) to favour the other one. So, the handicap formula will use the median number of blocks authored by peers within the current window.</p> <ul> <li><p><code>nbPersonalBlocksInFrame</code> is the number of blocks authored by a single member within the current window.</p></li> <li><p><code>medianOfBlocksInFrame</code> is the median number of blocks written by the calculating members during the same timeframe.</p></li> </ul> -<div class="highlight"> -<pre><code>handicap = FLOOR(LN(MAX(1;(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)) / LN(1.189))</code></pre> -</div> -<p>Let’s unwrap the formula: <code>(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)</code> is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored <code>9</code> blocks in the current window and the median is <code>5</code>, then the ratio will be <code>(9+1)/5 = 2</code>. The MAX function allows us to ensure that the handicap has a value at least equal to <code>1</code>.</p> +<pre><code>a = (nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame +handicap = FLOOR(LN(MAX( 1 ; a )) / LN(1.189))</code></pre> +<p>Let’s unwrap the formula:</p> +<pre><code>(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)</code></pre> +<p>is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored <code>9</code> blocks in the current window and the median is <code>5</code>, then the ratio will be <code>(9+1)/5 = 2</code>. The MAX function allows us to ensure that the handicap has a value at least equal to <code>1</code>.</p> <p>The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers.</p> -<p>If we want the handicap to be applied as soon as the median is reached, we’d have to divide it by <code>LN(1)</code>, the problem is that we’ve already set a minimum value of <code>1</code> with the MAX function, so if we were to divide the ratio by <code>LN(1)</code> all calculating peers would have a handicap >= <code>1</code>. In addition, is it really fair to handicap a member who’s right on the median?</p> +<p>If we wanted the handicap to be applied as soon as the median is reached, we would divide it by <code>LN(1)</code>. The problem is that we have already set a minimum value of <code>1</code> with the MAX function. If we were to divide the ratio by <code>LN(1)</code> all calculating peers would have a handicap <code>\>= 1</code>. In addition, is it really fair to handicap a member who is right on the median?</p> <p>That’s why we went for <code>1.189</code> rather than <code>1</code>. A member has to be at least <code>18.9%</code> above the median to be assigned a handicap. 18.9% is actually 16^(1/16), the difficulty factor between two levels of the proof work (hexadecimal hash).</p> <p>To conclude, you have to remember that :</p> <ul> -<li>the handicap is indexed on the logarithm of the ratio to the median,</li> -<li>handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work’s difficulty.</li> +<li>The handicap is indexed on the logarithm of the ratio to the median,</li> +<li>Handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work’s difficulty.</li> </ul> -<h2 id="conclusion-1">Conclusion</h2> +<h2 id="conclusion">Conclusion</h2> <!-- source : https://duniter.org/en/theoretical/ --> <p>Duniter’s Blockchain can be compared to Bitcoin’s : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend.</p> -<p>More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers while maintaining a good security on the network.</p> +<p>More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers, maintaining a good security and helping decentralization of calculation.</p> <p>The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties :</p> <ul> -<li>The freedom to choose your currency system: because money should not be imposed</li> -<li>The freedom to access resources: because we all should have access to economic & monetary resources</li> -<li>The freedom to estimate and produce value: because value is a purely relative to each individual</li> -<li>The freedom to trade with the money: because we should not be limited by the avaible money supply</li> +<li>The freedom to choose your currency system: because money should not be imposed.</li> +<li>The freedom to access resources: because we all should have access to economic & monetary resources.</li> +<li>The freedom to estimate and produce value: because value is a purely relative to each individual.</li> +<li>The freedom to trade with the money: because we should not be limited by the avaible money supply.</li> </ul> <p>Those 4 economic freedoms should be understood together, not exclusively. Plus, “freedom” has to be understood as “non-nuisance”. So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency.</p> -<h2 id="duniter-projects-sources-1">Duniter project’s sources :</h2> -<ul> -<li>Theoretical, by Cgeek: https://duniter.org/en/theoretical/</li> -<li>Lock conditions, by Inso: https://duniter.org/en/transactions-0-2-overview/</li> -<li>Individualised Proof of Work, by Elois: https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/</li> -<li>Deep dive into the Web of Trust, by Elois: https://duniter.org/en/deep-dive-into-the-web-of-trust/</li> -<li>Whitepaper sources: https://git.duniter.org/communication/duniter-whitepaper</li> -</ul> -<h2 id="other-sources-1">Other sources :</h2> -<ul> -<li>Relative Theory of Money, S.Laborde, 2010: http://en.trm.creationmonetaire.info/</li> -<li>Bitcoin Whitepaper, S.Nakamoto, 2008: https://bitcoin.org/bitcoin.pdf</li> -<li>Circles Whitepaper, A.Milenius, 2018: https://github.com/CirclesUBI/docs/blob/master/Circles.md</li> -<li>The Sibyl Attack, J.R.Douceur: https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</li> +<h2 id="sources">Sources :</h2> +<ul> +<li>Relative Theory of Money, S.Laborde, 2010: <a href="http://en.trm.creationmonetaire.info/">en.trm.creationmonetaire.info/</a></li> +<li>Bitcoin Whitepaper, S.Nakamoto, 2008: <a href="https://bitcoin.org/bitcoin.pdf">bitcoin.org/bitcoin.pdf</a></li> +<li>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : <a href="http://lightning.network/lightning-network-paper.pdf">lightning.network/lightning-network-paper.pdf</a></li> +<li>The GNU Privacy Handbook, M.Ashley, 1999 : <a href="https://www.gnupg.org/gph/en/manual.html#AEN335">www.gnupg.org/gph/en/manual.html#AEN335</a></li> +<li>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. <a href="https://cr.yp.to/papers.html#ed25519">cr.yp.to/papers.html#ed25519</a>.</li> +<li>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : <a href="https://archive.org/details/PPCoinPaper">archive.org/details/PPCoinPaper</a></li> +<li>Duniter Blockchain Protocol, v13, draft by Elois : <a href="https://git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md">git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md</a></li> +<li>The Sibyl Attack, J.R.Douceur: <a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf">www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</a></li> +<li>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992</li> </ul> -<!-- travaux en theorie des graphes pourla TdC --> </article> </main> </body> </html> +<section class="footnotes"> +<hr /> +<ol> +<li id="fn1"><p>Bitcoin Whitepaper, S.Nakamoto, 2008: <a href="https://bitcoin.org/bitcoin.pdf">bitcoin.org/bitcoin.pdf</a><a href="#fnref1" class="footnote-back">↩</a></p></li> +<li id="fn2"><p>Relative Theory of Money, S.Laborde, 2010: <a href="http://en.trm.creationmonetaire.info/">en.trm.creationmonetaire.info/</a><a href="#fnref2" class="footnote-back">↩</a></p></li> +<li id="fn3"><p>OpenPGP protocol defines standard formats for encrypted messages, signatures, private keys, and certificates for exchanging public keys. The GNU Privacy Handbook, M.Ashley, 1999 : <a href="https://www.gnupg.org/gph/en/manual.html#AEN335">www.gnupg.org/gph/en/manual.html#AEN335</a><a href="#fnref3" class="footnote-back">↩</a></p></li> +<li id="fn4"><p>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. <a href="https://cr.yp.to/papers.html#ed25519">cr.yp.to/papers.html#ed25519</a>.<a href="#fnref4" class="footnote-back">↩</a></p></li> +<li id="fn5"><p>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : <a href="https://archive.org/details/PPCoinPaper">archive.org/details/PPCoinPaper</a><a href="#fnref5" class="footnote-back">↩</a></p></li> +<li id="fn6"><p>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : <a href="http://lightning.network/lightning-network-paper.pdf">lightning.network/lightning-network-paper.pdf</a><a href="#fnref6" class="footnote-back">↩</a></p></li> +<li id="fn7"><p>Surfing a Web of Trust, Reputation and Reciprocity on CouchSurfing.com, D.Lauterbach, H.Truong, T.Shah, L.Adamic: <a href="http://snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf">snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf</a><a href="#fnref7" class="footnote-back">↩</a></p></li> +<li id="fn8"><p>Public key validation on GnuPG manual, M.Ashley, 1999 : <a href="https://www.gnupg.org/gph/en/manual.html#AEN335">www.gnupg.org/gph/en/manual.html#AEN335</a><a href="#fnref8" class="footnote-back">↩</a></p></li> +<li id="fn9"><p>The Sibyl Attack, J.R.Douceur: <a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf">www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</a><a href="#fnref9" class="footnote-back">↩</a></p></li> +<li id="fn10"><p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992<a href="#fnref10" class="footnote-back">↩</a></p></li> +<li id="fn11"><p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992<a href="#fnref11" class="footnote-back">↩</a></p></li> +<li id="fn12"><p>Pareto principle : <a href="https://en.wikipedia.org/wiki/Pareto_principle">en.wikipedia.org/wiki/Pareto_principle</a><a href="#fnref12" class="footnote-back">↩</a></p></li> +</ol> +</section> diff --git a/build/whitepaper_fr.md b/build/whitepaper_fr.md index a459ae656f4a3a9d2a6ab9d85e294399a935949e..6ab8bfa02502b162867261b90d3e11155ea90924 100644 --- a/build/whitepaper_fr.md +++ b/build/whitepaper_fr.md @@ -1,13 +1,22 @@ -Duniter : A libre currency blockchain generator ! +Duniter: A libre currency blockchain generator. ======================================= -## Abstract (TODO) +## Abstract {#abstract} -## Introduction +Many currency principles involve non-equal rights to monetary creation between humans. +We propose a monetary creation based on the Relative Theory of Money, which guarantee equal monetary creation for each willing human. +This type of currency can be centralised, however, this could lead to censorship and arbitrary choices of the central institution. +Thus, strongly inspired by Bitcoin example, we want the currency to be as decentralised as possible, in the transaction network as in the human identification process. +We use a Web of Trust between living humans for identification. +This web of trust allows us to impose personalised difficulty for transaction validation, keeping the calculation accessible to low-end hardware and allowing all competent members to secure the currency. + + + +## Introduction {#introduction} Duniter is a software to create and manage "libre currencies". Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question : -> How should a currency be created to match the principle of equality between all humans ? +> How should a currency be created to match the principle of equality between all humans, now and between generations ? The results of this demonstration implies a monetary creation : @@ -17,111 +26,118 @@ The results of this demonstration implies a monetary creation : Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula : -> UD(t+1) = UD(t) + c² * ( M(t) / N(t) ) - +``` +$$ UD(t+1) = UD(t) + c²*( {M(t) \over N(t) }) $$ +``` Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin. -The first currency created through Duniter is Ğ1 (say "June"). It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software. +The first currency created through Duniter is Ğ1, pronounced "June". It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software. -## State of the art : Bitcoin case + +## 1. State of the art : Bitcoin case {#state-of-the-art-bitcoin-case} <!-- source : https://duniter.org/en/theoretical/ --> -Duniter uses the crypto-currency concept introduced by Bitcoin, which is -to use cryptographic tools such as *signatures* to create digital -currencies. Duniter fits this definition, but it has completely +Duniter uses the crypto-currency concept introduced by Bitcoin[^BTC_whitepaper], which is +to use cryptographic tools such as signatures to create trustless digital +currencies. Duniter fits this definition, but it has two completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects. -### Monetary creation of Bitcoin : a space-time asymmetry +[^BTC_whitepaper]: Bitcoin Whitepaper, S.Nakamoto, 2008: [bitcoin.org/bitcoin.pdf](https://bitcoin.org/bitcoin.pdf) + +### 1.1. Monetary creation of Bitcoin : a space-time asymmetry {#monetary-creation-a-space-time-asymmetry} Space-time asymmetry refers to the relative access of individuals to -newly created money (Relative Theory of Money, S.Laborde, 2010). Concretely, all existing currencies (c. 2015) are +newly created money[^RTM]. Concretely, most existing currencies (c. 2020) are both spatially and temporally asymmetrical for their users. Let\'s take Bitcoin as an example to understand why. -#### Spatial asymmetry +[^RTM]: Relative Theory of Money, S.Laborde, 2010: [en.trm.creationmonetaire.info/](http://en.trm.creationmonetaire.info/) + +#### 1.1.1. Spatial asymmetry {#spatial-asymmetry} -When new Bitcoins are created, *only some Bitcoin users* (the miners) -are given new Bitcoins, while everyone else get nothing. **We believe -this is the *first* injustice.** However, some might say: +When new Bitcoins are created, only some Bitcoin users (the miners) +are given new Bitcoins, while everyone else get nothing. We believe +this is the first injustice. However, some might say: -> \"Miners used their *electricity and time* to get it!\" +> \"Miners used their electricity and time to get it!\" -\... we would answer that this work *shouldn\'t have been rewarded by -newly created Bitcoins*. New Bitcoins should be distributed to the whole -Bitcoin community. Miners should be rewared another way, but not by -money issuance. Of course, Bitcoin can\'t create money through Basic -Income since *Bitcoin users are not strongly identified*, and one might -benefit from money creation multiple times if he owned several wallets. -Duniter gets rid of this problem completely by identifying its users and -giving *the same amount of Basic Income to everyone*. +\... we would answer that this work should not have been rewarded by +newly created Bitcoins. New units should be distributed to the whole +community. Miners should be rewared another way, but not by +money issuance. Of course, Bitcoin cannot create money through Basic +Income since Bitcoin users are not strongly identified, and one might +benefit from money creation multiple times if they owned several wallets. +Duniter gets rid of this problem by identifying its users and +creating the same amount of Basic Income to everyone. -#### Temporal-asymmetry +#### 1.1.2. Temporal-asymmetry {#temporal-asymmetry} Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, -how will future joiners get Bitcoins? Just like Euros or +how will future joiners get Bitcoins? Just like most of us do for Euros or Dollars: to get money, they will have to work for the ones who already own it. -**We believe this is the *second* injustice.** Every member of a + +We believe this is the second injustice. Every member of a monetary community should be equal concerning monetary creation, and get -the same relative amount of money over time, *even if they are a late -adopter*. Duniter aims to fix this by making the Universal Dividend -(a.k.a. *UD*) *grow by the time* (S.Laborde, 2010) according to precise rules, thus making +the same relative amount of money over time, even if they are a late +adopter. Duniter aims to fix this by making the Universal Dividend +(a.k.a. UD) grow by the time according to precise rules, thus making members equal toward money issuance on a half-lifespan. +Most currencies present one of these two asymmetries, including metal currencies +and mutual credit, as exposed in the RTM. +#### 1.1.3. A solution {#a-solution} - -#### A solution - -Bitcoin has taught us that *it is possible* to create a currency system +Bitcoin has taught us that it is possible to create a currency system allowing one to both create digital money and to exchange it without a -central authority. What we need to change is *the way money is issued* -so we finally have a symmetrical system. We need Bitcoin *+ Universal -Dividend*. But Universal Dividend *implies* that the community consists +central authority. What we need to change is the way money is issued +so we finally have a symmetrical system. We need **Bitcoin + Universal +Dividend**. But Universal Dividend implies that the community consists of only identified people. This is where the Web of Trust (WoT) comes -into place. This concept, introduced by cryptography with the -[OpenPGP](https://www.wikiwand.com/en/Pretty_Good_Privacy) format, -allows us to identify people in a *decentralized* manner. It works as -follows: each person creates *a personal identity* that is linked to its +into place. + +This concept, introduced by cryptography with the OpenPGP format[^OpenPGP], +allows us to identify people in a decentralized manner. It works as +follows: each person creates a personal identity that is linked to its cyptographic certificate. The identity must be confirmed by others -members who use their own cryptographic key. It is that simple: **people +members who use their own cryptographic key. It is that simple: people choose who is part of the community and who is not, not a central -authority.** +authority. -> Duniter however won\'t use OpenPGP for its cryptographic features: -> Elliptic Curves will be used instead for the conciseness of its -> generated keys and its pratical advantages. Duniter has its own Web -> of Trust principles, that shall be exposed later. +[^OpenPGP]: OpenPGP protocol defines standard formats for encrypted messages, signatures, private keys, and certificates for exchanging public keys. The GNU Privacy Handbook, M.Ashley, 1999 : [www.gnupg.org/gph/en/manual.html#AEN335](https://www.gnupg.org/gph/en/manual.html#AEN335) -### Proof-of-Work mining : a power race (TODO) +However, Duniter will not use OpenPGP for its cryptographic features: +Elliptic Curves[^Elliptic] will be used instead for the conciseness of its +generated keys and its pratical advantages. Duniter has its own Web +of Trust principles, that will be exposed later. -In Bitcoin Model, the calculation and incentive principles cause a power race : -new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. -The goal of Duniter is to make blockchain validation much less energy and hardware consuming while -keeping a strong level of security. As a consequence, even low-power hardware can secure Duniter Blockchain, -which leads to a better decentralization of forging operations. +[^Elliptic]: High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. [cr.yp.to/papers.html#ed25519](https://cr.yp.to/papers.html#ed25519). -### Other projects ? +### 1.2. Proof-of-Work mining : a power race {#proof-of-work-mining-a-power-race} -#### What about PoS ? +In Bitcoin Model, the calculation and incentive principles cause a power race : +new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. +This leads to a power race an places the control over the currency in the hands of the richest hardware owners. +We want to make Duniter blockchain validation much less energy and hardware consuming while +keeping a strong level of security. This will be further explained later. A consequence of +this choice is the participation of low-end hardware in the Duniter network, +leading to a better decentralization of blockchain validation. -When conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. -Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead -to placing power over the currency in the richests hands : this is contrary to the symmetical principles of Duniter. +#### 1.2.1 What about Proof of Stake ? {#what-about-proof-of-stake} -Now that PoS is well-tested, one could try to use Duniter's WoT to create a PoS-like algorithm with equal chances among members. -But this is not our aim for now. +Proof of stake consensus algorythm was first introduced in 2012[^PPCoin]. The basic principle is to allow the richest wallets to issue blocks, putting their coin balance as a "stake" they would lose in case of cheat. -#### What about Directed Acyclic Graph ? +[^PPCoin]: PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : [archive.org/details/PPCoinPaper](https://archive.org/details/PPCoinPaper) -The Circles project uses DAG in a basic income cryptocurrency. However, in this project, -one peer cannot know the whole monetary mass and the exact number of other peers. -The calculation of Universal Dividend `UD = c * M/N` seems impossible, since we know neither M nor N. +At the time of conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. We did not chose this consensus principle. +Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead +to placing power over the currency in the richests hands : this is contrary to the symmetical principles of a libre currency. -## Duniters Blockchain +## 2. Duniters Blockchain {#duniters-blockchain} <!-- source : https://duniter.org/en/theoretical/ --> @@ -130,138 +146,165 @@ Duniters Blockchain follows the basic principles of Bitcoins. This is essential for synchronization between peers, as to prevent double-spend attacks. However, Duniters Blockchain will store different informations than Bitcoins. -The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no *generation transaction* exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either: +The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no generation transaction exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either: * a former transaction (as in Bitcoin) * a Universal Dividend (specific to Duniter). -Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactinos are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where "space" are members of the WoT and "time" the basci blockchain units : the blocks. On each point of time, one can determain whick account is legitimate to create the UD, only with a blockchain analysis. +Duniters Web of Trust is also written in the Blockchain. The identity of each +member gets registered much like transactions are, with a strong link to the +time reference. Thus, the Blockchain is a representation of a space-time frame +of reference, where "space" are members of the WoT and "time" the basic blockchain +units : the blocks. On each point of time, one can determine which account is +legitimate to create the UD, only with a blockchain analysis. +### 2.1. Spam countermeasures {#spam-countermeasures} -### Spam countermeasures (TODO) -An issue of most cryptocurrency projects is to prevent the common ledger from growing too much and require lot of storage and computing power to be usable. In particular, we don't want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don't want to do this since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented. +An issue of most cryptocurrency projects is to prevent the common ledger from +growing too much. This would require nodes to have a lot of storage and computing +power to be usable. In particular, we don't want an attacker to be able to make the +Blockchain grow too fast. Most projects implement transaction fees as a way to prevent +this, making the attacker lose money. We don't want to introduce this mean since a +currency with automatic fees on transactions is no more neutral. Several +countermeasuers against such spam attacks are implemented. <!-- see : https://forum.duniter.org/t/sans-frais-de-transaction-comment-resister-aux-attaques/3846/25 (implemented ?)--> -* output minimal de 100*Unitbase / 1 unité -> empêche un attaquant de faire grossir la BC et les index trop vite (DUBP v12) -* chaînage maximal des tx -* seuils de dépense (implémentés ? en tout et par issuer ?) +#### 2.1.1. Minimum output amount {#minimum-output-amount} + +<!-- This has to be implemented in DUBPv13. --> + +Fixing a minimal output amount reduces the power of an attack. Duniter deals with cents of Ğ1 or 1/1000 of the first UD. An attacker could create thousand accounts with only 1 UD. To prevent this, a valid transaction must have output amounts of minimum 1Ğ1. This reduces the power an attack by 100. + +#### 2.1.2. Limited block size and chainability {#limited-block-size-and-chainability} -### Scaling +The block size is always limited. While the protocol allows this limit to evolve to address scaling issues, an attacker cannot register as many transaction as they wish. + +With the same goal to prevent too many transactions to get registered, while transactions can be "chained" (refer to another transaction in the same block), the chainability of transactions is limited to 5. + + +### 2.2. Scaling {#scaling} Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons : -* Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don't want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT limits its size to around 16 million members. -* Duniter's aim is to be used to create *multiple* libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community. +* Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don't want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT should limit its size to around 16 million members. +* Duniter's aim is to be used to create multiple libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community. -However, Duniter has two assets that might be used if the number of users grow. +However, Duniter has assets that will help if the number of users and transactions grow. -#### Dynamic block size +#### 2.2.1 Dynamic block size {#dynamic-block-size} While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. -On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks( *current window* will be described in the PoW part). -This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. +On high use of the blockchain, the maximal block size would be 110% of the +average size of the current window blocks(see "personalised difficulty" part for more information). +This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. The block size (in bytes) is limited as so : -:::{highlight} +``` block_size < max(500 ; CEIL(1.10 * (average block size)) -::: +``` +#### 2.2.2. Lightning Networks {#lightning-networks} -#### Lightning Networks - -The Lightning Networks allow almost instant and off-chain transactions. +The Lightning Networks[^Lightning] allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed. +[^Lightning]: The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : [lightning.network/lightning-network-paper.pdf](http://lightning.network/lightning-network-paper.pdf) + +#### 2.2.3. Unit base {#unit-base} + +As the Universal Dividend grows exponentially, with time Duniter nodes would have had to deal with always largest amounts, eventually reaching the BIGINT limit. To avoid this, the amounts are expressed with a unit base in base 10. We want the UD amount to always fit in 4 digits. To manage it, the `unitbase` is updated each time the UD value reaches 100.00 : it goes from `99.99*10^(unitbase)` to `10.00*10^(unitbase+1)`. All the unit amounts are thus divided by 10. While this might seem strange, this process has already hapened in state currencies. Moreover, the amounts expressed in UD will not change. -## Duniter Web of Trust +With a monetary growth of 10% each year and a stable population, such a change of unit base would happen each 25 years. -<!-- source : https://duniter.org/en/deep-dive-into-the-web-of-trust --> +## 3. Duniter Web of Trust -### Basic Principles -In order to identify "members" account - which create monetary units - from other accounts, Duniter uses a Web of Trust. This can be summarized into few principles: +### 3.1. Basic Principles {#duniter-wot-basic-principles} -* Each account becomes a member if it received a minimal number of certifications (5 for Ğ1 currency) -* Only members accounts can send certifications. Certifications have a limited lifespan. -* A certification indicates that the sender accepts the receiver as a legitimate identity. +In order to identify "members" accounts - which create monetary units - +and other accounts, Duniter uses a Web of Trust. This can be summarized +into few principles: -The aim of the WoT is to identify a blockchain account to a living human. Each member of the Ğ1 currency signs a licence stating that they will only certify humans they know well (among other rules). -Thus, if a member is part of an attack on the currency, they can be found by mutual friends. The security of Ğ1 currency stands on: +- Each account becomes a member if it received a minimal number of + certifications - 5 for Ğ1 currency. +- Only members accounts can send certifications. Certifications have a + limited lifespan. +- A certification indicates that the sender accepts the receiver as a + legitimate identity. -* Corroborating informations on members (5 certifications) -* Peer pressure by close relatives -* Law if the licence has not been respected. +The aim of the WoT is to identify a blockchain account to a living +human. According to Lauterbach et.al[^Couchsurf], the strengh of a relationship should be considered when building a vouch system. +For this reason, the Ğ1 Web of Trust rules are expressed in a licence stating what WoT certifications are. +A certification represents a strong human relationship : one may certify a close relative, not an acquaintance. +Each member has to accept this licence before being included in the WoT. +Thus, if a member is part of an attack on the currency, they can be found by mutual relatives. +Additional security rules occur to prevent cheat and attacks on a large scale. -Note that non-members accounts can use the currency, but cannot create money. They can be used by individuals as secondary wallets, or by institutions. +[^Couchsurf]: Surfing a Web of Trust, Reputation and Reciprocity on CouchSurfing.com, D.Lauterbach, H.Truong, T.Shah, L.Adamic: [snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf](http://snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf) -However, the WoT does not rely only on trust betwenn people. Rules have been added to increase the security, and we will present them. +Note that non-members accounts can use the currency, but cannot create +money. Non-members accounts can be used by individuals as secondary wallets, or by +institutions. +We were inspired by the OpenPGP Trust system[^OpenPGP_Trust]. However, the OpenPGP +trust principles aim at defining trust from a particular point of view while Duniter needs to +identify humans for the whole community. To achieve this goal, while OpenPGP allows each +user to tweak its trust parameters individually, Duniter sets rules in the "genesis" block for the whole community. -### Why do we need a Web of Trust? +[^OpenPGP_Trust]: Public key validation on GnuPG manual, M.Ashley, 1999 : [www.gnupg.org/gph/en/manual.html#AEN335](https://www.gnupg.org/gph/en/manual.html#AEN335) + +### 3.2. Why do we need a Web of Trust ? {#why-do-we-need-a-web-of-trust} There are two reasons we need it : 1. To make sure that only one Universal Dividend is produced per member - at each specified creation interval -in the Ğ1's case this interval - is set as daily `86 400` seconds-, it is the *monetary parameter* - known as `dt`-. -2. To identify the nodes hashing the blocks and assign them each a - personalised difficulty. This custom difficulty [proof of - work](https://en.wikipedia.org/wiki/Proof-of-work_system) is there - to avoid the blockchain's validation mechanism becoming too + at each specified creation interval. In the Ğ1's case this interval + is set as daily `86 400` seconds, it is the *monetary parameter* + known as `dt`. +2. To identify the nodes hashing the blocks and assign each a + personalised difficulty. This custom difficulty proof of work is + there to avoid the blockchain's validation mechanism becoming too centralised as is the case with many \'non-libre' cryptocurrencies. - > Wait, what's a 'monetary parameter' ? - -Every currency implementing Duniter has its own blockchain whose -behaviour is dictated by a set of 'parameters' -defined in block zero, -the so-called genesis block- that can be tweaked to achieve the desired -results. At the time of writing this article, the Duniter protocol -aka -DUP- has a total of 21 parameters of which 10 are for the WoT alone. -We'll focus on these 10. - -Suffice to say that in the Ğ1's case, the DU is created every 24 hours --86 400 seconds- but this interval -set through the time derivative `dt` -parameter- can have a different value in an other implementation of the -protocol. - -I won't write about the second parameter having to do with the proof of -work, it's outside our scope here, just know that the Web of Trust -allows us to **identify** the members providing hashing power, which we -couldn't do without it. This crucial feature means we can impose a -rotation between the members hashing the blocks so that no single rich -individual or group invests in a giant 'hash farm' and takes a hold of -the blockchain, paralysing the community! - -Let's go back to the first objective: to make sure that each member can -only have one account. As we all know, achieving zero-risk isn't -possible, our goal is therefore not to create a WoT within which fraud -would be absolutely impossible but instead to discourage it. Here is a +> **Monetary parameter** : Each currency that use Duniter has its own blockchain whose behaviour is +> dictated by a set of 'parameters' defined in block zero - the so-called +> genesis block - that can be tweaked to achieve the desired results. At +> the time of writing the Whitepaper, the Duniter Blockchain Protocol +> (DUBP) has a total of 21 parameters of which 10 are for the WoT alone. +> We'll focus on these 10. +> +> Suffice to say that in the Ğ1's case, the DU is created every 24 hours - +> 86 400 seconds. This interval is set through the time derivative `dt` +> parameter and can have a different value in other implementations of the +> protocol. + +We want to make sure that each member can only have one account. As we +all know, achieving zero-risk isn't possible[^Sybil_Attack]. +Our goal is therefore not to create a WoT within which fraud +would be absolutely impossible, but instead to discourage it. Here is a rewording of our goal in 4 smaller ones : -1. To make the certification process lengthy enough that all members +1. Make the certification process lengthy enough that all members exercise due diligence and are wary of risks. -2. To make fraudulent acts as hard as we can to the extent that they +2. Make fraudulent acts as hard as we can to the extent that they become pointless. -3. To ensure that any Sybil attacks have a negligible impact on the - currency -*by ensuring that illegitimate double Universal Dividends - have no significant bearing on the legitimate monetary mass*- -4. To slow the growth of 'Sybil regions' to give enough time for the +3. Ensure that any Sybil attacks have a negligible impact on the + currency by ensuring that illegitimate double Universal Dividends + have no significant bearing on the legitimate monetary mass +4. Slow the growth of 'Sybil regions' to give enough time for the community to react and isolate the threat. -> **Wait, a Sybil what ?** +[^Sybil_Attack]: The Sibyl Attack, J.R.Douceur: [www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf](https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf) -A [**Sybil attack**](https://en.wikipedia.org/wiki/Sybil_attack), is the -name given to attacks perpetrated on a reputation system through the -creation of fake identities. A Web of Trust is a specific instance of a -[**Reputation -System**](https://en.wikipedia.org/wiki/Reputation_system). +> **Sybil attack** : A Sybil attack is an attack perpetrated on a +> reputation system through the creation of fake identities. A Web of +> Trust is a specific instance of a Reputation System. There are plenty of Sybil attack scenarios we can think of and just as many reasons why their perpetrators would want to carry them out. Our @@ -272,23 +315,28 @@ This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web's role isn't to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing -your tap water and electricity but isn't responsible for any burglaries +your tap water and electricity but isn't responsible for any burglaries, etc. Much in the same way, Duniter's WoT guarantees us all a functional -currency and that's quite a feat in itself! +currency, but do not detect small fraud. + +### 3.3. The importance of having our own certification system {#own-certification-system} -### The importance of having our own certification system +Centralized identification systems can achieve the goal we want. State +Identification is an example. However, this has many drawbacks : -We are regularly offered to switch over to third-party or state-owned -authentication systems but these are centralised and go against the -principles of our community. We feel that we would lose our independence -and universality by adopting a state-controlled system. People without -an official state-provided identity or homeless people would also run -the risk of being excluded from the WoT. It is of the utmost importance -that we remain free from any state or corporation. To this day we depend -only on the Internet and yet, were it to fail, there are already -alternatives being tested around the world for a decentralised network. +* The authority may have arbitrary criteria for identification, for example +preventing people without an official state-provided identity or +homeless people to be included in the WoT. +* Payment might be required +to get identified, thus making the monetary creation not "free". +* The authority is a point of failure for any attacker. -### A few foundational concepts on graph theory : a bit of vocabulary +It is of the utmost importance that we remain free from any state or +corporation. The WoT is an answer to this criterium. To this day we +depend only on the Internet and yet, were it to fail, there are already +alternatives being tested around the world for a decentralised communication network. + +### 3.4. A few foundational concepts on graph theory : a bit of vocabulary {#graph-theory-vocabulary} - **Graph**: set of points -called 'vertices'- joined by edges -called paths/walks-. @@ -298,12 +346,10 @@ alternatives being tested around the world for a decentralised network. have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise. - [Wikipedia](https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms) - **Directed graph**: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. - [Wikipedia](https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms) Arrow A --\> B is therefore different from arrow B --\> A. - **Endpoints**: the edge with vertex A --\> B has A and B as @@ -311,7 +357,6 @@ alternatives being tested around the world for a decentralised network. - **Isolated vertex**: a vertex whose degree is zero, that is, a vertex with no incident edges. - [Wikipedia](https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms) - **Degree of a vertex**: number of its incident edges -in and out-. @@ -321,59 +366,52 @@ alternatives being tested around the world for a decentralised network. - **In-degree of vertex A**: number of incoming edges / head ends to A. - + - **Path**: -aka "walk"- path to follow to get from vertex A to vertex B. -### Definition of the Duniter Web of Trust +### 3.5. Definition of the Duniter Web of Trust {#definition-of-the-duniter-web-of-trust} The Duniter WoTs -one per currency- are simple directed graphs without isolated vertices. The vertices are the members and the edges are the certifications given and received. -Directed, what does that mean? - -The responsibility of issuing a certification is unique and personal to -the certifier. The trust he/she places in the receiver cannot be imposed -in the other direction although in most circumstances both parties -equally trust each other. +*Directed* means that the responsibility of issuing a certification is +unique and personal to the certifier. The trust they place in the +receiver cannot be imposed in the other direction although in most +circumstances both parties equally trust each other. In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific 'deactivated state' and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered -'pending' to avoid the web collapsing like a house of cards. +'pending' to avoid a collapse of the WoT. If these old members don't +come back into the WoT, their pending certifications will eventually +expire and they will switch from 'deactivated' to 'isolated' vertices. -If these old members don't come back into the web, their pending -certifications will eventually expire and they will switch from -'deactivated' to 'isolated' vertices. - -To wrap up with old members, after a certain period of time -set in the +To wrap up with old members, after a certain period of time - set in the currency's parameters - their deactivated vertex is removed from the web and the associated identity is 'revoked'. The person who owned the account can no longer use this identity but is free to join the web with -another one. :-) - -> What do you mean by 'identity'? - -An identity is a set of three pieces of information: a public key, a -name and a blockstamp. A blockstamp points to a specific block in the -chain. Its main use is to freeze the point in time at which an identity -was created and to link this identity to a specific chain and of course, -a currency -each currency having its own blockchain-. +another one. -An identity can be in any one of 5 different status: pending, member, -old member, revoked or excluded. +> **Identity** : An identity is a set of three pieces of information: a public key, a +> name and a blockstamp. A blockstamp points to a specific block in the +> chain. Its main use is to freeze the point in time at which an identity +> was created and to link this identity to a specific chain and a currency +> - each currency having its own blockchain. +> +> An identity can be in any one of 5 different status: pending, member, +> old member, revoked or excluded. Let's take a simple example: -::: {.highlight} +``` A -> B -> C | \--> D -::: +``` If, for whatever reason, A were to lose its member status, the web would crumble and all other members would be excluded as a consequence. To @@ -383,80 +421,73 @@ or D. Because our WoT doesn't have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications -it has received -in the same block-. This calls for a temporary 'buffer' -storage space for **pending** identities and the certifications they've -received. This storage space is called 'the pool' -of Duniter nodes- -which we could also have called the 'sandbox' as that's the name used in -Duniter's code. I might add that these 'pools' also include other +it has received, all in the same block. This calls for a temporary +'buffer' storage space for **pending** identities and the certifications +they have received. This storage space is called 'the pool' of Duniter +nodes, which we could also have called the 'sandbox' as that's the name +used in Duniter's code. Duniter nodes inclued other 'pools' for other documents and metadata not mentioned here. -### Exploring the rules behind a Duniter Web of Trust +### 3.6. Exploring the rules behind a Duniter Web of Trust {#exploring-the-rules-behind-duniter-wot} -The Duniter WoTs -one per currency- work with a set of eight fundamental -rules, themselves enforced through eleven different parameters. Ten of +The Duniter WoTs - one per currency - works with a set of eight +fundamental rules enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - `msPeriod`- having being hard-coded in the Ğ1's code subsequently. -#### 1.Distance rule and referent members (`stepMax` and `xPercent`) {#1distance-rule-and-referent-members-stepmax-and-xpercent} +#### 3.6.1. Distance rule and referent members (`stepMax` and `xPercent`) {#distance-rule-and-referent-members-stepmax-and-xpercent} These two parameters are closely linked and together define the 'distance rule'. The 'distance rule' can only be described after defining what a 'referent member' is: > **Referent member**: member A is said to be 'referent' if and only if -> the total of his/her degrees are greater than or equal to -> `CEIl-N^-1/stepMax--` where N is the total number of members.\*\* As -> the size of the web will grow this number will grow too, meaning it -> will take more certification issuances to become a referent member as -> the number of certifications needed to become a member shouldn't -> change. +> the total of their degrees are greater than or equal to +> `CEIL-N^-1/stepMax` where N is the total number of members. As the +> size of the web will grow this number will grow too, meaning it will +> take more certification issuances to become a referent member. The +> number of certifications needed to become a member shouldn't change. Let's now define the distance rule: > **Distance rule**: member A is said to observe this rule if and only > if for a subset xPercent % of referent members R there exists a path -> of length less than or equal to `stepMax` between R and A.\*\* +> of length less than or equal to `stepMax` between R and A. Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect -web, that is one in which each member has certified all members he/she +web, that is one in which each member has certified all members they legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time `t` who haven't yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would -effectively stop growing. -You can see what would happen if the notion -of 'referent member' didn't exist by going to the 'gaussianWotQuality' -page on -[currency-monit](https://g1-monit.librelois.fr/gaussianWotQuality?lg=en&unit=quality) -and activating 'if the concept of referent members didn't exist'-. - -> **When is the distance rule applied?** +effectively stop growing. Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets -confirmed into the web or an existing member gets renewed. *Exception to -the rule: the distance rule is not observed in the genesis block -when -the web is first implemented-.* +confirmed into the web or an existing member gets renewed. There is an +exception to this rule: the distance rule is not observed in the genesis +block -when the web is first implemented. -#### 2. Rule of the minimum number of certifications needed (`sigQty`) {#2-rule-of-the-minimum-number-of-certifications-needed-sigqty} +#### 3.6.2. Rule of the minimum number of certifications needed (`sigQty`) {#rule-of-the-minimum-number-of-certifications-needed-sigqty} This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least `sigQty` active certifications. If, for whatever reason, member A were -to have less than `sigQty` active certifications in a given block, -he/she would cease being a member and be required to publish a request -for identity renewal. +to have less than `sigQty` active certifications in a given block, they +would cease to be a member and be required to publish a request for +identity renewal. -#### 3. The membership renewal rule (`msValidity`, `msPeriod` and `msWindow`) {#3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow} +#### 3.6.3. The membership renewal rule (`msValidity`, `msPeriod` and `msWindow`) {#the-membership-renewal-rule-msvalidity-msperiod-and-mswindow} Bear in mind that a membership doesn't last a lifetime but instead has a lifespan set to `msValidity` seconds. Every single member -or old member who hasn't revoked his identity or been excluded- can request a membership renewal so long as the last -request was made more than `msPeriod` seconds ago -if a member has never +request was made more than `msPeriod` seconds ago. If a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the 'pool' for a maximum of `msWindow` seconds before it's included @@ -466,25 +497,25 @@ are already matched it's just a case of waiting for a new block to be mined-. If a member hasn't requested a renewal for longer than `msValidity` -seconds, he/she automatically ceases being a member. From this moment -on, the ex-member has another `msValidity` window to renew his/her -membership. When this period of \`2 × msValidity' runs out, the -membership will expire and this identity will never be available for use -again in the web. If the person so desires, he/she will have to start -from zero to regain access to the WoT. +seconds, they automatically cease to be a member. From this moment on, +the ex-member has another `msValidity` window to renew their membership. +When this period of `2 × msValidity` runs out, the membership will +expire and this identity will never be available for use again in the +web. If the person so desires, they will have to publish new identity +and membership documents and find enough certifiers, as any newcomer. -#### 4. Rule of certification lifespan (`sigValidity`) {#4-rule-of-certification-lifespan-sigvalidity} +#### 3.6.4. Rule of certification lifespan (`sigValidity`) {#rule-of-certification-lifespan-sigvalidity} All certifications included in the blockchain expire **sigValidity** seconds after they were **issued**. -/!\\ The issuance and the inclusion of a certification in the blockchain -occur at different times. When member A issues a certification at time -t1, it gets stored in the pool starting at t1 and only finds its way -into the blockchain at t2 when all of the web's rules are observed. -Several weeks can thus go by between t1 and t2!!! +> /!\\ The issuance and the inclusion of a certification in the +> blockchain occur at different times. When member A issues a +> certification at time t1, it gets stored in the pool starting at t1 +> and only finds its way into the blockchain at t2 when all of the web's +> rules are observed. Several weeks can thus go by between t1 and t2!!! -#### 5. Rule of limited supply of active certifications (`sigStock`) {#5-rule-of-limited-supply-of-active-certifications-sigstock} +#### 3.6.5. Rule of limited supply of active certifications (`sigStock`) {#rule-of-limited-supply-of-active-certifications-sigstock} By 'active certifications' we refer to certifications included in the blockchain and that haven't yet expired. @@ -494,26 +525,26 @@ time must be less than or equal to `sigStock`. When this threshold is reached the member will have to wait for one of his active certifications to expire before he/she can issue a new one. -#### 6. Rule of the time period between two certification issuances. (`sigPeriod`) {#6-rule-of-the-time-period-between-two-certification-issuances-sigperiod} +#### 3.6.6. Rule of the time period between two certification issuances. (`sigPeriod`) {#rule-of-the-time-period-between-two-certification-issuances-sigperiod} As soon as a certification issued by member A gets included in the -blockchain, he/she will be unable to issue a new one before another +blockchain, they will be unable to issue a new one before another `sigPeriod` seconds. -#### 7. Expiry of a certification issuance (`sigWindow`) {#7-expiry-of-a-certification-issuance-sigwindow} +#### 3.6.7. Expiry of a certification issuance (`sigWindow`) {#expiry-of-a-certification-issuance-sigwindow} When a certification is issued by member A, it will be stored in the 'pool' for a maximum of `sigWindow` seconds. If the certification hasn't been included in the blockchain by then, it will be cancelled and the member's `sigStock` will be repleted by one. -#### 8. Lifespan of a 'pending' active certification (`idtyWindow`) {#8-lifespan-of-a-pending-active-certification-idtywindow} +#### 3.6.8. Lifespan of a 'pending' identity (`idtyWindow`) {#lifespan-of-a-pending-identity-idtywindow} When a new identity is created, it is stored in the 'pool' for a maximum of `idtyWindow` seconds. If the person hasn't achieved member status by then, the certification will simply be cancelled. -### Details on some of the WoT's peculiarities at the genesis block. {#details-on-some-of-the-wots-peculiarities-at-the-genesis-block} +### 3.7. Details on some of the WoT's peculiarities at the genesis block {#details-on-some-of-the-wots-peculiarities-at-the-genesis-block} The aforementioned rules can only be enforced with an existing web. They cannot be observed when first creating the web, that is when defining @@ -522,25 +553,25 @@ the genesis block. Only rules 2 and 5 can be observed at the genesis block. The genesis block has to be manually created by the founding members. In -practice this means that there must be a choice of which identities to +practice this means that there must be a choice on which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities. As soon as the genesis block has been created, the other identities can -start mining the blockchain and the member who begat block \#0 +start mining the blockchain and the member who created block \#0 effectively looses the decision power he had at creation. -### Why these rules and application cases in the Ğ1 {#why-these-rules-and-application-cases-in-the-g1} +### 3.8. Why these rules and application cases in the Ğ1 {#why-these-rules-and-application-cases-in-the-g1} -#### 1. Distance and maximum size {#1-distance-and-maximum-size} +#### 3.8.1. Distance and maximum size {#distance-and-maximum-size} The distance rule is there to curb the maximum size of a Sybil region as well as that of the monetary community as a whole. The `xpercent` parameter prevents the creation of a 'faction' that could take hold of the blockchain. - + The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned @@ -550,34 +581,36 @@ endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as `stepAttackers`. The maximum size of a Sybil region created by `sigQty` -members depends on the L parameter, defined as L = sigQty/sigStock: +members depends on the L parameter, defined as `L = sigQty/sigStock`: -::: {.highlight} - Maximum Sybil region size = (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L) -::: +``` +MaxSybilSize= (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L) +``` The maximum size of the Web of Trust is given by the following formula: -::: {.highlight} - WoTmax = (sigStock)*L^(stepMax-1) -::: +``` +WoTmax = (sigStock)*L^(stepMax-1) +``` However we know for a fact that members will never use all of their -available certifications. Many studies have proven that we all know a -maximum average of fifty people, let's then replace sigStock by fifty: +available certifications. +According to Dunbar[^Dunbar], on average, one is able to maintain relationships to around 150 people. +Being conservative, we will consider that on average, each person will certify 50 accounts. +We can calculate the size of the average web of trust `WoTavg` : + +``` +WoTavg= (50)*(sigQty/50)^(stepMax-1) +``` + +[^Dunbar]: Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992 -::: {.highlight} - WoTavg= (50)*(sigQty/50)^(stepMax-1) -::: Our goal with the Ğ1 is to create a community of about one million -members enjoying the world's first true -[catallaxy](https://en.wikipedia.org/wiki/Catallaxy) -free economy with -a spontaneous order of things-. Let's see how we can tweak the pair of -sigQty and stepMax- to reach this size: +members to test the consequences of a libre monetary system. Let's see +how we can tweak the pair of sigQty and stepMax- to reach this size: - + The maximum size of a Sybil region grows linearly with `sigQty` but exponentially with `stepMax`. Logic has it that we need to keep @@ -598,13 +631,23 @@ knowing that the smaller `sigQty` is, the easier it is to launch a Sybil attack -it's easier to find four accomplices than five-. For security reasons we have settled on five: -stepMax = 5 sigQty = 5 sigStock \>= 50 +``` +stepMax = 5 +sigQty = 5 +sigStock \>= 50 +``` The maximum size of a Sybil region therefore is: -`(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))` + +``` +(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5)) +``` with sigStock = 50 we have a Sybil region of: -`45*(1-10^(5-stepAttackers))/(-9)` + +``` +45*(1-10^(5-stepAttackers))/(-9) +``` A good practice for protecting the web is to maximise `stepAttackers`. That's why we decided that referent members in the genesis block had to @@ -618,7 +661,7 @@ renewed. But what if bot accounts were created and certified each other super fast and following all rules, how would we counter that? By introducing a minimum length of time between two certifications! -#### 2. Time is our friend {#2-time-is-our-friend} +#### 3.8.2. Time is our friend {#time-is-our-friend} To help us deter a Sybil attack, we've decided to impose a minimum period of time between any two certifications issued from a single @@ -626,12 +669,12 @@ account. This parameter called `sigPeriod` affords us a greater chance to detect the formation of a 'hostile' faction. Here is a graph showing the evolution of a Sybil region with the -variation of `sigPeriod`: +variation of `sigPeriod`. The simulation considers that honest members +and attackers both issue a certification each `sigPeriod` interval, in days: - + -As you'll easily be able to tell, there is a strong link between the +As we see, there is a strong link between the growth speed of the region and `sigPeriod`. As evidenced here, we need a `sigPeriod` high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher @@ -641,47 +684,47 @@ gingerly, the action coming at a higher 'cost'. There are numerous advantages to giving `sigPeriod` a high value and no technical barriers to it, hence our choice of five days. -We could have also gone for days days -one week- for the sake of -simplicity however there was an underlying idea behind our choice which -was quite simply the pace of today's life. Certifying someone can be a -lengthy process as one needs to make sure he/she is correctly applying -the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit -of free-time. Thus the idea to allow one to certify at the end of every -working week -five days- instead of a whole calendar one. +We could have also gone for one week for the sake of simplicity. However +there is an underlying idea behind our choice which was quite simply the +pace of today's life. Certifying someone can be a lengthy process as one +needs to make sure they are correctly applying the Ğ1 licence and people +nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea +to allow one to certify at the end of every working week -five days- +instead of a whole calendar one. -#### 3. Trust me now, trust me forever? (`sigValidity`, `msValidity`) {#3-trust-me-now-trust-me-forever-sigvalidity-msvalidity} +#### 3.8.3. Trust me now, trust me forever ? (`sigValidity`, `msValidity`) {#trust-me-now-trust-me-forever-sigvalidity-msvalidity} There would be two main drawbacks to a lifetime membership in the Ğ1's Web of Trust: -> First of all we need to take into account that some members will pass -> and those accounts should no longer produce the Universal Dividend. -> Secondly it is of the utmost importance that 'rogue' accounts can be -> excluded from the web at some point. +- First of all, some members will pass and those accounts should no + longer produce the Universal Dividend. +- Secondly it is of the utmost importance that 'rogue' accounts can be + excluded from the web at some point. -To achieve this, certifications have a limited lifetime and members need -to seek renewal from their peers after `sigValidity` time. On the other +To achieve this, certifications have a limited lifespan. Members need to +seek renewal from their peers after `sigValidity` time. On the other hand, this time can't be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, -a certification with too short a lifetime would foster careless -certifying behaviours. The act of certifying must have a 'perceived' -cost high-enough to make it feel like an important act. Lastly, we also -wanted this lifetime to be easy enough to remember. Historically -speaking, we first settled on the values of `sigPeriod` and `sigStock`, -meant one could issue all of his/her certifications in 495 days, one -year was therefore not long enough. We deemed three years to bee much -and that's how we agreed on two years in the end. +a certification with too short a lifespan would foster careless +certifying behaviours. The act of certifying must have a high-enough +'perceived' cost to make it feel like an important act. Lastly, we also +wanted this lifespan to be easy to remember. Historically speaking, we +first settled on the values of `sigPeriod` and `sigStock`, meant one +could issue all of their certifications in 495 days, one year was +therefore not long enough. We deemed three years to be too much and +that's how we agreed on two years in the end. Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we -needed to address. We choose a value of one year for **msValidity**. The +needed to address. We chose a value of one year for **msValidity**. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to 'prune' the web of past or inactive members who don't renew their membership. -#### 4. Keeping the pools free of information glut -(`idtyWindow`, `sigWindow`, `msWindow`) {#4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow} +#### 3.8.4. Keeping the pools free of information glut (`idtyWindow`, `sigWindow`, `msWindow`) {#keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow} The pools need to be cleaned up on a regular basis to avoid them clogging up with information and to ensure that machines with less @@ -698,16 +741,15 @@ wanted a time period that would be easy enough to remember by all. We settled on two months, and gave this value to all three parameters `idtyWindow`, `sigWindow` and `msWindow`. -#### 5. Avoiding single members from 'knowing too many people' (`sigStock`) {#5-avoiding-single-members-from-knowing-too-many-people-sigstock} +#### 3.8.5. Avoiding single members from 'knowing too many people' (`sigStock`) {#avoiding-single-members-from-knowing-too-many-people-sigstock} -Many sociology studies have shown that we all know an average of fifty -people. This of course is an average, some of us know more than fifty -people, others much less. Once again we went for a number that would be -easy to remember. Although `sigStock`'s impact on the size of a Sybil -region is fairly limited, its value nonetheless has to be kept -reasonable. We settled on hundred. +We considered that on average, each person will certify 50 people. +However, we know for a fact that some members will use more than 50 certifications. +The maximum social network of one individual is around 150 people[^Dunbar]. +Being conservative, we settled on a maximum certification number `sigstock` of 100. +Since `sigStock`'s impact on the size of a Sybil region is fairly limited, we did not investigate further this parameter. -#### 6. Avoiding locking minorities (`xpercent`) {#6-avoiding-locking-minorities-xpercent} +#### 3.8.6. Avoiding locking minorities (`xpercent`) {#avoiding-locking-minorities-xpercent} It's easy enough to become a referent member, one of the Sybil strategies could therefore be to create a region of referent members. @@ -722,19 +764,20 @@ This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance -rule. The `xpercent` parameter was one of the hardest to define, we -therefore reserve ourselves the right of modifying its value during the -Ğ1 experiment. +rule. The `xpercent` parameter was one of the hardest to define, +therefore we might decide to change its value during the Ğ1 experiment. -We were inspired by the [Pareto -principle](https://en.wikipedia.org/wiki/Pareto_principle): if at least +We were inspired by the Pareto +principle[^Pareto]: if at least 20% of members give good density to the web, 80% of the referent members -will be five or less steps from any other member -referent or non-. The +will be five or less steps from any other member -referent or not-. The maximum value for `xpercent` is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%. -#### 7. Spam protection with (`msPeriod`) {#7-spam-protection-with-msperiod} +[^Pareto]: Pareto principle : [en.wikipedia.org/wiki/Pareto_principle](https://en.wikipedia.org/wiki/Pareto_principle) + +#### 3.8.7. Spam protection with (`msPeriod`) {#spam-protection-with-msperiod} This parameter stands out a bit on its own, as it was added after the genesis block. It is there to protect the Duniter P2P infrastructure @@ -746,11 +789,12 @@ supposed to address all renewal requests, even in cases where they were last published five minutes ago! The `msPeriod` parameter was given the same value as `idtyWindow`, `sigWindow` and `msWindow`, i.e. two months. -## Proof of Work with personal difficulty + +## 4. Proof of Work with personal difficulty {#proof-of-work-with-personalized-difficulty} As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human. -This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each "winning" member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. The knowledge of the whole network is not needed. +This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each "winning" member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. A view of the whole network is not needed. Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power. @@ -760,7 +804,7 @@ One could say that Duniter uses a PoW that needs very low energy consumption com <!-- source : https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ --> -### Why do we need Proof of Work ? +### 4.1. Why do we need Proof of Work ? {#why-proof-of-work} Duniter nodes share a database as part of a p2p environment. The proof of work (PoW) allows machines to synchronize with each other. In Duniter's case, the blockchain is @@ -773,9 +817,9 @@ as we want to create Universal Dividends on a regular basis, and keep track of membership status, both in human time. -Proof-of-work provides a clever solution to both problems: -1. Any -machine can write into the blockchain (create a new block) but is only +Proof-of-work provides a clever solution to both problems: + +1. Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, @@ -785,15 +829,15 @@ ensuring the unicity of a block's creator. takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and -Duniter adapts the challenge difficulty to get an *average* duration +Duniter adapts the challenge difficulty to get an average duration corresponding to this block time. -### Only members can "mine" +### 4.2. Only members can "mine" {#only-members-can-mine} One of Duniter's major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member's private key, allowing the algorithm to determine a -*personalised difficulty*. +personalised difficulty. This personalised difficulty eliminates the rat-race for the most sophisticated and powerful mining equipment. Another benefit is the fact @@ -804,21 +848,21 @@ This lightweight PoW is much less energy-consuming than other PoW cryptocurrenci Members can mine with anything from a raspberry pi to a privacy-first internet cube. -### How does it work? +### 4.3. How does it work ? {#how-does-duniter-pow-work} -#### The hash (aka digest) +#### 4.3.1. The hash (aka digest) {#the-hash} Example of a valid hash: -::: {.highlight} - 00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653 -::: +``` +00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653 +``` As you can see this hash starts with five zeros which was very hard to -achieve and took a lot of *work* for someone's computer. Hence the term +achieve and took a lot of work for someone's computer. Hence the term "proof of work". -#### The common difficulty +#### 4.3.2. The common difficulty {#common-difficulty} A common difficulty is needed to settle on a yardstick for our time reference. Its role is to make sure the blockchain moves forward @@ -830,32 +874,32 @@ Duniter `v1.5.x`) and then acts as a spring, regulating blocktime creation by increasing itself if the creation interval drops under `avgGenTime` and vice-versa. -##### How is difficulty applied? +##### 4.3.2.1. How is difficulty applied ? {#how-is-difficulty-applied} The numeric value of difficulty is taken from an array of possible -hashes out of all possible hashes. In duniter v1.5.x the hash +hashes out of all possible hashes. In DUBPv13 the hash of a block is its sha256 hexadecimal hash. To understand the difficulty, we make a euclidiean division of the difficulty by 16. -Here's an example with a difficulty value of `70` : 70 // 16 = **4** with a -remainder of **6**. The valid hashes are the ones starting with four +Here's an example with a difficulty value of 70 : + +``` +70 // 16 = 4 with a remainder of 6. +``` + +The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : `0000[0-9]`. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes. -> Fine, but the hash of a mined block will never change and there's no -> reason it should start with a given sequence of numbers. So how then -> can we make sure a block hash starts with exactly the sequence -> needed? +##### 4.3.2.2. The Nonce {#the-nonce} -Enter the nonce, short for "number once". When a member is forging a new +When a member is forging a new block, his computer freezes the block's content and changes the Nonce -until the hash reaches the required number of zeroes. - -##### The Nonce +until the hash reaches the required number of zeroes. The nonce allows us to mine a new block by finding a hash. The hash value allows us to determine the difficulty level of the @@ -875,7 +919,7 @@ built: - X is a number assigned to a specific peer. Let's assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with - different nodes. Each block will therefore have its own unique X to + different nodes. Each ~~block~~ **node ?** will therefore have its own unique X to prevent this from happening. - Y is the number of cores of the processor. The Nonce starting with @@ -889,11 +933,11 @@ For the sake of accuracy, we use the term CPU in the wider sense, it can be understood as a bi-CPU for example. We take into consideration the number of cores for the resulting PoW. -### Personalised difficulty +### 4.4. Personalised difficulty {#personalised-difficulty} Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other -*PoW-based* cryptocurrencies such as Bitcoin. +PoW-based cryptocurrencies. Here is how this personalised difficulty is calculated and assigned: @@ -904,11 +948,11 @@ Let `powMin` be the common difficulty, `exFact` a member's exclusion factor and `handicap` their handicap. This member's personalised difficulty `diff` is: -::: {.highlight} - diff = powMin*exFact + handicap -::: +``` +diff = powMin*exFact + handicap +``` -#### Understanding `exFact`, the exclusion factor +#### 4.4.1. Understanding `exFact`, the exclusion factor {#the-exclusion-factor} Members who have never produced blocks or haven't for quite some time are assigned an exclusion factor of `1`. Their personalised difficulty @@ -926,7 +970,7 @@ proportion is 1/3, meaning that if there are fifteen members currently forging, the member's exclusion factor will drop down to one after five blocks. -> What is intended by "the number of members forging"? +##### 4.4.1.1. What is intended by "the number of members forging" ? We mean the number of members trying to create the next block. In reality, there is no way to precisely know how @@ -935,12 +979,12 @@ to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block -in the last X blocks, minus the very last one. +in the last blocks in the current window, minus the very last one. -> Hox is X determined? +##### 4.4.1.2. Current window -We use the concept of **current window**. X's value is equal to the size of -this window. Let's see how it works: +We use the concept of **current window**. The current window is the number of blocks we look back at to determine how many members are forging. +Let's see how it works: * `issuersFrame` is the size of the current window in blocks. @@ -979,11 +1023,11 @@ and [BR\_G06](https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g06-headissuersframevar) of the DUP protocol. -> Let's go back to the personalised difficulty. +##### 4.4.1.3. exFact and the personalised difficulty {#exfact-and-the-personalised-difficulty} We explained that `exFact` spikes immediately after the member has found a block. It decreases then rapidly to `1` after a number of -blocks `X = 1/3 * issuersCount`. Let's see precisely +blocks equal to `1/3 * issuersCount`. Let's see precisely how we calculate `exFact`: * `nbPreviousIssuers` is the value of issuersCount at the @@ -994,27 +1038,36 @@ found by the rest of the network since block `N`. * `percentRot` is the number of *not excluded* peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency. -::: {.highlight} - exFact = MAX [ 1 ; FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) ] -::: +``` +a = FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) +exFact = MAX [ 1 ; a ] +``` The FLOOR is a simple truncate function. For `exFact` to exclude the member, we need : -> (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2 +``` +(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2 +``` We can see that the member is not excluded if `nbBlocksSince` is greater than 1/3 of -the calculating members. Take as an example nbPreviousIssuers = 6 and nbBlocksSince = 3: +the calculating members. Take as an example `nbPreviousIssuers = 6` and `nbBlocksSince = 3`: -> (0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1 +``` +(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1 +``` However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded: -> (0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2 +``` +(0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2 +``` Moreover if the last block was authored by the said member, then: -> `nbBlocksSince=0` and -> `exFact` = `0.67 * nbPreviousIssuers` +``` +nbBlocksSince=0 and +exFact = 0.67 * nbPreviousIssuers +``` ExFact value increases according to the number of members calculating. Thus, if there is enough members calculating, even @@ -1023,7 +1076,7 @@ succeeded in our intent to deter attempts to seize the blockchain and its currency. -However, at any time t, the two-thirds of +However, at any time `t`, the two-thirds of calculating members all have an exclusion factor of `1`, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then @@ -1032,11 +1085,11 @@ third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn't stand a chance... -#### The handicap +#### 4.4.2. The handicap {#the-handicap} The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. -A higher handicap is assined to members with higher calculating +A higher handicap is assigned to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW. @@ -1052,12 +1105,18 @@ single member within the current window. median number of blocks written by the calculating members during the same timeframe. -::: {.highlight} - handicap = FLOOR(LN(MAX(1;(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)) / LN(1.189)) -::: +``` +a = (nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame +handicap = FLOOR(LN(MAX( 1 ; a )) / LN(1.189)) +``` Let's unwrap the formula: -`(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)` is simply the + +``` +(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame) +``` + +is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored `9` blocks in the current window and the median is `5`, then the ratio @@ -1067,11 +1126,11 @@ the handicap has a value at least equal to `1`. The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers. -If we want the handicap to be applied as soon as the median is reached, -we'd have to divide it by `LN(1)`, the problem is that we've already set -a minimum value of `1` with the MAX function, so if we were to divide -the ratio by `LN(1)` all calculating peers would have a handicap \>= -`1`. In addition, is it really fair to handicap a member who's right on +If we wanted the handicap to be applied as soon as the median is reached, +we would divide it by `LN(1)`. The problem is that we have already set +a minimum value of `1` with the MAX function. If we were to divide +the ratio by `LN(1)` all calculating peers would have a handicap `\>= +1`. In addition, is it really fair to handicap a member who is right on the median? That's why we went for `1.189` rather than `1`. A member has to @@ -1081,43 +1140,39 @@ factor between two levels of the proof work (hexadecimal hash). To conclude, you have to remember that : -* the handicap is indexed on the logarithm of the ratio to the median, -* handicap is only applied on members whose ratio to the median is greater than the ratio between two +* The handicap is indexed on the logarithm of the ratio to the median, +* Handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work's difficulty. -## Conclusion + +## Conclusion {#conclusion} <!-- source : https://duniter.org/en/theoretical/ --> Duniter's Blockchain can be compared to Bitcoin's : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend. -More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers while maintaining a good security on the network. +More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers, maintaining a good security and helping decentralization of calculation. The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties : -* The freedom to choose your currency system: because money should not be imposed -* The freedom to access resources: because we all should have access to economic & monetary resources -* The freedom to estimate and produce value: because value is a purely relative to each individual -* The freedom to trade with the money: because we should not be limited by the avaible money supply +* The freedom to choose your currency system: because money should not be imposed. +* The freedom to access resources: because we all should have access to economic & monetary resources. +* The freedom to estimate and produce value: because value is a purely relative to each individual. +* The freedom to trade with the money: because we should not be limited by the avaible money supply. Those 4 economic freedoms should be understood together, not exclusively. Plus, "freedom" has to be understood as "non-nuisance". So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency. -## Duniter project's sources : - -* Theoretical, by Cgeek: https://duniter.org/en/theoretical/ -* Lock conditions, by Inso: https://duniter.org/en/transactions-0-2-overview/ -* Individualised Proof of Work, by Elois: https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ -* Deep dive into the Web of Trust, by Elois: https://duniter.org/en/deep-dive-into-the-web-of-trust/ -* Whitepaper sources: https://git.duniter.org/communication/duniter-whitepaper - -## Other sources : - -* Relative Theory of Money, S.Laborde, 2010: http://en.trm.creationmonetaire.info/ -* Bitcoin Whitepaper, S.Nakamoto, 2008: https://bitcoin.org/bitcoin.pdf -* Circles Whitepaper, A.Milenius, 2018: https://github.com/CirclesUBI/docs/blob/master/Circles.md -* The Sibyl Attack, J.R.Douceur: https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf - -<!-- travaux en theorie des graphes pourla TdC --> +## Sources : {#sources} + +* Relative Theory of Money, S.Laborde, 2010: [en.trm.creationmonetaire.info/](http://en.trm.creationmonetaire.info/) +* Bitcoin Whitepaper, S.Nakamoto, 2008: [bitcoin.org/bitcoin.pdf](https://bitcoin.org/bitcoin.pdf) +* The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : [lightning.network/lightning-network-paper.pdf](http://lightning.network/lightning-network-paper.pdf) +* The GNU Privacy Handbook, M.Ashley, 1999 : [www.gnupg.org/gph/en/manual.html#AEN335](https://www.gnupg.org/gph/en/manual.html#AEN335) +* High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. [cr.yp.to/papers.html#ed25519](https://cr.yp.to/papers.html#ed25519). +* PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : [archive.org/details/PPCoinPaper](https://archive.org/details/PPCoinPaper) +* Duniter Blockchain Protocol, v13, draft by Elois : [git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md](https://git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md) +* The Sibyl Attack, J.R.Douceur: [www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf](https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf) +* Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992 diff --git a/build/whitepaper_fr.mobi b/build/whitepaper_fr.mobi new file mode 100644 index 0000000000000000000000000000000000000000..464a160f26f9bd5eebda3c7bce5be7fb634c1ead Binary files /dev/null and b/build/whitepaper_fr.mobi differ diff --git a/chapters/en/1_intro.md.txt b/chapters/en/1_intro.md.txt index 437d2c608c3dad106ce8d6eb59d0aac3234a109b..8dfb6c7d328c4a4da37f795257f029c7ee520259 100644 --- a/chapters/en/1_intro.md.txt +++ b/chapters/en/1_intro.md.txt @@ -26,9 +26,9 @@ The results of this demonstration implies a monetary creation : Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula : -``` $$ UD(t+1) = UD(t) + c²*( {M(t) \over N(t) }) $$ -``` + + Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin. The first currency created through Duniter is Ğ1, pronounced "June". It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software. diff --git a/publication.sh b/publication.sh index 93cdce2945193ad5baf1a3ab88e20e0c6873a0df..0e2a6a142ed29849d6870b338f3cc693da8a65c0 100644 --- a/publication.sh +++ b/publication.sh @@ -6,13 +6,13 @@ # ce script doit être lancé dans le dossier contenant les chapitres. # dépendances : pandoc -hash pandoc 2>/dev/null || { echo >&2 "Ce générateur a besoin de la commande pandoc pour fonctionner. Mais cette commande n'est pas installée."; exit 1; } +hash pandoc 2>/dev/null || { echo >&2 "Ce générateur a besoin de la commande pandoc pour fonctionner. Mais cette commande n'est pas installée. Fin de l'exécution."; exit 1; } mkdir -p build/src/js ## Clean des dossiers de build et copie des assets [ -f whitepaper.html ] && rm whitepaper.html -rm -rf build +rm -rf build temp_whitepaper_html_en temp_whitepaper_html_fr temp_whitepaper_en.md temp_whitepaper_fr.md mkdir -p build/js -cp src/js/* build/js/ +#cp src/js/* build/js/ mkdir build/img cp src/img/* build/img/ cp src/*.css build/ @@ -43,33 +43,33 @@ cat src/foot.html >> temp_whitepaper_html_fr ## Générer le html à partir du md pandoc -o whitepaper_fr.html temp_whitepaper_html_fr pandoc -o whitepaper_en.html temp_whitepaper_html_en -## déplacer dans le dossier de build -mv temp_whitepaper_fr.md build/whitepaper_fr.md -mv temp_whitepaper_en.md build/whitepaper_en.md + mv whitepaper_fr.html build/whitepaper_fr.html mv whitepaper_en.html build/whitepaper_en.html -# clean de fichiers temporaires -rm temp_whitepaper_html_fr temp_whitepaper_html_en - -firefox build/whitepaper_en.html - +firefox "$PWD/build/whitepaper_en.html" ## add ebook conversion -hash pandoc 2>/dev/null || { echo >&2 "Ce générateur peut utiliser ebook-convert fourni avec Calibre, disponible dans les dépots apt. Mais cette commande n'est pas installée."; exit 1; } -ebook-convert build/whitepaper.html build/whitepaper.mobi -ebook-convert build/whitepaper.html build/whitepaper.fb2 -ebook-convert build/whitepaper.html build/whitepaper.epub +hash pandoc 2>/dev/null || { echo >&2 "Ce générateur peut utiliser ebook-convert fourni avec Calibre, disponible dans les dépots apt. Mais cette commande n'est pas installée. Fin de l'exécution."; exit 1; } +ebook-convert build/whitepaper_fr.html build/whitepaper_fr.mobi +ebook-convert build/whitepaper_en.html build/whitepaper_en.mobi +ebook-convert build/whitepaper_fr.html build/whitepaper_fr.fb2 +ebook-convert build/whitepaper_en.html build/whitepaper_en.fb2 +ebook-convert build/whitepaper_fr.html build/whitepaper_fr.epub +ebook-convert build/whitepaper_en.html build/whitepaper_en.epub echo "===== ok ebooks" ls -lArth build ## Création du fichier lateX et pdf ## Attention, certains caractères (U+2028) ne sont pas acceptés par LaTeX. -pandoc -o whitepaper.pdf temp_whitepaper.md +pandoc -o whitepaper_fr.pdf temp_whitepaper_fr.md +pandoc -o whitepaper_en.pdf temp_whitepaper_en.md -# git add files -git add whitepaper.md whitepaper.html -git add chapters/1_intro.md.txt chapters/2_looking_at_Bitcoin.md.txt chapters/3_blockchain.md.txt chapters/4_Web_Of_Trust.md.txt chapters/5_individualized_difficulty.md.txt chapters/6_conclusion.md.txt chapters/9_sources.md.txt -git add publication.sh +## déplacer les md, html et pdf dans le dossier de build +mv temp_whitepaper_fr.md build/whitepaper_fr.md +mv temp_whitepaper_en.md build/whitepaper_en.md -#we want to add the .pdf only for publication -# git add whitepaper.pdf +mv whitepaper_fr.pdf build/whitepaper_fr.pdf +mv whitepaper_en.pdf build/whitepaper_en.pdf + +# clean de fichiers temporaires +rm temp_whitepaper_fr.md temp_whitepaper_en.md temp_whitepaper_html_fr temp_whitepaper_html_en missfont.log diff --git a/src/head.html b/src/head.html index eded7e16a817e794a6cba2c5503abafe30932766..02dbdabf017c7a568eeaff9ffc9f587f61463093 100644 --- a/src/head.html +++ b/src/head.html @@ -9,18 +9,53 @@ <link rel='stylesheet' href='main.css' > - <script src='js/jquery.js' ></script > - <script src='js/toc.js' ></script > - <script type='javascript' > - if ($) { - $('#whitepaper').tableofcontents({ id: '#toc' }); - } + <script type='text/javascript' > + /** + * Generates a table of contents for your document based on the headings + * present. Anchors are injected into the document and the + * entries in the table of contents are linked to them. The table of + * contents will be generated inside of the first element with the id `toc`. + * @param {HTMLDOMDocument} documentRef Optional A reference to the document + * object. Defaults to `document`. + * @author Matthew Christopher Kastor-Inare III + * @version 20130726 + * @example + * // call this after the page has loaded + * htmlTableOfContents(); + */ + function htmlTableOfContents(documentRef) { + var documentRef = documentRef || document; + var toc = documentRef.getElementById('table_of_contents'); + var headings = [].slice.call(documentRef.body.querySelectorAll('h1, h2, h3, h4, h5, h6')); + headings.forEach(function (heading, index) { + var anchor = documentRef.createElement('a'); + anchor.setAttribute('name', 'toc' + index); + anchor.setAttribute('id', 'toc' + index); + + var link = documentRef.createElement('a'); + link.setAttribute('href', '#toc' + index); + link.textContent = heading.textContent; + + var div = documentRef.createElement('div'); + div.setAttribute('class', heading.tagName.toLowerCase()); + + div.appendChild(link); + toc.appendChild(div); + heading.parentNode.insertBefore(anchor, heading); + }); + } + + try { + module.exports = htmlTableOfContents; + } catch (e) { + // module.exports is not defined + console.error('e', e) + } </script > </head > -<body > +<body onload='htmlTableOfContents();' > <main > - <div id='toc' ></div > + <nav id='table_of_contents' ></nav > <article id='whitepaper' class='content' > - diff --git a/src/js/jquery.js b/src/js/jquery.js deleted file mode 100644 index d105c25fb8a794c6a02a5bb6f65452b6cb6b3244..0000000000000000000000000000000000000000 --- a/src/js/jquery.js +++ /dev/null @@ -1,5 +0,0 @@ -/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\f]' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function qa(){}qa.prototype=d.filters=d.pseudos,d.setFilters=new qa,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function ra(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1; - - return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[m.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=Z.test(e)?this.mouseHooks:Y.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new m.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||y),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||y,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ca()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===ca()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return m.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return m.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=m.extend(new m.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?m.event.trigger(e,null,b):m.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},m.removeEvent=y.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===K&&(a[d]=null),a.detachEvent(d,c))},m.Event=function(a,b){return this instanceof m.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?aa:ba):this.type=a,b&&m.extend(this,b),this.timeStamp=a&&a.timeStamp||m.now(),void(this[m.expando]=!0)):new m.Event(a,b)},m.Event.prototype={isDefaultPrevented:ba,isPropagationStopped:ba,isImmediatePropagationStopped:ba,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=aa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=aa,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=aa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},m.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){m.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!m.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.submitBubbles||(m.event.special.submit={setup:function(){return m.nodeName(this,"form")?!1:void m.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=m.nodeName(b,"input")||m.nodeName(b,"button")?b.form:void 0;c&&!m._data(c,"submitBubbles")&&(m.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),m._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&m.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return m.nodeName(this,"form")?!1:void m.event.remove(this,"._submit")}}),k.changeBubbles||(m.event.special.change={setup:function(){return X.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(m.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),m.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),m.event.simulate("change",this,a,!0)})),!1):void m.event.add(this,"beforeactivate._change",function(a){var b=a.target;X.test(b.nodeName)&&!m._data(b,"changeBubbles")&&(m.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||m.event.simulate("change",this.parentNode,a,!0)}),m._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return m.event.remove(this,"._change"),!X.test(this.nodeName)}}),k.focusinBubbles||m.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){m.event.simulate(b,a.target,m.event.fix(a),!0)};m.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=m._data(d,b);e||d.addEventListener(a,c,!0),m._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=m._data(d,b)-1;e?m._data(d,b,e):(d.removeEventListener(a,c,!0),m._removeData(d,b))}}}),m.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=ba;else if(!d)return this;return 1===e&&(g=d,d=function(a){return m().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=m.guid++)),this.each(function(){m.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,m(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=ba),this.each(function(){m.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){m.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?m.event.trigger(a,b,c,!0):void 0}});function da(a){var b=ea.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var ea="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",fa=/ jQuery\d+="(?:null|\d+)"/g,ga=new RegExp("<(?:"+ea+")[\\s/>]","i"),ha=/^\s+/,ia=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ja=/<([\w:]+)/,ka=/<tbody/i,la=/<|&#?\w+;/,ma=/<(?:script|style|link)/i,na=/checked\s*(?:[^=]|=\s*.checked.)/i,oa=/^$|\/(?:java|ecma)script/i,pa=/^true\/(.*)/,qa=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ra={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:k.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},sa=da(y),ta=sa.appendChild(y.createElement("div"));ra.optgroup=ra.option,ra.tbody=ra.tfoot=ra.colgroup=ra.caption=ra.thead,ra.th=ra.td;function ua(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ua(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function va(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wa(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xa(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function ya(a){var b=pa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function za(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Aa(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Ba(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xa(b).text=a.text,ya(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!ga.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ta.innerHTML=a.outerHTML,ta.removeChild(f=ta.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ua(f),h=ua(a),g=0;null!=(e=h[g]);++g)d[g]&&Ba(e,d[g]);if(b)if(c)for(h=h||ua(a),d=d||ua(f),g=0;null!=(e=h[g]);g++)Aa(e,d[g]);else Aa(a,f);return d=ua(f,"script"),d.length>0&&za(d,!i&&ua(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=da(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(la.test(f)){h=h||o.appendChild(b.createElement("div")),i=(ja.exec(f)||["",""])[1].toLowerCase(),l=ra[i]||ra._default,h.innerHTML=l[1]+f.replace(ia,"<$1></$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&ha.test(f)&&p.push(b.createTextNode(ha.exec(f)[0])),!k.tbody){f="table"!==i||ka.test(f)?"<table>"!==l[1]||ka.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ua(p,"input"),va),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ua(o.appendChild(f),"script"),g&&za(h),c)){e=0;while(f=h[e++])oa.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ua(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&za(ua(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ua(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fa,""):void 0;if(!("string"!=typeof a||ma.test(a)||!k.htmlSerialize&&ga.test(a)||!k.leadingWhitespace&&ha.test(a)||ra[(ja.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ia,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ua(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ua(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&na.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ua(i,"script"),xa),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ua(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,ya),j=0;f>j;j++)d=g[j],oa.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qa,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Ca,Da={};function Ea(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fa(a){var b=y,c=Da[a];return c||(c=Ea(a,b),"none"!==c&&c||(Ca=(Ca||m("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Ca[0].contentWindow||Ca[0].contentDocument).document,b.write(),b.close(),c=Ea(a,b),Ca.detach()),Da[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Ga=/^margin/,Ha=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ia,Ja,Ka=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ia=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)},Ja=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ia(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Ha.test(g)&&Ga.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ia=function(a){return a.currentStyle},Ja=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ia(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Ha.test(g)&&!Ka.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function La(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight),b.removeChild(i)),b.innerHTML="<table><tr><td></td><td>t</td></tr></table>",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Ma=/alpha\([^)]*\)/i,Na=/opacity\s*=\s*([^)]*)/,Oa=/^(none|table(?!-c[ea]).+)/,Pa=new RegExp("^("+S+")(.*)$","i"),Qa=new RegExp("^([+-])=("+S+")","i"),Ra={position:"absolute",visibility:"hidden",display:"block"},Sa={letterSpacing:"0",fontWeight:"400"},Ta=["Webkit","O","Moz","ms"];function Ua(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Ta.length;while(e--)if(b=Ta[e]+c,b in a)return b;return d}function Va(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fa(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wa(a,b,c){var d=Pa.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xa(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Ya(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ia(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Ja(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ha.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xa(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Ja(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ua(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qa.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ua(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Ja(a,b,d)),"normal"===f&&b in Sa&&(f=Sa[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Oa.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Ra,function(){return Ya(a,b,d)}):Ya(a,b,d):void 0},set:function(a,c,d){var e=d&&Ia(a);return Wa(a,c,d?Xa(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Na.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Ma,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Ma.test(f)?f.replace(Ma,e):f+" "+e)}}),m.cssHooks.marginRight=La(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Ja,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Ga.test(a)||(m.cssHooks[a+b].set=Wa)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ia(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Va(this,!0)},hide:function(){return Va(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Za(a,b,c,d,e){ - return new Za.prototype.init(a,b,c,d,e)}m.Tween=Za,Za.prototype={constructor:Za,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Za.propHooks[this.prop];return a&&a.get?a.get(this):Za.propHooks._default.get(this)},run:function(a){var b,c=Za.propHooks[this.prop];return this.options.duration?this.pos=b=m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Za.propHooks._default.set(this),this}},Za.prototype.init.prototype=Za.prototype,Za.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Za.propHooks.scrollTop=Za.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Za.prototype.init,m.fx.step={};var $a,_a,ab=/^(?:toggle|show|hide)$/,bb=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cb=/queueHooks$/,db=[ib],eb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bb.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bb.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fb(){return setTimeout(function(){$a=void 0}),$a=m.now()}function gb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hb(a,b,c){for(var d,e=(eb[b]||[]).concat(eb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fa(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fa(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ab.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fa(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hb(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=db.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$a||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$a||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);g>f;f++)if(d=db[f].call(j,a,k,j.opts))return d;return m.map(k,hb,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kb,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],eb[c]=eb[c]||[],eb[c].unshift(b)},prefilter:function(a,b){b?db.unshift(a):db.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kb(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),m.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($a=m.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||m.fx.stop(),$a=void 0},m.fx.timer=function(a){m.timers.push(a),a()?m.fx.start():m.timers.pop()},m.fx.interval=13,m.fx.start=function(){_a||(_a=setInterval(m.fx.tick,m.fx.interval))},m.fx.stop=function(){clearInterval(_a),_a=null},m.fx.speeds={slow:600,fast:200,_default:400},m.fn.delay=function(a,b){return a=m.fx?m.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e;b=y.createElement("div"),b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lb=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lb,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mb,nb,ob=m.expr.attrHandle,pb=/^(?:checked|selected)$/i,qb=k.getSetAttribute,rb=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nb:mb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rb&&qb||!pb.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qb?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nb={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rb&&qb||!pb.test(c)?a.setAttribute(!qb&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ob[b]||m.find.attr;ob[b]=rb&&qb||!pb.test(b)?function(a,b,d){var e,f;return d||(f=ob[b],ob[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,ob[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rb&&qb||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mb&&mb.set(a,b,c)}}),qb||(mb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},ob.id=ob.name=ob.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mb.set},m.attrHooks.contenteditable={set:function(a,b,c){mb.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sb=/^(?:input|select|textarea|button|object)$/i,tb=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sb.test(a.nodeName)||tb.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var ub=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ub," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ub," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ub," ").indexOf(b)>=0)return!0;return!1}}),m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vb=m.now(),wb=/\?/,xb=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yb,zb,Ab=/#.*$/,Bb=/([?&])_=[^&]*/,Cb=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Db=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Eb=/^(?:GET|HEAD)$/,Fb=/^\/\//,Gb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hb={},Ib={},Jb="*/".concat("*");try{zb=location.href}catch(Kb){zb=y.createElement("a"),zb.href="",zb=zb.href}yb=Gb.exec(zb.toLowerCase())||[];function Lb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mb(a,b,c,d){var e={},f=a===Ib;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nb(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Ob(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zb,type:"GET",isLocal:Db.test(yb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nb(Nb(a,m.ajaxSettings),b):Nb(m.ajaxSettings,a)},ajaxPrefilter:Lb(Hb),ajaxTransport:Lb(Ib),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cb.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zb)+"").replace(Ab,"").replace(Fb,yb[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gb.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yb[1]&&c[2]===yb[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yb[3]||("http:"===yb[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mb(Hb,k,b,v),2===t)return v;h=m.event&&k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Eb.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wb.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bb.test(e)?e.replace(Bb,"$1_="+vb++):e+(wb.test(e)?"&":"?")+"_="+vb++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jb+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mb(Ib,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Ob(k,v,c)),u=Pb(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qb=/%20/g,Rb=/\[\]$/,Sb=/\r?\n/g,Tb=/^(?:submit|button|image|reset|file)$/i,Ub=/^(?:input|select|textarea|keygen)/i;function Vb(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rb.test(a)?d(a,e):Vb(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vb(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vb(c,a[c],b,e);return d.join("&").replace(Qb,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Ub.test(this.nodeName)&&!Tb.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sb,"\r\n")}}):{name:b.name,value:c.replace(Sb,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zb()||$b()}:Zb;var Wb=0,Xb={},Yb=m.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Xb)Xb[a](void 0,!0)}),k.cors=!!Yb&&"withCredentials"in Yb,Yb=k.ajax=!!Yb,Yb&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wb;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xb[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xb[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zb(){try{return new a.XMLHttpRequest}catch(b){}}function $b(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _b=[],ac=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_b.pop()||m.expando+"_"+vb++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ac.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ac.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ac,"$1"+e):b.jsonp!==!1&&(b.url+=(wb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_b.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bc=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bc)return bc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("<div>").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cc=a.document.documentElement;function dc(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cc;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cc})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=La(k.pixelPosition,function(a,c){return c?(c=Ja(a,b),Ha.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ec=a.jQuery,fc=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fc),b&&a.jQuery===m&&(a.jQuery=ec),m},typeof b===K&&(a.jQuery=a.$=m),m}); diff --git a/src/js/toc.js b/src/js/toc.js deleted file mode 100644 index d24dbbb4a12edfb7745039f12470a6f84f6b9ec8..0000000000000000000000000000000000000000 --- a/src/js/toc.js +++ /dev/null @@ -1,65 +0,0 @@ -(function ($) { - $.fn.tableofcontents = function(options) { - var settings = $.extend({ - id: "container", // target element id - css: { - "padding": "3px", // padding size - "border": "solid 1px #CCC", // border style - "width": null // width - } - }, options); - - options = $.extend(settings, options); - - var target = $(options.id) - .append($("<div></div>").html("Contents").css({ "font-weight": "bold" })) - .append("<ul></ul>") - .css(options.css); - - var prevLevel = 0; - var getLevel = function(tagname) { - switch(tagname) { - case "H1": return 1; - case "H2": return 2; - case "H3": return 3; - case "H4": return 4; - case "H5": return 5; - case "H6": return 6; - } - - return 0; - }; - - var getUniqId = function() { - return "__toc_id:" + Math.floor(Math.random() * 100000); - }; - - this.find("h1, h2, h3, h4, h5, h6").each(function() { - var that = $(this); - var currentLevel = getLevel(that[0].tagName); - if(currentLevel > prevLevel) { - var tmp = $("<ul></ul>").data("level", currentLevel); - target = target.append(tmp); - target = tmp; - - }else { - while(target.parent().length && currentLevel <= target.parent().data("level")) { - target = target.parent(); - } - } - - var txt = that.html(); - var txtId = that.attr("id"); - if(!!!txtId) { - txtId = getUniqId(); - that.attr({ "id": txtId }); - } - - var alink = $("<a></a>").text(txt).attr({ "href": "#" + txtId }); - target.append($("<li></li>").append(alink)); - prevLevel = currentLevel; - }); - - return this; - }; -}(jQuery)); diff --git a/src/main.css b/src/main.css index afec41249dee4edc446028c1ffadec35a3800e2b..ac400d5c2d7dd6ff88b61cd81908af79ffc4774d 100644 --- a/src/main.css +++ b/src/main.css @@ -1,48 +1,72 @@ -body{ +html{ + background: #999; +} +body { + background: #fff; padding: 4em 6em; max-width: 65em; margin: 0 auto; box-shadow: 0 0 1em #ccc; + margin-left: 550px; } -#toc { +#table_of_contents { top: 0px; left: 0px; height: 100%; position: fixed; background: #333; box-shadow: inset -5px 0 5px 0px #000; - width: 150px; + width: 458px; padding-top: 20px; color: #fff; + padding-left: 2em; + overflow: auto; + padding-bottom: 5em; +} +.h2 { + margin-left: 2ch; + font-size: 0.85em; +} +.h3 { + margin-left: 4ch; + font-size: 0.75em; +} +.h4 { + margin-left: 6ch; + font-size: 0.65em; } -#toc ul { +#table_of_contents ul { margin: 0; padding: 0; list-style: none; } -#toc li { +#table_of_contents li { padding: 5px 10px; } -#toc a { +#table_of_contents a { color: #fff; text-decoration: none; display: block; } -#toc .toc-h2 { +#table_of_contents .table_of_contents-h2 { padding-left: 10px; } -#toc .toc-h3 { +#table_of_contents .table_of_contents-h3 { padding-left: 20px; } -#toc .toc-active { +#table_of_contents .table_of_contents-active { background: #336699; box-shadow: inset -5px 0px 10px -5px #000; } + +table tr:nth-of-type(odd) { + background: #dedede; +} diff --git a/whitepaper.html b/whitepaper.html deleted file mode 100644 index 3a0e6164ed6aa7a0c8bea7c3d296d297a5fe43e4..0000000000000000000000000000000000000000 --- a/whitepaper.html +++ /dev/null @@ -1,434 +0,0 @@ -<h1 id="duniter-a-libre-currency-blockchain-generator.">Duniter: A libre currency blockchain generator.</h1> -<h2 id="abstract">Abstract</h2> -<p>Many currency principles involve non-equal rights to monetary creation between humans. We propose a monetary creation based on the Relative Theory of Money, which guarantee equal monetary creation for each willing human. This type of currency can be centralised, however, this could lead to censorship and arbitrary choices of the central institution. Thus, strongly inspired by Bitcoin example, we want the currency to be as decentralised as possible, in the transaction network as in the human identification process. We use a Web of Trust between living humans for identification. This web of trust allows us to impose personalised difficulty for transaction validation, keeping the calculation accessible to low-end hardware and allowing all competent members to secure the currency.</p> -<h2 id="introduction">Introduction</h2> -<p>Duniter is a software to create and manage “libre currencies”. Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question :</p> -<blockquote> -<p>How should a currency be created to match the principle of equality between all humans, now and between generations ?</p> -</blockquote> -<p>The results of this demonstration implies a monetary creation :</p> -<ul> -<li>on a regular basis</li> -<li>for each human being</li> -<li>which amount has to be reassessed on fixed intervals according to a fixed formula.</li> -</ul> -<p>Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula :</p> -<pre><code>UD(t+1) = UD(t) + c² * ( M(t) / N(t) )</code></pre> -<p>Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin.</p> -<p>The first currency created through Duniter is Ğ1, pronounced “June”. It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software.</p> -<h2 id="state-of-the-art-bitcoin-case">1. State of the art : Bitcoin case</h2> -<!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniter uses the crypto-currency concept introduced by Bitcoin<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a>, which is to use cryptographic tools such as signatures to create trustless digital currencies. Duniter fits this definition, but it has two completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects.</p> -<h3 id="monetary-creation-a-space-time-asymmetry">1.1. Monetary creation of Bitcoin : a space-time asymmetry</h3> -<p>Space-time asymmetry refers to the relative access of individuals to newly created money<a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a>. Concretely, most existing currencies (c. 2020) are both spatially and temporally asymmetrical for their users. Let's take Bitcoin as an example to understand why.</p> -<h4 id="spatial-asymmetry">1.1.1. Spatial asymmetry</h4> -<p>When new Bitcoins are created, only some Bitcoin users (the miners) are given new Bitcoins, while everyone else get nothing. We believe this is the first injustice. However, some might say:</p> -<blockquote> -<p>"Miners used their electricity and time to get it!"</p> -</blockquote> -<p>... we would answer that this work should not have been rewarded by newly created Bitcoins. New units should be distributed to the whole community. Miners should be rewared another way, but not by money issuance. Of course, Bitcoin cannot create money through Basic Income since Bitcoin users are not strongly identified, and one might benefit from money creation multiple times if they owned several wallets. Duniter gets rid of this problem by identifying its users and creating the same amount of Basic Income to everyone.</p> -<h4 id="temporal-asymmetry">1.1.2. Temporal-asymmetry</h4> -<p>Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, how will future joiners get Bitcoins? Just like most of us do for Euros or Dollars: to get money, they will have to work for the ones who already own it.</p> -<p>We believe this is the second injustice. Every member of a monetary community should be equal concerning monetary creation, and get the same relative amount of money over time, even if they are a late adopter. Duniter aims to fix this by making the Universal Dividend (a.k.a. UD) grow by the time according to precise rules, thus making members equal toward money issuance on a half-lifespan.</p> -<p>Most currencies present one of these two asymmetries, including metal currencies and mutual credit, as exposed in the RTM.</p> -<h4 id="a-solution">1.1.3. A solution</h4> -<p>Bitcoin has taught us that it is possible to create a currency system allowing one to both create digital money and to exchange it without a central authority. What we need to change is the way money is issued so we finally have a symmetrical system. We need <strong>Bitcoin + Universal Dividend</strong>. But Universal Dividend implies that the community consists of only identified people. This is where the Web of Trust (WoT) comes into place.</p> -<p>This concept, introduced by cryptography with the OpenPGP format<a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a>, allows us to identify people in a decentralized manner. It works as follows: each person creates a personal identity that is linked to its cyptographic certificate. The identity must be confirmed by others members who use their own cryptographic key. It is that simple: people choose who is part of the community and who is not, not a central authority.</p> -<p>However, Duniter will not use OpenPGP for its cryptographic features: Elliptic Curves<a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a> will be used instead for the conciseness of its generated keys and its pratical advantages. Duniter has its own Web of Trust principles, that will be exposed later.</p> -<h3 id="proof-of-work-mining-a-power-race">1.2. Proof-of-Work mining : a power race</h3> -<p>In Bitcoin Model, the calculation and incentive principles cause a power race : new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. This leads to a power race an places the control over the currency in the hands of the richest hardware owners. We want to make Duniter blockchain validation much less energy and hardware consuming while keeping a strong level of security. This will be further explained later. A consequence of this choice is the participation of low-end hardware in the Duniter network, leading to a better decentralization of blockchain validation.</p> -<h4 id="what-about-proof-of-stake">1.2.1 What about Proof of Stake ?</h4> -<p>Proof of stake consensus algorythm was first introduced in 2012<a href="#fn5" class="footnote-ref" id="fnref5"><sup>5</sup></a>. The basic principle is to allow the richest wallets to issue blocks, putting their coin balance as a “stake” they would lose in case of cheat.</p> -<p>At the time of conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. We did not chose this consensus principle. Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead to placing power over the currency in the richests hands : this is contrary to the symmetical principles of a libre currency.</p> -<h2 id="duniters-blockchain">2. Duniters Blockchain</h2> -<!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniters Blockchain follows the basic principles of Bitcoins. This is essential for synchronization between peers, as to prevent double-spend attacks. However, Duniters Blockchain will store different informations than Bitcoins.</p> -<p>The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no generation transaction exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either:</p> -<ul> -<li>a former transaction (as in Bitcoin)</li> -<li>a Universal Dividend (specific to Duniter).</li> -</ul> -<p>Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactions are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where “space” are members of the WoT and “time” the basic blockchain units : the blocks. On each point of time, one can determine which account is legitimate to create the UD, only with a blockchain analysis.</p> -<h3 id="spam-countermeasures">2.1. Spam countermeasures</h3> -<p>An issue of most cryptocurrency projects is to prevent the common ledger from growing too much. This would require nodes to have a lot of storage and computing power to be usable. In particular, we don’t want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don’t want to introduce this mean since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented.</p> -<!-- see : https://forum.duniter.org/t/sans-frais-de-transaction-comment-resister-aux-attaques/3846/25 (implemented ?)--> -<h4 id="minimum-output-amount">2.1.1. Minimum output amount</h4> -<!-- This has to be implemented in DUBPv13. --> -<p>Fixing a minimal output amount reduces the power of an attack. Duniter deals with cents of Ğ1 or 1/1000 of the first UD. An attacker could create thousand accounts with only 1 UD. To prevent this, a valid transaction must have output amounts of minimum 1Ğ1. This reduces the power an attack by 100.</p> -<h4 id="limited-block-size-and-chainability">2.1.2. Limited block size and chainability</h4> -<p>The block size is always limited. While the protocol allows this limit to evolve to address scaling issues, an attacker cannot register as many transaction as they wish.</p> -<p>With the same goal to prevent too many transactions to get registered, while transactions can be “chained” (refer to another transaction in the same block), the chainability of transactions is limited to 5.</p> -<h3 id="scaling">2.2. Scaling</h3> -<p>Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons :</p> -<ul> -<li>Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don’t want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT should limit its size to around 16 million members.</li> -<li>Duniter’s aim is to be used to create multiple libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community.</li> -</ul> -<p>However, Duniter has assets that will help if the number of users and transactions grow.</p> -<h4 id="dynamic-block-size">2.2.1 Dynamic block size</h4> -<p>While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks(see “personalised difficulty” part for more information). This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. The block size (in bytes) is limited as so :</p> -<pre><code>block_size < max(500 ; CEIL(1.10 * (average block size))</code></pre> -<h4 id="lightning-networks">2.2.2. Lightning Networks</h4> -<p>The Lightning Networks<a href="#fn6" class="footnote-ref" id="fnref6"><sup>6</sup></a> allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed.</p> -<h4 id="unit-base">2.2.3. Unit base</h4> -<p>As the Universal Dividend grows exponentially, with time Duniter nodes would have had to deal with always largest amounts, eventually reaching the BIGINT limit. To avoid this, the amounts are expressed with a unit base in base 10. We want the UD amount to always fit in 4 digits. To manage it, the <code>unitbase</code> is updated each time the UD value reaches 100.00 : it goes from <code>99.99*10^(unitbase)</code> to <code>10.00*10^(unitbase+1)</code>. All the unit amounts are thus divided by 10. While this might seem strange, this process has already hapened in state currencies. Moreover, the amounts expressed in UD will not change.</p> -<p>With a monetary growth of 10% each year and a stable population, such a change of unit base would happen each 25 years.</p> -<h2 id="duniter-web-of-trust">3. Duniter Web of Trust</h2> -<h3 id="duniter-wot-basic-principles">3.1. Basic Principles</h3> -<p>In order to identify “members” accounts - which create monetary units - and other accounts, Duniter uses a Web of Trust. This can be summarized into few principles:</p> -<ul> -<li>Each account becomes a member if it received a minimal number of certifications - 5 for Ğ1 currency.</li> -<li>Only members accounts can send certifications. Certifications have a limited lifespan.</li> -<li>A certification indicates that the sender accepts the receiver as a legitimate identity.</li> -</ul> -<p>The aim of the WoT is to identify a blockchain account to a living human. According to Lauterbach et.al<a href="#fn7" class="footnote-ref" id="fnref7"><sup>7</sup></a>, the strengh of a relationship should be considered when building a vouch system. For this reason, the Ğ1 Web of Trust rules are expressed in a licence stating what WoT certifications are. A certification represents a strong human relationship : one may certify a close relative, not an acquaintance. Each member has to accept this licence before being included in the WoT. Thus, if a member is part of an attack on the currency, they can be found by mutual relatives. Additional security rules occur to prevent cheat and attacks on a large scale.</p> -<p>Note that non-members accounts can use the currency, but cannot create money. Non-members accounts can be used by individuals as secondary wallets, or by institutions.</p> -<p>We were inspired by the OpenPGP Trust system<a href="#fn8" class="footnote-ref" id="fnref8"><sup>8</sup></a>. However, the OpenPGP trust principles aim at defining trust from a particular point of view while Duniter needs to identify humans for the whole community. To achieve this goal, while OpenPGP allows each user to tweak its trust parameters individually, Duniter sets rules in the “genesis” block for the whole community.</p> -<h3 id="why-do-we-need-a-web-of-trust">3.2. Why do we need a Web of Trust ?</h3> -<p>There are two reasons we need it :</p> -<ol type="1"> -<li>To make sure that only one Universal Dividend is produced per member at each specified creation interval. In the Ğ1’s case this interval is set as daily <code>86 400</code> seconds, it is the <em>monetary parameter</em> known as <code>dt</code>.</li> -<li>To identify the nodes hashing the blocks and assign each a personalised difficulty. This custom difficulty proof of work is there to avoid the blockchain’s validation mechanism becoming too centralised as is the case with many 'non-libre’ cryptocurrencies.</li> -</ol> -<blockquote> -<p><strong>Monetary parameter</strong> : Each currency that use Duniter has its own blockchain whose behaviour is dictated by a set of ‘parameters’ defined in block zero - the so-called genesis block - that can be tweaked to achieve the desired results. At the time of writing the Whitepaper, the Duniter Blockchain Protocol (DUBP) has a total of 21 parameters of which 10 are for the WoT alone. We’ll focus on these 10.</p> -<p>Suffice to say that in the Ğ1’s case, the DU is created every 24 hours - 86 400 seconds. This interval is set through the time derivative <code>dt</code> parameter and can have a different value in other implementations of the protocol.</p> -</blockquote> -<p>We want to make sure that each member can only have one account. As we all know, achieving zero-risk isn’t possible<a href="#fn9" class="footnote-ref" id="fnref9"><sup>9</sup></a>. Our goal is therefore not to create a WoT within which fraud would be absolutely impossible, but instead to discourage it. Here is a rewording of our goal in 4 smaller ones :</p> -<ol type="1"> -<li>Make the certification process lengthy enough that all members exercise due diligence and are wary of risks.</li> -<li>Make fraudulent acts as hard as we can to the extent that they become pointless.</li> -<li>Ensure that any Sybil attacks have a negligible impact on the currency by ensuring that illegitimate double Universal Dividends have no significant bearing on the legitimate monetary mass</li> -<li>Slow the growth of ‘Sybil regions’ to give enough time for the community to react and isolate the threat.</li> -</ol> -<blockquote> -<p><strong>Sybil attack</strong> : A Sybil attack is an attack perpetrated on a reputation system through the creation of fake identities. A Web of Trust is a specific instance of a Reputation System.</p> -</blockquote> -<p>There are plenty of Sybil attack scenarios we can think of and just as many reasons why their perpetrators would want to carry them out. Our objective is that the configuration of the WoT protects both users and its IT backbone infrastructure against these attacks.</p> -<p>This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web’s role isn’t to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing your tap water and electricity but isn’t responsible for any burglaries, etc. Much in the same way, Duniter’s WoT guarantees us all a functional currency, but do not detect small fraud.</p> -<h3 id="own-certification-system">3.3. The importance of having our own certification system</h3> -<p>Centralized identification systems can achieve the goal we want. State Identification is an example. However, this has many drawbacks :</p> -<ul> -<li>The authority may have arbitrary criteria for identification, for example preventing people without an official state-provided identity or homeless people to be included in the WoT.</li> -<li>Payment might be required to get identified, thus making the monetary creation not “free”.</li> -<li>The authority is a point of failure for any attacker.</li> -</ul> -<p>It is of the utmost importance that we remain free from any state or corporation. The WoT is an answer to this criterium. To this day we depend only on the Internet and yet, were it to fail, there are already alternatives being tested around the world for a decentralised communication network.</p> -<h3 id="graph-theory-vocabulary">3.4. A few foundational concepts on graph theory : a bit of vocabulary</h3> -<ul> -<li><p><strong>Graph</strong>: set of points -called ‘vertices’- joined by edges -called paths/walks-.</p></li> -<li><p><strong>Simple graph</strong>: a graph with no loops and with no multiple edges. That is, each edge connects two distinct endpoints and no two edges have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise.</p></li> -<li><p><strong>Directed graph</strong>: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. Arrow A –> B is therefore different from arrow B –> A.</p></li> -<li><p><strong>Endpoints</strong>: the edge with vertex A –> B has A and B as endpoints, respectively as start and end of the path/walk.</p></li> -<li><p><strong>Isolated vertex</strong>: a vertex whose degree is zero, that is, a vertex with no incident edges.</p></li> -<li><p><strong>Degree of a vertex</strong>: number of its incident edges -in and out-.</p></li> -<li><p><strong>Out-degree of vertex A</strong>: number of outbound edges / tail ends from A.</p></li> -<li><p><strong>In-degree of vertex A</strong>: number of incoming edges / head ends to A.</p></li> -</ul> -<figure> -<img src="./images/degres.jpg" alt="degrees of a vertex diagram" /><figcaption>degrees of a vertex diagram</figcaption> -</figure> -<ul> -<li><strong>Path</strong>: -aka “walk”- path to follow to get from vertex A to vertex B.</li> -</ul> -<h3 id="definition-of-the-duniter-web-of-trust">3.5. Definition of the Duniter Web of Trust</h3> -<p>The Duniter WoTs -one per currency- are simple directed graphs without isolated vertices. The vertices are the members and the edges are the certifications given and received.</p> -<p><em>Directed</em> means that the responsibility of issuing a certification is unique and personal to the certifier. The trust they place in the receiver cannot be imposed in the other direction although in most circumstances both parties equally trust each other.</p> -<p>In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific ‘deactivated state’ and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered ‘pending’ to avoid a collapse of the WoT. If these old members don’t come back into the WoT, their pending certifications will eventually expire and they will switch from ‘deactivated’ to ‘isolated’ vertices.</p> -<p>To wrap up with old members, after a certain period of time - set in the currency’s parameters - their deactivated vertex is removed from the web and the associated identity is ‘revoked’. The person who owned the account can no longer use this identity but is free to join the web with another one.</p> -<blockquote> -<p><strong>Identity</strong> : An identity is a set of three pieces of information: a public key, a name and a blockstamp. A blockstamp points to a specific block in the chain. Its main use is to freeze the point in time at which an identity was created and to link this identity to a specific chain and a currency - each currency having its own blockchain.</p> -<p>An identity can be in any one of 5 different status: pending, member, old member, revoked or excluded.</p> -</blockquote> -<p>Let’s take a simple example:</p> -<pre><code> A -> B -> C - | - \--> D</code></pre> -<p>If, for whatever reason, A were to lose its member status, the web would crumble and all other members would be excluded as a consequence. To avoid this, the certification from A –> B will remain valid until its expiry date, leaving enough time for B to receive certifications from C or D.</p> -<p>Because our WoT doesn’t have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications it has received, all in the same block. This calls for a temporary ‘buffer’ storage space for <strong>pending</strong> identities and the certifications they have received. This storage space is called ‘the pool’ of Duniter nodes, which we could also have called the ‘sandbox’ as that’s the name used in Duniter’s code. Duniter nodes inclued other ‘pools’ for other documents and metadata not mentioned here.</p> -<h3 id="exploring-the-rules-behind-duniter-wot">3.6. Exploring the rules behind a Duniter Web of Trust</h3> -<p>The Duniter WoTs - one per currency - works with a set of eight fundamental rules enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - <code>msPeriod</code>- having being hard-coded in the Ğ1’s code subsequently.</p> -<h4 id="distance-rule-and-referent-members-stepmax-and-xpercent">3.6.1. Distance rule and referent members (<code>stepMax</code> and <code>xPercent</code>)</h4> -<p>These two parameters are closely linked and together define the ‘distance rule’. The ‘distance rule’ can only be described after defining what a ‘referent member’ is:</p> -<blockquote> -<p><strong>Referent member</strong>: member A is said to be ‘referent’ if and only if the total of their degrees are greater than or equal to <code>CEIL-N^-1/stepMax</code> where N is the total number of members. As the size of the web will grow this number will grow too, meaning it will take more certification issuances to become a referent member. The number of certifications needed to become a member shouldn’t change.</p> -</blockquote> -<p>Let’s now define the distance rule:</p> -<blockquote> -<p><strong>Distance rule</strong>: member A is said to observe this rule if and only if for a subset xPercent % of referent members R there exists a path of length less than or equal to <code>stepMax</code> between R and A.</p> -</blockquote> -<p>Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect web, that is one in which each member has certified all members they legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time <code>t</code> who haven’t yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would effectively stop growing.</p> -<p>Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets confirmed into the web or an existing member gets renewed. There is an exception to this rule: the distance rule is not observed in the genesis block -when the web is first implemented.</p> -<h4 id="rule-of-the-minimum-number-of-certifications-needed-sigqty">3.6.2. Rule of the minimum number of certifications needed (<code>sigQty</code>)</h4> -<p>This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least <code>sigQty</code> active certifications. If, for whatever reason, member A were to have less than <code>sigQty</code> active certifications in a given block, they would cease to be a member and be required to publish a request for identity renewal.</p> -<h4 id="the-membership-renewal-rule-msvalidity-msperiod-and-mswindow">3.6.3. The membership renewal rule (<code>msValidity</code>, <code>msPeriod</code> and <code>msWindow</code>)</h4> -<p>Bear in mind that a membership doesn’t last a lifetime but instead has a lifespan set to <code>msValidity</code> seconds.</p> -<p>Every single member -or old member who hasn’t revoked his identity or been excluded- can request a membership renewal so long as the last request was made more than <code>msPeriod</code> seconds ago. If a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the ‘pool’ for a maximum of <code>msWindow</code> seconds before it’s included in the blockchain. Once again, this can only happen once/if the member meets both the <code>siqQty</code> rule and the distance rule -if these criterion are already matched it’s just a case of waiting for a new block to be mined-.</p> -<p>If a member hasn’t requested a renewal for longer than <code>msValidity</code> seconds, they automatically cease to be a member. From this moment on, the ex-member has another <code>msValidity</code> window to renew their membership. When this period of <code>2 × msValidity</code> runs out, the membership will expire and this identity will never be available for use again in the web. If the person so desires, they will have to publish new identity and membership documents and find enough certifiers, as any newcomer.</p> -<h4 id="rule-of-certification-lifespan-sigvalidity">3.6.4. Rule of certification lifespan (<code>sigValidity</code>)</h4> -<p>All certifications included in the blockchain expire <strong>sigValidity</strong> seconds after they were <strong>issued</strong>.</p> -<blockquote> -<p>/!\ The issuance and the inclusion of a certification in the blockchain occur at different times. When member A issues a certification at time t1, it gets stored in the pool starting at t1 and only finds its way into the blockchain at t2 when all of the web’s rules are observed. Several weeks can thus go by between t1 and t2!!!</p> -</blockquote> -<h4 id="rule-of-limited-supply-of-active-certifications-sigstock">3.6.5. Rule of limited supply of active certifications (<code>sigStock</code>)</h4> -<p>By ‘active certifications’ we refer to certifications included in the blockchain and that haven’t yet expired.</p> -<p>The total of active certifications issued by any member at any single time must be less than or equal to <code>sigStock</code>. When this threshold is reached the member will have to wait for one of his active certifications to expire before he/she can issue a new one.</p> -<h4 id="rule-of-the-time-period-between-two-certification-issuances-sigperiod">3.6.6. Rule of the time period between two certification issuances. (<code>sigPeriod</code>)</h4> -<p>As soon as a certification issued by member A gets included in the blockchain, they will be unable to issue a new one before another <code>sigPeriod</code> seconds.</p> -<h4 id="expiry-of-a-certification-issuance-sigwindow">3.6.7. Expiry of a certification issuance (<code>sigWindow</code>)</h4> -<p>When a certification is issued by member A, it will be stored in the ‘pool’ for a maximum of <code>sigWindow</code> seconds. If the certification hasn’t been included in the blockchain by then, it will be cancelled and the member’s <code>sigStock</code> will be repleted by one.</p> -<h4 id="lifespan-of-a-pending-identity-idtywindow">3.6.8. Lifespan of a ‘pending’ identity (<code>idtyWindow</code>)</h4> -<p>When a new identity is created, it is stored in the ‘pool’ for a maximum of <code>idtyWindow</code> seconds. If the person hasn’t achieved member status by then, the certification will simply be cancelled.</p> -<h3 id="details-on-some-of-the-wots-peculiarities-at-the-genesis-block">3.7. Details on some of the WoT’s peculiarities at the genesis block</h3> -<p>The aforementioned rules can only be enforced with an existing web. They cannot be observed when first creating the web, that is when defining the genesis block.</p> -<p>Only rules 2 and 5 can be observed at the genesis block.</p> -<p>The genesis block has to be manually created by the founding members. In practice this means that there must be a choice on which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities.</p> -<p>As soon as the genesis block has been created, the other identities can start mining the blockchain and the member who created block #0 effectively looses the decision power he had at creation.</p> -<h3 id="why-these-rules-and-application-cases-in-the-g1">3.8. Why these rules and application cases in the Ğ1</h3> -<h4 id="distance-and-maximum-size">3.8.1. Distance and maximum size</h4> -<p>The distance rule is there to curb the maximum size of a Sybil region as well as that of the monetary community as a whole. The <code>xpercent</code> parameter prevents the creation of a ‘faction’ that could take hold of the blockchain.</p> -<figure> -<img src="./images/wot-sybil.jpg" alt="Sybil region" /><figcaption>Sybil region</figcaption> -</figure> -<p>The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned Sybil members. As a consequence, the shortest edge/path between a legitimate member and a Sybil one has to have the attack’s author as an endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as <code>stepAttackers</code>. The maximum size of a Sybil region created by <code>sigQty</code> members depends on the L parameter, defined as <code>L = sigQty/sigStock</code>:</p> -<pre><code>MaxSybilSize= (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L)</code></pre> -<p>The maximum size of the Web of Trust is given by the following formula:</p> -<pre><code>WoTmax = (sigStock)*L^(stepMax-1)</code></pre> -<p>However we know for a fact that members will never use all of their available certifications. According to Dunbar<a href="#fn10" class="footnote-ref" id="fnref10"><sup>10</sup></a>, on average, one is able to maintain relationships to around 150 people. Being conservative, we will consider that on average, each person will certify 50 accounts. We can calculate the size of the average web of trust <code>WoTavg</code> :</p> -<pre><code>WoTavg= (50)*(sigQty/50)^(stepMax-1)</code></pre> -<p>Our goal with the Ğ1 is to create a community of about one million members to test the consequences of a libre monetary system. Let’s see how we can tweak the pair of sigQty and stepMax- to reach this size:</p> -<figure> -<img src="./images/wot-moy.png" alt="Average WoT size graph as a function of sigQty and stepMax" /><figcaption>Average WoT size graph as a function of sigQty and stepMax</figcaption> -</figure> -<p>The maximum size of a Sybil region grows linearly with <code>sigQty</code> but exponentially with <code>stepMax</code>. Logic has it that we need to keep <code>stepMax</code> as low as possible to ensure sufficient strength to the web. The above graph shows that the lowest value of <code>stepMax</code> for a web of a million members is of 5. This is an order of magnitude and is likely to be much higher in reality, we cannot measure it for sure.</p> -<p>For <code>sigQty</code> we can choose a value of <strong>4</strong> for a web of <strong>1.5 million members</strong> or <strong>5</strong> for <strong>half a million members</strong>. Bear in mind these are gross figures and could be significantly higher, we are talking anywhere between 1 and 10 million in reality. Calculating WOTavg gives us a pretty good idea of how the web would scale bearing in mind that it considers all members are referent members too -which isn’t the case as explained previously-. Hence the maximum size of the web is likely larger, a ballpark figure of half a million is enough for now especially knowing that the smaller <code>sigQty</code> is, the easier it is to launch a Sybil attack -it’s easier to find four accomplices than five-. For security reasons we have settled on five:</p> -<pre><code>stepMax = 5 -sigQty = 5 -sigStock \>= 50</code></pre> -<p>The maximum size of a Sybil region therefore is:</p> -<pre><code>(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))</code></pre> -<p>with sigStock = 50 we have a Sybil region of:</p> -<pre><code>45*(1-10^(5-stepAttackers))/(-9)</code></pre> -<p>A good practice for protecting the web is to maximise <code>stepAttackers</code>. That’s why we decided that referent members in the genesis block had to be at least four steps away from each other.</p> -<p>Another way to keep a Sybil attack at bay, were it slow enough for members to notice it, would be for referent members to ‘stretch’ the web intentionally to limit the growth of the region by ensuring that the attackers’ legitimate certifications received in the first place aren’t renewed. But what if bot accounts were created and certified each other super fast and following all rules, how would we counter that? By introducing a minimum length of time between two certifications!</p> -<h4 id="time-is-our-friend">3.8.2. Time is our friend</h4> -<p>To help us deter a Sybil attack, we’ve decided to impose a minimum period of time between any two certifications issued from a single account. This parameter called <code>sigPeriod</code> affords us a greater chance to detect the formation of a ‘hostile’ faction.</p> -<p>Here is a graph showing the evolution of a Sybil region with the variation of <code>sigPeriod</code>. The simulation considers that honest members and attackers both issue a certification each <code>sigPeriod</code> interval, in days:</p> -<figure> -<img src="./images/impact_sig_period.png" alt="size of the WoT according to sigPeriod and stepAttackers" /><figcaption>size of the WoT according to sigPeriod and stepAttackers</figcaption> -</figure> -<p>As we see, there is a strong link between the growth speed of the region and <code>sigPeriod</code>. As evidenced here, we need a <code>sigPeriod</code> high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher <code>sigPeriod</code> is, the more members will exercise their certification power gingerly, the action coming at a higher ‘cost’.</p> -<p>There are numerous advantages to giving <code>sigPeriod</code> a high value and no technical barriers to it, hence our choice of five days.</p> -<p>We could have also gone for one week for the sake of simplicity. However there is an underlying idea behind our choice which was quite simply the pace of today’s life. Certifying someone can be a lengthy process as one needs to make sure they are correctly applying the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea to allow one to certify at the end of every working week -five days- instead of a whole calendar one.</p> -<h4 id="trust-me-now-trust-me-forever-sigvalidity-msvalidity">3.8.3. Trust me now, trust me forever ? (<code>sigValidity</code>, <code>msValidity</code>)</h4> -<p>There would be two main drawbacks to a lifetime membership in the Ğ1’s Web of Trust:</p> -<ul> -<li>First of all, some members will pass and those accounts should no longer produce the Universal Dividend.</li> -<li>Secondly it is of the utmost importance that ‘rogue’ accounts can be excluded from the web at some point.</li> -</ul> -<p>To achieve this, certifications have a limited lifespan. Members need to seek renewal from their peers after <code>sigValidity</code> time. On the other hand, this time can’t be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, a certification with too short a lifespan would foster careless certifying behaviours. The act of certifying must have a high-enough ‘perceived’ cost to make it feel like an important act. Lastly, we also wanted this lifespan to be easy to remember. Historically speaking, we first settled on the values of <code>sigPeriod</code> and <code>sigStock</code>, meant one could issue all of their certifications in 495 days, one year was therefore not long enough. We deemed three years to be too much and that’s how we agreed on two years in the end.</p> -<p>Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we needed to address. We chose a value of one year for <strong>msValidity</strong>. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to ‘prune’ the web of past or inactive members who don’t renew their membership.</p> -<h4 id="keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow">3.8.4. Keeping the pools free of information glut (<code>idtyWindow</code>, <code>sigWindow</code>, <code>msWindow</code>)</h4> -<p>The pools need to be cleaned up on a regular basis to avoid them clogging up with information and to ensure that machines with less calculating power can still run a Duniter node.</p> -<p>To achieve this, identities with pending membership approval and the corresponding certifications have to remain the shortest time possible in the pool while still having a chance of making it into the blockchain.</p> -<p>For the Ğ1, our opinion was that two months would be enough for all potential certifiers to agree on a specific identity to certify. We also wanted a time period that would be easy enough to remember by all. We settled on two months, and gave this value to all three parameters <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>.</p> -<h4 id="avoiding-single-members-from-knowing-too-many-people-sigstock">3.8.5. Avoiding single members from ‘knowing too many people’ (<code>sigStock</code>)</h4> -<p>We considered that on average, each person will certify 50 people. However, we know for a fact that some members will use more than 50 certifications. The maximum social network of one individual is around 150 people<a href="#fn11" class="footnote-ref" id="fnref11"><sup>11</sup></a>. Being conservative, we settled on a maximum certification number <code>sigstock</code> of 100.<br /> -Since <code>sigStock</code>’s impact on the size of a Sybil region is fairly limited, we did not investigate further this parameter.</p> -<h4 id="avoiding-locking-minorities-xpercent">3.8.6. Avoiding locking minorities (<code>xpercent</code>)</h4> -<p>It’s easy enough to become a referent member, one of the Sybil strategies could therefore be to create a region of referent members. Such a region would grow slower than otherwise but could confer a locking power to its members by using the distance rule. That’s why the distance rule cannot be calculated on 100% of the referent members. Hence the introduction of the <code>xpercent</code> parameter which defines the percentage of referent members needing to be less than five edges -steps- from each other.</p> -<p>This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance rule. The <code>xpercent</code> parameter was one of the hardest to define, therefore we might decide to change its value during the Ğ1 experiment.</p> -<p>We were inspired by the Pareto principle<a href="#fn12" class="footnote-ref" id="fnref12"><sup>12</sup></a>: if at least 20% of members give good density to the web, 80% of the referent members will be five or less steps from any other member -referent or not-. The maximum value for <code>xpercent</code> is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%.</p> -<h4 id="spam-protection-with-msperiod">3.8.7. Spam protection with (<code>msPeriod</code>)</h4> -<p>This parameter stands out a bit on its own, as it was added after the genesis block. It is there to protect the Duniter P2P infrastructure against ‘spam’ attacks. We had to think of a strategy against attacks such as high-frequency membership renewal requests -i.e: in every block, every five minutes- or worse still, hundreds of these requests per minute to flood the Duniter nodes. Without such limits, nodes are supposed to address all renewal requests, even in cases where they were last published five minutes ago! The <code>msPeriod</code> parameter was given the same value as <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>, i.e. two months.</p> -<h2 id="proof-of-work-with-personalized-difficulty">4. Proof of Work with personal difficulty</h2> -<p>As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human.</p> -<p>This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each “winning” member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. A view of the whole network is not needed.</p> -<p>Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power.</p> -<p>One could say that Duniter uses a PoW that needs very low energy consumption compared to BitCoin : an “ecological” PoW ?</p> -<!-- source : https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ --> -<h3 id="why-proof-of-work">4.1. Why do we need Proof of Work ?</h3> -<p>Duniter nodes share a database as part of a p2p environment. The proof of work (PoW) allows machines to synchronize with each other. In Duniter’s case, the blockchain is our database, and acts as a ledger keeping a trace of all transactions, status of the WoT and more. How can we let several machines add data (ie: a transaction) at the same time? In addition, how do we settle on how much time has gone by since the blockchain was last updated? Agreement on time is of the utmost importance as we want to create Universal Dividends on a regular basis, and keep track of membership status, both in human time.</p> -<p>Proof-of-work provides a clever solution to both problems:</p> -<ol type="1"> -<li><p>Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, ensuring the unicity of a block’s creator.</p></li> -<li><p>Solving this challenge takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and Duniter adapts the challenge difficulty to get an average duration corresponding to this block time.</p></li> -</ol> -<h3 id="only-members-can-mine">4.2. Only members can “mine”</h3> -<p>One of Duniter’s major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member’s private key, allowing the algorithm to determine a personalised difficulty.</p> -<p>This personalised difficulty eliminates the rat-race for the most sophisticated and powerful mining equipment. Another benefit is the fact that no “supercomputer” can take control of the blockchain. Lastly, Duniter implements a rotation in forging members thanks to this personalized difficulty.</p> -<p>This lightweight PoW is much less energy-consuming than other PoW cryptocurrencies. Members can mine with anything from a raspberry pi to a privacy-first internet cube.</p> -<h3 id="how-does-duniter-pow-work">4.3. How does it work ?</h3> -<h4 id="the-hash">4.3.1. The hash (aka digest)</h4> -<p>Example of a valid hash:</p> -<pre><code>00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653</code></pre> -<p>As you can see this hash starts with five zeros which was very hard to achieve and took a lot of work for someone’s computer. Hence the term “proof of work”.</p> -<h4 id="common-difficulty">4.3.2. The common difficulty</h4> -<p>A common difficulty is needed to settle on a yardstick for our time reference. Its role is to make sure the blockchain moves forward at a steady pace - one block every <code>avgGenTime</code> seconds, <code>avgGenTime</code> being one of the 20 parameters behind the Duniter protocol-.</p> -<p>This difficulty’s initial value can be set to any arbitrary value (<code>70</code> in Duniter <code>v1.5.x</code>) and then acts as a spring, regulating blocktime creation by increasing itself if the creation interval drops under <code>avgGenTime</code> and vice-versa.</p> -<h5 id="how-is-difficulty-applied">4.3.2.1. How is difficulty applied ?</h5> -<p>The numeric value of difficulty is taken from an array of possible hashes out of all possible hashes. In DUBPv13 the hash of a block is its sha256 hexadecimal hash.</p> -<p>To understand the difficulty, we make a euclidiean division of the difficulty by 16.</p> -<p>Here’s an example with a difficulty value of 70 :</p> -<pre><code>70 // 16 = 4 with a remainder of 6. </code></pre> -<p>The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : <code>0000[0-9]</code>. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes.</p> -<h5 id="the-nonce">4.3.2.2. The Nonce</h5> -<p>When a member is forging a new block, his computer freezes the block’s content and changes the Nonce until the hash reaches the required number of zeroes.</p> -<p>The nonce allows us to mine a new block by finding a hash. The hash value allows us to determine the difficulty level of the proof-of-work performed. Examples of possible Nonce values:</p> -<ul> -<li>10100000112275</li> -<li>10300000288743</li> -<li>10400000008538</li> -<li>10700000079653</li> -<li>10300000070919</li> -</ul> -<p>In reality the <code>Nonce</code> value follows a pre-determined format akin to <code>XYY00000000000</code>. The Nonce’s value isn’t the number of attempts but rather a value within a set of possible ones. This is how the Nonce is built:</p> -<ul> -<li><p>X is a number assigned to a specific peer. Let’s assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with different nodes. Each <del>block</del> <strong>node ?</strong> will therefore have its own unique X to prevent this from happening.</p></li> -<li><p>Y is the number of cores of the processor. The Nonce starting with <code>107[…]</code> belongs to a seven cores processor, while <code>199[...]</code> could be the proof generated by a 99 cores processor.</p></li> -</ul> -<p>The rest of the Nonce, the part that follows after the XYY, is the numerical space for this individual node and is unique to each of the CPU’s core. This space is comprised of eleven digits (<code>00000000000</code>). For the sake of accuracy, we use the term CPU in the wider sense, it can be understood as a bi-CPU for example. We take into consideration the number of cores for the resulting PoW.</p> -<h3 id="personalised-difficulty">4.4. Personalised difficulty</h3> -<p>Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other PoW-based cryptocurrencies.</p> -<p>Here is how this personalised difficulty is calculated and assigned:</p> -<p>It is determined by a combination of two different constraints with complimentary roles: the <strong>exclusion factor</strong> and the <strong>handicap</strong>.</p> -<p>Let <code>powMin</code> be the common difficulty, <code>exFact</code> a member’s exclusion factor and <code>handicap</code> their handicap. This member’s personalised difficulty <code>diff</code> is:</p> -<pre><code>diff = powMin*exFact + handicap</code></pre> -<h4 id="the-exclusion-factor">4.4.1. Understanding <code>exFact</code>, the exclusion factor</h4> -<p>Members who have never produced blocks or haven’t for quite some time are assigned an exclusion factor of <code>1</code>. Their personalised difficulty is therefore simply the sum of <code>powMin + handicap</code>.</p> -<p>Before reading on, let’s precise the role of this exclusion factor. When a member adds a block to the chain, his <code>exFact</code> jumps up from one to a very high value, to prevent them from forging other blocks immediately after and taking control of the blockchain.</p> -<p>The exclusion factor will then rapidly return to one. This delay is expressed as a number of blocks. It is calculated as a proportion of the number of members forging. In the Ğ1’s case, this proportion is 1/3, meaning that if there are fifteen members currently forging, the member’s exclusion factor will drop down to one after five blocks.</p> -<h5 id="what-is-intended-by-the-number-of-members-forging">4.4.1.1. What is intended by “the number of members forging” ?</h5> -<p>We mean the number of members trying to create the next block. In reality, there is no way to precisely know how many members are calculating at any given time, because it is impossible to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block in the last blocks in the current window, minus the very last one.</p> -<h5 id="current-window">4.4.1.2. Current window</h5> -<p>We use the concept of <strong>current window</strong>. The current window is the number of blocks we look back at to determine how many members are forging. Let’s see how it works:</p> -<ul> -<li><p><code>issuersFrame</code> is the size of the current window in blocks.</p></li> -<li><p><code>issuersCount</code> the number of members who have calculated at least one block during the current window.</p></li> -</ul> -<p>Both <code>issuersFrame</code> and <code>issuersCount</code> are block fields. When first starting a blockchain, the very first block has an <code>issuersFrame=1</code> and an <code>issuersCount=0</code>. The genesis block is excluded as there are no members in the current window!</p> -<p>From the second block onwards (block #1) we track the variation of <code>issuersCount</code>. The member having mined block #0 enters the current window and in block #1 we will therefore mention <code>issuersCount=1</code>.</p> -<p><code>issuersFrame</code> then varies as follows:</p> -<ul> -<li>if <code>issuersCount</code> increases by N (with a maximum step of N = 1), then <code>issuersFrame</code> will increase by one unit over a period of 5N blocks.</li> -<li>Conversely, if <code>issuersCount</code> decreases by Y (with a maximum step of Y = 2 = current window inching forward + loss of one calculating member), then <code>issuersFrame</code> will decrease by one unit during 5Y blocks.</li> -<li>When such events overlap, <code>issuersFrame</code> evolves as so :</li> -</ul> -<table> -<thead> -<tr class="header"> -<th>bloc</th> -<th>event</th> -<th>issuersFrame</th> -</tr> -</thead> -<tbody> -<tr class="odd"> -<td>T</td> -<td>Babar writes a block and enters issuersCount</td> -<td>160</td> -</tr> -<tr class="even"> -<td>T+1</td> -<td>Celeste leaves issuersCount</td> -<td>160 +1 = 161</td> -</tr> -<tr class="odd"> -<td>T+2</td> -<td>N/a</td> -<td>161 +1 -1 = 161</td> -</tr> -<tr class="even"> -<td>T+3/4/5</td> -<td>N/a</td> -<td>161 +1 -1 = 161</td> -</tr> -<tr class="odd"> -<td>T+6</td> -<td>N/a</td> -<td>161 -1 = 160</td> -</tr> -</tbody> -</table> -<p>The calculation can be found under rules <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g05-headissuersframe">BR_G05</a> and <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g06-headissuersframevar">BR_G06</a> of the DUP protocol.</p> -<h5 id="exfact-and-the-personalised-difficulty">4.4.1.3. exFact and the personalised difficulty</h5> -<p>We explained that <code>exFact</code> spikes immediately after the member has found a block. It decreases then rapidly to <code>1</code> after a number of blocks equal to <code>1/3 * issuersCount</code>. Let’s see precisely how we calculate <code>exFact</code>:</p> -<ul> -<li><p><code>nbPreviousIssuers</code> is the value of issuersCount at the last block <code>N</code> found by the member.</p></li> -<li><p><code>nbBlocksSince</code> is the number of blocks found by the rest of the network since block <code>N</code>.</p></li> -<li><p><code>percentRot</code> is the number of <em>not excluded</em> peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency.</p></li> -</ul> -<pre><code>a = FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) -exFact = MAX [ 1 ; a ]</code></pre> -<p>The FLOOR is a simple truncate function. For <code>exFact</code> to exclude the member, we need :</p> -<pre><code>(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2</code></pre> -<p>We can see that the member is not excluded if <code>nbBlocksSince</code> is greater than 1/3 of the calculating members. Take as an example <code>nbPreviousIssuers = 6</code> and <code>nbBlocksSince = 3</code>:</p> -<pre><code>(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1</code></pre> -<p>However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded:</p> -<pre><code>(0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2</code></pre> -<p>Moreover if the last block was authored by the said member, then:</p> -<pre><code>nbBlocksSince=0 and -exFact = 0.67 * nbPreviousIssuers</code></pre> -<p>ExFact value increases according to the number of members calculating. Thus, if there is enough members calculating, even mining farms would be excluded. We have therefore succeeded in our intent to deter attempts to seize the blockchain and its currency.</p> -<p>However, at any time <code>t</code>, the two-thirds of calculating members all have an exclusion factor of <code>1</code>, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then only the members with the highest computational power from the remaining third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn’t stand a chance…</p> -<h4 id="the-handicap">4.4.2. The handicap</h4> -<p>The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. A higher handicap is assigned to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW.</p> -<p>The aim is to handicap the half that has authored most blocks (the most powerful half) to favour the other one. So, the handicap formula will use the median number of blocks authored by peers within the current window.</p> -<ul> -<li><p><code>nbPersonalBlocksInFrame</code> is the number of blocks authored by a single member within the current window.</p></li> -<li><p><code>medianOfBlocksInFrame</code> is the median number of blocks written by the calculating members during the same timeframe.</p></li> -</ul> -<pre><code>a = (nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame -handicap = FLOOR(LN(MAX( 1 ; a )) / LN(1.189))</code></pre> -<p>Let’s unwrap the formula:</p> -<pre><code>(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)</code></pre> -<p>is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored <code>9</code> blocks in the current window and the median is <code>5</code>, then the ratio will be <code>(9+1)/5 = 2</code>. The MAX function allows us to ensure that the handicap has a value at least equal to <code>1</code>.</p> -<p>The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers.</p> -<p>If we wanted the handicap to be applied as soon as the median is reached, we would divide it by <code>LN(1)</code>. The problem is that we have already set a minimum value of <code>1</code> with the MAX function. If we were to divide the ratio by <code>LN(1)</code> all calculating peers would have a handicap <code>\>= 1</code>. In addition, is it really fair to handicap a member who is right on the median?</p> -<p>That’s why we went for <code>1.189</code> rather than <code>1</code>. A member has to be at least <code>18.9%</code> above the median to be assigned a handicap. 18.9% is actually 16^(1/16), the difficulty factor between two levels of the proof work (hexadecimal hash).</p> -<p>To conclude, you have to remember that :</p> -<ul> -<li>The handicap is indexed on the logarithm of the ratio to the median,</li> -<li>Handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work’s difficulty.</li> -</ul> -<h2 id="conclusion">Conclusion</h2> -<!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniter’s Blockchain can be compared to Bitcoin’s : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend.</p> -<p>More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers, maintaining a good security and helping decentralization of calculation.</p> -<p>The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties :</p> -<ul> -<li>The freedom to choose your currency system: because money should not be imposed.</li> -<li>The freedom to access resources: because we all should have access to economic & monetary resources.</li> -<li>The freedom to estimate and produce value: because value is a purely relative to each individual.</li> -<li>The freedom to trade with the money: because we should not be limited by the avaible money supply.</li> -</ul> -<p>Those 4 economic freedoms should be understood together, not exclusively. Plus, “freedom” has to be understood as “non-nuisance”. So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency.</p> -<h2 id="sources">Sources :</h2> -<ul> -<li>Relative Theory of Money, S.Laborde, 2010: <a href="http://en.trm.creationmonetaire.info/">en.trm.creationmonetaire.info/</a></li> -<li>Bitcoin Whitepaper, S.Nakamoto, 2008: <a href="https://bitcoin.org/bitcoin.pdf">bitcoin.org/bitcoin.pdf</a></li> -<li>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : <a href="http://lightning.network/lightning-network-paper.pdf">lightning.network/lightning-network-paper.pdf</a></li> -<li>The GNU Privacy Handbook, M.Ashley, 1999 : <a href="https://www.gnupg.org/gph/en/manual.html#AEN335">www.gnupg.org/gph/en/manual.html#AEN335</a></li> -<li>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. <a href="https://cr.yp.to/papers.html#ed25519">cr.yp.to/papers.html#ed25519</a>.</li> -<li>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : <a href="https://archive.org/details/PPCoinPaper">archive.org/details/PPCoinPaper</a></li> -<li>Duniter Blockchain Protocol, v13, draft by Elois : <a href="https://git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md">git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md</a></li> -<li>The Sibyl Attack, J.R.Douceur: <a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf">www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</a></li> -<li>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992</li> -</ul> -<section class="footnotes"> -<hr /> -<ol> -<li id="fn1"><p>Bitcoin Whitepaper, S.Nakamoto, 2008: <a href="https://bitcoin.org/bitcoin.pdf">bitcoin.org/bitcoin.pdf</a><a href="#fnref1" class="footnote-back">↩</a></p></li> -<li id="fn2"><p>Relative Theory of Money, S.Laborde, 2010: <a href="http://en.trm.creationmonetaire.info/">en.trm.creationmonetaire.info/</a><a href="#fnref2" class="footnote-back">↩</a></p></li> -<li id="fn3"><p>OpenPGP protocol defines standard formats for encrypted messages, signatures, private keys, and certificates for exchanging public keys. The GNU Privacy Handbook, M.Ashley, 1999 : <a href="https://www.gnupg.org/gph/en/manual.html#AEN335">www.gnupg.org/gph/en/manual.html#AEN335</a><a href="#fnref3" class="footnote-back">↩</a></p></li> -<li id="fn4"><p>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. <a href="https://cr.yp.to/papers.html#ed25519">cr.yp.to/papers.html#ed25519</a>.<a href="#fnref4" class="footnote-back">↩</a></p></li> -<li id="fn5"><p>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : <a href="https://archive.org/details/PPCoinPaper">archive.org/details/PPCoinPaper</a><a href="#fnref5" class="footnote-back">↩</a></p></li> -<li id="fn6"><p>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : <a href="http://lightning.network/lightning-network-paper.pdf">lightning.network/lightning-network-paper.pdf</a><a href="#fnref6" class="footnote-back">↩</a></p></li> -<li id="fn7"><p>Surfing a Web of Trust, Reputation and Reciprocity on CouchSurfing.com, D.Lauterbach, H.Truong, T.Shah, L.Adamic: <a href="http://snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf">snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf</a><a href="#fnref7" class="footnote-back">↩</a></p></li> -<li id="fn8"><p>Public key validation on GnuPG manual, M.Ashley, 1999 : <a href="https://www.gnupg.org/gph/en/manual.html#AEN335">www.gnupg.org/gph/en/manual.html#AEN335</a><a href="#fnref8" class="footnote-back">↩</a></p></li> -<li id="fn9"><p>The Sibyl Attack, J.R.Douceur: <a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf">www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</a><a href="#fnref9" class="footnote-back">↩</a></p></li> -<li id="fn10"><p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992<a href="#fnref10" class="footnote-back">↩</a></p></li> -<li id="fn11"><p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992<a href="#fnref11" class="footnote-back">↩</a></p></li> -<li id="fn12"><p>Pareto principle : <a href="https://en.wikipedia.org/wiki/Pareto_principle">en.wikipedia.org/wiki/Pareto_principle</a><a href="#fnref12" class="footnote-back">↩</a></p></li> -</ol> -</section> diff --git a/whitepaper.md b/whitepaper.md deleted file mode 100644 index 4b01d3622c3f83838dd8cd3853b9899a754497f1..0000000000000000000000000000000000000000 --- a/whitepaper.md +++ /dev/null @@ -1,1178 +0,0 @@ -Duniter: A libre currency blockchain generator. -======================================= - -## Abstract {#abstract} - -Many currency principles involve non-equal rights to monetary creation between humans. -We propose a monetary creation based on the Relative Theory of Money, which guarantee equal monetary creation for each willing human. -This type of currency can be centralised, however, this could lead to censorship and arbitrary choices of the central institution. -Thus, strongly inspired by Bitcoin example, we want the currency to be as decentralised as possible, in the transaction network as in the human identification process. -We use a Web of Trust between living humans for identification. -This web of trust allows us to impose personalised difficulty for transaction validation, keeping the calculation accessible to low-end hardware and allowing all competent members to secure the currency. - - - -## Introduction {#introduction} - -Duniter is a software to create and manage "libre currencies". Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question : - -> How should a currency be created to match the principle of equality between all humans, now and between generations ? - -The results of this demonstration implies a monetary creation : - -* on a regular basis -* for each human being -* which amount has to be reassessed on fixed intervals according to a fixed formula. - -Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula : - -``` -UD(t+1) = UD(t) + c² * ( M(t) / N(t) ) -``` -Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin. - -The first currency created through Duniter is Ğ1, pronounced "June". It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software. - - -## 1. State of the art : Bitcoin case {#state-of-the-art-bitcoin-case} - -<!-- source : https://duniter.org/en/theoretical/ --> - -Duniter uses the crypto-currency concept introduced by Bitcoin[^BTC_whitepaper], which is -to use cryptographic tools such as signatures to create trustless digital -currencies. Duniter fits this definition, but it has two completely -different principles than Bitcoin : the Web of Trust and the Universal -Dividend . These differences are on both monetary and technical aspects. - -[^BTC_whitepaper]: Bitcoin Whitepaper, S.Nakamoto, 2008: [bitcoin.org/bitcoin.pdf](https://bitcoin.org/bitcoin.pdf) - -### 1.1. Monetary creation of Bitcoin : a space-time asymmetry {#monetary-creation-a-space-time-asymmetry} - -Space-time asymmetry refers to the relative access of individuals to -newly created money[^RTM]. Concretely, most existing currencies (c. 2020) are -both spatially and temporally asymmetrical for their users. Let\'s take -Bitcoin as an example to understand why. - -[^RTM]: Relative Theory of Money, S.Laborde, 2010: [en.trm.creationmonetaire.info/](http://en.trm.creationmonetaire.info/) - -#### 1.1.1. Spatial asymmetry {#spatial-asymmetry} - -When new Bitcoins are created, only some Bitcoin users (the miners) -are given new Bitcoins, while everyone else get nothing. We believe -this is the first injustice. However, some might say: - -> \"Miners used their electricity and time to get it!\" - -\... we would answer that this work should not have been rewarded by -newly created Bitcoins. New units should be distributed to the whole -community. Miners should be rewared another way, but not by -money issuance. Of course, Bitcoin cannot create money through Basic -Income since Bitcoin users are not strongly identified, and one might -benefit from money creation multiple times if they owned several wallets. -Duniter gets rid of this problem by identifying its users and -creating the same amount of Basic Income to everyone. - -#### 1.1.2. Temporal-asymmetry {#temporal-asymmetry} - -Bitcoin has an absolute limit of 21 million BTC (its unit of currency), -which means ever fewer bitcoins will be created over time until no new BTC are -being generated. So, once the first adopters have mined every bitcoin, -how will future joiners get Bitcoins? Just like most of us do for Euros or -Dollars: to get money, they will have to work for the ones who already own it. - -We believe this is the second injustice. Every member of a -monetary community should be equal concerning monetary creation, and get -the same relative amount of money over time, even if they are a late -adopter. Duniter aims to fix this by making the Universal Dividend -(a.k.a. UD) grow by the time according to precise rules, thus making -members equal toward money issuance on a half-lifespan. - -Most currencies present one of these two asymmetries, including metal currencies -and mutual credit, as exposed in the RTM. - -#### 1.1.3. A solution {#a-solution} - -Bitcoin has taught us that it is possible to create a currency system -allowing one to both create digital money and to exchange it without a -central authority. What we need to change is the way money is issued -so we finally have a symmetrical system. We need **Bitcoin + Universal -Dividend**. But Universal Dividend implies that the community consists -of only identified people. This is where the Web of Trust (WoT) comes -into place. - -This concept, introduced by cryptography with the OpenPGP format[^OpenPGP], -allows us to identify people in a decentralized manner. It works as -follows: each person creates a personal identity that is linked to its -cyptographic certificate. The identity must be confirmed by others -members who use their own cryptographic key. It is that simple: people -choose who is part of the community and who is not, not a central -authority. - -[^OpenPGP]: OpenPGP protocol defines standard formats for encrypted messages, signatures, private keys, and certificates for exchanging public keys. The GNU Privacy Handbook, M.Ashley, 1999 : [www.gnupg.org/gph/en/manual.html#AEN335](https://www.gnupg.org/gph/en/manual.html#AEN335) - -However, Duniter will not use OpenPGP for its cryptographic features: -Elliptic Curves[^Elliptic] will be used instead for the conciseness of its -generated keys and its pratical advantages. Duniter has its own Web -of Trust principles, that will be exposed later. - -[^Elliptic]: High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. [cr.yp.to/papers.html#ed25519](https://cr.yp.to/papers.html#ed25519). - -### 1.2. Proof-of-Work mining : a power race {#proof-of-work-mining-a-power-race} - -In Bitcoin Model, the calculation and incentive principles cause a power race : -new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. -This leads to a power race an places the control over the currency in the hands of the richest hardware owners. -We want to make Duniter blockchain validation much less energy and hardware consuming while -keeping a strong level of security. This will be further explained later. A consequence of -this choice is the participation of low-end hardware in the Duniter network, -leading to a better decentralization of blockchain validation. - -#### 1.2.1 What about Proof of Stake ? {#what-about-proof-of-stake} - -Proof of stake consensus algorythm was first introduced in 2012[^PPCoin]. The basic principle is to allow the richest wallets to issue blocks, putting their coin balance as a "stake" they would lose in case of cheat. - -[^PPCoin]: PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : [archive.org/details/PPCoinPaper](https://archive.org/details/PPCoinPaper) - -At the time of conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. We did not chose this consensus principle. -Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead -to placing power over the currency in the richests hands : this is contrary to the symmetical principles of a libre currency. - -## 2. Duniters Blockchain {#duniters-blockchain} - -<!-- source : https://duniter.org/en/theoretical/ --> - - -Duniters Blockchain follows the basic principles of Bitcoins. -This is essential for synchronization between peers, as to prevent double-spend attacks. -However, Duniters Blockchain will store different informations than Bitcoins. - -The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no generation transaction exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either: - -* a former transaction (as in Bitcoin) -* a Universal Dividend (specific to Duniter). - -Duniters Web of Trust is also written in the Blockchain. The identity of each -member gets registered much like transactions are, with a strong link to the -time reference. Thus, the Blockchain is a representation of a space-time frame -of reference, where "space" are members of the WoT and "time" the basic blockchain -units : the blocks. On each point of time, one can determine which account is -legitimate to create the UD, only with a blockchain analysis. - - -### 2.1. Spam countermeasures {#spam-countermeasures} - - -An issue of most cryptocurrency projects is to prevent the common ledger from -growing too much. This would require nodes to have a lot of storage and computing -power to be usable. In particular, we don't want an attacker to be able to make the -Blockchain grow too fast. Most projects implement transaction fees as a way to prevent -this, making the attacker lose money. We don't want to introduce this mean since a -currency with automatic fees on transactions is no more neutral. Several -countermeasuers against such spam attacks are implemented. - -<!-- see : https://forum.duniter.org/t/sans-frais-de-transaction-comment-resister-aux-attaques/3846/25 (implemented ?)--> - -#### 2.1.1. Minimum output amount {#minimum-output-amount} - -<!-- This has to be implemented in DUBPv13. --> - -Fixing a minimal output amount reduces the power of an attack. Duniter deals with cents of Ğ1 or 1/1000 of the first UD. An attacker could create thousand accounts with only 1 UD. To prevent this, a valid transaction must have output amounts of minimum 1Ğ1. This reduces the power an attack by 100. - -#### 2.1.2. Limited block size and chainability {#limited-block-size-and-chainability} - -The block size is always limited. While the protocol allows this limit to evolve to address scaling issues, an attacker cannot register as many transaction as they wish. - -With the same goal to prevent too many transactions to get registered, while transactions can be "chained" (refer to another transaction in the same block), the chainability of transactions is limited to 5. - - -### 2.2. Scaling {#scaling} - -Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons : - -* Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don't want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT should limit its size to around 16 million members. -* Duniter's aim is to be used to create multiple libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community. - -However, Duniter has assets that will help if the number of users and transactions grow. - -#### 2.2.1 Dynamic block size {#dynamic-block-size} - -While Bitcoin has a fixed block size, Duniters blocks size can evolve. -On low use of the blockchain, the maximal block size is 500 bytes. -On high use of the blockchain, the maximal block size would be 110% of the -average size of the current window blocks(see "personalised difficulty" part for more information). -This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. The block size (in bytes) is limited as so : - -``` -block_size < max(500 ; CEIL(1.10 * (average block size)) -``` - -#### 2.2.2. Lightning Networks {#lightning-networks} - -The Lightning Networks[^Lightning] allow almost instant and off-chain transactions. -They were first implemented on Lightcoin, and are now on Bitcoin. -One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. -The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. -While not available yet, this payment channel might get implemented when needed. - -[^Lightning]: The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : [lightning.network/lightning-network-paper.pdf](http://lightning.network/lightning-network-paper.pdf) - -#### 2.2.3. Unit base {#unit-base} - -As the Universal Dividend grows exponentially, with time Duniter nodes would have had to deal with always largest amounts, eventually reaching the BIGINT limit. To avoid this, the amounts are expressed with a unit base in base 10. We want the UD amount to always fit in 4 digits. To manage it, the `unitbase` is updated each time the UD value reaches 100.00 : it goes from `99.99*10^(unitbase)` to `10.00*10^(unitbase+1)`. All the unit amounts are thus divided by 10. While this might seem strange, this process has already hapened in state currencies. Moreover, the amounts expressed in UD will not change. - -With a monetary growth of 10% each year and a stable population, such a change of unit base would happen each 25 years. - -## 3. Duniter Web of Trust - - -### 3.1. Basic Principles {#duniter-wot-basic-principles} - -In order to identify "members" accounts - which create monetary units - -and other accounts, Duniter uses a Web of Trust. This can be summarized -into few principles: - -- Each account becomes a member if it received a minimal number of - certifications - 5 for Ğ1 currency. -- Only members accounts can send certifications. Certifications have a - limited lifespan. -- A certification indicates that the sender accepts the receiver as a - legitimate identity. - -The aim of the WoT is to identify a blockchain account to a living -human. According to Lauterbach et.al[^Couchsurf], the strengh of a relationship should be considered when building a vouch system. -For this reason, the Ğ1 Web of Trust rules are expressed in a licence stating what WoT certifications are. -A certification represents a strong human relationship : one may certify a close relative, not an acquaintance. -Each member has to accept this licence before being included in the WoT. -Thus, if a member is part of an attack on the currency, they can be found by mutual relatives. -Additional security rules occur to prevent cheat and attacks on a large scale. - -[^Couchsurf]: Surfing a Web of Trust, Reputation and Reciprocity on CouchSurfing.com, D.Lauterbach, H.Truong, T.Shah, L.Adamic: [snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf](http://snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf) - -Note that non-members accounts can use the currency, but cannot create -money. Non-members accounts can be used by individuals as secondary wallets, or by -institutions. - -We were inspired by the OpenPGP Trust system[^OpenPGP_Trust]. However, the OpenPGP -trust principles aim at defining trust from a particular point of view while Duniter needs to -identify humans for the whole community. To achieve this goal, while OpenPGP allows each -user to tweak its trust parameters individually, Duniter sets rules in the "genesis" block for the whole community. - -[^OpenPGP_Trust]: Public key validation on GnuPG manual, M.Ashley, 1999 : [www.gnupg.org/gph/en/manual.html#AEN335](https://www.gnupg.org/gph/en/manual.html#AEN335) - -### 3.2. Why do we need a Web of Trust ? {#why-do-we-need-a-web-of-trust} - -There are two reasons we need it : - -1. To make sure that only one Universal Dividend is produced per member - at each specified creation interval. In the Ğ1's case this interval - is set as daily `86 400` seconds, it is the *monetary parameter* - known as `dt`. -2. To identify the nodes hashing the blocks and assign each a - personalised difficulty. This custom difficulty proof of work is - there to avoid the blockchain's validation mechanism becoming too - centralised as is the case with many \'non-libre' cryptocurrencies. - -> **Monetary parameter** : Each currency that use Duniter has its own blockchain whose behaviour is -> dictated by a set of 'parameters' defined in block zero - the so-called -> genesis block - that can be tweaked to achieve the desired results. At -> the time of writing the Whitepaper, the Duniter Blockchain Protocol -> (DUBP) has a total of 21 parameters of which 10 are for the WoT alone. -> We'll focus on these 10. -> -> Suffice to say that in the Ğ1's case, the DU is created every 24 hours - -> 86 400 seconds. This interval is set through the time derivative `dt` -> parameter and can have a different value in other implementations of the -> protocol. - -We want to make sure that each member can only have one account. As we -all know, achieving zero-risk isn't possible[^Sybil_Attack]. -Our goal is therefore not to create a WoT within which fraud -would be absolutely impossible, but instead to discourage it. Here is a -rewording of our goal in 4 smaller ones : - -1. Make the certification process lengthy enough that all members - exercise due diligence and are wary of risks. -2. Make fraudulent acts as hard as we can to the extent that they - become pointless. -3. Ensure that any Sybil attacks have a negligible impact on the - currency by ensuring that illegitimate double Universal Dividends - have no significant bearing on the legitimate monetary mass -4. Slow the growth of 'Sybil regions' to give enough time for the - community to react and isolate the threat. - -[^Sybil_Attack]: The Sibyl Attack, J.R.Douceur: [www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf](https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf) - -> **Sybil attack** : A Sybil attack is an attack perpetrated on a -> reputation system through the creation of fake identities. A Web of -> Trust is a specific instance of a Reputation System. - -There are plenty of Sybil attack scenarios we can think of and just as -many reasons why their perpetrators would want to carry them out. Our -objective is that the configuration of the WoT protects both users and -its IT backbone infrastructure against these attacks. - -This means that micro-attacks performed by small groups of individuals -looking for personal enrichment are of no interest to us. The web's role -isn't to deter these attacks, this being instead the role of the -community. Just like the town you live in is responsible for providing -your tap water and electricity but isn't responsible for any burglaries, -etc. Much in the same way, Duniter's WoT guarantees us all a functional -currency, but do not detect small fraud. - -### 3.3. The importance of having our own certification system {#own-certification-system} - -Centralized identification systems can achieve the goal we want. State -Identification is an example. However, this has many drawbacks : - -* The authority may have arbitrary criteria for identification, for example -preventing people without an official state-provided identity or -homeless people to be included in the WoT. -* Payment might be required -to get identified, thus making the monetary creation not "free". -* The authority is a point of failure for any attacker. - -It is of the utmost importance that we remain free from any state or -corporation. The WoT is an answer to this criterium. To this day we -depend only on the Internet and yet, were it to fail, there are already -alternatives being tested around the world for a decentralised communication network. - -### 3.4. A few foundational concepts on graph theory : a bit of vocabulary {#graph-theory-vocabulary} - -- **Graph**: set of points -called 'vertices'- joined by edges -called - paths/walks-. - -- **Simple graph**: a graph with no loops and with no multiple edges. - That is, each edge connects two distinct endpoints and no two edges - have the same endpoints. A simple edge is an edge that is not part - of a multiple adjacency -of edges-. In many cases, graphs are - assumed to be simple unless specified otherwise. - -- **Directed graph**: a graph in which the edges have a distinguished - direction, from one vertex to another. A directed edge can also be - called a path or walk. - Arrow A --\> B is therefore different from arrow B --\> A. - -- **Endpoints**: the edge with vertex A --\> B has A and B as - endpoints, respectively as start and end of the path/walk. - -- **Isolated vertex**: a vertex whose degree is zero, that is, a - vertex with no incident edges. - -- **Degree of a vertex**: number of its incident edges -in and out-. - -- **Out-degree of vertex A**: number of outbound edges / tail ends - from A. - -- **In-degree of vertex A**: number of incoming edges / head ends - to A. - - - -- **Path**: -aka "walk"- path to follow to get from vertex A to - vertex B. - -### 3.5. Definition of the Duniter Web of Trust {#definition-of-the-duniter-web-of-trust} - -The Duniter WoTs -one per currency- are simple directed graphs without -isolated vertices. The vertices are the members and the edges are the -certifications given and received. - -*Directed* means that the responsibility of issuing a certification is -unique and personal to the certifier. The trust they place in the -receiver cannot be imposed in the other direction although in most -circumstances both parties equally trust each other. - -In addition, all vertices are either currently active members or -past-members. Past-member vertices are in a specific 'deactivated state' -and can no longer issue or receive certifications although the ones -already issued or received to/from other members are still considered -'pending' to avoid a collapse of the WoT. If these old members don't -come back into the WoT, their pending certifications will eventually -expire and they will switch from 'deactivated' to 'isolated' vertices. - -To wrap up with old members, after a certain period of time - set in the -currency's parameters - their deactivated vertex is removed from the web -and the associated identity is 'revoked'. The person who owned the -account can no longer use this identity but is free to join the web with -another one. - -> **Identity** : An identity is a set of three pieces of information: a public key, a -> name and a blockstamp. A blockstamp points to a specific block in the -> chain. Its main use is to freeze the point in time at which an identity -> was created and to link this identity to a specific chain and a currency -> - each currency having its own blockchain. -> -> An identity can be in any one of 5 different status: pending, member, -> old member, revoked or excluded. - -Let's take a simple example: - -``` - A -> B -> C - | - \--> D -``` - -If, for whatever reason, A were to lose its member status, the web would -crumble and all other members would be excluded as a consequence. To -avoid this, the certification from A --\> B will remain valid until its -expiry date, leaving enough time for B to receive certifications from C -or D. - -Because our WoT doesn't have any isolated vertices, each new identity -created needs to be pulled into the web with all of the certifications -it has received, all in the same block. This calls for a temporary -'buffer' storage space for **pending** identities and the certifications -they have received. This storage space is called 'the pool' of Duniter -nodes, which we could also have called the 'sandbox' as that's the name -used in Duniter's code. Duniter nodes inclued other 'pools' for other -documents and metadata not mentioned here. - -### 3.6. Exploring the rules behind a Duniter Web of Trust {#exploring-the-rules-behind-duniter-wot} - -The Duniter WoTs - one per currency - works with a set of eight -fundamental rules enforced through eleven different parameters. Ten of -these parameters are set within the genesis block, the eleventh one - -`msPeriod`- having being hard-coded in the Ğ1's code subsequently. - -#### 3.6.1. Distance rule and referent members (`stepMax` and `xPercent`) {#distance-rule-and-referent-members-stepmax-and-xpercent} - -These two parameters are closely linked and together define the -'distance rule'. The 'distance rule' can only be described after -defining what a 'referent member' is: - -> **Referent member**: member A is said to be 'referent' if and only if -> the total of their degrees are greater than or equal to -> `CEIL-N^-1/stepMax` where N is the total number of members. As the -> size of the web will grow this number will grow too, meaning it will -> take more certification issuances to become a referent member. The -> number of certifications needed to become a member shouldn't change. - -Let's now define the distance rule: - -> **Distance rule**: member A is said to observe this rule if and only -> if for a subset xPercent % of referent members R there exists a path -> of length less than or equal to `stepMax` between R and A. - -Referent members only exist so that the distance rule can take effect, -they have no special privileges over non-referent members. In a perfect -web, that is one in which each member has certified all members they -legitimately can, all members would be referent members. However, -because the web progressively grows in size and because members die and -are replaced by new ones, there are always members at any given time `t` -who haven't yet certified all members they legitimately could. These -members would hinder the evolution of the web if they were taken into -account in the calculation of the distance rule and the web would -effectively stop growing. - -Because verifying the application of the distance rule is -calculation-greedy, it is only performed when a new identity gets -confirmed into the web or an existing member gets renewed. There is an -exception to this rule: the distance rule is not observed in the genesis -block -when the web is first implemented. - -#### 3.6.2. Rule of the minimum number of certifications needed (`sigQty`) {#rule-of-the-minimum-number-of-certifications-needed-sigqty} - -This is the simplest rule, it essentially says that each member must at -any given time -meaning in any single block- have received at least -`sigQty` active certifications. If, for whatever reason, member A were -to have less than `sigQty` active certifications in a given block, they -would cease to be a member and be required to publish a request for -identity renewal. - -#### 3.6.3. The membership renewal rule (`msValidity`, `msPeriod` and `msWindow`) {#the-membership-renewal-rule-msvalidity-msperiod-and-mswindow} - -Bear in mind that a membership doesn't last a lifetime but instead has a -lifespan set to `msValidity` seconds. - -Every single member -or old member who hasn't revoked his identity or -been excluded- can request a membership renewal so long as the last -request was made more than `msPeriod` seconds ago. If a member has never -requested a renewal, the date of last renewal is equal to the timestamp -at which his membership was first created. A new request will be stored -in the 'pool' for a maximum of `msWindow` seconds before it's included -in the blockchain. Once again, this can only happen once/if the member -meets both the `siqQty` rule and the distance rule -if these criterion -are already matched it's just a case of waiting for a new block to be -mined-. - -If a member hasn't requested a renewal for longer than `msValidity` -seconds, they automatically cease to be a member. From this moment on, -the ex-member has another `msValidity` window to renew their membership. -When this period of `2 × msValidity` runs out, the membership will -expire and this identity will never be available for use again in the -web. If the person so desires, they will have to publish new identity -and membership documents and find enough certifiers, as any newcomer. - -#### 3.6.4. Rule of certification lifespan (`sigValidity`) {#rule-of-certification-lifespan-sigvalidity} - -All certifications included in the blockchain expire **sigValidity** -seconds after they were **issued**. - -> /!\\ The issuance and the inclusion of a certification in the -> blockchain occur at different times. When member A issues a -> certification at time t1, it gets stored in the pool starting at t1 -> and only finds its way into the blockchain at t2 when all of the web's -> rules are observed. Several weeks can thus go by between t1 and t2!!! - -#### 3.6.5. Rule of limited supply of active certifications (`sigStock`) {#rule-of-limited-supply-of-active-certifications-sigstock} - -By 'active certifications' we refer to certifications included in the -blockchain and that haven't yet expired. - -The total of active certifications issued by any member at any single -time must be less than or equal to `sigStock`. When this threshold is -reached the member will have to wait for one of his active -certifications to expire before he/she can issue a new one. - -#### 3.6.6. Rule of the time period between two certification issuances. (`sigPeriod`) {#rule-of-the-time-period-between-two-certification-issuances-sigperiod} - -As soon as a certification issued by member A gets included in the -blockchain, they will be unable to issue a new one before another -`sigPeriod` seconds. - -#### 3.6.7. Expiry of a certification issuance (`sigWindow`) {#expiry-of-a-certification-issuance-sigwindow} - -When a certification is issued by member A, it will be stored in the -'pool' for a maximum of `sigWindow` seconds. If the certification hasn't -been included in the blockchain by then, it will be cancelled and the -member's `sigStock` will be repleted by one. - -#### 3.6.8. Lifespan of a 'pending' identity (`idtyWindow`) {#lifespan-of-a-pending-identity-idtywindow} - -When a new identity is created, it is stored in the 'pool' for a maximum -of `idtyWindow` seconds. If the person hasn't achieved member status by -then, the certification will simply be cancelled. - -### 3.7. Details on some of the WoT's peculiarities at the genesis block {#details-on-some-of-the-wots-peculiarities-at-the-genesis-block} - -The aforementioned rules can only be enforced with an existing web. They -cannot be observed when first creating the web, that is when defining -the genesis block. - -Only rules 2 and 5 can be observed at the genesis block. - -The genesis block has to be manually created by the founding members. In -practice this means that there must be a choice on which identities to -include on the premise that all of them observe rules 2 and 5. In -addition, the genesis block must be signed with the private key of one -of these identities. - -As soon as the genesis block has been created, the other identities can -start mining the blockchain and the member who created block \#0 -effectively looses the decision power he had at creation. - -### 3.8. Why these rules and application cases in the Ğ1 {#why-these-rules-and-application-cases-in-the-g1} - -#### 3.8.1. Distance and maximum size {#distance-and-maximum-size} - -The distance rule is there to curb the maximum size of a Sybil region as -well as that of the monetary community as a whole. The `xpercent` -parameter prevents the creation of a 'faction' that could take hold of -the blockchain. - - - -The Sybil regions are isolated from the rest of the graph in the sense -that they can only receive certifications from other ill-intentioned -Sybil members. As a consequence, the shortest edge/path between a -legitimate member and a Sybil one has to have the attack's author as an -endpoint. The maximum depth the Sybil region can attain is therefore -contingent on the distance between the attacking edge-s- and the -xpercent% closest referent members, this distance is known as -`stepAttackers`. The maximum size of a Sybil region created by `sigQty` -members depends on the L parameter, defined as `L = sigQty/sigStock`: - -``` -MaxSybilSize= (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L) -``` - -The maximum size of the Web of Trust is given by the following formula: - -``` -WoTmax = (sigStock)*L^(stepMax-1) -``` - -However we know for a fact that members will never use all of their -available certifications. -According to Dunbar[^Dunbar], on average, one is able to maintain relationships to around 150 people. -Being conservative, we will consider that on average, each person will certify 50 accounts. -We can calculate the size of the average web of trust `WoTavg` : - -``` -WoTavg= (50)*(sigQty/50)^(stepMax-1) -``` - -[^Dunbar]: Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992 - - -Our goal with the Ğ1 is to create a community of about one million -members to test the consequences of a libre monetary system. Let's see -how we can tweak the pair of sigQty and stepMax- to reach this size: - - - -The maximum size of a Sybil region grows linearly with `sigQty` but -exponentially with `stepMax`. Logic has it that we need to keep -`stepMax` as low as possible to ensure sufficient strength to the web. -The above graph shows that the lowest value of `stepMax` for a web of a -million members is of 5. This is an order of magnitude and is likely to -be much higher in reality, we cannot measure it for sure. - -For `sigQty` we can choose a value of **4** for a web of **1.5 million -members** or **5** for **half a million members**. Bear in mind these -are gross figures and could be significantly higher, we are talking -anywhere between 1 and 10 million in reality. Calculating WOTavg gives -us a pretty good idea of how the web would scale bearing in mind that it -considers all members are referent members too -which isn't the case as -explained previously-. Hence the maximum size of the web is likely -larger, a ballpark figure of half a million is enough for now especially -knowing that the smaller `sigQty` is, the easier it is to launch a Sybil -attack -it's easier to find four accomplices than five-. For security -reasons we have settled on five: - -``` -stepMax = 5 -sigQty = 5 -sigStock \>= 50 -``` - -The maximum size of a Sybil region therefore is: - -``` -(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5)) -``` - -with sigStock = 50 we have a Sybil region of: - -``` -45*(1-10^(5-stepAttackers))/(-9) -``` - -A good practice for protecting the web is to maximise `stepAttackers`. -That's why we decided that referent members in the genesis block had to -be at least four steps away from each other. - -Another way to keep a Sybil attack at bay, were it slow enough for -members to notice it, would be for referent members to 'stretch' the web -intentionally to limit the growth of the region by ensuring that the -attackers' legitimate certifications received in the first place aren't -renewed. But what if bot accounts were created and certified each other -super fast and following all rules, how would we counter that? By -introducing a minimum length of time between two certifications! - -#### 3.8.2. Time is our friend {#time-is-our-friend} - -To help us deter a Sybil attack, we've decided to impose a minimum -period of time between any two certifications issued from a single -account. This parameter called `sigPeriod` affords us a greater chance -to detect the formation of a 'hostile' faction. - -Here is a graph showing the evolution of a Sybil region with the -variation of `sigPeriod`. The simulation considers that honest members -and attackers both issue a certification each `sigPeriod` interval, in days: - - - -As we see, there is a strong link between the -growth speed of the region and `sigPeriod`. As evidenced here, we need a -`sigPeriod` high enough in order to ensure that the legitimate web can -grow at least as fast as a Sybil region. In addition, the higher -`sigPeriod` is, the more members will exercise their certification power -gingerly, the action coming at a higher 'cost'. - -There are numerous advantages to giving `sigPeriod` a high value and no -technical barriers to it, hence our choice of five days. - -We could have also gone for one week for the sake of simplicity. However -there is an underlying idea behind our choice which was quite simply the -pace of today's life. Certifying someone can be a lengthy process as one -needs to make sure they are correctly applying the Ğ1 licence and people -nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea -to allow one to certify at the end of every working week -five days- -instead of a whole calendar one. - -#### 3.8.3. Trust me now, trust me forever ? (`sigValidity`, `msValidity`) {#trust-me-now-trust-me-forever-sigvalidity-msvalidity} - -There would be two main drawbacks to a lifetime membership in the Ğ1's -Web of Trust: - -- First of all, some members will pass and those accounts should no - longer produce the Universal Dividend. -- Secondly it is of the utmost importance that 'rogue' accounts can be - excluded from the web at some point. - -To achieve this, certifications have a limited lifespan. Members need to -seek renewal from their peers after `sigValidity` time. On the other -hand, this time can't be too short that members would spend more time -seeking renewal than they would exchanging in the currency. Furthermore, -a certification with too short a lifespan would foster careless -certifying behaviours. The act of certifying must have a high-enough -'perceived' cost to make it feel like an important act. Lastly, we also -wanted this lifespan to be easy to remember. Historically speaking, we -first settled on the values of `sigPeriod` and `sigStock`, meant one -could issue all of their certifications in 495 days, one year was -therefore not long enough. We deemed three years to be too much and -that's how we agreed on two years in the end. - -Thinking that a deceased member could continue producing the UD for two -long years without anyone benefitting from it was also something we -needed to address. We chose a value of one year for **msValidity**. The -act of renewing every year is done through one of the clients -interacting with the blockchain, through a simple click on a button. -This parameter is less important than others and is mostly there to -'prune' the web of past or inactive members who don't renew their -membership. - -#### 3.8.4. Keeping the pools free of information glut (`idtyWindow`, `sigWindow`, `msWindow`) {#keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow} - -The pools need to be cleaned up on a regular basis to avoid them -clogging up with information and to ensure that machines with less -calculating power can still run a Duniter node. - -To achieve this, identities with pending membership approval and the -corresponding certifications have to remain the shortest time possible -in the pool while still having a chance of making it into the -blockchain. - -For the Ğ1, our opinion was that two months would be enough for all -potential certifiers to agree on a specific identity to certify. We also -wanted a time period that would be easy enough to remember by all. We -settled on two months, and gave this value to all three parameters -`idtyWindow`, `sigWindow` and `msWindow`. - -#### 3.8.5. Avoiding single members from 'knowing too many people' (`sigStock`) {#avoiding-single-members-from-knowing-too-many-people-sigstock} - -We considered that on average, each person will certify 50 people. -However, we know for a fact that some members will use more than 50 certifications. -The maximum social network of one individual is around 150 people[^Dunbar]. -Being conservative, we settled on a maximum certification number `sigstock` of 100. -Since `sigStock`'s impact on the size of a Sybil region is fairly limited, we did not investigate further this parameter. - -#### 3.8.6. Avoiding locking minorities (`xpercent`) {#avoiding-locking-minorities-xpercent} - -It's easy enough to become a referent member, one of the Sybil -strategies could therefore be to create a region of referent members. -Such a region would grow slower than otherwise but could confer a -locking power to its members by using the distance rule. That's why the -distance rule cannot be calculated on 100% of the referent members. -Hence the introduction of the `xpercent` parameter which defines the -percentage of referent members needing to be less than five edges --steps- from each other. - -This percentage needs to be low enough to prevent the formation of a -locking minority -referent Sybil members being too far from legitimate -referent members-. On the other hand, it needs to be high enough so as -to restrict the maximum size of the Sybil region through the distance -rule. The `xpercent` parameter was one of the hardest to define, -therefore we might decide to change its value during the Ğ1 experiment. - -We were inspired by the Pareto -principle[^Pareto]: if at least -20% of members give good density to the web, 80% of the referent members -will be five or less steps from any other member -referent or not-. The -maximum value for `xpercent` is therefore 80%, anything above that and -the distance rule could be too restrictive for legitimate use cases. -With security our top concern, we chose the maximum value of 80%. - -[^Pareto]: Pareto principle : [en.wikipedia.org/wiki/Pareto_principle](https://en.wikipedia.org/wiki/Pareto_principle) - -#### 3.8.7. Spam protection with (`msPeriod`) {#spam-protection-with-msperiod} - -This parameter stands out a bit on its own, as it was added after the -genesis block. It is there to protect the Duniter P2P infrastructure -against 'spam' attacks. We had to think of a strategy against attacks -such as high-frequency membership renewal requests -i.e: in every block, -every five minutes- or worse still, hundreds of these requests per -minute to flood the Duniter nodes. Without such limits, nodes are -supposed to address all renewal requests, even in cases where they were -last published five minutes ago! The `msPeriod` parameter was given the -same value as `idtyWindow`, `sigWindow` and `msWindow`, i.e. two months. - - -## 4. Proof of Work with personal difficulty {#proof-of-work-with-personalized-difficulty} - -As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human. - -This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each "winning" member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. A view of the whole network is not needed. - -Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power. - -One could say that Duniter uses a PoW that needs very low energy consumption compared to BitCoin : an "ecological" PoW ? - - - -<!-- source : https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ --> - -### 4.1. Why do we need Proof of Work ? {#why-proof-of-work} - -Duniter nodes share a database as part of a p2p environment. The proof of -work (PoW) allows machines to synchronize with each other. In Duniter's case, the blockchain is -our database, and acts as a ledger keeping -a trace of all transactions, status of the WoT and more. -How can we let several machines add data (ie: a transaction) at -the same time? In addition, how do we settle on how much time has gone -by since the blockchain was last updated? Agreement on time is of the utmost importance -as we want to create Universal Dividends on a regular basis, and keep track -of membership status, both in human time. - - -Proof-of-work provides a clever solution to both problems: - -1. Any machine can write into the blockchain (create a new block) but is only -authorised to do so if it has previously solved a mathematical equation -that require a certain amount of work. The challenge has to -be hard enough to prevent two machines to solve it at the same time, -ensuring the unicity of a block's creator. - -2. Solving this challenge -takes a certain amount of time, which depends on the calculating power -of the whole network. This provides a common ground for defining -the needed time reference. A block time is set (ie: 1 block = 5 min) and -Duniter adapts the challenge difficulty to get an average duration -corresponding to this block time. - -### 4.2. Only members can "mine" {#only-members-can-mine} - -One of Duniter's major differences with other PoW-based cryptocurrencies -is that only members are allowed to author blocks. Each block is signed -with the member's private key, allowing the algorithm to determine a -personalised difficulty. - -This personalised difficulty eliminates the rat-race for the most -sophisticated and powerful mining equipment. Another benefit is the fact -that no "supercomputer" can take control of the blockchain. Lastly, Duniter -implements a rotation in forging members thanks to this personalized difficulty. - -This lightweight PoW is much less energy-consuming than other PoW cryptocurrencies. -Members can mine with anything from a raspberry pi to a privacy-first -internet cube. - -### 4.3. How does it work ? {#how-does-duniter-pow-work} - -#### 4.3.1. The hash (aka digest) {#the-hash} - -Example of a valid hash: - -``` -00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653 -``` - -As you can see this hash starts with five zeros which was very hard to -achieve and took a lot of work for someone's computer. Hence the term -"proof of work". - -#### 4.3.2. The common difficulty {#common-difficulty} - -A common difficulty is needed to settle on a yardstick for our time reference. -Its role is to make sure the blockchain moves forward -at a steady pace - one block every `avgGenTime` seconds, `avgGenTime` -being one of the 20 parameters behind the Duniter protocol-. - -This difficulty's initial value can be set to any arbitrary value (`70` in -Duniter `v1.5.x`) and then acts as a spring, regulating blocktime -creation by increasing itself if the creation interval drops under -`avgGenTime` and vice-versa. - -##### 4.3.2.1. How is difficulty applied ? {#how-is-difficulty-applied} - -The numeric value of difficulty is taken from an array of possible -hashes out of all possible hashes. In DUBPv13 the hash -of a block is its sha256 hexadecimal hash. - -To understand the difficulty, we make a euclidiean division of the -difficulty by 16. - -Here's an example with a difficulty value of 70 : - -``` -70 // 16 = 4 with a remainder of 6. -``` - -The valid hashes are the ones starting with four -zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). -The valid hashes are then written as starting with : `0000[0-9]`. -This is a bit different from Bitcoin, -where the difficulty is only ruled by the number of zeroes. - -##### 4.3.2.2. The Nonce {#the-nonce} - -When a member is forging a new -block, his computer freezes the block's content and changes the Nonce -until the hash reaches the required number of zeroes. - -The nonce allows us to mine a new block by finding a hash. The -hash value allows us to determine the difficulty level of the -proof-of-work performed. Examples of possible Nonce values: - -- 10100000112275 -- 10300000288743 -- 10400000008538 -- 10700000079653 -- 10300000070919 - -In reality the `Nonce` value follows a pre-determined format akin to -`XYY00000000000`. The Nonce's value isn't the number of attempts but -rather a value within a set of possible ones. This is how the Nonce is -built: - -- X is a number assigned to a specific peer. Let's assume that someone - has several nodes each with the same private key, this would lead to - possible collisions if this person were to mine the same block with - different nodes. Each ~~block~~ **node ?** will therefore have its own unique X to - prevent this from happening. - -- Y is the number of cores of the processor. The Nonce starting with - `107[…]` belongs to a seven cores processor, while `199[...]` could - be the proof generated by a 99 cores processor. - -The rest of the Nonce, the part that follows after the XYY, is the -numerical space for this individual node and is unique to each of the -CPU's core. This space is comprised of eleven digits (`00000000000`). -For the sake of accuracy, we use the term CPU in the wider sense, it can -be understood as a bi-CPU for example. We take into consideration the -number of cores for the resulting PoW. - -### 4.4. Personalised difficulty {#personalised-difficulty} - -Earlier in this article, we explained that the personalised difficulty -is the new and key concept that sets Duniter apart from other -PoW-based cryptocurrencies. - -Here is how this personalised difficulty is calculated and assigned: - -It is determined by a combination of two different constraints with -complimentary roles: the **exclusion factor** and the **handicap**. - -Let `powMin` be the common difficulty, `exFact` a member's exclusion -factor and `handicap` their handicap. This member's personalised -difficulty `diff` is: - -``` -diff = powMin*exFact + handicap -``` - -#### 4.4.1. Understanding `exFact`, the exclusion factor {#the-exclusion-factor} - -Members who have never produced blocks or haven't for quite some time -are assigned an exclusion factor of `1`. Their personalised difficulty -is therefore simply the sum of `powMin + handicap`. - -Before reading on, let's precise the role of this exclusion factor. -When a member adds a block to the chain, his `exFact` jumps up from one to -a very high value, to prevent them from forging other blocks -immediately after and taking control of the blockchain. - -The exclusion factor will then rapidly return to one. -This delay is expressed as a number of blocks. It is calculated as a -proportion of the number of members forging. In the Ğ1's case, this -proportion is 1/3, meaning that if there are fifteen members currently -forging, the member's exclusion factor will drop down to one after five -blocks. - -##### 4.4.1.1. What is intended by "the number of members forging" ? - -We mean the number of members trying to create the next block. -In reality, there is no way to precisely know how -many members are calculating at any given time, because it is impossible -to view the entire network. But we need this information, whithout which -assigning a personalised difficulty is impossible. -To achieve this, Duniter looks back at the blockchain and assumes that there is as much -members forging as those who have found at least one block -in the last blocks in the current window, minus the very last one. - -##### 4.4.1.2. Current window - -We use the concept of **current window**. The current window is the number of blocks we look back at to determine how many members are forging. -Let's see how it works: - -* `issuersFrame` is the size of the -current window in blocks. - -* `issuersCount` the number of members who -have calculated at least one block during the current window. - -Both `issuersFrame` and `issuersCount` are block fields. When first -starting a blockchain, the very first block has an `issuersFrame=1` and -an `issuersCount=0`. The genesis block is excluded as there are no members in the current -window! - -From the second block onwards (block \#1) we track the variation of -`issuersCount`. The member having mined block \#0 enters the current -window and in block \#1 we will therefore mention `issuersCount=1`. - - -`issuersFrame` then varies as follows: - -* if `issuersCount` increases by N (with a maximum step of N = 1), then `issuersFrame` will increase by one unit over a period of 5N blocks. -* Conversely, if `issuersCount` decreases by Y (with a maximum step of Y = 2 = current window inching forward + loss of one calculating member), then `issuersFrame` will decrease by one unit during 5Y blocks. -* When such events overlap, `issuersFrame` evolves as so : - -| bloc | event | issuersFrame| -|---|---|---| -| T | Babar writes a block and enters issuersCount | 160 | -| T+1 | Celeste leaves issuersCount | 160 +1 = 161 | -| T+2 | N/a | 161 +1 -1 = 161 | -| T+3/4/5 | N/a | 161 +1 -1 = 161 | -| T+6 | N/a | 161 -1 = 160 | - - -The calculation can be found under rules -[BR\_G05](https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g05-headissuersframe) -and -[BR\_G06](https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g06-headissuersframevar) -of the DUP protocol. - -##### 4.4.1.3. exFact and the personalised difficulty {#exfact-and-the-personalised-difficulty} - -We explained that `exFact` spikes immediately after the member has -found a block. It decreases then rapidly to `1` after a number of -blocks equal to `1/3 * issuersCount`. Let's see precisely -how we calculate `exFact`: - -* `nbPreviousIssuers` is the value of issuersCount at the -last block `N` found by the member. - -* `nbBlocksSince` is the number of blocks -found by the rest of the network since block `N`. - -* `percentRot` is the number of *not excluded* peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency. - -``` -a = FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) -exFact = MAX [ 1 ; a ] -``` - -The FLOOR is a simple truncate function. For `exFact` to exclude the -member, we need : - -``` -(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2 -``` - -We can see that the member is not excluded if `nbBlocksSince` is greater than 1/3 of -the calculating members. Take as an example `nbPreviousIssuers = 6` and `nbBlocksSince = 3`: - -``` -(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1 -``` - -However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded: - -``` -(0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2 -``` - -Moreover if the last block was authored by the said member, then: -``` -nbBlocksSince=0 and -exFact = 0.67 * nbPreviousIssuers -``` - -ExFact value increases according to the number of -members calculating. Thus, if there is enough members calculating, even -mining farms would be excluded. We have therefore -succeeded in our intent to deter attempts to seize the blockchain and -its currency. - - -However, at any time `t`, the two-thirds of -calculating members all have an exclusion factor of `1`, even though -they might not all have the same computational power at hand. If the -personalised difficulty only took into account the exclusion factor, then -only the members with the highest computational power from the remaining -third would be able to author new blocks and the other 2/3s would almost -always be excluded. Lesser machines wouldn't stand a -chance... - -#### 4.4.2. The handicap {#the-handicap} - -The handicap is the second parameter of the personalised difficulty. Its -main role is to improve the rotation of forging peers. -A higher handicap is assigned to members with higher calculating -power, so lesser machines can also compute blocks. As a consequence, -there is no incentive on forging with powerful computers. -Security can be achieved with less computing power than with pure PoW. - -The aim is to handicap the half that has -authored most blocks (the most powerful half) to favour the other one. -So, the handicap formula will use the median number of blocks authored by peers within the current window. - -* `nbPersonalBlocksInFrame` is the number of blocks authored by a -single member within the current window. - -* `medianOfBlocksInFrame` is the -median number of blocks written by the calculating members during the -same timeframe. - -``` -a = (nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame -handicap = FLOOR(LN(MAX( 1 ; a )) / LN(1.189)) -``` - -Let's unwrap the formula: - -``` -(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame) -``` - -is simply the -ratio between the number of blocks authored by the peer and the median -number of blocks. For example, if a peer has authored `9` -blocks in the current window and the median is `5`, then the ratio -will be `(9+1)/5 = 2`. The MAX function allows us to ensure that -the handicap has a value at least equal to `1`. - -The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. -We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers. - -If we wanted the handicap to be applied as soon as the median is reached, -we would divide it by `LN(1)`. The problem is that we have already set -a minimum value of `1` with the MAX function. If we were to divide -the ratio by `LN(1)` all calculating peers would have a handicap `\>= -1`. In addition, is it really fair to handicap a member who is right on -the median? - -That's why we went for `1.189` rather than `1`. A member has to -be at least `18.9%` above the median to be assigned a handicap. -18.9% is actually 16\^(1/16), the difficulty -factor between two levels of the proof work (hexadecimal hash). - -To conclude, you have to remember that : - -* The handicap is indexed on the logarithm of the ratio to the median, -* Handicap is only applied on members whose ratio to the median is greater than the ratio between two -levels of the proof-of-work's difficulty. - - - -## Conclusion {#conclusion} - -<!-- source : https://duniter.org/en/theoretical/ --> - -Duniter's Blockchain can be compared to Bitcoin's : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend. - -More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers, maintaining a good security and helping decentralization of calculation. - -The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties : - - -* The freedom to choose your currency system: because money should not be imposed. -* The freedom to access resources: because we all should have access to economic & monetary resources. -* The freedom to estimate and produce value: because value is a purely relative to each individual. -* The freedom to trade with the money: because we should not be limited by the avaible money supply. - - -Those 4 economic freedoms should be understood together, not exclusively. Plus, "freedom" has to be understood as "non-nuisance". So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency. - -## Sources : {#sources} - -* Relative Theory of Money, S.Laborde, 2010: [en.trm.creationmonetaire.info/](http://en.trm.creationmonetaire.info/) -* Bitcoin Whitepaper, S.Nakamoto, 2008: [bitcoin.org/bitcoin.pdf](https://bitcoin.org/bitcoin.pdf) -* The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : [lightning.network/lightning-network-paper.pdf](http://lightning.network/lightning-network-paper.pdf) -* The GNU Privacy Handbook, M.Ashley, 1999 : [www.gnupg.org/gph/en/manual.html#AEN335](https://www.gnupg.org/gph/en/manual.html#AEN335) -* High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. [cr.yp.to/papers.html#ed25519](https://cr.yp.to/papers.html#ed25519). -* PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : [archive.org/details/PPCoinPaper](https://archive.org/details/PPCoinPaper) -* Duniter Blockchain Protocol, v13, draft by Elois : [git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md](https://git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md) -* The Sibyl Attack, J.R.Douceur: [www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf](https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf) -* Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992