Introduction
MultiChain streams allow for the storage and retrieval of arbitrary data. Each item in a stream is associated with one or more keys, a publisher, and a timestamp (block time). Streams are ideal for audit logs, supply chain tracking, and sharing data between participants without the overhead of native assets.
library(multichainr)
# Set the path to MultiChain binaries
mc_set_path(Sys.getenv("MULTICHAIN_PATH"))1. Node Initialization
We begin by setting up a local node and a temporary blockchain.
chain_name <- "streams_demo_chain"
# Create and start the node
mc_node_init(chain_name)
mc_node_start(chain_name)
# Wait for the node to initialize
Sys.sleep(3)
# Connect to the local node
config <- mc_get_config(chain_name)
conn <- mc_connect(config)2. Creating and Subscribing to Streams
A stream can be open (anyone with global
send permissions can write) or restricted
(only specific addresses with write permissions on that
stream can publish).
stream_name <- "sensor_data"
# Create an open stream
mc_create_stream(conn, stream_name, open = TRUE)
# Before reading from a stream, the node must be subscribed to it.
# This instructs the node to index the stream's items locally.
mc_subscribe(conn, stream_name)
# Verify stream information
info <- mc_get_stream_info(conn, stream_name)
print(info$name)3. Publishing Data
Data can be published as plain text, JSON, or raw hexadecimal strings.
# 1. Publish a simple text message
mc_publish(conn, stream_name, "device_01", list(text = "Temperature: 22.5C"))
# 2. Publish structured JSON data
sensor_log <- list(
temp = 23.1,
humidity = 45,
status = "OK"
)
mc_publish(conn, stream_name, "device_01", list(json = sensor_log))
# 3. Publish an item with multiple keys
mc_publish(conn, stream_name, c("device_02", "alert"), list(text = "Critical Battery Level"))4. Retrieving and Querying Items
You can retrieve items by their specific transaction ID, or list multiple items using various filters.
# List the 10 most recent items in the stream
# Returns a data frame with columns: publishers, key, data, blocktime, etc.
recent_items <- mc_list_stream_items(conn, stream_name, count = 10)
print(recent_items)
# List all items associated with a specific key
device_history <- mc_list_stream_key_items(conn, stream_name, "device_01")
print(device_history)5. Stream Summaries (State Tracking)
MultiChain can automatically merge multiple JSON objects published under the same key. This is useful for tracking the “current state” of an object without manual aggregation.
# Update the status of device_01
mc_publish(conn, stream_name, "device_01", list(json = list(status = "MAINTENANCE")))
# Get the merged summary for 'device_01'.
# We use "jsonobjectmerge,ignoreother" to skip the plain text items
# we published earlier.
current_state <- mc_get_stream_key_summary(conn,
stream_name,
"device_01",
mode = "jsonobjectmerge,ignoreother")
print(current_state)6. Cleanup
Shut down the node and clean up the data directory.
# Stop the node
mc_node_stop(conn)
Sys.sleep(2)
# Determine data directory
if (.Platform$OS.type == "windows") {
base_dir <- file.path(Sys.getenv("APPDATA"), "MultiChain")
} else if (Sys.info()["sysname"] == "Darwin") {
base_dir <- file.path(Sys.getenv("HOME"), "Library/Application Support/MultiChain")
} else {
base_dir <- file.path(Sys.getenv("HOME"), ".multichain")
}
chain_dir <- file.path(base_dir, chain_name)
if (dir.exists(chain_dir)) {
unlink(chain_dir, recursive = TRUE)
}Summary
In this vignette, we demonstrated how to:
-
Create and Subscribe: Using
mc_create_streamandmc_subscribeto initialize data storage. -
Publish Data: Using
mc_publishto store text and JSON payloads associated with keys. -
Retrieve History: Using
mc_list_stream_itemsandmc_list_stream_key_itemsto query the blockchain ledger. -
State Management: Using
mc_get_stream_key_summaryto aggregate JSON data and view the current state of a specific key.