Smart Contracts
A particular block body data structure with special instructions to be executed.
Compute power.
Regardless of the implementation, any block where the 'blockContent' property starts with //
is interpreted as a smart contracts and its content will be executed with a JavaScript interpreter. All smart contracts must start with a comment on the first line as shown below:
// <DESCRIPTION?> || <CONTRACT_INVOCATION(HASH/ALIAS)
When declaring a smart contract, this line is commonly used to provide a description or version information. However, when invoking a smart contract, this line must be filled with either the contract hash or the contract alias, if it has been set previously.
The scope
A core concept within NxtFi, the scope is regarded as a branch of the tree-like framework architecture. It is an essential component of the hierarchical structure that empowers the network's most robust features. In its simplest and most practical form, the scope is defined as the pathway to the organization of the smart contracts domain. It serves as a directory to organize code, state, and their interactions. But they are not arbitrary in every sense, meaning that a scope is either the name of the entity who is signing, or a contract hash identifier, or even a child entity authorized by its parent through the grantWrite
authorization process.
Usage
The first stage when declaring a smart contract involves following simple syntax rules. As mentioned earlier, it is mandatory to begin with a commented headline. Following that, the execution logic needs to be implemented. This includes:
Inputting Parameter and Variable declarations (JSON inputs are allowed to interact with SC).
Access Control Layer system middleware (ACL to hide sensitive data or to serve data directly from an API).
Smart Contract code logic.
Smart Contract Alias setters (directly set a SC alias in deploy to initialize a custom/dedicated scope).
The code will be executed every time the smart contract is invoked, in a synchronous loop. It is important to consider the initial execution (when the SC is deployed for the first time) and handle all possible exceptions to prevent crash faults.
Whenever the execution thread is blocked due to an asynchronous call, a crash fault, or an infinite loop, the interpreter is not able to distinguish between them. Consequently, the code will be executed again until the code resolves or a specific time interval (δ) has elapsed. Therefore, it is important to be cautious and avoid infinite loops, as they can cause the block to fail.
Smart contract Call
After declaring and propagating (deploy) a smart contract code block on the NxtFi blockchain, it becomes ready for usage and execution. As mentioned earlier, you can choose to use either the contract hash identifier or the alias label, depending on the specific use case. However, it is highly recommended to use the alias label right from the beginning. (if it was not immediately configured in SC deploy)
As this field will become the scope of its implementation. Every piece of state associated with the smart contract will be tracked and stored using the scope route. In other words using the label will enable the possibility to upgrade the code without loosing the connection to smart contract data.
Alias
Aliases are utilized to offer a concise and user-friendly representation of a smart contract hash identifier. They also provide the capability to link different versions of smart contracts within a single route, enabling orthogonal persistence throughout smart contract code upgrades.
Essentially, an alias is a label that points to a specific memory allocation, which hosts data and Smart Contract's Code instructions in different slots but still referenced between each other.
So Code can be upgraded by re-deploying a new version in that allocation. It is important to notice that every time a new SC is deployed in a specific allocation (triggered by the setAlias()
function), the system will keep track of every encrypted block hash that was executed, represented in a registry list.
The alias must be set before making any state changes. To accomplish this, a block needs to be propagated with the appropriate embedded function specifically designed for this purpose (the setAlias()
function). The Alias result has this structure: <entity>__<name>
(Refer to the functions section for usage details.)
Parameters
When a Smart Contract requires inputs to delivery some special functionality, they must be declared as a strigifyable object literal.
Each smart contract can receive parameters as one object. The syntax for delimiting these attributes is achieved with the commands //INPUT
and //INPUT END
, as shown below:
Embedded functions
The functions described below work as a two way communication channel between the instructions written in the submitted Smart Contract, the invoked Smart Contract( if is the case) and the NxtFi storage system.
By default when a block body goes through the NxtFi virtual machine, the execution logic will check if the declared scope in the functions comply the 'alias'
syntax (see 'Alias'), if it doesn't this field will be automatically filled with the imported contract hash or the block hash(see SC environment variables below)
put({ name: string, value: <any> })
PUT Key/Value storage
get({ name: string})
GET Key/Value storage
gettrace({ path: string, scope?: string, options?:{object}})
GET Storage system Trace logs. allow same options <obj> as list
list({ name: string, scope?: string, options?:{maxkeys?: int, startafter?: string, raw?: boolean<default=false>})
List existing keys and directories
del({name: string})
Delete one key/dir
delMany({prefix: string, options?: <list-opt-object>})
Delete all keys that match
grantKey({name:String, pubKey:String, permissions?:Object{canGrant:Boolean, maxGrantLimit:Number, expiration: Timestamp }})
Authorize child key-pair
revokeKey({name: String})
Revoke child key-pair
log({ properties: <Computable Variables>, optional?: "key/pair" })
describe logs in block body
result({ message: <Computable variables> })
display computable results
persistArchive({ name: <fileName string-with-extension>, fileHash: <FILE_HASH>, data: <custom-metadata any-type>})
persist temporary uploaded files to permanent storage.
setAlias({scope?: String, name: String<identifier>, value: <contract-hash-pointing-to> })
configure alias name to any smart contract hash.
Smart Contract Environment available variables
To enhance the coding experience and increase the functionality of smart contracts, there are two distinct property fields that can be utilized: {block} and {contract} objects. These objects have the same structure and key names, but they refer to different blocks (if applicable).
block.<prop>
is pointing to the current working block.
contract.<prop>
is pointing to the invoked Smart Contract block.
For example: (current)
block.prevhash
= hash of the last block of the scopeblock.height
= height of the current block.block.data
= data field of the current block.block.scope
= current block scope nameblock.timeStamp
= current block time-stampblock.by
= Signer - entityblock.version
= API version numberblock.signature
= current block signatureblock.hash
= hash of the imported Smart Contract
For example: (invoked)
contract.prevhash
= hash of the previews block of the invoked SCcontract.height
= height of the SC block.contract.data
= data field of the SC block. (code to be executed)contract.scope
= SC block scope name(usually the entity who wrote the code)contract.timeStamp
= SC block time-stampcontract.by
= SC Signercontract.version
= API version numbercontract.signature
= SC block signaturecontract.hash
= hash of the imported Smart Contract
Example of a block declaring a smart contract:
Using different embedded functions.
Example of a block invoking a smart contract
Invoke a smart contract using alias nomenclature.
System only accepts JSON objects as inputs.
Last updated