Norsh
HomeNTP
NCLAPI
HomeNTP
NCLAPI
  1. NTP
  • NTP-1: Norsh Technical Paper Specification
  • NTP-2: Standards for Encoding, Time and Localization
  • NTP-3: Cryptography and Hash Specification
  • NTP-4: Interchangeable Data Standard
  • NTP-5: Temporal Time-Step Model
  • NTP-6: Modular Prime Fragmentation
  • NTP-7: The End of Mining - PoW
  • NTP-8: The Fallacy of Stake - PoS
  • NTP-9: The Myth of Absolute Non-Censorship
  • NTP-10: Structural Failures of Decentralization
  • NTP-11: Universal Blockchain Protocol (UBP)
  • NTP-12: Sharded Certificate Storage for the Norsh Ecosystem
HomeNTP
NCLAPI
HomeNTP
NCLAPI
  1. NTP

NTP-11: Universal Blockchain Protocol (UBP)

Status: PUBLISHED
Authors: Danthur Lice
Date of Creation: 2025-07-31
Date of Publication: 2025-07-31
License: NCL-11

1. Scope#

This document specifies the Universal Blockchain Protocol (UBP), a standardized message format for blockchain operations. UBP defines how commands, parameters, metadata, and cryptographic signatures are structured and exchanged between clients and blockchain systems. The protocol is designed to be transport-agnostic, deterministic, and auditable.

2. Message Format#

2.1 Standard Layout#

Each UBP request message is a JSON object containing 6 fields:
{
  "command": "tx.submit",
  "version": 1,
  "externalId": "id1",
  "preimage": [ ... ],
  "signature": "BASE64SIG",
  "ghost": { ... }
}
Batch mode is represented as an array of such objects.

2.2 Field Definitions#

FieldTypeDescription
commandstringThe operation identifier (e.g., "tx.submit", "element.create")
versionintegerProtocol version used in the request (e.g., 1)
externalIdstring/nullUnique identifier for correlating responses; required in batch mode
preimagearraySigned parameters including metadata and public key
signaturestring (Base64)Signature over the serialized preimage
ghostobject/nullOptional, unsigned payload (e.g., secrets, OTPs); not persisted


2.3 JSON Schema (Request)#

{
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "command": {
        "type": "string",
        "description": "The UBP command to execute."
      },
      "version": {
        "type": "integer",
        "description": "API version of the UBP protocol used in the message."
      },
      "externalId": {
        "type": ["string","null"],
        "description": "Optional external identifier for tracking or correlating the request. Required for batch input."
      },
      "preimage": {
        "type": ["array","null"],
        "items": {
          "type": ["array","null"],
          "items": {
            "description": "Individual preimage element, representing command parameters or data to be registered or updated in the blockchain."
          },
          "description": "Preimage entry, which may be a list of values or null."
        },
        "description": "List of preimage data, containing the core payload for the UBP command."
      },
      "signature": {
        "type": ["string","null"],
        "description": "Cryptographic signature for verifying the authenticity and integrity of the message.",
        "format": "Base64"
      },
      "ghost": {
        "type": ["object","null"],
        "properties": {},
        "description": "Transactional data used only during request processing (e.g., passwords, TOTP codes, or other sensitive information). Not saved on the blockchain and not part of the main UBP protocol"
      }
    },
    "description": "UBP Message (6-element tuple) representing a single blockchain operation.",
  },
  "description": "UBP Batch: an array of UBP messages for batch processing."
}

3. Preimage#

3.1 Structure#

The preimage is an array containing command-specific parameters, always ending with:
[
  ...,                          
  { ... },         
  "BASE64SPKI"     
]

3.2 Field Definitions#

PositionFieldTypeDescription
0...Ncustom paramsanyCommand-specific arguments
N+1metadataobject/nullContextual info; values used for signature canonicalization
N+2publicKeystring (Base64)Signer’s public key in SPKI DER Base64 format
The positions of metadata and publicKey are always the last two in the preimage array. Only the values of metadata, sorted by key, are used in the signature preimage.

3.3 Signature Preimage Conversion#

Process:
1.
Start with the preimage array.
2.
If metadata is an object:
Sort its keys lexicographically.
Extract only the values, in key order.
3.
Replace the metadata object in the array with a flat list of values.
4.
Concatenate all elements using | as a delimiter.

Example#

Given:
[
  "TYPE",
  null,
  123.45,
  { "y": "b", "x": "a", "z": "c" },
  "BASE64SPKI"
]
Convert to:
TYPE||123.45|a|b|c|BASE64SPKI
This string becomes the signature preimage.

3.4 Serialization Rules#

To ensure deterministic serialization and avoid inconsistencies:
1.
Preimage values (except metadata)
All values must be represented as strings, even if they are numeric.
Example: 123.45 → "123.45"
Clients and validators must enforce numeric format validation but preserve the string type in JSON.
2.
Metadata values
When metadata is used, it must be a flat JSON object with only string keys and string values.
Numeric formats are allowed, but must also be represented as strings.
Subobjects or nested structures are not permitted.
Allowed:
{ "a": "123", "x": "yz" }
Not allowed:
{ "a": 123, "x": "yz", "object": {} }
These constraints guarantee consistent canonicalization across different clients and platforms.

4. Validation Rules#

4.1 Top-Level Fields#

FieldRequiredNotes
commandYesMust be a string
versionYesMust match the expected version
externalIdYes*Required only in batch mode
preimageYesMust be a list with the defined layout
signatureYesMust be valid Base64

Version Declaration Rule#

The UBP protocol version must always be explicitly declared in the message body (version) and must not be inferred from the transport layer (e.g., URL path). This ensures transport-agnostic compatibility, batch version heterogeneity, and future-proof validation logic.

4.2 Preimage Fields#

Validation is contextual:
For address.generate, the preimage must be [] (empty).
For other commands:
The last two fields must be metadata and publicKey.
metadata must be null or an object.
publicKey must decode to a valid value.
All required parameters must be non-null unless explicitly marked as optional.

5. Signature#

See NTP-3.

6. Metadata#

Type: object or null
Keys must be strings
Values are extracted and ordered by key name for signature purposes
Validation:
If metadata != null, it must be a flat JSON object.
It must not contain secrets or private keys.
Values are included in the signature as an ordered list — keys are not.

7. Ghost#

Always present: type object or null
Purpose: to transmit transient, sensitive, or non-signed fields (e.g., passwords, OTPs)
Excluded from the preimage and not stored
May be validated by command logic

8. Batch#

UBP supports batch messages:
[
  {
    "command": "tx.submit",
    "version": 1,
    "externalId": "id1",
    "preimage": [...],
    "signature": "sig1",
    "ghost": { "otp": "123456" }
  },
  {
    "command": "tx.submit",
    "version": 1,
    "externalId": "id2",
    "preimage": [...],
    "signature": "sig2",
    "ghost": { "otp": "654321" }
  }
]
Each entry is validated independently
externalId must be unique within the batch

9. Endpoint#

POST /v1/ubp — Submit UBP messages
GET /.well-known/ubp — Discover protocol version
{
  "protocol": "UBP",
  "versions": ["1"],
  "current": "1",
  "endpoints": ["https://api.norsh.org/v1/ubp"]
}

10. Response Format#

Each processed UBP request returns a JSON object with 8 fields. In batch mode, the response is an array of such objects.
{
  "command": "element.create",
  "version": 1,
  "externalId": "id1",
  "status": 200,
  "timestamp": "2025-08-31T21:00:00Z",
  "success": true,
  "result": { ... },
  "info": { ... }
}

10.1 Field Definitions#

FieldTypeDescription
commandstringThe command executed (e.g., "element.create", "tx.submit")
versionintegerProtocol version used in the request (typically 1)
externalIdstringIdentifier from the original message; helps the client track responses
statusintegerHTTP status code representing the result of the operation
timestampstringResponse timestamp in ISO 8601 UTC format
successbooleantrue if the command succeeded; false if there was an error
resultobjectCommand-specific response on success, or error details on failure
infoobjectAdditional operation metadata: ledger, transaction, block, processing time
Ucp Response


10.2 Success Example#

{
  "command": "element.create",
  "version": 1,
  "externalId": "id1",
  "status": 200,
  "timestamp": "2025-08-31T21:00:00Z",
  "success": true,
  "result": {
    "elementId": "NSH012345",
    "status": "created"
  },
  "info": {
    "ledger": "bigledger",
    "transaction": "05036377...",
    "block": "e0e8a311...",
    "durationMs": 1575
  }
}

10.3 Failure Example#

{
  "command": "element.create",
  "version": 1,
  "externalId": "id1",
  "status": 400,
  "timestamp": "2025-08-31T21:00:00Z",
  "success": false,
  "result": {
    "code": -1,
    "message": "Error message"
  },
  "info": {
    "ledger": null,
    "transaction": null,
    "block": null,
    "durationMs": 32
  }
}

10.4 JSON Schema (Response)#

{
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "command": {
        "type": "string",
        "description": "The UBP command that was executed."
      },
      "version": {
        "type": "integer",
        "description": "API version of the UBP protocol used in the response."
      },
      "externalId": {
        "type": ["string","null"],
        "description": "External identifier for tracking or correlating the request. Required for batch input."
      },
      "status": {
        "type": "integer",
        "description": "HTTP status code representing the result of the operation."
      },
      "timestamp": {
        "type": "string",
        "description": "Timestamp when the response was generated, in ISO 8601 format."
      },
      "success": {
        "type": "boolean",
        "description": "Indicates whether the operation was successful."
      },
      "result": {
        "type": "object",
        "properties": {},
        "description": "Result object containing the output or data returned by the command."
      },
      "info": {
        "type": "object",
        "properties": {
          "ledger": {
            "type": ["string","null"],
            "description": "Ledger identifier where the transaction was recorded."
          },
          "transaction": {
            "type": ["string","null"],
            "description": "Transaction identifier for the blockchain operation."
          },
          "block": {
            "type": ["string","null"],
            "description": "Block identifier containing the transaction."
          },
          "durationMs": {
            "type": "integer",
            "description": "Processing duration in milliseconds."
          }
        },
        "description": "Additional information about the blockchain operation, including ledger, transaction, block, and processing duration.",
        "required": ["durationMs"]
      }
    },
    "description": "UBP Response message representing the result of a single blockchain operation.",
    "required": ["info","success","timestamp","status","version","command"]
  },
  "description": "UBP Batch Response: an array of UBP response messages for batch processing."
}

11. HTTP Status Reflection#

The status field in each response object reflects the HTTP status code of the operation result.
For batch responses:
If all entries return the same status (e.g., all 200, all 403), the HTTP response itself will also use that same status code.
If entries return different status codes (e.g., a mix of success and error), the HTTP response will use 207 Multi-Status, while each entry preserves its own status field.
This ensures consistency between transport-level status and per-operation response codes.

12. References#

RFC 5785: Defining Well-Known Uniform Resource Identifiers (URIs)

13. Conclusion#

The Universal Blockchain Protocol (UBP) establishes a deterministic, extensible, and transport-agnostic message format for blockchain operations. It consolidates element creation, transaction submission, asset registration, and governance under a single, versioned envelope. By standardizing the structure of blockchain interactions, UBP ensures auditability, minimizes conceptual overhead, and provides a sustainable foundation for blockchain infrastructure across domains.
Modified at 2025-09-21 06:19:48
Previous
NTP-10: Structural Failures of Decentralization
Next
NTP-12: Sharded Certificate Storage for the Norsh Ecosystem
Built with