on 705ca06 help sign in
urbit.org/tutorials/concepts/technical-overview.md
172 lines 8.7 kB history raw
1+++
2title = "Technical overview"
3weight = 1
4template = "doc.html"
5aliases = ["/understanding-urbit/technical-overview"]
6+++
8Urbit is a clean-slate software stack designed to implement an encrypted P2P
9network of general-purpose personal servers. Each server on this network is a
10deterministic computer called an 'urbit' that runs on a Unix-based virtual
11machine.
13The current Urbit stack includes (among other things):
15- Arvo: the functional operating system of each urbit, written in Hoon.
16- Azimuth: the Urbit identity layer, built on the Ethereum blockchain.
17- Hoon: a strictly typed functional programming language whose standard library
18 includes a Hoon-to-Nock compiler.
19- Nock: a low-level combinator language whose formal specification fits readably on a t-shirt.
20- Vere: a Nock interpreter and Unix-based virtual machine that mediates between
21 each urbit and the Unix software layer.
23## Anatomy of a personal server
25Your urbit is a deterministic computer in the sense that its state is a pure
26function of its event history. Every event in this history is a
27[transaction](https://en.wikipedia.org/wiki/Transaction_processing); your
28urbit's state is effectively an [ACID database](https://en.wikipedia.org/wiki/ACID).
30Because each urbit is deterministic we can describe its role appropriately in
31purely functional terms: it maps an input event and the old urbit state to a
32list of output actions and the subsequent state. This is the Urbit transition
33function.
35```
36<input event, old state> -> <output actions, new state>
37```
39For example, one input event could be a keystroke from the terminal, say
40`[enter]` after having already typed `(add 2 2)`; and an output action could be
41to print in the terminal window the resulting value of a computation performed
42when the user hit `[enter]`, in this case `4`. The input event is stored in the
43urbit's event history.
45Events always start from outside of your urbit, whether they're local to the
46computer running the urbit (e.g., a keystroke in the terminal) or they originate
47elsewhere (e.g., a packet received from another urbit). When an event is
48processed, various parts of the urbit state can be modified before the resulting
49list of output actions is returned.
51Can output actions from your urbit cause side-effects in the outside world?
52The answer had better be "yes," because a personal server without side effects
53isn't useful for much. In another sense the answer had better be "no," or else
54there is a risk of losing functional purity; your urbit cannot _guarantee_ that
55the side effects in question actually occur. What's the solution?
57Each urbit is
58[sandboxed](https://en.wikipedia.org/wiki/Sandbox_%28computer_security%29) in a
59virtual machine, Vere, which runs on Unix. Code running in your urbit cannot
60make Unix system calls or otherwise directly affect the underlying platform.
61Strictly speaking, internal urbit code can only change internal urbit state; it
62has no way of sending events outside of its runtime environment. Functional
63purity is preserved.
65In practical terms, however, you don't want your urbit to be an impotent
66[brain in a vat](https://en.wikipedia.org/wiki/Brain_in_a_vat). That's why
67Vere also serves as the intermediary between your urbit and Unix. Vere observes
68the list of output events, and when external action is called for makes the
69appropriate system calls itself. When external events relevant to your urbit
70occur in the Unix layer, Vere encodes and delivers them as input events.
72### Arvo
74Arvo is a purely functional, [non-preemptive](https://en.wikipedia.org/wiki/Cooperative_multitasking)
75OS, written in Hoon, that serves as the event manager of your urbit.
76It can upgrade itself from over the network without downtime. The Arvo kernel
77proper is quite simple -- it's only about 600 lines of code, excluding its
78various modules.
80The Urbit transition function is implemented in Arvo. Upon being 'poked' by
81Vere with the pair of `<input event, state>`, Arvo directs the event to the
82appropriate OS module. The result of each Vere 'poke' is a pair of
83`<output events, new state>`. Events are typed, and each has an explicit
84call-stack structure indicating the event's source module in Arvo.
86Arvo modules are also called 'vanes'. Arvo's vanes are:
88- Ames: defines and implements Urbit's encrypted P2P network protocol, as well
89 as Urbit's identity protocol.
90- Behn: manages timer events for other vanes.
91- Clay: global, version-controlled, and referentially-transparent file system.
92- Dill: terminal driver.
93- Eyre: HTTP web client and server.
94- Ford: typed functional build system.
95- Gall: application sandbox and manager.
96 - Dojo (app): Shell and Hoon REPL.
97 - Talk (app): Chat client.
99### Hoon
101Hoon is a strictly typed functional programming language that compiles itself
102to Nock and is designed to support higher-order functional programming without
103requiring knowledge of category theory or other advanced mathematics. Haskell
104is fun but it isn't for everybody.
106Hoon aspires to a concrete, imperative feel. To discourage the creation of
107write-only code, Hoon forbids user-level macros and uses ASCII digraphs instead
108of keywords. The type system infers only forward and does not use unification,
109but is not much weaker than Haskell's. The compiler and inference engine is
110about 3000 lines of Hoon.
112### Nock
114Nock is a low-level [homoiconic](https://en.wikipedia.org/wiki/Homoiconicity)
115combinator language. It's so simple that its [specification](@/docs/tutorials/nock/definition.md)
116fits on a t-shirt. In some ways Nock resembles a nano-Lisp but its ambitions
117are more narrow. Most Lisps are one-layer: a practical language is to be
118created by extending a theoretically simple interpreter. The abstraction is
119simple and the implementation is practical. Unfortunately it's far more difficult
120to enforce both simplicity and practicality in an actual Lisp codebase. Hoon
121and Nock are two layers: Hoon, the practical layer, compiles itself to Nock, the
122simple layer. Your urbit runs in Vere, which includes a Nock interpreter, so it
123can upgrade Hoon over the network without downtime.
125The Nock data model is quite simple. Every piece of data is a 'noun'. A [noun](/docs/glossary/noun/)
126is an [atom](/docs/glossary/atom/) or a cell. An atom is any unsigned integer. A cell is an ordered
127pair of nouns. Nouns are acyclic and expose no pointer equality test.
129### Vere
131Vere is the Nock runtime environment and Urbit VM. It's written in C, runs on
132Unix, and is the intermediate layer between your urbit and Unix. As noted
133earlier, Unix system calls are made by Vere, not Arvo; Vere must also encode
134and deliver relevant external events to Arvo. Vere is also responsible for
135implementing jets and maintaining the persistent state of each urbit.
137In principle, Vere keeps a comprehensive log of every event from the time you
138initially booted your urbit. What happens if the physical machine loses power
139and your urbit's state is 'lost' from memory? When your urbit restarts it will
140replay its entire event history and totally recover its latest state from
141scratch.
143In practice, event logs become large and unwieldy over time. Periodically a
144snapshot of the permanent state is taken and the logs are pruned. You're still
145able to rebuild your state in case of power outage, down to the last keystroke.
147Vere is not essential to the Urbit stack; one can imagine using Urbit on a
148hypervisor, or even bare metal. One member of the community is even working on
149an independent implementation of Urbit using Graal/Truffle on the JVM.
151The Urbit stack (compiler, standard library, kernel, modules, and applications,
152but excluding Vere) is about 30,000 lines of Hoon. Urbit is patent-free and MIT
153licensed.
155### Azimuth
157Azimuth is a general-purpose public-key infrastructure (PKI) on the Ethereum
158blockchain, used as a decentralized ledger for what are known as **Urbit
159identities**, or simply **identities**. Having an identity is necessary to use
160the Urbit network, which makes it important to have a neutral ledger to
161determine who owns what.
163Azimuth is not, however, part of the Urbit stack. Azimuth is a parallel system
164that can be used as a generalized identity system for other projects. Azimuth
165"touches" the Urbit ecosystem when an Urbit identity is used to boot a virtual
166computer on the Arvo network for the first time. When that happens, the identity
167considered **linked** to Azimuth and the identity's full powers are available
168for use. Once an identity is linked, it cannot be unlinked.
170A metaphor might make the relationship between these two systems to understand:
171Azimuth is the bank vault that stores the deed to your house. The Urbit network
172is the neighborhood that you live in.