Smart Contract operations on tokens
One of the ways an owner of tokens can perform operations on them, is by using smart contracts referencing the tokens. The operations that can be used are defined by the https://paiwise.tagroot.io/Schema/NeuroFeatures.xsd
namespace, the same namespace used to create the tokens.
The operations supported include:
Create
Destroy
Donate
(new)Transfer
Create
A smart contract with the Create
machine-readable element creates one or more Neuro-Feature tokens. Creating tokens may require a comission fee to be paid first, as defined by the smart contract template used. An initial value is set by the creator.
Destroy
Destroy
on the other hand, in a smart contract, destroys the token, if such is permitted by the token definition. During the creation of the token, the creator defines under what cirumstances the tokenⓈ can be destroyed, and by whom (if at all):
CreatorCanDestroy
defines if the creator is allowed to destroy the token.OwnerCanDestroyBatch
specifies that an owner can destroy a token or tokens, but only if the owner is the owner of all tokens created using the same creation contract (here called a batch of tokens).OwnerCanDestroyIndividual
allows the owner to be able to destroy any token it owns, regardless if other owners owns tokens from the same batch.CertifierCanDestroy
can be used to give privileges to a certifier signing the token creation contract, to destroy any of the certified tokens. This gives the certifier the authority to ensure and enforce the rules set forth in the creation contract.
Donate
The Donate
operation is new as of build 2025-01-30
. It allows an owner to donate a token or set of tokens to another, without a monetary recompensation. This operation does not change the registered last value of the token. (This is the initial value set during creation if the token has never been transferred, i.e. sold.) The donation operation registers a specific donation event for transparency, showing the ownership has changed without compensation.
Transfer
The original way to change ownership of a token is called Transfer
and includes a payment of eDaler® to compensate for the transfer. This payment may include a commission to the Trust Provider hosting the token. The payment will also be recorded as the new value of the token, and a corresponding event will be recorded, for transparency, giving future new owners (buyers) a way to transparently review a token’s history and trade.
LegalLab
The LegalLab repository contains multiple examples of token operations. This includes examples of the Create
, Destroy
, Donate
and Transfer
operations.
Adding external notes to Neuro-Feature™ tokens
Each Neuro-Feature™ token has an event log. Notes can be added to this log. If the Neuro-Feature™ token runs a state-machine, the state-machine can process the contents of such notes also.
There are 2 × 2 × 2 types of notes that can be added: Plain text and XML notes can be added, and they can be either by owner or an external source. They can also be personal or public. Personal notes are deleted when the token changes owner. This article describes how a public (to those with access to the token) external note can be added to the Neuro-Feature™ token.
External Sources
To add an external note on the token, you need to be an approved external source. Depending on method used to add the token, this source is typically a User name on the Neuron® hosting the token. This User name, can also be a domain name of the caller, if mutual TLS (mTLS) is used to authenticate the call. If note is added by an XMPP client or Agent API client, the source would be the Bare JID of the client adding the source. In all cases, the source needs to be an approved source, otherwise the note will be discarded.
Methods of adding an External Note
There are multiple ways how a note can be added to a token. If the caller is not the owner of the token, the note will be added as an external token. Some of the methods described allow the Owner to add a note. If this is the case, the note will be added as a normal note, and may be processed differently to an external note.
XMPP Library
You can use an XMPP extension library, such as the NeuroFeatures nuget from TAG. It extends the Waher.Networking.XMPP library using in the Neuron®, LegalLab, IdApp, Neuro-Access, and other projects. Once the XMPP Client is connected, you can use the extension library to add notes to any tokens.
Approved Sources: If adding a note via the XMPP library, the account you use to sign in must either be part of the contract that created the token, or be an approved external source. The token (if running a state-machine) can define what external sources are approved.
Agent API
The Agent API can be used to add notes to tokens in the network. Multiple implementations exist, including an Agent API nuget. Depending on the type of note you want to add, you can use the AddTextNote or AddXmlNote resources to add notes.
Approved Sources: As with using an XMPP Library, the account you use to sign in must either be part of the contract that created the token, or be an approved external source. The token (if running a state-machine) can define what external sources are approved.
NeuroFeatureNotes Nuget
A specific nuget exists for adding external notes to Neuro-Feature™ tokens: NeuroFeatureNotes. The source-code of this nuget is available in the AddNote repository published by TAG. The repository also contains information about the methods to use to add an external note, and what parameters are required.
Approved Sources: The nuget performs an HTTP POST to the Neuron® hosting the token. The request is authenticated using mutual TLS (or mTLS), where the caller provides a valid certificate that can be used to sign the request. To be able to use this method, you need to do the following:
Enabled mTLS on the Neuron® hosting the Neuro-Feature™ token. This is done in the gateway.config file, and then restarting the Neuron®. You need to set mTLS option to Optional at least, for mTLS to be activated for use in HTTP requests.
Create a Role on the Neuron® for users that are permitted to add notes on the Neuron®. The regular expression approving adding of notes specifically is:
+NeuroFeatures\.Notes\.Add\.(Text|XML)
Create a User on the Neuron® with the same user name as the domain name in the certificate you want to use. The user needs at least the privileges define in the Role above.
Note: There is no need to specifically in the token approve the external source, if the operator has approved the domain name already, authenticated using mTLS, as described above.
Once the settings have been made, the library can be used to add external notes to tokens on the Neuron®.
Command-Line tool
The AddNote repository contains a command-line tool that can be used to add external notes on tokens. This command-line tool can be used to automate adding notes via script. The repository lists the arguments required to run the tool.
Approved Sources: As the command-line tool uses the NeuroFeatureNotes nuget to add notes, authentication is performed using client certificates and mTLS, and the same steps of configuring the hosting Neuron® is required, as described above.
Script
If running multiple Neurons, you can add an external note using script on one Neuron® on a Neuro-Feature™ token on another Neuron®, using the certificate of the calling Neuron®.
To add a text note, call the following script (on the first Neuron®, via a web-service or the Prompt):
Post("https://DOMAIN/AddNote/TOKEN_ID","ADD THE TEXT YOU WANT TO ADD HERE.",\{\},Waher.IoTGateway.Gateway.Certificate)
To add an XML note, call a similar script, but instead of POSTing a string, POST an XML document (the XML needs to be valid, in accordance with the schema, downloadable from the namespace):
Post("https://DOMAIN/AddNote/TOKEN_ID",<ADD THE XML YOU WANT TO ADD HERE>,\{\},Waher.IoTGateway.Gateway.Certificate)
PS: The Community site adds backslash characters before the start and stop braces in the script examples above. These need to be removed when executing the script.
Approved Sources: The script above performs a POST that will be authenticated using mTLS, as in the examples above. Therefore, the same steps of configuring the Neuron® hosting the token is required, as described above.
Creating a Neuro-Feature token on credit using AgentAPI
This article describes how you can use the Agent API to create Neuro-Feature™ tokens on credit. It assumes you already have an account, and a wallet created. The wallet will receive the tokens created, as well as receive the credits required to pay for any token creation fees required. If you do not have an account with a wallet, check out the recipe Creating a wallet using Agent API.
The process is as follows:
- A smart contract template is created and approved. The purpose of the template is to define how tokens are created, and their legal context.
- A smart contract is created based on the approved template.
- Neuro-Credits™ are bought, to generate sufficient eDaler® in the wallet to create the tokens.
- Invoices with reminders are sent to the e-mail registered for the account.
- Payment of invoices can be done at a later stage (before the due-date) on the links provided in the e-mails.
- The contract is signed. This casues a series of events:
- The token generation process to start (if contract successfully approved, and not failed).
- Funds required to create the token or tokens are withdrawn from the wallet.
- The created token or tokens are received in the wallet.
Creating a smart contract template for token creation
The creation of smart contract templates is done outside of the scope of the Agent API. It is typically a development process, where token developers generate the template in some form of tool, such as LegalLab, and publish the templates on Neurons. Once the templates have been approved by the Neuron® operators, they can be the basis of creating smart contracts using the Agent API. When creating a smart contract based on a template, you can change the parties that sign, and the parameter values, within the valid ranges defined by the template, but you cannot change the underlying definition of the token, or any human-readable sections or validation rules of the smart contract template.
Note: The LegalLab repository contains many examples of templates for creating Neuro-Feature™ tokens. These can be used for development purposes, and for testing the concepts described in this article.
Creating a smart contract for token creation, based on a template
When automating the creation of smart contracts based on a smart contract template, you typically need the following information:
- A Contract ID for the template.
- What Roles are defined in the template, and how many are needed of each for the contract to become valid.
- What Parameters exist, and their types and valid value ranges.
This information is readily available from the template itself, and it may vary from template to template. It can also be provided by the developer of the template. But there are some roles and parameters that will occur frequently, if they are not hard-coded into the contract template itself. They are provided here, for reference:
Common Roles | ||
---|---|---|
Role | Use | Description |
Creator |
Required | The creator of the token. The party that signs the contract as a Creator pays the fees required to create the token or tokens. This would be the Agent API client, in the example of this article. |
Owner |
Optional | If the template allows the owner to be different from the creator, the party that signs as Owner will receive the created tokens in their wallet. |
TrustProvider |
Required | This role is reserved for the Neuron® itself. The Trust Provider is the party that permits the creation and hosting of the token, and assures the integrity of the token, as well as protects the confidentiality and privacy of the associated information. |
Valuator |
Optional | A party that attests to the initial value stated for the contract. |
Assessor |
Optional | A party that has provided necessary input in the creation of the token. |
Certifier |
Optional | A privileged role albeit external role of a token. They can certify to the correctness, legality, contents or context of the token. They can also be given special privileges with control over the life-cycle of the token (meaning, if the token definition permits it, they can kill the token if compliance quirements are not met). |
Witness |
Optional | A witness to the signature and creation of the tokens. |
Common Parameters | |||
---|---|---|---|
Parameter | Use | Type | Description |
Value |
Optional | Numeric | The initial value of the token. |
Currency |
Optional | String | The currency of the token. |
CommissionPercent |
Optional | Numeric | The number of percent of the value that needs to be paid by the creator, for the creation of the token or tokens. |
Note: There may be other parameters available that are required, depending on the type of token that is to be created. Check with the creator of the token definition to get a detailed list of parameters required to be set.
Getting token creation attributes
The Currency
and CommissionPercent
parameters that will be accepted by the Neuron®, as well as the Legal Identity identifier for the TrustProvider
Role, can be retrieved by calling the GetCreationAttributes resource using the Agent API. After retrieving these values, you can preset the parameter values accordingly.
Buying Neuro-Credits™
When you know the amount of eDaler® that is required to create a token, or the tokens, you can generate eDaler® on credit, by buying Neuro-Credits™. You can also generate more eDaler® than the token creation requires, and use it for multiple operations, to save on invoicing fees. Use the following resources in the AgentAPI to manage eDaler® in the wallet:
To get the current balance of the wallet, call the GetBalance resource.
To generate eDaler® in the wallet, you buy eDaler®. To see options available for buying eDaler®, call the GetServiceProvidersForBuyingEDaler resource. It will present configured options available for your choice of country and currency. Some of these providers are contract-based (i.e. they are initated by signing a smart contract with relevant information), and some are initiated by collecting information from the user via an external web page.
If you already know what service provider you want to use, like in the case for using Neuro-Credits™, you can skip this part. The Service Provider ID in this case is
TAG.Payments.NeuroCredits
, the Service ID isTAG.Payments.NeuroCredits.NeuroCreditsService
, and the ID of the smart contract template for initiating the process is2cdbfa69-6c21-82d9-880e-301af77b53f6@legal.paiwise.tagroot.io
(at the time of writing; you might want to double-check this regularly).To initiate the process of buying eDaler®, you can call the InitiateBuyEDaler if the service collects information from external web pages. If the process is started via smart contracts (like in the case for Neuro-Credits™) you simply create and sign a smart contract based on the template provided for the service.
Following is some information required to create a smart contract for buying Neuro-Credits™:
Defined roles Role Description Buyer
The one buying eDaler®, i.e. the Agent API client. TrustProvider
The Neuron® itself, giving the credit to the buyer. The following parameters need to be provided:
Required parameters Name Type Description Amount
¹Numeric Amount of eDaler® to buy. Currency
²String Currency to buy. InvoiceFee
³Numeric A fee for each invoice that is sent. Message
String A text message that will be included in invoices sent to the client, for reference. Period
³Duration The duration of the credit, or the time between installments, if multiple installments are used. PeriodInterest
³Numeric The interest rate of the (remaining) amount, calculated over the period. Installments
4Integer Number of installments desired. Some of the parameters are limited in range, and some must be set to a fixed value, depending on the configuration of the Neuro-Credits™ service on the Neuron®. To get these values and ranges, you call the GetServiceProvidersForBuyingEDaler resource:
- Amount is restricted to the maximum remaining credit allowed to the client.
- Currency must be the same as defined in the wallet of the client.
- The fees, period and interest rates are fixed by the service.
- The amount of installments allowed may vary on client.
Note: A smart contract with parameters outside of the authorized ranges will fail the contract.
The following parameters will be required to exist in the legal identity of the buyer, and will be visible to auditors of the contract, if a personal credit is requested:
- Full Name
- Personal Number
- Full Address
- Postal Code
- City
- Country
If an organizational credit is requested, the following additional information must be available in the legal identity of the buyer. This information will be visible to auditors of the contract:
- Organization Name
- Organization Number
- Department
- Role
- Organization Address
- Organization Postal Code
- Organization City
- Organization Country
Additional information that may be required include an associated e-mail address and phone number of the client. These will not be engraved into the contract however, for privacy reasons, and only be available to the operators of the service.
Once the parameter values have been determined, you create the smart contract by calling the CreateContract resource, and then sign it using the SignContract resource. Once everyone has signed the contract except the Trust Provider, the contract is analyzed, and the Neuron® signs as Trust Provider given that all parameters are correct. If information is incorrect or the process fails, the contract will be set to a
Failed
state, otherwise the contract will be set to aSigned
state and the corresponding eDaler® will be generated and placed in the wallet of the client. Al lasynchronous processes generate messages sent to the client, which the client can read by calling the PopMessages resource.
Note: Any changes to the balance of the wallet, or transactions being performed, are notified to the client asycnrhonously (i.e. as they happen). You can use the PopMessages resource to retrieve all such asynchronously sent messages to you.
Getting the human-readable text of a smart contract
The GetContract resource allows you to get the contents of a smart contract (that you have access rights to). If you want to present the contents of the contract to the user, you have to choose if you will render the contents, based on the existing object-model for human-readable text, or if you want the Nueuron® to format it for you. The default is to let the client render the contents in its own way. If you provide a value in the Format
argument, in the call to the GetContract resource, you can get the human-readable texts pre-rendered instead in the corresponding format. The following formats are supported (at the time of writing):
Human-readable text formats | |
---|---|
Value | Format |
Markdown |
Texts are returned in Markdown format. Markdown is easy to edit in text editors, and can be transformed to any of a series of other formats. |
Html |
Text is converted to HTML for insertion into existing HTML (i.e. it does not include HTML, HEAD and BODY tags.) |
Text |
Contents is converted to plain, unformatted text. |
Xaml |
XAML is generated for use together with Windows Presentation Foundation (WPF). |
XamarinXaml |
A special dialect of XAML, for use in Xamarin Forms, is returned. |
SmartContract |
An XML string containing the contents using the smart contract object model is returned. |
Signing smart contract to create tokens
When it is time to sign the contract, you call the SignContract resource for each signature you perform. You will sign the contract using the legal identity referred to in the call, and using the associated key. A contract becomes signed when all required signatures have been provided.
When then smart contract is to create a Neuro-Feature™ token, one of the roles is that of a Trust Provider. This role is reserved for the Neuron® itself, and represents the party that will host the token. Typically, a smart contract for token generation includes at least a Creator role, and often (but not always) an Owner role as well (if different from the Creator. If no Owner role is available, the Creator becomes the initial Owner.
When all signatures, except then Trust Provider has signed, the Neuron® validates the contract and signatures, and if all is OK, signs the contract itself. Once the contract has been signed, the token creation process begins. In this step, if the Neuron® detects there are missing funds, or other prohibited content is detected within the token itself, the contract becomes failed, and a message is sent to the creator.
Note: All changes to the contract, and generated token or tokens are notified to the concerned parties asynchronously. Use the PopMessages resource to receive such notification messages.
Transferring ownership of token
Once a token is created and alive, it can be transferred to a new owner. Such a transfer is basically a contract in itself. In this contract, the prospective new owner (or buyer) agrees with the current owner (or seller) to transfer the token from the seller to the buyer, and transfer an agreed amount of eDaler® from the buyer to the seller. The amount of eDaler® transferred is logged on the token itself, and visible to future buyers, and acts as the basis for the current value of the token.
The LegalLab repository contains example contracts for transferring ownership of a token between owners.
Note: The process of creating a transfer contract, and signing it, is the same as creating the token in the first place: You refer to a template when creating the contract, providing the corresponding parameters, and sign the contract accordingly. The Neurons take care of the rest.
#agent, #api, #neuro-feature, #credit, #edaler, #recipe, #legallab
Note commands in state-machine neuro-feature tokens
One way to interact with state-machines defined by Neuro-Feature™ tokens can be done using notes. Such notes can be either text or XML, and they can be either logged by the owner of a token creating the state-machine, or by approved external sources. All notes are logged also to the Neuro-Ledger™, for transparency reasons. For XML-tokens, an additional XML-validation is performed, before accepting a note: The XML must use publicly downloadable schema-files, and the XML must be valid, in accordance with these schema files. Personal notes are deleted, if the tokenⓈ change owner.
Until build 2023-09-22
of the Neuron®, owners and external sources had to know the syntax of such notes, to interact with the state-machines. The token, and underlying state-machine, can now instead describe what notes are available, under what contexts they are available, and how they are formed, in a way that is both understandable by machines, and humans. It is therefore possible to create user interfaces automatically and generatively, directly from the state-machine definition. LegalLab has also been updated to support such note commands, as have the corresponding example contracts in the repository.
Example: Digital Sensor Twin
The DigitalSensorTwin example contains several context-specific note commands. The owner can poll the sensor, pause reading, resume reading, reconfigure the digital twin, and terminate it. Some of these commands are parameter-less, others are parametrized. Parametrized note-commands require the user to fill in a form before the note can be logged. All XML-based commands use a corresponding schema file, available in the repository, and also downloadable from the corresponding namespace URL.
In the following example, LegalLab is used to create a digital sensor twin of a weather station, available at the XMPP address concon.openweathermap@lab.tagroot.io
.

Once the contract has been created and signed, the token is created, together with the state-machine of the digital twin of the sensor. The corresponding token appears in the Tokens tab. Note commands, defined in the token itself, will now appear in both the context menu, as well as in the token details view.

Parametrized note commands
As an example of a parametrized note command, let’s review the Reconfiguration command in the digital sensor twin, and how it is defined:

The parameters are defined in a similar manner, as contract parameters. An optional note context script can be added to tell the client under what conditions the command is visible. The script is run on the client, is checked to be safe, and can include references to the state or internal variables of the state-machine to evaluate if the command should be visible or not. The script should return a Boolean value. Anything else, will hide the command.
Once the command is executed, the note generation script is executed, and should return either a text string (for text notes) or XML (for XML notes). Anything else is ignored. If text or XML is returned, this is the basis for the note that will be logged.
Note: To avoid confusion as to what is XML, and what is script, it may be a good idea to always embed script in CDATA constructs, as shown in the example. This becomes especially important, if the script also contains XML, as in this case.
Parameter-less note commands
If a note command does not require parameters, simply skip the Parameters section in the definition. Such commands may still be context-sensitive, for instance, be based on the current state of the state-machine, or its internal variables. You can try such commands by testing the Pause and Resume commands of the digital sensor twin. The Pause command is only available in the active state, while the Resume command is only available in the Paused state.

State-Machine Schema
The most recent schema for State-Machines is always available by downloading the schema from its URL, which is the same as its namespace: https://paiwise.tagroot.io/Schema/StateMachines.xsd. It contains the details, what attributes are available, as well as what is required and what is optional.
Bug Fixed: State machines did not persist the beforeActionScript
attribute
State-machines using the beforeActionScript
attribute on action reference nodes, such as event handlers, have lost their corresponding attribute values after restart. The reason is that the attribute value was not persisted.
Cause
The root cause of this is that the property was declared incorrectly. To be persisted, an attribute needs to have a public get and set method available, for the persistance layer to be able to persist it. Persistence is implicit, and no code is written explicitly to persist or load objects. Instead, the persistence layer relies on the declaration of the properties to persist. In this case, this particular property lacked such get and set methods.
Background
The beforeActionScript
attribute was introduced to provide a means to re-use actions for different types of events. It allows the event handler to customize the execution of the action, by (for instance) providing variable declarations. (In such cases, the before-action script would work as assigning argument values in a function or method call in procedural or object-oriented programming languages.)
Tests
The problem was not detected in unit tests, since these are implemented in such a way to create new state machines for every test, to not rely on earlier execution, and therefore, they did not test more than the operation (which worked), and that persistance occurred without error. The tests missed that this particular attribute was lost once loaded after server restart.
Fix
The attribute is now declared properly, and value is persisted.
Review
After a review of the entire state machine model, it is concluded that this attribute was the only attribute that lacked a proper declaration.
Affected tokens
This problem affects generated tokens on Neurons with a build-time before 2023-09-21
, if and only if they used the beforeActionScript
attribute. After update, new tokens generated will persist the attribute correctly. Upgrading your Neuron® to a newer version, will not resture the attribute value.
Repair
A new method has been added to the State-machine object: ReparseDefinition()
. As the original XML of the state-machine is available (and kept immutable in the token), the lost attribute can be regained by calling the ReparseDefinition()
method on each state-machine, resave the objects, and then restart the Neuron®, for the changes to take effect.
Following is some script you can execute in the script prompt to re-parse all state-machines on the Neuron®. It will return a vector of all state-machine-IDs processed. Depending on the number of state-machines, complexities of the models, etc., execution of the script may take some time. (You can adapt this script if you want to apply it only to specific state-machines.) Make sure to take a backup before executing the script.
preview("Loading state-machines. This may take some time.");
Machines:=select * from StateMachines;
[foreach Machine in Machines do
(
preview("Processing "+Machine.StateMachineId);
Machine.ReparseDefinition();
UpdateObject(Machine);
Machine.StateMachineId
)]
Note: All changes to the operational state of the state-machine, as well as script executed via the script prompt, will be logged, both to the event log, as well as to the Ledger.
Note 2: If expecting many state-machines to be processed, you can use the TOP
and OFFSET
operands in the select
statement, to paginate the processing into chunks.
Note 3: Keep the event log sniffer open while processing the script, to check for any unexpected events.
Note 4: Test this script in your lab/development environment first, and consider whether you need the update in your production environment or not, before applying the change. You can also modify the script to only process the state-machines you decide are important to update, to minimize any risks when performing the update.
Posts tagged #neuro-feature
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.