Uniclient CLI tool: User Manual

For more information on Uniclient, see Uniclient.

This document is available at 🔗lnd.im/UniClientUserManual short link.

Overview

Warning: This document describes early-access beta version of the Uniclient tool. While it is fully functional, its interface is a subject to change without notice.

Uniclient is the CLI (command-line interface) tool that allows to use Universa network without writing even a single line of code. It is optimized for both console use by the operator, and for integration with other software being able to reformat output to the structured machine-readable JSON form.

The client has many features and is self-documented when executed as uniclient --help, or without arguments.

Important. This is a beta version, fully functional but under constant development. It contains all the basic functionality but still there are many features and improvements we are working on. Sorry for inconvenience and please be patient.

Installation

JRE 1.8+ is required to run uniclient, it could be downloaded from the Oracle downloads site (tested with JRE 1.8).

Download the current version of the uniclient tool from our cloud storage (short link) and unzip it. Now you can start it with the bundled uniclient command on unix or uniclient.bat on windows. Alternatively, you can start it directly using java -jar uniclient.jar.

Executing uniclient with no arguments will show built-in help.

Important. Session keys created for uniclient is stored in the ~/.universa folder. Uniclient does not copy or move your own private keys, it will use them from the paths you point to.

Configure your system

On Unix-like architectures (especially Linux), to prevent Uniclient operating unexpectedly slow (especially on cryptography-related operations), you may need to configure the entropy source for your Java setup:

  • Find the java.security file of your Java setup. On webupd8-based installations, you can find it in /etc/java-8-oracle/security/java.security. Normally, it is available in $JAVA_HOME/jre/lib/security/java.security.

  • Change the line:

securerandom.source=file:/dev/random

to read:

securerandom.source=file:/dev/./urandom
  • Save your change and exit the text editor.

Usage scenarios

All the commands and options report their overall success using the regular application exit codes. Exit code equal to 0 means the successful execution, non-zero means that some error has occured (please examine STDERR for details).

If you want to use uniclient from your scripts, your best approach would be to use the --json option and parse the parameters. The result structure will contain the "errors" field. If this field contains the empty list, the execution has succeeded; in most other cases, you may want to re-check the status/state of all the involved contracts (including the U contract).

To ignore the currently stored session cache, you can use --no-cache setting.

Examine the existing contracts

Get the registered ID of a contract

Use --id command with the binary file of the contract, to get the ID of this contract:

uniclient --id contract.unicon

The ID you receive you can later use with the --probe command (see below).

Check a contract locally

It is advised to check the contract state locally before sending it to the network. For it, you can use the following command:

uniclient --check contract.unicon

Add --verbose to see more details. Use --json to have the uniclient format its output in the machine-readable format for further processing. For example,

uniclient --check test1.unicon --json

produces the following output:

{
   "messages":[
      "",
      "Checking loaded contracts",
      "Checking contract at /Users/home/uniclient-test/test1.unicon",
      "Contract is valid"
  ],
   "errors":[]
}

The successful result is confirmed by the empty errors array or by analysing the exit code, which is 0 for success; but it is recommended to check the errors to get more information on what is wrong.

Also you can check all contracts in the specified path:

uniclient -ch dir_to_check

or do it recursively:

uniclient -ch dir_to_check -r

Of course, you can check multiple files via:

uniclient -ch contract1.unicon contract2.unicon

or comma-separated:

uniclient -ch contract1.unicon,contract2.unicon

or passing multiple paths:

uniclient -ch dir_to_check1 dir_to_check2

Search for contracts in a directory

You may find contracts at the specified path using the following command:

uniclient --find my_path

or

uniclient -f my_path

The found contracts will be printed to the console. As usual, -r will search the directory tree.

uniclient -f my_path -r

Of course, you can looking for multiple paths via:

uniclient -f my_path1 my_path2

or comma-separated:

uniclient -f my_path1,my_path2

Convert the contracts between formats

Import a contract from XML, JSON or YAML

To automate contract processing in your system. It is advisable to export contract to XML/JSON/YAML, edit it and import it back to binary form to seal and register with the Universa network.

If you have JSON, XML or YAML representation of a contract stored in the file, e.g. contract.json, you can import contract from that file by typing the command:

uniclient --import contract.json

or:

uniclient -i contract.json

Contract will be saved as an .unicon file with same name as given file name of a structure.

You can specify the name where the imported contract file should be saved, by adding option --output and the desired filename:

uniclient -i contract.json --output MyContract

The contract will be saved as MyContract.unicon file.

Of course, you can do import for multiple files via:

uniclient -i contract1.json contract2.xml

or comma-separated:

uniclient -i contract1.json,contract2.xml

or specify a name for each contract independently:

uniclient -i contract1.json --output contract1.unicon contract2.xml --output contract2.unicon

If you about to import new revision of a contract it is possible to specify the parent of the imported contract by adding option --revision-of with filename parameter

uniclient -i rev2.json --revision-of rev1.unicon

Parent contract will be added to imported contract revoking items and you won't get "parent ref is missing" error.

Important: the imported contract will have no signatures unless the -k or -keys option was provided, see “Signing the contract” section below.

Export a contract to XML, JSON or YAML

This is important if you want to see or manually modify the state of the contract. To convert a binary sealed contract.unicon file use:

uniclient --export contract.unicon

or

uniclient -e contract.unicon

The contract will be saved as a .json file with same name as given contract file name by default.

You can specify export format by adding option --as and typing one of possible values: json, xml or yaml:

uniclient -e contract.unicon --as <format>

where <format> is one of: xml, json, yaml.

Use --pretty key to export contract to JSON with pretty formatting:

uniclient -e contract.unicon --as json --pretty

You can specify name of file contract will be export to by adding option -o or --output parameter with filename argument immediately following it:

uniclient -e contract.unicon --as xml --o MyContract

The contract will be saved as MyContract.xml file. If you specify the name of contract you can omit command --as if the extension of target file matches the format you want to export.

Use -o /dev/stdout (in the Unix-compatible environments) to print the exported structure to the console:

uniclient -e test1.unicon -o /dev/stdout --as yaml

In the Windows terminal use -o con instead.

Of course, you can do export for multiple files via:

uniclient -e contract1.unicon contract2.unicon

or comma-separated:

uniclient -e contract1.unicon,contract2.unicon

or specify a name for each contract independently:

uniclient -e contract1.unicon --output contract1.json contract2.unicon --output contract2.xml

Type the --as option once to choose format for export for all contracts:

uniclient -e contract1.unicon contract2.unicon --as yaml

or specify the format for each contract separately:

uniclient -e contract1.unicon --as xml contract2.unicon --as yaml

Create/edit the smart contracts

Create a new smart contract from a DSL template

The DSL templates are useful to create new contracts. There are some DSL templates in the Github to play with. The DSL template does differ from the exported contract: the latter is more machine-style than human readable.

If you have a DSL template stored in the .yaml file, e.g. template.yaml, you can create new contract by typing in the command line:

uniclient --create template.yaml

or

uniclient -c template.yaml

Contract will be saved as .unicon file in the same path and will have the same name as the template.

You can specify the name of the file contract will be saved to by adding option --output with filename parameter:

uniclient -c template.yaml --output MyContract

The created contract will be saved as MyContract.unicon file.

Of course, you can create multiple contracts via:

uniclient -c template1.yaml template2.yaml

or comma-separated:

uniclient -c template1.yaml,template2.yaml

or specify a name for each contract independently:

uniclient -c template.yaml --output contract1.unicon template.yaml --output contract2.unicon

Update the fields

During create, import or export operations you can update fields of the result contract by using pair of options --set and --value, e.g.:

uniclient -e contract.unicon --set "definition.expires_at" --value "{\"definition.expires_at\": {\"seconds\": 6373524323,\"__type\":\"unixtime\"}}"

will export a contract with the updated expiration date. Note: the value must be formatted as a JSON, XML or YAML string with a root element called similarly as a field name you want to update. The values of simple numeric or string fields can be specified by string constants. Uniclient will determine the format of the value string automatically.

Sign the contract

Universa requires each new contract or contract revision to be properly signed by the required parties. To do it, seal the contract while creating it, use -k or --keys option pointing to your key files:

uniclient -c some_dsl_template.yaml -k your.private.unikey

Also, you should provide the proper signing keys when importing any text format (see import section above), similarly with the -k or --keys option. Note that the -k option should precede -i:

uniclient -k sample.private.unikey -i test1.yml

Note that whenever -k/--keys option is used, you can provide multiple files, comma-separated, to sign with multiple keys at the same time:

uniclient -k sample1.private.unikey,sample2.private.unikey -i test1.yml

The improperly signed contracts will not be accepted by the Universa network.

For the scenarios when multiple parties may sign the same contract sequentially and independently of each other (like, when a quorum of 3 signatures is needed), the participants may use --sign command to add their signature to the batch:

uniclient -k sample.private.unikey --sign multisig-required.unicon

Pack and unpack the contract

If you have contract stored as a packed transaction you can unpack it using:

uniclient --unpack contract.unicon

This command extracts revoking and new items from contract and save them in the files named like contract_new_item_1.unicon for new items or contract_revoke_1.unicon for items to revoke.

And you can pack them together using:

uniclient --pack-with contract.unicon --add-sibling sibling.unicon --add-revoke revoke.unicon

As a result, the contract.unicon file will be created from the counterpart contracts. Note: use --output to save the contract with the name different from the original contract.

You can also add referenced items to transaction pack using --add-referenced

uniclient --pack-with contract.unicon --add-referenced referenced.unicon

See References for more info.

Split and join the tokens

You can join and split token contracts by using --split-off parameter. It is followed by filename of the main contract the other will be joined to/split from.

Note that you must provide the private keys (with -k or --keys) for the contracts you are trying to split or join, to confirm you have sufficient rights for this operation!

To join:

uniclient --split-off token_contract.unicon token_contract_to_join_1.unicon token_contract_to_join_2.unicon

This will join the tokens stored in token_contract.unicon, token_contract_to_join_1.unicon and token_contract_to_join_2.unicon into single token_contract_main.unicon.

By default, the new filename will be constructed from the primary contract name, appending _main to it.

To split:

uniclient --split-off token_contract.unicon --parts 100,200 --owners YjnUzcSYCc95NWxJavHVBksexoC6AszuHLsD43HHFgHcJvehn8,ZNHRkMQcpFqrvB43PMLjeiAPT64HpD8WAtVsEWzrDxMEcX3B77

This will split two parts off token_contract.unicon containing 100 and 200 units correspondingly. Owners of new contracts will be set to key addresses passed in --owners option.

Together:

uniclient --split-off token_contract.unicon token_contract_to_join_1.unicon --parts 100 --owners YjnUzcSYCc95NWxJavHVBksexoC6AszuHLsD43HHFgHcJvehn8

You can also use custom state data field to split/join by passing it after --field-name option. The default is amount.

If you want to edit the paths(s) of the generated file(s), use the --output option to specify them:

uniclient --split-off token_contract.unicon token_contract_to_join_1.unicon token_contract_to_join_2.unicon --output new_file.unicon

In case of splitting the token for multiple packs, you can specify multiple --output arguments with the paths for the files; if there are less --output arguments than the number of files to be created, the remaining file names will be autogenerated as usual.

uniclient --split-off token_contract.unicon --parts 100,200 --owners YjnUzcSYCc95NWxJavHVBksexoC6AszuHLsD43HHFgHcJvehn8,ZNHRkMQcpFqrvB43PMLjeiAPT64HpD8WAtVsEWzrDxMEcX3B77 --output piece1.unicon --output piece2.unicon

Anonymize the contract

You can make roles in your contract anonymous. It means erasing the public keys for the role from the contract binary. To do it use key --anonymize together with --role:

uniclient --anonymize contract.unicon --role owner

The anonymized contract will be saved to contract_anonymized.unicon. Old contract_anonymized.unicon is not modified and stays non-anonymized. To save the anonymized contract to some specific path use the --output key:

uniclient --anonymize contract.unicon --role owner --output myAnon.unicon

If you want to anonymize all roles in the contract just omit the --role key:

uniclient --anonymize contract.unicon

Important. You public keys still will be packed to the transaction pack for the signed contract. So send or publish anonymous contracts without the transaction pack, as a sealed binary; or do not sign it at all until sending to Universa network for registration.

Key operations

Generate the key pairs

The command like

uniclient -g key_name_prefix

or

uniclient -generate key_name_prefix

will create a key pair files key_name_prefix.public.unikey and key_name_prefix.private.unikey. Keep them safe and never transmit your private key over the network except that inside of some very well encrypted containers (such as Universa CryptoCloud capsules).

Use key -s to specify key strength, e.g.:

uniclient -g key_name_prefix -s 2048

Additionally you can see fingerprints of the specified with option -k keys using the --fingerprints option:

uniclient --fingerprints -k key_name.private.unikey

Work with addresses

You can generate address for any key using command --address (long address by default, add --short option for short address generation):

uniclient --address any_key.private.unikey

Of cause, you can check if some address matches some key, use --address-match (--keyfile option should point to the key being matched):

uniclient --address-match 26RzRJDLqze3P5Z1AzpnucF75RLi1oa6jqBaDh8MJ3XmTaUoF8R -keyfile any_key.public.unikey

If you have a folder with multiple keys you can know which keys is matching some address, use the command --folder-match (option -addr point to address for checking);

uniclient --folder-match folder_with_keys -addr 26RzRJDLqze3P5Z1AzpnucF75RLi1oa6jqBaDh8MJ3XmTaUoF8R

And as a result, the matching keys will be printed to the console.

Extract the public keys

If you need to get a public key from some specific role defined in the contract, use --extract-key option specifying the role name:

uniclient -e contract.unicon --extract-key owner

The extracted key will be saved to .public.unikey file in the common Universa key file format.

When modifying the exported text files it might be useful to extract the keys in Base64 format which could be done adding the --base64 argument. You can still export the keys from multiple contracts as described at the “Export contract” section.

Access the Universa network

For most of the operations, you can specify the node you are connecting to, using the --node option with the number of the node to connect. It doesn’t work with --probe/--probe-file though, as the probing process intentionally checks the data with multiple nodes, about 30% of the whole network.

Check the network status

The most basic uniclient command is checking the whole network status:

uniclient --network

Depending on the network status, it will return the current version of network software and the number of active nodes, example below:

Network version: 3.9.15
Universa network is active, 33 node(s) are reachable

Register and revoke a contract

When the contract is prepared and checked (using the --check option), it is a time to register it in the Universa network. Since version 3.0.1 the contract processing fees are calculated in U (known as merely “U” in the web client software). Point to you U contract with key --u. Also, don’t forget to use -k to point to the key which is permitted to utilize the payment contract you use.

To register contract, run the command like:

uniclient --register contract.unicon --u u.unicon -k key.private.unikey

This command submits the contract for approval. The response will be similar to:

registering the contract SWlZ0U73oUJ3hWLeIFAJeUaU0y0CowYOxzhfAfPCQ6zouwFUyfXlJoyO1fUb1jbFoSPv/zXiAzVaEBGrdU62SA

Will try to connect to to the random node:
Node(http://node-30-com.utoken.io:8080,Key(RSAPublic,None,PP7s8Mo):PP7s8Mo)

submitted with result:
ItemResult<PENDING_POSITIVE 2017-11-01T02:04:29+01:00[Europe/Warsaw] (copy)>

This means that the node 30 has initiated the voting. Notice the contract ID in the “registering the contract” line. It is a Base64-encoded ID of the contract which will be used from now to uniquely identify it.

You can use the --wait option to specify the time (in milliseconds) how long to wait for the network to get consensus:

uniclient --register contract.unicon --u u.unicon -k key.private.unikey --wait 1000

Important. After the command execution, the file containing the old revision of your U contract will be backed up to <file_name>_rev<rev_number>.unicon. And new approved revision of U contract will save with old file name. So, you always will have actual U in one file. But if something went wrong you can restore previous revisions from backups.

The state of the contract initially (especially if you specify the short --wait time or omit it altogether) could be one of PENDING / PENDING_NEGATIVE / PENDING_POSITIVE as the starting node checks it against its copy of the shared ledger. To update the state, --probe it in a second or two:

uniclient --probe SWlZ0U73oUJ3hWLeIFAJeUaU0y0CowYOxzhfAfPCQ6zouwFUyfXlJoyO1fUb1jbFoSPv/zXiAzVaEBGrdU62SA

The network will answer with something like:

Will try to connect to to the random node: Node(http://node-12-com.utoken.io:8080,Key(RSAPublic,None,jtxGVvs):jtxGVvs)

Universa network has reported the state:
ItemResult<APPROVED 2017-11-01T02:04:29+01:00[Europe/Warsaw] (copy)>

As stated by this listing, the system has accepted the contract the same second it was submitted.

The exit code returned by this command is either 0 if the node consensus about the registration was APPROVED and no other errors were spotted during the process, or non-0 if any problems arisen. Receiving the non-APPROVED state doesn’t necessary mean the contract failed to register; it is possible that the --wait delay was just too short, and you should --probe it until either APPROVED, LOCKED, DECLINED or REVOKED state is reached.

For more details on the item states (and how they should be interpreted), see the Item state article.

Use key --amount to manually set the amount of U to be spent for contract processing:

uniclient --register contract.unicon --u u.unicon --amount 1

Use approved U contract with key --u. After any --register your file with U contract will be saved with new revision of U contract and decreased amount of U, so you can use it again without additionally operations.

If you want to try payment in the test mode use --utest key with --register and --u:

uniclient --register contract.unicon --u u.unicon --utest

If you registered the contract you may revoke contract via simple command (use the same private key you have used before to sign the contract):

uniclient --revoke contract.unicon -k my_key.private.unikey

And if you check contract with --probe you will see status will have changed to REVOKED

Of course, you can register and revoke multiple contracts via:

uniclient --register contract1.unicon contract2.unicon

or comma-separated:

uniclient --register contract1.unicon,contract2.unicon

Calculate the cost of contract processing

If you want to know the cost of contract registration in the network measured in U, add the --cost key after the --register:

uniclient --register contract.unicon --cost

This will calculate the cost of processing and print it to the console.

Alternatively, you can calculate the cost of contract processing without actually wasting your U contract, using the --cost key without the --register one:

uniclient --cost contract.unicon

This command will calculate the cost of transaction registration and print it to the console, but without actually registering it in the network.

The command can accept multiple contract filenames.

Check the contract state

As in the example above, it is possible to ask the network about the current contract state of some smart contract, passing its ID:

uniclient --probe SWlZ0U73oUJ3hWLeIFAJeUaU0y0CowYOxzhfAfPCQ6zouwFUyfXlJoyO1fUb1jbFoSPv/zXiAzVaEBGrdU62SA

This should be a single line. The network will answer with something like:

Will try to connect to to the random node: Node(http://node-12-com.utoken.io:8080,Key(RSAPublic,None,jtxGVvs):jtxGVvs)

Universa network has reported the state:
ItemResult<APPROVED 2017-11-01T02:04:29+01:00[Europe/Warsaw] (copy)>

Of course, you can probe multiple contracts via:

uniclient --probe SWlZ0U73oUJ3hWLeIFAJeUaU0y0CowYOxzhfAfPCQ6zouwFUyfXlJoyO1fUb1jbFoSPv/zXiAzVaEBGrdU62SA G0lCqE2TPn9wiioHDy5nllWbLkRwPA97HdnhtcCn3EDAuoDBwiZcRIGjrBftGLFWOVUY8D5yPVkEj+wqb6ytrA

or comma-separated:

uniclient --probe SWlZ0U73oUJ3hWLeIFAJeUaU0y0CowYOxzhfAfPCQ6zouwFUyfXlJoyO1fUb1jbFoSPv/zXiAzVaEBGrdU62SA,G0lCqE2TPn9wiioHDy5nllWbLkRwPA97HdnhtcCn3EDAuoDBwiZcRIGjrBftGLFWOVUY8D5yPVkEj+wqb6ytrA

If you have a contract as the .unicon file, you could either learn its ID using the aforementioned --id command, and then use it with --probe; or you can use the --probe-file command with the path of the contract file:

uniclient --probe-file mycontract.unicon

UUTN wallets

Besides using the specified private key, you can create a UUTN wallet, which simplifies payments and private key maintenance.

See the dedicated article on it in UUTN wallets for more details. Consult it as well to learn how to configure the wallet for auto-top-up of U balance.

Below is just the basic overview of supported features/commands.

“Putting” something into the UUTN wallet

You can put some contracts (especially contracts containing U, or UTN tokens) to the wallet; also you can put a private key, specifying it with --keys.

uniclient --put-into-wallet --keys mykey.private.unikey my_u_contract.unicon

You can specify a non-default wallet, passing the path to its directory:

uniclient --put-into-wallet ~/uutnwallets/wallet1 --keys mykey.private.unikey my_u_contract.unicon

Using the wallet

Whenever you don’t provide the private key and the contract file with U explicitly, they will be taken from the default wallet. So, for example, the registration of some contract may be as simple as:

uniclient --register contract.unicon

A non-default wallet can be selected if you use the --wallet option:

uniclient --register contract.unicon --wallet ~/uutnwallets/wallet1 

Check the current U rate

Using the --u-rate command, you can get the current U price in UTNs (or actually, how many Us are given for a single UTN).

uniclient --u-rate

Manually top-up the U balance

Using the --u-for-utn command, you may reserve the required amount of U for UTN; pass --amount option to specify how many U you want to reserve.

uniclient --u-for-utn --amount 5

… to reserve 5 U, using the UTN contract stored in the UUTN wallet.

(As usual, you may choose a non-default wallet with --wallet).

Offline parcel preparation

Sometimes, you may want to prepare a whole paying parcel on a fully offline computer, so that the private key is never compromised being on a potentially vulnerable host. In such case, you can create the whole transaction pack offline; turn it into the paying parcel (providing the proper U fee and signing with the private keys that can use the U contract); then transport it to an online computer (using some means like a thumb drive) and just register it directly.

Normally, the parcel files are stored in the files with .uniparcel extension.

Create a paying parcel

On an offline computer where the private key (for an U contract) is stored, create a whole complete parcel to be transported to the online computer:

uniclient --create-parcel --u u.unicon -k key.private.unikey --amount 2 contract.unicon

… will create a parcel to register the contract.unicon contract, using the u.unicon file with U reserve and signing it with key.private.unikey, and requesting to spend 2 U for its registration.

If a UUTN wallet is used, you may don’t need to provide --u/-k options, but choose a specific wallet; if nothing is chosen, the default wallet will be used.

uniclient --create-parcel --amount 2 contract.unicon

… will create a parcel to register the contract.unicon contract, using the default UUTN wallet, and requesting to spend 2 U for its registration.

As often, you can use --output option to provide the name(s)/paths of the files to be created.

Registering a parcel on an online computer

On an online computer where you’ve transported the parcel to, start its registration:

uniclient --register-parcel someparcel.uniparcel

Similarly to --register, --wait option can be used to wait for the result of the consensus, like:

uniclient --register-parcel someparcel.uniparcel --wait 1000 # wait 1 second

Javascript, HTTP server mode

You can attach some JavaScript code to the contract and execute it by the client, including som handler functions for use in HTTP server. The appropriate HTTP server is included in uniclient. The attached JavaScript source will be executed using the by the Oracle's NashornScriptEngineFactory, so the appropriate language limitations should be considered.

So, if you have prepared some JavaScript file named ./script.js, use:

uniclient --create-contract-with-js ./script.js -o ./contract1.unicon -k ./your-priv-key.unikey

Now you can find new contract ./contract1.unicon (it was just now created with key ./your-priv-key.unikey). Register it (see Register and revoke a contract). Next, you can execute it with --exec-js. If it has any custom HTTP handlers, yoy can start the HTTP server with --start-http-server.

To execute, just use:

uniclient --exec-js ./contract1.unicon

To start an HTTP server you need to create ./routes.json file, like:

{
  "listenPort": "8880",
  "routes": [
    {"endpoint": "/contract1/getRevision", "handlerName": "httpHandler_getRevision", "contractPath": "/home/user1/contract1.unicon", "scriptName": "script.js"},
  ]
}

and then, use it like this:

uniclient --start-http-server ./routes.json

See Client JavaScript for details.

Output control

It is possible to format all uniclient output in the JSON format for easy parsing and further processing. Use --json key for that.

Examples

Release custom tokens

Imagine, you want to release your own tokens.

You have edited the DSL template as you want (e.g. token_dsl.yml), have keys (e.g. my_key.private.unikey), and you’ve bought some U (e.g. u.unicon with my_key.private.unikey as owner). Do the following:

uniclient --create token_dsl.yml --output my_token.unicon -k my_key.private.unikey    
uniclient --register my_token.unicon -u uContract -k my_key.private.unikey --wait 1000

as result you have approved by Universa contract my_token.unicon as binary file. That means you released your own tokens and can do split or join operations with it.

Release company shares

Imagine, you want to release the shares for your company.

You have edited the DSL template as you want (e.g. shares_dsl.yml), have the keys (e.g. my_key.private.unikey) and you’ve bought some U (e.g. u.unicon with my_key.private.unikey as owner). Do the following:

uniclient --create shares_dsl.yml --output my_company_shares.unicon -k my_key.private.unikey    
uniclient --register my_company_shares.unicon -u uContract -k my_key.private.unikey --wait 1000

as result you have approved by Universa contract my_company_shares.unicon as binary file. That means you released shares for your company and can distribute them between your partners and so on.

Notarize a file

Imagine, you have some file and you want to be notarially certified that you own it at this moment.

You have edited the DSL template as you want (e.g. notary_dsl.yml), have the keys (e.g. my_key.private.unikey) and you’ve bought some U (e.g. u.unicon with my_key.private.unikey as owner). Do the following:

uniclient --create notary_dsl.yml --output notarized_stuff.unicon -k my_key.private.unikey    
uniclient --register notarized_stuff.unicon -u uContract -k my_key.private.unikey --wait 1000

as a result, you have the notarized_stuff.unicon Universa contract (stored as binary file) approved by the network. That means you are certified as the owner of this file by Universa.

FAQ

I get the ** ERROR: FORBIDDEN: … not permitted changes in … error

Like, the following:

** ERROR: FORBIDDEN: state.data: not permitted changes in [amount]: {amount=457.609} -> {amount=434.159}

Some data in this log may vary (like, the fields or changes which are not permitted); but if you get the “ERROR: FORBIDDEN” and “not permitted changes” record in your output, it means you cannot execute the changes you are attempting.

This usually happens for one of the following reasons:

  1. You don’t have sufficient permissions to perform the change. Maybe the change (like, changing the owner of contract/token) is allowed for a different role only; maybe you haven’t provided your private key (using --keys) at all.

    Please doublecheck that the command line includes the --keys (or, obviously, -k) argument, and the key you are providing is the one that should be used with this operation; for example, if you are trying to give some tokens to some other user, you must provide the private key which now owns these tokens.

  2. The permissions restrict this change. For example, the tokens may request that the token amount cannot be split to the numbers lower than 0.01, and you are requesting a split with the 0.008 precision.