Rust HDK (Holochain Development Kit): Basics of Developing Distributed Peer-to-Peer Holochain Apps

By rhyzom | rhyzom | 18 Apr 2020


"Computers are language machines."
— ­Paul N. Edwards

So, Holochain, as some of you are perhaps well aware, is a development framework for peer-to-peer social apps (for, broadly speaking, large-scale sense-making, coordination and distributed, collective intelligence) — such that they run on distributed hash tables (DHTs, similar to BitTorrent), with each hApp (holochain app) instantiating and using its own (self-validating) DHT, according to the app-specific validation rules (as specified in its DNA file). So, Holochain uses DHTs as the public space and sourcechains (local hashchains, basically, in principle blockchains - but as associated with an agent/user and his private records) as the local records — holochain entries need to be explicitly marked public otherwise they're committed to an agent’s local chain. A public entry to the DHT on the other hand will be passed to other agents/peers via gossip, validated and collectively held together (as referenced in the DHT by its key) and any other agent can retrieve your public entries. Such arrangement allows that one records/stores only what is relevant to him/her in any given circumstance and doesn't need a massively replicated monolithic blockchain or universal network-wide consensus (instead of consensus, there are the app-specific validation rules which define the individual perspectives and behaviors of participants relative to their preferences, records and relationships, i.e. agent-centric).

 

3143414223-130dc4b010cab40d729a6aea6e043999a25dbadf3c1624e4b0048cdeb38ffa36.png

Holochain application architecture. A shared DHT as the public space with each individual agent storing his own source hashchain which interacts with the DHT via the Zomes in the applications DNA (which specifies the validation rules and application logic and every DNA has its own private, end-to-end encrypted network of peers who gossiping with one another). Holochain started out with a Kademlia type DHT, but what later changed to rrDHT (the working name for Holochain's specific DHT) which embeds Holochain's agent-centric assumptions deep into the design - the address space looks like a wheel, and (as with Kademlia) agents and data live in the same address space. A DHT is basically a key-value store that locates information and value by mapping it to a key. The node ID itself actually provides a direct map to value/information hashes and stores information on where to obtain that value, information file or  resource. When searching for a value, the algorithm needs to be given the associated key and the traverses the peer-to-peer network in several steps, getting closer to the key at each following step until eventually hitting on a node which returns sought value.

Anyway, Holochain is meant to make app development easy and accessible, kind of like a simple and intuitive web development framework. And hApps are meant to be interoperable and composable similar to how UNIX pipes for example can make one program take another program's output as input (in a kind of dataflow style programming). The already mentioned Semtrex (Semantic Tree Regular Expression Matcher) is also a kind of extended Regex. Holochain and the broader concept of Ceptr (which is to be evolved and extended from Holochain as the fabric of a new crypto-semantic Internet) basically constitute a computational model and framework inspired by the principle of biomimicry — also known known as bio-inspired computing (or applying principles from biology and living systems in tackling computational problems, and specifically such to do with scalable distributed systems and social behavior).

Distributed hash tables store resource locations throughout the network. A major criterion for these protocols is locating the desired nodes quickly. In Kademlia type DHTs, a node's ID provides a direct map to file hashes and stores information on where to obtain the file or resource. When searching for some value, the algorithm needs to know the associated key and traverses the network in several steps with each step coming closer to the key until a node eventually returns the value or no further closer nodes are found.

Distributed hash tables are a much more mature decentralized technology than blockchain and is particularly resistant against things like denial-of-service attacks since even if a whole set of nodes is flooded, this will have limited effect on network availability, since the network will recover and re-constitute itself by knitting the network around these "holes", much like a rhizome, "ceaselessly established connections between semiotic chains, organizations of power, and circumstances relative to the arts, sciences, and social struggles"

Overall, DHTs are a very powerful technological basis for a wide range of possible networked media scenarios, but particularly such that elude capture and mitigate central points of failure in distributing themselves widely across time and space. Holochain provides a more general framework for building applications that run on distributed hash tables.

The initial Holochain prototype was written in Go, but later the whole thing had been re-written in Rust and the initial release and the first HDK will be in Rust as well — later on there will be SDKs on Javascript, Python and others, but Holochain is to use Rust and compile down to Wasm under the hood (which, as a highly secure and incredibly efficient systems language, designed as a kind of C/C++ for the networked world of tomorrow, seems to be an obvious choice for something like Holochain). The HDK is basically a customized/optimized Rust, making extensive use of macros (which can be used to design/implement domain-specific languages (DSLs) on the basis of Rust) to make hApp development as smooth as possible.

Bootstrap an hApp in a Single Command

Before diving in the HDK itself should perhaps mention the recently released scaffolding tool for hApps. Apps tend to have a common structure they share, of what's located where and under what file name or sub-directory, etc. — which is known as the general application scaffold. And there's hApp crate available now which spares you the creating of project (config, etc.) files and folders manually by instantiating the scaffold for a basic hApp. To test it, open terminal and install the nix package manager (which Holochain uses) with "curl https://nixos.org/nix/install | sh". Then enter the Holochain development environment with "nix-shell https://holochain.love" and create your app with "hn-happ-create basic-app". To then run it, go to the root directory (with "cd basic-app") and launch it with "yarn start".   

Holochain Development Kit (HDK) in Rust

Holochain DNA needs to be written in something that compiles down to Wasm (WebAssembly) and an ideal candidate for that very purpose is Rust. The HDK is designed to allow the developer to focus on application logic as much as possible, without the bother of having to think about the underlying low-level implementation - and here, again, the Rust language and the compiler (which is particularly verbose) are built so that they relieve you from much of that low-level burden. Not least of all, learning Rust is actually something that would end up being mighty useful in the new world paradigm of peer-to-peer decentralization — a skill which is to be highly valued and sought after. 

Anyhow, the Rust HDK does take care of some of the low-level details of Wasm execution, such as memory allocation, (de-)serializing data and shuffling data and functions in and out of Wasm memory with the help of the pre-defined Holochain-specific macros functionalities that Rust allows (using Rust macros is how you go about designing domain-specific languages in Rust). There's also an Atom package of Rust HDK snippets available that may come handy (for those using the Atom editor as an IDE and for highlighting/syntax/etc. anyway).

What is a (Rust) macro?

Macro, in Rust, refers to a family of features which include declarative macros (the ones in question currently), expressed with macro_rules! and 3 kinds of procedural ones, which we'll not get into right now. Fundamentally, macros are a way of writing code that writes other code (e.g., println!), thereby reducing the need for boilerplate code. This approach is also known as meta-programming — macros basically expand to produce more code than the code that's written manually. Also, macros are expanded before the compiler interprets the meaning of the code, so a macro can, for example, implement a trait on a given type.

A function can’t, because it gets called at run-time and a trait needs to be implemented at compile time. Another important difference between macros and functions is that you must define macros or bring them into scope before you call them in a file, as opposed to functions you can define anywhere and call anywhere. As already mentioned, macros in Rust can be used to implement various domain-specific languages (DSLs, such as contracts scripting languages, etc.) based on Rust.

Throughout the process of developing on Holochain using the HDK it will be helpful to check around and come back to the reference, but the starting point is the define_zome! macro, and the list of exposed functions that Holochain offers, namely the API. The underlying API functions and callbacks are binary and Wasm based in the Rust release and Containers have been introduced to the architecture stack of Holochain with Rust becoming the underlying programming paradigm of choice.

The define_zome! macro

Zomes (from rybosomes, the building blocks of the language of DNA; the analogy actually runs deeper than it may seem at first as Holochain does apply the concept of biomimicry and is at bottom an bio-inspired project) are the fundamental units of composability of an app's DNA — like modules providing some self-contained functionality or other that are callable via exposed API calls. Every zome uses the define_zome! macro to define the structure of that zome — what entries it contains, which functions it exposes and what to do on first starting (genesis or being called/executed/initialized for the first time). As seen in the code below, the define_zome! macro is defined by 4 components: entries, init, receive and functions:

      • entries: an array of ValidatingEntryType as returned by using the entry macro (explained further below).
      • init: init is a callback called by Holochain to every Zome within a DNA when a new agent is initializing an instance of the DNA for the first time, and should return Ok or an Err, depending on whether the agent can join the network or not.
      • receive (optional): receive is a callback called by Holochain when another agent on a hApp has initiated a direct end-to-end/node-to-node message (initiated via the send function of the API, which is where you can read about the use of send and receive) — receive is optional to include, based on whether you use send anywhere in the code.
      • functions: functions declares all the Zome's functions with their input/output signatures.

Here's the Rust code that defines the define_zome! macro:

macro_rules! define_zome {
    (
        entries : [
            $( $entry_expr:expr ),*
        ]

        init : || {
            $init_expr:expr
        }


        validate_agent: |$agent_validation_param:ident : EntryValidationData::<AgentId>| {
            $agent_validation_expr:expr
        }


        $(
            receive : |$receive_from:ident, $receive_param:ident| {
                $receive_expr:expr
            }
        )*

        functions : [
            $(
                        $zome_function_name:ident : {
                            inputs: | $( $input_param_name:ident : $input_param_type:ty ),* |,
                            outputs: | $( $output_param_name:ident : $output_param_type:ty ),* |,
                            handler: $handler_path:path
                        }
            )*
        ]

        traits : {
                $(
                    $trait:ident [
                        $($trait_fn:ident),*
                    ]
                )*
            }


    ) => { ... };
}

 

And here's an example of its usage in defining the simplest Zome possible (with no entries and no exposed functions):

#[macro_use]
extern crate hdk;

define_zome! {
    entries: [
    ]

    init: || {
        Ok(())
    }

    validate_agent: |validation_data : EntryValidationData::<AgentId>| {
        Ok(())
    }

    functions: [
    ]

    traits: {
    }
}

Zome definitions as the above are stored in the lib.rs of the Zome (in its corresponding sub-directory in the DNA folder).

The other HDK-specific macros are entry, from, link and to:

  • entry! macro - a helper for creating ValidatingEntryType definitions for use within the define_zome macro - has 7 component parts:
    • name: descriptive name of the entry type, such as "post", or "user".
    • description: primarily for human readers of the code, just describing the entry type.
    • sharing: defines what distribution over the DHT, or not, occurs with entries of this type, possible values are defined in the Sharing enum.
    • native_type: references a given Rust struct, which provides a clear schema for entries of this type.
    • validation_package: a special identifier, which declares which data is required from peers when attempting to validate entries of this type — possible values are found within ValidationPackageDefinition. It is a function defining what data should be passed to the validation function which is a function that performs custom validation for the entry. An argument can be an entry, but also it is possible to pass chain headers, chain entries or the entire local chain.
    • validation: is a callback function which will be called any time that a (DHT) node processes or stores this entry, triggered through actions such as commit_entryupdate_entryremove_entry — it always expects two arguments, the first of which is the entry attempting to be validated, the second is the validation context, which offers a variety of meta-data useful for validation (see ValidationData for more details).
    • links: a vector of link definitions represented by ValidatingLinkDefinition, can be defined with the link! macro or, more concise, with either the to! or from! macro, to define an association pointing from this entry type to another, or one that points back from the other entry type to this one (see link!to! and from! for more details).
  • from! macro — a helper for creating ValidatingEntryType definitions for use within the entry! macro — a convenience wrapper around link! that has all the same properties except for the direction which gets set to LinkDirection::From.
  • link! macro - a helper for creating ValidatingEntryType definitions for use within the entry! macro - has 5 component parts:
    • direction: direction defines if the entry type (in which the link is defined) points to another entry, or if it is referenced from another entry — must be of type LinkDirection, so either hdk::LinkDirection::To or hdk::LinkDirection::From.
    • other_type: other_type is the entry type this link connects to — if direction is to this would be the link target, if direction is from this defines the link's base type.
    • link_type: link_type is the name of this association and thus the handle by which it can be retrieved if given to get_links() in conjunction with the base address.
    • validation_package: similar to entries, links have to be validated — validation_package is a special identifier, which declares which data is required from peers when attempting to validate entries of this type (the possible values are found within ValidationPackageDefinition).
    • validation: validation is a callback function which will be called any time that a (DHT) node processes or stores a link of this kind, triggered through the link actions link_entries and remove_link — it always expects three arguments, the first being the base and the second the target of the link, the third is the validation context, which offers a variety of meta-data useful for validation (see ValidationData for more details).
  • to! macro - a helper for creating ValidatingEntryType definitions for use within the entry! macro. It is a convenience wrapper around link! that has all the same properties except for the direction which gets set to LinkDirection::To.

The `Serialize` and `Deserialize` derived traits allow the structs to be converted to and from JSON, which is how entries are managed internally in Holochain. JSON was chosen as the interchange format because it is universal and almost all languages have serializers and parsers. Rust’s is called serde. The three serde (Serialization framework for Rust) related dependencies all relate to the need to serialize to and from JSON within Zomes. The process of translating/converting one stream/format/data/convention to and from some other is most of what Holochain actually does in practice — and how "current-sees" or flows are defined (within the constraints of their validation rules which define them as such).

Links in holochain work, in principle, similarly to Linked Data (in how Solid makes use of RDF, etc.) - it is likewise a kind of ontology engineering, allowing for the traversing across different domains and translating between them, revealing/creating otherwise hidden or surprising connections between things. Web ontologies have come to be of much significance in the digital humanities, one such example being the Seshat Global History databank (in .ttl / Turtle), extensively used in cliodynamics research to test theories and models and discover correlations, inter-dependencies and key factors driving socio-economic and historical processes. Holochain aims to both reveal and create (making us actively aware of) social flows and allow for composable arrangements between them as means for organizational coherence. (Imagine breathing, animated Chinese or Mayan ideograms.)

5079a1a2a93b27f595989a716e6fc0e57bf1b5afed6ab39514a4599de219b21b.jpeg

Mayan ideograms (hieroglyphs). Ideographic scripts/languages, unlike alphabetic ones, directly express concepts and ideas and compose meaning and expressions by combining them in arrangements. This has the effect of immediately revealing etymology, intention, scope and nuance, context and circumstance and tends to encode/compress much more information than the alphabetic phonemes, which simply stand for glottal sounds and is rather (to use the words of Marshall McLuhan) "an aggressive and militant absorber and transformer of culture". Holochain's composability follows a somewhat similar underlying principle as that of ideographic languages like Chinese and Mayan scripts. hApp creation is a kind of concept creation (which, according to Deleuze, is the work/function of philosophy) - as component glyphs of the vocabulary, but dynamic and animated, machinic and distributed (as DHTs). The formed connections and relationships (translations/transformations) between hApps, records, agents and entries, constituting a massive growing DAG of complex webs, mapping planes of consistency and immanence, virtuality and actuality, potentiality and possibility.

Self-writing historical records on the surface of a BwO ("body-without-organs") and the implied possibility of universal history therein (what schizoanalysis aims for) — in a way, Holochain is practical schizoanalysis as applied in its proper scales and domains (and as a critique/opposite of psychoanalysis, its privately bourgeois character of thinly veiled hypocrisy and institutionalized bullshit enacted as seriousness and deep esoteric knowledge). Perhaps another word for "schizoanalysis" - or something close enough to it to be almost exactly the same (even in the words of Latour himself, who said he would have termed it "rhizome-actant theory") - Actor Network Theory (ANT). “We neither think nor reason,” Bruno Latour writes, “Rather, we work on fragile materials—­texts, inscriptions, traces, or paints—­with other people.”

Holochain can also serve as a research instrumentarium in helping one become his own anthropologist (in the sense of McLuhan media theory as radical anthropology) and/or analyst (of the schizo type, not the ego preoccupied and fixated neurotic of Freud and Lacan) - all kinds of conceptual tools, methodologies and heuristics can be implemented and combined using Holochain (could become an invaluable tool for the digital humanities), and various machinic assemblages and bricolages put together ad hoc and on the fly as circumstances require, operational/organizational regimes switched between one and the other in response to changes and necessity, etc. - in a word, precisely what an approach dealing with non-linear complex dynamics in the real world requires.

As a framework for currencies design (in the sense of "current-sees", or social flows of things with money-like qualities, but not necessarily money per se), Holochain is meant to enable the making visible of such flows and organizing them in articulating vectors of distribution towards clearly defined and desired outcomes. It shares something of the view of social ecology (of Murray Bookchin and as taken up by Abdullah Ocalan and his democratic confederalism, as practiced in the Rojava region in Northern Syria today) — which, interestingly enough, is also quite fully captured and contained in the concept of what is in Greek referred to as "miasma" (meaning, among other things, stain, pollution, defilement, taint of guilt).

>>> ...bit of a U-turn drifting away into other things Holochain, this above and the section just below....

Software as Art Rather Than Engineering

Recently came across Warren Sack's book, "The Software Arts" which makes an actually important (or important enough to be explicitly made, I think) point about software development and it being more like art — as "software engineering" isn't quite exactly engineering for the most part (and neither is financial one for that matter), but the term itself has done some harm as it does imply an engineering approach to problems and things where much more nuanced and inter-disciplinary methods and mindsets ought to apply. An engineering problem is a complicated, expertise problem, as per the Cynefin Framework, while most real world problems tend to be of the complex non-linear variety, involving unknown number of unknown unknowns and myriads of interwoven, tangled variables across many dimensions and domains - where gentle probing and small scale experimentation necessitate, along with ad hoc heuristics and domain-specific designs (or Feyerabend's methodological pluralism and epistemological anarchism of the single universal principle of "Anything goes").

Increasingly, in academia, industry and government, ideas and concepts are exchanged as software and code rather than as printed prose documents. Software now constitutes a new form of logic, rhe­toric and grammar, a new means of thinking, arguing and interpreting. Although, if we take Deleuze's distinction between the domains of science, art and philosophy (and what each of them deals with), software ought to more closely overlaps with philosophy (as the practice of inventing concepts) than with art (as producing affects). Although, if we consider performance art and the Artaudian theater of cruelty or art as embedded in and indistinguishable from everyday reality (rather than its own stage, domain, gallery or sphere), Bitcoin has without a doubt been the greatest piece of such demonstrative performance art in history (as I've always claimed) — in its pedagogic and educational value as well as sociopathic mockery and almost unbelievable spectacle of human stupidity, quasi-ideological nonsense and boiling of lower instincts and passions.

And without a doubt computing does also have strong aesthetic aspects and dimensions (except for Microsoft, of course, but Apple's innovations in commodity fetishism don't really count as anything of any actual value either I think) — in that regard, I find Urbit to be particularly aesthetic in its every aspect, from the minimally concise code base to the tabula rasa overlay of existing systems to its grounding of a calm technology sense and the kind of mindset that conditions (or is conditioned by). Urbit is more in the category of things that go about dealing with complexity by first grounding a Schelling fence of immutable simplicity and first principles (like Bitcoin in a way) - making sure that whatever can be simple and has no need to be complicated or muddled does not end up being so. Another example of such philosophy of simplicity is the constructed pidgin-like philosophical language Toki Pona

Most mainstream crypto-networks right now tend to focus on so-called "smart contracts" and financial applications — DeFi, open finance and the like. Basically enabling one to write business logic in code that executes deterministically on a public ledger and in a peer-to-peer fashion. All this is mildly interesting and mostly useless or even perhaps meaningless compared to what is (technologically and otherwise) possible and the kinds of things that might come to be that we can't currently even quite imagine yet. In that sense, Ethereum does lack something of a character or flavor, purpose and clearly defined goals, vision and consistency — being "general-purpose" and "value agnostic" doesn't really get one too far when one is not really sure what they want to accomplish or why they're even doing what they are. (And Tezos, in that same department and of open finance / fintech crypto-networks, seems to instead be very purpose-driven in its innovative approach and seeming clarity of what end goals it pursues.)

A whole lot more can be mentioned, but in any case Holochain also stands out as a great example of how "software is art" — as it strives to organically develop and evolve rich expressive and grammatic capacities of what it could articulate possible and the kinds of vocabularies, ontologies and terms it would have at its disposal to raise and state problems as such (as valid problems in the terms which raise them as such and in revealing in their statement the range of possible solutions) — ontology, or the language of what could be said and raised as such, is what conditions the epistemology of what it could possibly know within its structural constraints. (Perhaps also why whenever one switches from one language to another he tends to, in a certain neurological and psychological senses, switch between two distinct personalities of himself articulated in those languages.)

Art's role in facilitating sense-making and shocking or waking us into some other phenomenology of experience or being, sensing the surrounding world or being more acutely aware of things normally lying dormant and hidden in the background of our attention, etc. — all this is more easily achieved by making use of networked media and technologies in actually creating the conditions of what we seek to call into being or make possible, virtually or actually. Art should be made with a purpose and for use, but its adoption and common use and/or capture, appropriation and functional re-purpose ("deterritorialization") can be things rather opaque, double edged and operating simultaneously in a number of levels for the benefits of different things (e.g., honeypots). "The Medium is the message", or: the content of the TV news broadcast is as important as the graffiti inscribed on the atom bomb.

Thus, as the means for creating art get more powerful and dangerous, so should art become so as per the nature of its employed technological media — otherwise it ceases to be art (as art can only be such that it embodies the spirit of its times/Zeitgeist, an expression/manifestation of the era, such that it provides it with broader historical and social context and gives it its spiritual and intellectual taste and flavor). Therefore, art today may cross all boundaries necessary for it to have influence and affect, be those even legal or moral, etc. Sense-making being another function of art, the deliberate and programmed introduction/execution of unpredictability, insecurity and volatility does, as such, provide new information (information defined as difference from the usual and routine, the inertial drift and repetition, entropy and sudden abrupt change) and reveal things previously unknown. Also, counterinduction does constitute a legitimate approach to knowing something.

So, in a word, Holochain is also a framework for making art. The various possible expressions and embodiments of exactly what kinds of art is up to whatever the intended purposes and sought effects have been in the putting the technical artifact together. 

Conductors: Interfaces Between the Transport Layer and the DNA Instances

Architecturally, as already mentioned, holochain app DNAs are meant to be small composable units that provide bits of distributed data integrity functionality (like simple/basic  Unix shell programs that are built to work together). Thus, most holochain-based applications will really constitute assemblages of various different “bridged” DNA instances. For this to work a distinct layer that organizes the data flow (i.e., zome function call requests and responses) is necessary, one that interfaces between the transport layer (i.e., HTTP, Web sockets, Unix sockets, etc.) and the DNA instances. This layer is called the Conductor and there's a conductor_api library for building Conductor implementations. They (conductors) play a number of important roles:

  • Installing, un-installing, configuring, starting and stopping DNA instances.
  • Exposing APIs to securely make function calls to the Zome functions of DNA instances.
  • Accepting information concerning the cryptographic keys and agent info to be used for identity and signing.
  • Establishing “bridging” between DNA instances.
  • Serving files for web-based user interfaces that connect to these DNA instances over the interfaces.

Those are the basic functions of a Conductor, but in addition to that, a Conductor also allows for the configuration of the networking module for holochain, enables logging, and if you choose to, exposes APIs at a special ‘admin’ level that allows for the dynamic configuration of the Conductor while it runs. By default, configuration of the Conductor is done via a static configuration file, written in TOML.

In order to run a DNA, a conductor needs to be configured to:

  • Know about that DNA (i.e., its hash, DNA file location, how it should be referred to).
  • Have an agent configuration that wraps the cryptographic keys and identity of the agent running the DNA.
  • Incorporate the two in an instance that also specifies what storage back-end to use.

This creates a running DNA instance, but in order to use it there needs to also be some user interface and a connection between it and the DNA. So, the holochain conductor implements interfaces that also need to be set in the conductor config and each such interface configuration picks the instances made available through that specific interface.

Holoscape: End-User Deployment of a Conductor With Admin UI and a Run-time for hApp UIs 

Holoscape sets up and maintains your Conductor config so that you don't even have to know what that even is, providing graphical user interface with access to all configuration dialogs and with simple means to install hApps via hApp bundles, as well as open/close hApp UIs via the tray icon (although the DNA/DHT instances keep running in the conductor even when an hApp UI is closed). 

e96082f25e47cc39ca4b37a8503f8d0c00e55085c0ae16f0ace651a50535058f.png

hApp developers can much easier deploy their hApps by bundling them with everything related/relevant to the application and sharing those through Holoscape (similar to how an app store works). HoloSqape was the first such MVP hApp container to be released (using Qt and now non-maintained) with Holochain's Rust re-write which came with an UI that created inputs and buttons for each zome function a DNA exposes.

Other tools and useful resources

There's a handful of available useful helpers and tooling around Holochain, including a generic zome explorer interface for calling holochain dna zome functions, a development commons (Holonix) and others. Socket Wrench is also a useful GUI for talking to a WebSocket server that can be used to talk to a running conductor or one of its instances.

Zome Explorer for Calling/Examining Running Zomes in a Conductor

4df1151504fdca35f060475100662adf0c526b410f3f11b4ea1f66831393db7c.png

A GUI tool for examining and calling running zomes in a Holochain conductor. To install, clone the Github repo with git clone https://github.com/Hylozoic/zome-explorer.git and then run:

$ cd zome-explorer 
$ yarn install

Basically a must among tooling and developer tools/components — seeing how things actually work in practice under the hood and getting sense of the p2p dynamics of how apps run and the underlying architecture/structure you'll write the application logic in.

Sim2h: Simple “switch-board” Networking

Sim2h is a centralized test networking alternative which is no longer used much. It was a secure centralized "switchboard" implementation of lib3h and a multiplexer for nodes using lib3h protocol to connect through a centralized security and validation service. 

Holonix: Developer Commons and Environment Based on NixOS

Holonix was designed for facilitating developer productivity in an extensible and open source manner and focus on evolving conventions around a set of basic workflows — in this case, the building and testing of zomes and UIs, the documenting of code in the process and the release of artifacts. Holochain and the Holo initiative specifically work to build a rich ecosystem of many small micro-service style apps and the benefits of leveraging well tested sets of common use scripts and conventions tends to usually outweigh the reinventing of the wheel each time.

Workflows are achieved through a combination of automated management of dependencies and tools (on $PATH), the setting environment variables inside a shell session, simple bash scripts and scaffolding tools (such as hn-happ-create, mentioned in the beginning), virtual machines for continuous integration and extended platform support, conventions and project-specific configurations and the leveraging of the NixOS toolkit and package manager.

Holonix can be used in three basic ways that allow for increasing levels of sophistication and control:

  • A project-agnostic one https://holochain.love 1-liner.

  • A project-specific one with the default.nix configuration, and

  • as a native NixOS overlay.

 

Write a simple hApp

For sharing data publicly you need to set the entry in the definition to 'public' — for that, go to your zomes/zome_name/code/src/lib.rs file and change the entry sharing from Sharing::Private to Sharing::Public:

    fn person_entry_def() -> ValidatingEntryType {
        entry!(
            name: "person",
            description: "Person to say hello to",
-            sharing: Sharing::Private,
+            sharing: Sharing::Public,
            validation_package: || {
                hdk::ValidationPackageDefinition::Entry
            },
            validation: | _validation_data: hdk::EntryValidationData<Person>| {
                Ok(())
            }
        )
    }

 

....to be continued soon..

also see: https://holochain-community-resources.github.io/design-workshop/#0  - how to design holochain app

 

How do you rate this article?

32


rhyzom
rhyzom

Verum ipsum factum. Chaotic neutral.


rhyzom
rhyzom

Ad hoc heuristics for approaching complex systems and the "unknown unknowns". Techne & episteme. Verum ipsum factum. In the words of Archimedes: "Give me a lever and a place to rest it... or I shall kill a hostage every hour." Rants, share-worthy pieces and occasional insights and revelations.

Send a $0.01 microtip in crypto to the author, and earn yourself as you read!

20% to author / 80% to me.
We pay the tips from our rewards pool.