-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 ******************************************************************************* * 0. Caveats. * *************** (0.0) Certain constants are specified as 'chosen at genesis'. This means that they are to retain their value, selected exactly once, for the lifetime of the Blockchain. (0.1) P != NP is taken as a postulate; as is the existence of a collision-resistant trapdoor function, H; and the existence of a hard asymmetric cryptosystem (see sect. 1.) (0.2) The minimal unit of accounting shall be referred to as a 'Satoshi', not to be confused with Bitcoin's minimal unit of accounting. (0.3) We will err on the side of pedantic restatement of the painfully obvious , rather than risking ambiguity. (0.4) This is NOT a formal spec! But it would like to become such a thing, when it grows up. ******************************************************************************* * 1. Foundations. * ******************* Let B(i) represent the number of bytes occupied by entity i. Let C(A(i_1,i_2..i_n)) represent the count of entities in an array entity A. Let H be a collision-resistant hash function (e.g., Keccak.) Let Q be a CSPRNG (Blum-Blum-Shub seems to be the only sane choice, but can use, e.g., Q(S, n) = H(S(H(S+1(H(S+2...H(S+n)))))) where S is the seed; if you are willing to live and die by H. Let the following functions comprise an asymmetric cryptosystem (e.g., RSA) : Rk(E) -> SK, PK (Keypair generation, using entropy input E, yielding secret key SK and public key PK) Rs(SK, P) -> SM (sealing, using secret key SK of payload P, yielding Sealed Message SM.) Rv(PK, SM) -> B (verification of Sealed Message SM using public key PK, yielding boolean truth value B) Re(PK, M, E) -> EM (encryption of message M, to public key PK, yielding encrypted message EM, after entropic padding E -- the latter will be omitted below, for clarity, we will refer simply to Re(PK, M).) Rd(SK, EM) -> M (decryption of encrypted message EM, using secret key SK, yielding plaintext message M, after removal of the padding emplaced by Re.) ******************************************************************************* * 2. Nodes. * ************* A Node is a device which verifies and permanently stores the blockchain, and, under certain circumstances, accepts transactions from other Nodes; and, also under certain circumstances, transmits transactions to other Nodes. A Miner is a Node which attempts to create new Blocks, as defined below. A Relay is a Node which does not attempt to create new blocks. Note that Miners may relay Transactions, or Blocks, to other nodes, when they so choose; but this is to be thought of as operating a separate Relay in the same facility as the Miner. A Parent of a Relay is a Node upstream from it (i.e. 1 step closer to any Miner) A Relay parented directly by a Miner will be referred to as an L1 Relay. A Child of a Node is a Relay downstream (i.e. 1 step further from any Miner.) An L1 relay is that which is a child of a Miner, etc. A Miner has no Parents. It ~may~ have one or more children. A Relay must have one or more Parents, in order to operate. A Node ~may~ accept another Node as a Child. A Node ~may~ ask another Node, if the former knows the latter's Public Key (see below) to become one of its Parents. The would-be Parent ~may~ accept this request. (Also see below.) A Leaf is a Relay having no Children. It is operated by someone who does not attempt to resell his Casks (see below) and is only interested in getting the Transactions which he produced himself, mined in a timely way. Note that the operator of a Relay can also author transactions himself, and may choose to make use of one of his Casks to send a transaction ~of his own~ upstream (rather than reselling said cask to a Child Node of his.) A Tree represents any set of Nodes having one or more Miners in common upstream. These Miners are said to be its 'Roots.' ******************************************************************************* * 3. Node Mechanics. * ********************** Let SKN be : The Secret Key (SK) of a Node. It is kept (surprise!) secret by the Node's operator. And is, ideally, to be destroyed if there is apprehension of danger of falling into enemy hands, like any reasonable Secret Key. SKN is generated via Rk. Let PKN be : The Public Key (PK) of a Node; generated likewise by Rk. This key is not necessarily "public" in the ordinary sense: it should only be shared with the Node's Children. A Node ~may~ choose to share its PKN with someone other than one of its Children -- in the interest of, for instance, attracting new Children. When Rk is used to produce a SKN, PKN keypair, we say that 'a Node is born.' When a SKN is destroyed, we say that 'a Node has died.' In order for any Node to communicate with another Node, both Nodes must know one another's PKN's. How this knowledge is to be arrived at, is deliberately unspecified in this document. All communication between any two Nodes consists of messages secured with asymmetric cryptography, via Re and Rd. A Child may speak to its Parent ~only when spoken to~. The ~only~ exception is: a request for an upstream Cask. (see Sect. 4.) The act of a Parent re-issuing a Cask down to a Child, is called Rolling. The act of a Child passing a Filled Cask up to a Parent, is called Floating. Think of 'Rolling' as a Cask moving down-stream; 'Floating' - up-stream. A Child requesting a Cask, is ~expected~ to produce a Fill for said Cask and Float it back to the Parent in a timely way. (See Section 5.) Other than the above, any valid message from a Child to a Parent is ~necessarily~ a Fill of a Cask Rolled by the Parent. A Relay which wishes to transmit a Transaction may request a Cask from a Parent. And wait for a Cask to be Rolled down. The request must contain a value for the desired Promise Height. It must also contain a Bid, comprising the amount (in Satoshi). See Sect. 5. The Relay's Parent may or may not Roll a Cask in answer to this request. If it does, the Cask will have a Promise Height greater or equal to the one requested by the Child. This is the block height at which the Child ~must~ Fill the Cask, or will be regarded by the Parent as having caused a Spill. (see below.) ( Warning: somewhat paradoxically, Spills are a thing that can happen only to ~empty~ Casks. Perhaps they will end up being called something else... ) A Leaf which wishes to transmit a Transaction may request a Cask from its parent. And wait for a Cask to be Rolled down. Just like a Relay, it must request a particular Promise Height, and offer a Bid. (See Sect. 5.) A Relay will Roll no Casks unless it has recently requested and received a Rolled Cask from one of its Parents. Relays will break this rule at their immediate peril; see discussion of Husks below. A Node may, at any time, destroy its SKN, and generate a new one, SKN', and a new PKN, PKN' , via Rk. For ALL practical purposes, the old Node - even if it occupies, e.g., the old Node's IP, or meatspace facility - is to be thought of as dead! and a new Node as having been thusly born. The new Node could attempt to demonstrate a continuity of cryptographic identity with the dead one, and the dead Node's Parents and Children ~may~, at their option, accept a valid Rs(SK, PKN') as proof of this continuity, and consequently become Parents and Children, respectively, of the new Node. A Node ~may~, at any time, choose to ~Unlink~ one or more of its Parents or Children. This is the act of removing a Node's PKN from another Node's list of Parent or Child PKN's, for whatever reason. This disconnects it from the unlinked Node; said Nodes are no longer in communion. Unlinking is to be thought of as similar to a WoT Negrating. Nodes ~may~ use an automatic mechanism to effect Unlinkings; or a manual one; or some combination of the two; or none at all. This is left wholly to each particular Node's operator. Typically, a Node might Unlink a Parent for often Rolling 'Husks'; Typically, a Node might Unlink a Child for often causing 'Spills' : A 'Husk' is a Cask, received by a Child from one of its Parents, which is not, upon the coming of the Casks's Promise Height, found to have carried the payload - the Cask Fill - which said Child had sent back to its Parent -- into a ~mature block~ (see Section 4.) It represents a broken promise by the Cask's Roller - to carry the Cask Fill, via ~his~ Parents, to a Miner, who will cement it into a Block, at or prior to the Promise Height. This broken promise ~may~ or may not be his fault; or an upstream Relay or Miner's -- the Children who were issued the Husk, have no reason to care! Ultimately, they want their Fills mined! A 'Spill' is the situation where a Cask that was requested by a Child from one of its Parents, did not end up Filled prior to the Promise Height of said Cask. It represents the failure of a Child to either: a) Fill the Cask with a Transaction from his own Leaf; or b) Fill the Cask by issuing a new Cask to a downstream Child, and receiving a valid Fill from same. A Cask Fill that turns out to contain a Transaction which fails to validate - is a Spill just the same as a Cask that is Rolled and never Floated by the Child at all. The one difference is, that this type of Spill can be diagnosed prior to the time of a Cask's Promise Height. This is called a Rotten Fill. A Cask Fill where the Transaction passed up from the Leaf (Transaction author) does not offer sufficient Fee (See Sect. 5) to cover a the cumulative cask-chain, is likewise considered a Rotten Fill. Under no circumstances is a Rotten Fill a candidate for mining: No Block containing any Rotten Fill is a valid Block per the Block validation rules. Any Spill propagates upstream - if a Child requests, and receives, a Cask from one of its Parents, and said Cask never makes it to a Leaf seeking to cause a Transaction to be mined - ~for any reason~ - the Parent whose Cask was Spilled, is now likewise a Spiller to ~its~ Parent, and so forth, all the way upstream to the original Cask Roller, a Miner. Any Cask that gets Rolled, but does not end up Floated, is a Spill. Any Cask that gets Rolled, then correctly Floated, but fails to deliver a Leaf's payload into a Block, at or prior to the specified Promise Height of said Cask - is a Husk. A Husk propagates downstream - if a Parent rolls one of its Children a Cask that fails - for any reason at all, other than failure by said Children to Float the Cask, or if they had Rotten Filled it, to end up in a mature block before the specified Promise Height - any of the Child's Children who have been re-issued this Cask, will likewise end up having been responsible for a Husk, and will be held thusly responsible by ~their~ Children. A Node that proves to be a chronic emitter of Husks or Spills --- for ~whatever reason~ -- is likely to be Unlinked by, respectively, its Children and Parents. A Node ~may~ attempt to publicly identify a Parent as a frequent emitter of Husks; or a Child as a frequent cause of Spills, by publicly sharing the offending Node's PKN, and displaying the Cask in question. Other Nodes ~may~ take this information into account when choosing Children or Parents. (See Sect. 5.) ******************************************************************************* * 4. Blocks. * ************** A Block, B, is a bitstring consisting of the concatenation of: Block Header Bh, a bitstring of fixed, constant length. The exact contents of Bh will vary, see section 7. Block Payload Bp, a bitstring of fixed, constant length (e.g., 1024 kB) which represents an array of Holes, S_1 .. S_n, where n is constant, chosen at genesis. A Bp in turn consists of a certain fixed number of Holes: Let Pn = C(Bp) , or the number of Holes in a Bp; Sl = B(S) , or the number of bytes comprising S, a Hole; Pl = B(Bp) , or the number of bytes in a Bp. ( E.g., the 1024 kB Payload, could contain 1024 Holes, of 1024 bytes each. or could be cut up differently, so long as Pn * Sl = Pl . Every Payload will contain the fixed number of Holes, chosen at genesis.) A Hole is to be thought of as an empty slot where a transaction can be emplaced by the Miner. (It can also be re-sold by Relays at a markup, see below.) We will begin with the base case of a Miner, but a very similar formulation will describe the behaviour of a Relay. In order to set the stage for the creation (mining) of a block B, a Miner generates, in order: 1) W, a random bitstring. (Preferably using a high-quality TRNG!) W is kept secret by the Miner, until it is time for the block to be broadcast to the network at large. At that time, it will be placed in the corresponding field of Bh. 2) Tickets T_1, T_i, ... T_Pn, generated by computing H(Q(W, i)). This sequence will be regeneratable on demand by anyone who comes into later possession of W. 3) A sequence of empty Casks, X_1, X_i, .. X_Pn: Each Cask X represents an available Hole in a block which the Miner promises to mine in the near future. An empty Cask X_i is a bitstring with the following substrings: T_i - A Ticket corresponding to this empty Cask. C_i - The Ask, in Satoshi, that the issuer of the Ticket is asking, for the privilege of filling this Cask. A_i - The destination Address for payment of C_i. (See Sect. 5 and 6 re: the mechanics.) Ph_i - The Promise Height, a Block Height at or prior to which the Miner promises to produce a mature Block where this Cask, when Floated, occupies a Hole. Tickets can be generated ahead of time. However, the Asks may depend on Bids received from the Miner's Children. (Or they may be fixed.) An Ask of, e.g., 10 Satoshi, means that any Cask containing a Transaction that does not ultimately leave 10 Satoshi for the Miner, is considered to be a Spill! An particular empty Cask is to be Rolled down to ONE of a Miner's (or any other Node's) Children. The existence of two Casks, Rolled down by a particular Node to two separate Children, having identical Tickets - is to be called a Fib. Fibs are ~the~ 'mortal sin' of the network: all but ONE recipient of a Fib Cask will end up in the guaranteed possession of a Husk. Fibs are 'the bezzle.' There is no mathematical means to rule out their existence. However they ~are~ detectable, and provable as such to any party in possession of: 1) Their Fibber's PKN and: 2) The two or more more identically-Ticketed Casks that - together - constitute the Fib itself. Therefore, any rational Node operator will configure his Nodes to immediately unlink -- and publicly expose -- any Node that can be shown to have emitted a Fib at any point in its existence. Prior to starting the hashing of a Block (see Sect. 7), a Miner ~may~ wait for all of the Casks he had Rolled, such as were marked with an appropriate Promised Height, to be Floated back to him, with valid Transactions inside. At his peril he may choose to fill prolongedly vacant Holes with Fibs (Casks created on the spot, and Filled with Transactions the Miner himself generated, solely to Fill said Casks.) It is in all cases in the best interest of a Miner to Roll only so many Casks downstream as he thinks will be Filled in a timely manner, rather than risking a reputation as a Husk-Roller. The creation of Fibs of this type can be thought of as similar to an airline's practice of 'overbooking' a plane. Ideally, Relays will seek to choose as Parents, those Miners who are known to emit few or no Husks. This means, at the very least, eschewing Fibs (given as a Fib is guaranteed to produce one or more Husks.) ******************************************************************************* * 5. The Rolling of Casks. * **************************** An Cask is said to be Rolled when it is passed by a Parent to a Child. Only empty Casks (i.e. those not yet containing a Transaction) may be Rolled. (Casks that have been Filled with a Transaction - can only be Floated. See below.) Rolling a Cask involves a transformation whereby the Parent creates a Sub-Cask, a new, empty Cask linkable to the one the Parent received (if he is a Relay) or created ex nihilo (if he is a Miner) by a unidirectionally- verifiable relation. (It becomes bidirectional when the Miner makes the Cask- Chain public; see Sect. 6.) An empty Sub-Cask is produced from an empty Cask via the following process: T'_i = H(T_i). And again here, anybody Rolling Casks could choose to Fib - i.e. to supply two or more distinct Children with empty Casks containing a repeated T. This is Bad and they ought to Feel Bad. And it will be ~detectably~ and ~opposably~ Bad. C'_i will be greater than C_i. So that the Relay can turn a profit via the act of successfully relaying. A'_i will quite obviously be an Address controlled by the owner of ~this~ Relay, as opposed to one belonging to the Parent's owner. But in principle, it can be whatever the Relay's operator wants it to be. Ph'_i will be a value equal to (living very dangerously) or greater than Ph_i. Again, it is in the best economic interests of every Relay to make no promises that it has no strong expectation of being able to ~reliably~ keep. The life cycle of a Cask: Empty Casks originate from Miners, who store them until their Children request them. (see Sect. 4.) But ultimately they must Roll all the way down to a Leaf, in order to get Filled: A Node which originates a Transaction, is definitionally - on that occasion - a Leaf (see Section 2.) A Leaf initiates a Transaction by generating the Transaction Payload (see Sect. 6), and thereafter requesting an empty Cask from one of its Parents. The request is accompanied by a Bid and a desired Promise Height. (See Sect. 3). The Leaf's Parent ~may~ then proceed to Roll an empty Cask, as described above. The Parent may be a Miner, in which case he is in possession of one or more empty Casks which he himself has created ex-nihilo; or a Relay, in which case said Relay requests an empty Cask from one of ~its~ Parents. A Leaf ought not to request casks which it fails to immediately (if they have been requested as having a near-term Promise Height) Fill and Float. Or it is considered, by the affected Parent, as having committed a Spill, and may consequently end up unlinked by selfsame Parent. A Leaf may send a request to one of its Parents for an empty Cask having a Promise Height some ways into the future, if such a thing is required. But the Parent may or may not be able to supply one, because it will request it from upstream, and ultimately some Miner in the Tree must be willing to offer such a Cask and Roll it downstream. Floating is the act of passing a Filled Cask upstream to a Parent. Floating, like Rolling, can only move a Cask vertically by one step in the Node tree. First we will describe the base case: how a Leaf fills and Floats a Cask that it has received from one of its Parents. The Leaf operator has crafted a Transaction (see Sect. 6) and wishes to see it mined by a Miner in a predictable time interval (See Sect. 7.) Thereby the Transaction's Fee must be greater than or equal to the empty Cask's C_i (Ask) in order for the Leaf's Parent, who has supplied the Cask, to not immediately consider the Leaf to have committed a Spill. The Transaction specifies that it assigns its Fee to ~this particular~ empty Cask's Cask-Chain by including H(T'_i) (the empty Cask's Ticket) in its sealed payload. (See Sect. 6 for Transaction format.) The Cask-Chain refers simply to the path linking the Leaf, via zero or more Relay middlemen, to a Miner, and the cumulative Ask resulting from this path. The Leaf now Floats the Filled Cask back to the ~specific~ Parent that it had received the empty Cask from. The Parent first verifies: 1) That the Ticket in the Floated Cask corresponds to the H(T'_i) that accompanied the original empty Cask. Thereby the Leaf proves that it has made use of a valid Ticket issued by this Parent. and: 2) That the Transaction in the Floated Cask is valid and includes sufficient Fee to cover the cumulative Cask-Chain (see Sect. 6) If both of these conditions are met, the Parent signs (in constant time, in avoidance of side-channel leakage) the Floated Cask, and passes it in turn to ~its own~ Parent, from whom it had received the empty cask, using the same scheme as above ( it signs, via Rs, the string created from the Floated Cask concatenated with the H(T'_i) Ticket it had received from its Parent. ) And so on, upstream, until the Filled Cask floats up to a Miner. Who emplaces it into a Block (or fails to.) ******************************************************************************* * 6. Transactions and the Cask-Chain. * *************************************** The life cycle of a Transaction consists of the following stages: 1) Egg. 2) Larva. 3) Adult. An Egg is a string consisting simply of : I : Input. The index of an Adult Transaction. O : An Address. (The structure of Addresses is not specified in this document.) C : An Amount, in Satoshi; the amount of the desired transfer. F : An Amount, in Satoshi, comprising the Fee offered up to the Leaf's Parent (See Sect. 5.) When the Cask ends up mined, each Node in the Cask-Chain (as illustrated in Sect. 5) will receive, to its specified A_i, the portion of this Fee corresponding to the difference between the C'_i ~it~ specified, and the C_i demanded by ~its~ upstream Parent. In the end, the Miner takes his cut (likewise specified ahead of time, per Section 4), and the entire Fee is accounted for. Q : The Conditions demanded of any future Z which purports to spend the Output, O, of this Transaction. An Egg is valid if and only if: 1) C + F is less than or equal to the balance of I.O - the balance of the Input's Output Address. A Larva is an Egg which also contains: T : A Ticket, obtained by H(T_i) from an upstream empty Cask. (See Sect. 4, 5.) Z : A Signature, specifying that the conditions imposed by the Input upon any would-be spender of its Output O, have been met. The structure of Z is not specified in this document. A Larva is what ends up Filled into an empty Cask which a Leaf receives from one of its Parents. In order for a Larva to be valid, the Egg must be valid; likewise, additionally, 1) Z satisfies I.Q -- the Transaction is validly signed by the encumberer of its Input 2) The fee F satisfies the Cask-Chain's cumulative Ask (See Sect. 4 and 5.) A Larva TX becomes an Adult TX ~if and only if~ it is mined, and the block matures (undergoes N - perhaps 6 ? - confirmations.) Until such a time, it remains a Larva and cannot become the Input of any new Egg. ******************************************************************************* * 7. Mining. * ************** Mining consists of the Empty Cask issuance as described in Sect. 4; the subsequent receipt of Floated Casks as described in Sects 4, 5, and 6; and the familiar gymnastics with time-variant Difficulty (not described here, assumed to resemble the process found in classical Bitcoin). The one substantial difference is that the hash algorithm must incorporate the proof-of-storage-of-entire-blockchain as described by mircea_popescu in his article http://trilema.com/2016/the-necessary-prerequisite-for-any-change-to-the-bitcoin-protocol . And that a complete Cask-Chain ends up incorporated into every particular Hole (see Sect. 4) in a Block, complete with Signatures. This allows each level of the Tree to determine who, downstream and upstream, had lived up to his declared promises, and who has not (issued one or more provable Husks, Spills, Fibs.) The material hashed by the miner in the process of attempting to create a valid block includes not only the entirety of the Cask material; the output of mircea_popescu's proof function; but also the value of W used to seed Q (see Sect. 4), which reveals the Tickets generated by the Miner and passed down in empty Casks, downstream. And in turn reveals which Relays have fulfilled their obligations to the Miner. And which Relays have fulfilled theirs to their Parents. ******************************************************************************* ********************* * To be continued.. * ********************* -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iQEcBAEBCgAGBQJYtQznAAoJELmCKKABq//HdpAIAK+CkXyqIFx5DhoN9d7B+OKK Rd/7Cijgb6WdxJCh/AXp86wJghnO2u/JeFVh01GuHHDgcEyQ8zS83q4igcrCcO4K 6rpH7xfV2ctlaVaVJVRUqsgWXE28FyEQlWJn5W5bW9JWMTj9i5C1XDDVnOvpF32G rH1Vua2jbm0zF1CRTS5XL5CL0NI2c/ZXFI7Rjl8TPKxou60KTJLsX4vUHt8Ywtyh +0SZieGHolqr525Po3boxVGSqmEmFzEE8l6WR6248Blie9qI0N3BOWrFIZxgRadL sfN5AhJcA1haYA3tgUrY3gYflEpaNrSnaxGUNPJ5mrTobMgKvmZy1A+0dDeshjI= =oZHy -----END PGP SIGNATURE-----