## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = FALSE ) ## ----setup-------------------------------------------------------------------- # library(multichainr) # # # Set the path to your MultiChain binaries # mc_set_path(Sys.getenv("MULTICHAIN_PATH")) ## ----init--------------------------------------------------------------------- # chain_name <- "logic_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) ## ----create_library----------------------------------------------------------- # # Define the JavaScript code for the library # lib_js <- " # function isSafeTemp(temp) { # return temp >= -50 && temp <= 100; # } # " # # # Create the library on the blockchain # # updatemode = 'instant' means updates take effect immediately without voting # mc_create_library(conn, "validator", updatemode = "instant", js_code = lib_js) # # cat("Library 'validator' created on-chain.\n") ## ----define_filter------------------------------------------------------------ # # The filter code imports the 'validator' library # filter_js <- " # function filterstreamitem() { # var item = getfilterstreamitem(); # # if (item.data.json && typeof item.data.json.temp !== 'undefined') { # if (!isSafeTemp(item.data.json.temp)) { # return 'Invalid temperature detected by on-chain logic'; # } # } # return true; # } # " ## ----test_filter-------------------------------------------------------------- # # 0. Setup a temporary stream for testing # mc_create_stream(conn, "test_stream", open = TRUE) # mc_subscribe(conn, "test_stream") # # # 1. Publish valid data and get its TXID # txid_valid <- mc_publish(conn, "test_stream", "key1", list(json = list(temp = 25.5))) # # # Test the filter against the valid transaction # test_valid <- mc_test_stream_filter(conn, # options = list(libraries = list("validator")), # js_code = filter_js, # tx = txid_valid) # print(test_valid) # Should be TRUE (logical) or 'true' (string) # # # 2. Publish invalid data and get its TXID # txid_invalid <- mc_publish(conn, "test_stream", "key1", list(json = list(temp = 500))) # # # Test the filter against the invalid transaction # test_invalid <- mc_test_stream_filter(conn, # options = list(libraries = list("validator")), # js_code = filter_js, # tx = txid_invalid) # print(test_invalid) # Should return our error message string ## ----deploy_filter------------------------------------------------------------ # # 1. Create the telemetry stream # mc_create_stream(conn, "telemetry", open = TRUE) # # # 2. Create the stream filter globally # # Here 'options' only specifies the libraries used. # mc_create_stream_filter(conn, "temp_range_check", # options = list(libraries = list("validator")), # js_code = filter_js) # # # 3. Activate the filter for the 'telemetry' stream # # In MultiChain, filters must be approved for specific entities. # admin_addr <- mc_get_addresses(conn)[1] # # mc_approve_from(conn, # from_address = admin_addr, # entity = "temp_range_check", # approve = list("for" = "telemetry", approve = TRUE)) ## ----verify------------------------------------------------------------------- # # This will SUCCEED (20 is within range) # txid_ok <- mc_publish(conn, "telemetry", "sensor_01", list(json = list(temp = 20))) # print(paste("Successful publish TXID:", txid_ok)) # # # This will FAIL at the protocol level. # # We use try() to catch the RPC error so the vignette can continue. # publish_error <- try(mc_publish(conn, "telemetry", "sensor_01", list(json = list(temp = 999))), # silent = TRUE) # # if (inherits(publish_error, "try-error")) { # cat("Rejected! As expected, the filter blocked the invalid data.\n") # } # # # Retrieve the filter code from the blockchain to verify # code_info <- mc_get_filter_code(conn, "temp_range_check") # cat("Stored filter code length:", nchar(code_info), "characters.\n") ## ----cleanup------------------------------------------------------------------ # # 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) # }