Geo-spatial contract parameters in LegalLab
LegalLab has been updated to support geo-spatial contract parameters. An example contract is also available showing how geo-spatial parameters in contracts can work. Make sure the Neuron® to which you are connected is updated to include support for geo-spatial parameters.
Adding to templates
A new button is available that you can click to add a geo-spatial parameter to a contract template you are designing:

Note: When editing geo-spatial parameter values, use GPS Coordinate syntax.
Geo-spatial Publish/Subscribe
When signing contracts with geo-spatial parameters, one of the parmeters can be used to give the contract a location. The example contract contains one such parameter. This means the contract, when signed, is assigned the geo-spatial coordinate provided in the parameter. The contract position is also published using the Neuron’s geo-spatial publish/subscribe service. If the visibility of the contract is set to Public & Searchable, the publication will be persisted. Otherwise, the publication will be ephemeral, i.e. shown only at the time of signature.
Processing signed contracts in a state machine: Open Vote example
The LegalLab repository contains a new example that illustrates how Neuro-Feature token state machines can be used to process signed smart contracts. The example implements a simple open voting system that tokenizes each vote, counting ballots within a given time frame, as they are cast. Each ballot is a smart contract signed by a participant. The state-machine of the vote counts accepted ballots, rejects incorrect ballots, and logs events to the Neuro-Ledger for transparency and auditability.
Note: The same architecture as exemplified by the Open Vote set of contracts (Vote + Ballot contracts) can be used in many technically similar (albeit conceptually different) cases. One such example is the tokenization of agriculture, for example, where each cultivation can be tokenized, and it can keep track of its current state transparently (for the end consumer) by processing observations, each observation recorded as a signed smart contract with information about what has occurred. Another example can be the tokenization of medical journals, for interoperability and privacy protection. The journal observes diagnoses and tests being performed, each one recorded as a signed smart contract with the appropriate information.
Vote Contract
The first contract in the Open Voting model (OpenVoteYesNoAbstain.xml
), contains the state-machine Neuro-Feature token definition and contract. It defines the basic states of ballot processing. It assumes each ballot contains machine-readable information, as defined by the schema OpenVote.xsd
, also downloadable online via its target namespace: https://paiwise.tagroot.io/Schema/OpenVote.xsd
.
Note: Each contract containing machine-readable instructions will only be accepted if each Neuron® can validate the XML it contains. This is done by downloading the schema files from the corresponding target namespaces and using these schemas for validation. If the validation does not complete successfully, the contract is automatically rejected.
The states defined in the contract can be illustrated with the following state diagram:

The voting contract allows the creator to pose a question, define if participants are allowed to change their votes, and between what times the vote will be active. Times are defined in UTC. Participants need personal digital IDs with at least a validated country code, personal number and full name. Only one ballot per (Country, Country Code) will be counted. Apart from a Creator, the contract also requires a Certifier, which can be the same as the creator. The Certifier are given rights to cancel (invalidate) an election.
The states a voting procedure passes through are:
During the Preparing state, the state machine checks if it is paired with a Ballot template that points to it. The Ballot template needs to define a contract reference parameter to the vote, and it needs to enforce the template of the vote to match the template used to create the vote. If one such Ballot template is found, it progresses automatically to the next state. If one is not found, it awaits until such a template is approved on the Neuron®.
The Pending state, is a state where the vote is prepared, but has not commenced yet. During this state, the present view can be displayed, and links to the vote can be distributed. Any ballots cast during this state will be automatically rejected. Once the time to open the vote has been reached, the state-machine progresses to the next state.
The Open state is where participants can vote by signing Ballot contracts. If they are signed using the appropriate template, and pointing to the vote, the state-machine will process the ballots. If any errors are encountered, the corresponding ballot is rejected, and error logged. When the finishing time has been reached, the state-machine progresses to the next state.
The last state is the Closed state. Here, the voting machine is kept alive, to present results, but no ballots are processed, so the tally cannot be changed. Once the expiry time is reached, the state-machine is ended.
During state changes, the creator is notified by XMPP (Instant Chat Message) and e-Mail about the state of the vote. The messages contain links to the vote. These can be distributed to participants of the vote. The vote can also be shown in a browser. If published, voters and other participants can follow the results in real-time.
Ballot Contract
The second contract template is the OpenBallotYesNoAbstain.xml contract. It defines the ballot contract that can be used to participate in any votes generated by the corresponding voting template. The two templates must be paired. So, once the voting template has been proposed and apporved, its ID must be set into the Ballot template contract, before it can be proposed. Once this has been done, it can be proposed and approved accordingly. Then, the pair can be used with as many votes as desired.
The Ballot template defines the Boolean parameters necessary to be able to select Yes, No or Abstain. The Machine-readable part (defined by the https://paiwise.tagroot.io/Schema/OpenVote.xsd
namespace) instructs the vote state-machine how the ballot is to be interpreted. The Ballot template has a contract reference parameter of a given name, and it must require a contract reference having a template ID restriction equal to the ID of the voting template. Once the voting state-machine is running, it will provide links to the corresponding Ballot contract template, with these references pre-set, so the user does not need to worry about providing the values for thse references. The user will only scan a QR code to vote.
Approved templates for experimentation
If you want to experiment with the open voting solution described, you can use the following approved contract templates. You can either copy the contract IDs and use in your application, or if you use an App, scan the corresponding QR code to access it.
To create a vote, i.e. define a question partiticpants will vote on, use the following template by scanning the code or entering its ID in the appropriate interface:

The matching Ballot template (which you will not need to scan here directly, as it will be presented pre-filled for you, see below), is:

After scanning the code, a new vote contract will be displayed. Fill in the details (question, if votes can be changed and the time interval the vote will be open; remember the times need to be provided in Universal Time Coordinates, or UTC). Sign the contract, both as Creator and Certifier (unless you want another person to sign as Certifier). Once the vote has been created and been properly signed, a Neuro-Feature token will be created. It will send you an e-mail with a link to the voting results page. The vote only passes slightly the preparation state, as an approved ballot template already exists. The vote page will look something as follows. Note the QR code to the right. It will point to the ballot contract template to use to cast a ballot, and also contain the reference to the current vote pre-filled. All you need to do after scanning the QR-code, is to select how you want to vote.
Note: The vote token is defined to be unique. This means, you can only create one token (one vote) with the same set of parameters. This means, you need to change any of the parameters from previous versions, including the question or time parameters, before you can create additional votes.
Vote Count & real-time presentation
The token that is generated by the vote contract has a present report that displays the current state of the vote. The creator can access the present report from the client used to create the vote contract, and by extension the token. The creator will also get an Instant Chat Message and an e-Mail, containing the present report and current vote count (which would be zero and pending, before the count starts). There will also be a web URL which can be distributed, that will show the vote to any online viewer. The URL will have a format similar to https://sa.id.tagroot.io/NF/a86d6033-b694-7b5e-c8d3-42d5200ec85c@edaler.sa.id.tagroot.io
. The ID in the URL corresponds to the ID of the Vote. You can match this ID with the ID displayed for the vote (see below). The present report can be projected and displayed in kiosk mode as well. It will be updated in real-time as votes are counted. The initial view may be something as follows:

Note The QR code in the report can be scanned by participants, and will point to the ballot template, with the vote reference pre-filled in. All the participant needs to do, is vote, and sign the ballot and the vote will be counted. Once the vote closes, the report will be updated accordingly also.

Note: Once the vote closes, the QR code changes. It is no longer pointing to the ballot template, but instead to the token that performed the count. Scanning it will give access to the token, and the reports it publishes.
Presentation Layout
The layout presenting the vote count is generated by the voting token itself, and is part of the vote contract template, and can therefore be reviewed as well. It is an XML Layout format, availble in the OpenVoteResultLayout.xml
file. You can edit such XML files and preview the layout using LegalLab as follows:

The variables and script functions used in the layout need to be initialized. This can be done in the Script tab. You can use the initialization script published in the repository: OpenVoteResultLayoutInit.script
to generate the view above.
Neuro-Ledger entries recorded
Apart from all entries recorded regarding Digital Identities, Smart Contracts, Tokens and State-Machines, the Open Vote example records several entries by itself. These include:
Entry | Description |
---|---|
BallotCounted |
A ballot has been counted. |
BallotRejected |
A ballot has been rejected. |
BallotRevoked |
When an older ballot has been revoked because the participant submits a new ballot. |
CommentReceived |
A comment by a participant has been received. |
Note: The vote contract defining the vote, also defines the Neuro-Ledger Collection these entries are recorded in.
The other common Neuro-Ledger collections annotating entries are:
Neuro-Ledger Collections | |
---|---|
LegalIdentities |
Contains entries related to digital identities, including Neuro-Access digital identities. |
Contracts |
Contains entries related to smart contracts, including the voting contract and the ballot contracts used during voting. |
NeauroFeatureTokens |
Contains information regarding Neuro-Feature tokens, including the token definition of the open voting logic. |
StateMachines |
State-Machine information is recorded in this collection. This includes the open voting process performing the ballot counting and presentation. |
StateMachineCurrentStates |
Contains current states of different State-Machines. |
StateMachineSamples |
Contains variable changes as they are persisted by State-Machines. These samples can be used to track the counting process. |
#tutorial, #example, #legallab, #contracts, #neuro-feature, #neuro-ledger, #state-machine
Troubleshooting Stack Overflow and Out of Memory Errors
The Neuron® normally runs as a Windows Service using the limited Local Service user account. Any errors in the Neuron® or any of the applications hosted within it, are normally logged to the internal event log, which distributes events to registered event sinks. These may record them in files, internal databases, the Windows Event Log, or forward them to external sources, both for real-time monitoring or storage. Communications can also be monitoried and trouble-shooted using sniffers that can be temporarily attached to different communication channels. Any Exception occurring within the system can also be logged separately together with stack traces, and statistics of such is generated when the Neuron® restarts. But one type of Exception is particularly difficult to troubleshoot, especially for a Windows Service that runs invisibly on a server: Stack Overflow, Out-of-Memory, Access Violation Exceptions and other fatal exceptions can typically shut down the service immediately, without any possibility to record details about the event for troubleshooting. The only notification an operator may receive, is that the Neuron® restarts unexpectedly. After reviewing the backups folder, the operator may also notice the database has been repaired, since the Neuron® was shut down ungracefully (i.e. the process was killed). There are a couple of ways you can find out what causes such an error.
Remote Debugging
One way to find this error, is to attach to the Neuron® process on the server using Visual Studio Remote Debugging tools. Once attached to the process, the debugger can be configured to break when the Exception occurs, giving you a chance to examine the stack trace before the process is killed. There are difficulties with this approach however. One is that the code is probably optimized for Release, and difficult to Debug. You must also open ports, install the remote debugger, etc.
Running as a Console
Another way to troubleshoot the Exception, is to run the console version of the Neuron® in a Terminal Window or Command Prompt. The difficulty here, is to make sure the Terminal Window is using the correct user privileges to mimic the environment the Windows Service has. This can be done by downloading PSTools from Microsoft. It provides tools to access internal features in the Windows operating system. Once installed, you open a Terminal Window (Command Prompt) with administrative privileges. You go to the folder where PSTools is installed, and you type the following command:
psexec -i -s -u "NT AUTHORITY\LocalService" cmd.exe
This will open a new terminal window with the correct user privileges. Before starting the Neuron® in the new terminal window, you need to stop and disable the Windows Service, so it does not interfere. Then, in the new terminal window, go to the installation folder of the Neuron®, and type:
Waher.IoTGateway.Svc.exe -console
It uses the same executable file that is executed by the Windows Service, but the -console
switch starts it in console mode. This will enable terminal output of the internal event log, and any system message that will appear. If a Stack Overflow, Out of Memory or Access Violation Exception occurs (or any other fatal type of Exception), this information will be output to the terminal window as the process is killed.
New Neuron Popup System
We have replaced window.alert
, window.confirm
, and window.prompt
with a custom popup system. This provides better control and accessibility for user interactions.
Overview
- Improved User Experience: The popups have a consistent style and can be customized.
- Accessibility: Focus trapping ensures proper keyboard navigation.
- Better Control: Supports handling of modal dialogs with promises.
How to use it
The popup system is located in the Master.js
file. To use it include the folowing headers in your markdown or master file.
Javascript: /AlertPopup.md.js
Javascript: /ConfirmPopup.md.js
Javascript: /PromptPopup.md.js
Javascript: /Master.js
You also need a dialog container in the bottom of your html body.
<div id="native-popup-container"></div>
Additionally, the theme used must implement the base theme base.cssx
for styling. Alternatively you could style it yourself, but it would be recomended to instead cascade over the already existing css or changing the themes cssx variables;
Usage
Alert
Use Alert(message)
to display a basic alert popup.
const popup = PopupHandler();
await popup.Alert("This is an alert message.");
Confirm
Use Confirm(message)
to display a confirmation dialog that returns a boolean.
const result = await popup.Confirm("Are you sure?");
if (result) {
console.log("User confirmed.");
} else {
console.log("User canceled.");
}
Prompt
Use Prompt(message)
to capture user input.
const userInput = await popup.Prompt("Enter your name:");
console.log("User entered:", userInput);
Details
- All popups are contained in a shared container.
- The popup backdrop is generated by the Master.js file, and placed at the bottom of the body tag
- If you initiate a new popup whilst one is already open, it will cover the old one. The old one will be accesible after you interact with the newly created one. You can think of the popups in a stack datastructure.
- Focus trapping disables focusing outside the popup using tab and shift + tab.
- Your master markdown file must include the following element at the bottom to contain the popups:
- If you dont need to wait for an Ok press when using Alert() you don’t need to await the response.
Developing for HTTPS with self-signed certificates
When developing on the Neuron® in a local environment, you typically don’t have access to a domain name accessible from the Internet. You can therefore not create a valid server certificate for the machine, something that is required for enabling encryption using protocols such as HTTP, XMPP, etc. If you do development that require such encryption, you can either choose to develop on a machine published on the Internet (not recommended), or temporarily use a self-signed certificate on your local version of the Neuron®, to enable encryption.
An example of task that requires use of HTTPS, is web access using HTTP/2. Using a browser to navigate your local Neuron®, typically results in the browser defaulting to HTTP/1.1. The original mechanism of upgrading a connection to HTTP/2 was obsoleted for unencrypted communication, so there’s no automatic manner for the browser to know it can upgrade. The upgrade mechanism typically used, requires use of TLS and ALPN, where the server states what protocols it supports. The browser therefore knows immediately which protocol to use, without having to perform a costly upgrade.
Another example that requires use of HTTPS, are connections that require authentication using mTLS.
For security reasons, uploading server certificates is not permitted in the GUIs of the Neuron®. Certificates are automatically created and maintained by the Neuron® using the ACME protocol, and certificate authorities on the Internet supporting the ACME protocol. The certificates are then maintained by the Neuron® itself and stored in its internal storage, to avoid the certificate being used elsewhere. To use a self-signed certificate therefore, we need to use script.
Checking if HTTPS is enabled
To check if HTTPS is enabled already on your machine, type the following in the script prompt:
Gateway.HttpServer.OpenHttpsPorts
If an empty array is returned, HTTPS is not enabled. If it contains one or more integers, they represent the port numbers you can use to access the Neuron® using HTTPS (i.e. HTTPS is enabled).
Creating a self-signed certificate
You can use the .NET runtime to create a self-signed certificate for your localmachine (localhost
) for use in development. Type the following in a command-prompt, where you replace the FILENAME
and PASSWORD
with the filename you want to get the certificate exported to, and the password you want to use to protect the certificate:
dotnet dev-certs https -ep FILENAME -p PASSWORD --format Pfx
Configuring the Neuron®
As the admin interface does not permit uploading of custom certificates, we need to configure the Neuron® using script. The following example illustrates the properties that must be set:
DConfig:=DomainConfiguration.Instance;
DConfig.Domain:="localhost";
DConfig.UseDomainName:=true;
DConfig.UseEncryption:=true;
DConfig.PFX:=LoadFile(FILENAME);
DConfig.Password:=PASSWORD;
UpdateObject(DConfig);
For this script to have an effect, you need to use a broker with a build-time of
2024-12-12
or later.
Port configuration in Gateway.config
For the web server to open one or more HTTPS ports, they must be configured in gateway.config
. From the Admin page, under Data and Sources & Nodes, you find the gateway configuration and port settings. There must be at least a port configuration for HTTPS, as illustrated in the following figure:

Restarting Neuron®
The configuration is applied when Neuron® is started. So for the changed to take effect, you need to restart the Neuron®. Once it has restarted, you can test the web server has opened at HTTP ports for incoming communication by executing the following script again:
Gateway.HttpServer.OpenHttpsPorts
Once you have confirmed the ports are open, you can direct a browser to the Neuron® using the domain localhost
and the corresponding port, if different from the default HTTPS port 443
.
Security Notice
Self-signed certificates should not be trusted, or installed or configured in the operating system to be trusted, as this would create a vulnerability that can be exploited. Instead, when navigating to the local development Neuron® using HTTPS, you will get a warning and the browser will initially refuse to show the contents. Accept the warning and tell the browser to view the content anyway.
Removing Certificate
To remove the certificate, and disable encryption on your local development server, you execute the following script:
DConfig:=DomainConfiguration.Instance;
DConfig.Domain:=null;
DConfig.UseDomainName:=false;
DConfig.UseEncryption:=false;
DConfig.PFX:=null;
DConfig.Password:=null;
UpdateObject(DConfig);
After executing the script, you need to restart the Neuron®.
Posts tagged #tutorial
No more posts with the given tag could be found. You can go back to the main view by selecting Home in the menu above.