or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Do you want to remove this version name and description?
Syncing
xxxxxxxxxx
#S:MODE=test #S:EXTERNAL=javascript=simple_micro_blog.js=test #S:EXTERNAL=rust=simple_micro_blog_p1.rs
Simple Micro Blog tutorial
Welcome to the Simple Micro blog tutorial in the Core Concepts tutorial series. The aim of this tutorial is to show how entries can be linked to each other in a Holochain app. A link is simply a relationship between two entries. It's a useful way to find some data from something you already know. For example, you could link from your user's agent ID entry to their blog posts.
You will be building on the previous Hello World tutorial and making a super simple blog app. The app's users will be able to post a blog post and then retrieve other users' posts.
DNA hash
The way you run your conductor has changed from
hc run
to callingholochain
directly. As a consequence, the hash of your app's DNA now lives in theconductor-config.toml
file. However, anytime you change your code and runhc package
the hash will be different. So you will need to update theconductor-config.toml
file.Enter the nix-shell:
Package your app:
Copy the DNA hash (example shown):
Update the
conductor-config.toml
dna hash:Post
We will store our posts as a
Post
struct that holds a message of typeString
, a timestamp of typeu64
, and an author ID of typeAddress
.We're done with the Hello World tutorial, so remove the
Person
struct and add thePost
struct:Entry
Update the
person
entry type definition topost
:Agent ID
#S:INCLUDE
#S:EXTERNAL=rust=simple_micro_blog_p2.rs
Now you have a post entry but you also need some way to find the posts an agent makes. To do this you can create an agent 'anchor' entry which you will use to link to the posts that the user makes. An anchor is a simple string whose only purpose is to be an easy-to-find entry to attach links to.
Define an agent anchor entry type by adding the following lines below the
post_entry_def
.Add an
agent_entry_def
function which creates an entry type for the agent:Start the
entry!
macro for the agent entry:Set sharing to public so other agents can find this agent's anchor (and hence their posts):
Add basic validation to make sure this is the
Agent
type that is passed in:Now you want to be able to link this agent entry to the post entry.
Start out with the
to!
link macro, which lets you create link definitions that link from this entry type to another entry type:Define a link type from this entry to the
post
entry calledauthor_post
:Add empty validation for this link:
Create a post
Remove the
create_person
function.You need a function for creating a new post. Think about the ingredients that might go into the
Post
structure: a message, a timestamp, and and the author's ID.The message will come from the UI. For simplicity the timestamp will come from the UI as well. Time is a pretty tricky concept in the distributed world and requires careful planning. The author's ID will come from the special constant
hdk::AGENT_ADDRESS
, which you can access from your zome functions.Add a public
create_post
function that takes a message as aString
and a timestamp as au64
:Create the
Post
using the message, timestamp, and author's address:Create the
Agent
struct from theAGENT_ADDRESS
, turn it into anEntry
and commit it:Commit the post entry:
Create an
author_post
link from the agent to the post:Return everything is Ok with the new post's address:
Retrieve all of a user's posts
Add the
retrieve_posts
public function that takes an author address and returns a vector of posts:Create an
Agent
struct from the passed address, turn it into anEntry
, and calculate its address:Get all the
author_post
links from the agent's address and load them as thePost
type:(Note that because you've already told Rust that this function is going to return a vector of posts, the compiler will tell
get_links_and_load_type
what type to use in the conversion.)We're using a new directive,
link::LinkMatch
. You'll need to add it to youruse
statements at the top of the file:#S:SKIP
Get the agent's ID
As a user, you will need some way of getting your own agent's ID in the UI later so that you can pass it to others. Then they can try getting your posts.
Add a public
get_agent_id
function that returns anAddress
:#S:INCLUDE
For this app you can use the agent's address as their ID, because that's what we're storing in the agent anchor entries:
Show the agent's ID in the UI
Let's start on the UI. Go to your GUI folder and open up the
index.html
file.To make it easy to pass around agent ID, you can display the ID for the instance that each GUI is currently targeting. This should happen when the page loads and when the instance ID changes.
Add an
onload
event to the body that will call theget_agent_id
function when the page loads:Add an
onfocusout
event to the instance text box that will call the same function when unfocused:Now open up the
hello.js
file and add theget_agent_id
function:#S:MODE=gui,SKIP
Get the instance value and set up a zome call connection:
Call the
get_agent_id
zome function and then update theagent_id
element with the result:Update the UI to allow posts to be created
Back in
index.html
turn the "create person" HTML into a post entry widget. Use atextarea
, call thecreate_post
function, and update all the labels and IDs:Update the UI to retrieve an agent's posts
Update the "retrieve person" HTML to retrieve posts:
Call
create_post
from JavaScriptIn the
hello.js
file add thecreate_post
function that your HTML calls:Get the post message and instance ID:
Get the current timestamp:
Make a zome call to
create_post
with the message and timestamp:Update the posts list dynamically
Add an empty list below the
post_agent_id
text box:In the
hello.js
file add the following lines to update theposts_output
dynamically.Add the
display_posts
function:Get the
posts_output
HTML element:Wipe the current contents of the list, if any:
Parse the zome function's result as JSON:
Sort the posts by their timestamps:
For each post add a
<li>
element that contains the post's message:Get this agent's ID
Add the
get_agent_id
function:Call the
get_agent_id
zome function and update theagent_id
element:Retrieve an agent's posts
This is very similar to
retrieve_person
, so just update that function:#S:INCLUDE,HIDE