Migration V5 → V6
The Klayr SDK v6 introduces many breaking changes and essential improvements to the Klayr Protocol and the Klayr Framework.
This migration guide summarizes the most important changes from Klayr SDK v5 to Klayr SDK v6, and explains why the changes are introduced.
- 1. Terminology changes
- 2. Failed transactions are included in blocks
- 3. Addition of blockchain events
- 4. Chain ID replaces network ID
- 5. Module & command IDs are removed
- 6. Methods replace reducers
- 7. Endpoints replace actions
- 8. Migration of store from v5 to v6
- 9. Addition of metadata
- 10. Module dependencies registration updates
1. Terminology changes
To improve understanding, we introduce several terminology changes.
An overview of the most important terminology updates is summarized in the table below.
SDKv6 (new) | SDKv5 (old) | Description |
---|---|---|
Block generation |
Forging |
The process of creating a new block in the Klayr ecosystem. |
Chain ID |
Network ID |
Unique identifier of a chain account. It is used when sending tokens to a specific chain and is also prepended for signing to protect against replay attacks. |
Module method |
Module reducer |
An interface for module-to-module communication. |
Module/Plugin endpoint |
Module/Plugin action |
An interface between a module/plugin and an external system via an RPC endpoint. |
PoS |
DPoS |
The validator selection algorithm of the Klayr Mainchain. In fact, the algorithm used by Klayr can be considered as a combination of DPoS and PoS. As the similarities with PoS (Proof of Stake) are quite big, it was decided to rename the DPoS module to PoS and to replace DPoS-specific terminology with more general terms. |
RPC event |
Application event |
Events that are natively included in the Klayr Framework and follow the publish/subscribe pattern. |
RPC node |
Non-forging node |
A type of node which allows users to query information from a blockchain network. |
Web3 app, blockchain application |
Blockchain application |
An application that utilizes blockchain technology. The application typically includes business logic running on blockchain clients (modules or smart contracts), middleware and UI. |
Klayr app, app on Klayr |
Blockchain application |
A Web3 app built on Klayr. |
Blockchain client |
A client is an implementation of the blockchain protocol that verifies data (blocks and transactions) against the protocol rules and keeps the network secure. In Klayr, Klayr Core is the client for the Klayr Mainchain and clients for other blockchains in the Klayr ecosystem can be built using the Klayr SDK. |
|
Blockchain node |
A node is an instance of a blockchain client that runs on a computer and is connected to other computers as part of the decentralized blockchain network. |
|
Sidechain |
A separate, independent blockchain that runs in parallel to a main blockchain. It is typically interoperable with the main blockchain. In Klayr, a sidechain is a blockchain registered on the Klayr mainchain following the Klayr Interoperability Protocol. |
|
Staker |
Voter |
A user staking KLY to "vote"/increase the delegate weight of their favourite validator(s). |
Staking |
Voting |
Process of locking tokens to support a specific validator. |
Validator |
Delegate |
Participants in charge of generating, processing and finalizing blocks in a PoS blockchain. |
Validator node |
Forging node |
A type of node which has the capability of generating a block. |
2. Failed transactions are included in blocks
In the event of a failed execution of a transaction’s business logic, the transaction will be assigned the status of fail
.
In Klayr SDK v5, transactions were only included in a block, if they could be executed successfully.
In Klayr SDK v6, this changes now: Failed transactions are included in blocks as well.
As you know, the transaction fee is paid for every transaction included in a block. This has the following consequence: By including failed transactions in blocks, the transaction fee is always paid even if it failed and didn’t introduce any state changes on the blockchain.
Main benefits of this change
- Increased rewards for validators
-
By doing this, validators will still be rewarded for executing the logic of the transaction until the point where it failed.
- Increased security
-
Additionally, it mitigates the danger of DDoSing blockchain networks by spamming transactions that will fail, because the transaction fee has to be paid in any case.
To verify, if a transaction that is included in a block was executed successfully, Klayr SDK v6 introduces the Addition of blockchain events.
3. Addition of blockchain events
Blockchain events are newly introduced, and Module pub/sub events are completely removed in Klayr SDK v6.
Although similar in name, Blockchain events follow a completely different approach. To avoid confusion between the two events, please read the summary below, which is comparing the new and old events inside modules.
Main benefits of this change
- Required, if failed transactions are included in blocks
-
As explained above, Failed transactions are included in blocks in v6.
This means, it cannot be assumed, that a transaction was successfully executed, just by checking that the transaction is included in a finalized block.
It could happen that the transaction inside a block has failed, and wasn’t executed on the blockchain.
But how to check if the transaction failed, or was executed successfully? To transmit this information, the standard event is emitted for every transaction included in the particular block. It informs if that particular transaction was successfully executed, or failed.
By adding events, it is therefore possible to check if a transaction was executed successfully.
- Enhanced developer experience
-
Events can store various additional information on-chain, which can be valuable for other services. Additional events can be defined per module by the blockchain developer.
Description |
Blockchain events are introduced newly in Klayr SDK v6. Blockchain events are still defined and emitted inside the module, but it is not possible to subscribe to them via the RPC API of a node. Instead, blockchain events are logged per block, i.e. directly included in the block header and can be queried through the RPC API of a node by requesting the RPC endpoint Blockchain events in Klayr SDK v6 are following a concept comparable to the Ethereum event log. Besides the newly introduced blockchain events, there is still a couple of RPC events included in the Klayr Framework, which can be retrieved via public-subscribe, as in v5. The blockchain developer can define new blockchain events per module as desired, but the RPC events are not customizable any more. Only new blockchain events can be included in the blockchain client by the developer. |
---|---|
Purpose |
Blockchain events are a way for modules to store important information which is not included in the transactions or block assets, verifiable using eventRoot property present inside the block header. They are part of the overall state of the blockchain, as an event root of all events included in a particular block is stored in the block header. They can include a lot of additional data if required, as the events themselves can be removed from the stores of the node after a certain time, and therefore don’t "pollute" the blockchain itself. |
Definition |
For more information on how to create the corresponding event class, please check out the guide: How to create a blockchain event |
Publishing |
|
Retrieving |
In Klayr SDK v6, events are requested per block height after an event is emitted. Retrieving events from a node:
|
4. Chain ID replaces network ID
Chain identifiers (or chain IDs) for transaction signatures and block signatures were already introduced in Klayr SDK v5 as "network identifiers" to prevent replay attacks on other chains. In Klayr SDK v6, the chain ID is now additionally used to identify chains for making cross chain transactions in the Klayr ecosystem.
Besides getting a more descriptive name, the chain ID is also constructed differently now:
Chain ID (Klayr SDK v6) |
Network ID (Klayr SDK v5) |
|
Description |
Unique identifier of a blockchain network for transactions and blocks to prevent replay attacks on other chains. |
Unique identifier of a blockchain network for transactions and blocks to prevent replay attacks on other chains. |
Bytes |
4 |
32 |
Creation |
Defined by the blockchain developer |
Randomly generated |
Read the LIP 0037 for more information about the chain ID. |
00000000
4c09e6a781fc4c7bdb936ee815de8f94190f8a7519becd9de2081832be309a99
Chain identifiers are 4-byte values that follow a specific format: the first byte is used to identify the network in which the chain is running (either the Klayr Mainnet, Klayr Testnet, or any other test network); the other 3 bytes identify the blockchain within the network.
The network-specific prefix is included explicitly to ensure that a chain does not use the same chain identifier in the test network as in the mainnet. |
Main benefits of this change
- Improved developer experience
-
-
The chain identifier can be directly set by the blockchain creator, which is more convenient than generating a random 32-byte value.
-
- Improved user experience
-
-
By using a much shorter ID, users can easily verify that they are signing a transaction for the correct blockchain.
-
5. Module & command IDs are removed
The module and command IDs are removed completely in Klayr SDKv6.
Instead of IDs, the name of a module and the name of a command are now used as unique identifiers for modules and commands, respectively.
Main benefits of this change
- Enhanced developer experience
-
Reduces the number of required properties and uses strings which are more descriptive than numbers.
6. Methods replace reducers
The module reducers are renamed to methods.
Methods in Klayr SDK v6 still have the same purpose as reducers in v5, but besides the name change, they are also defined a bit differently, as summarized below:
Main benefits of this change
- Improved developer experience
-
-
By providing a base class for the creation of module methods, developers can follow a dedicated pattern to include methods into a module in a straightforward manner.
-
The renaming from reducers to methods was introduced to improve intuitive understanding of the meaning behind this data structure.
-
Name |
Method |
---|---|
Description |
An interface for module-to-module communication. |
Definition |
|
Usage |
|
Description |
An interface for module-to-module communication. |
---|---|
Definition |
|
Usage |
Reducers can be invoked through the
|
7. Endpoints replace actions
The module actions are renamed to endpoints.
Endpoints in Klayr SDK v6 still have the same purpose as actions in v5, but besides the name change, they are also defined a bit differently, as summarized below:
Main benefits of this change
- Improved developer experience
-
-
By providing a base class for the creation of module endpoints, developers can follow a dedicated pattern to include endpoints into a module in a straightforward manner.
-
The renaming from actions to endpoints was introduced to improve intuitive understanding of the meaning behind this data structure.
-
Description |
An interface between a module and an external system via an RPC endpoint. |
---|---|
Definition |
|
Usage |
|
Description |
An interface between a module and an external system via an RPC endpoint. |
---|---|
Definition |
|
Usage |
|
8. Migration of store from v5 to v6
A store, aka key-value store is a special kind of database that follows a data storage paradigm designed for storing, retrieving, and managing associative arrays.
In the Klayr SDK, stores are used to store the on-chain and off-chain related data of a node. Each module has its own dedicated store, which only the module itself can access.
In Klayr SDK v5, this principle was not followed consistently: There were the chain store and the account store, and the account store was accessible by every module.
In Klayr SDK v6, the account store is removed completely, and integrated into the respective module stores. Additionally, the implementation of stores into modules is improved, to store any key-value pair in the database consistently.
Main benefits of this change
- Improved developer experience
-
-
By providing a base class for the creation of module stores, developers can follow a dedicated pattern to include stores into a module in a consistent manner.
-
- Improved modularity
-
-
Confines data per module
-
Definition |
How to define a new module store
How to register stores with the module
|
---|---|
Usage |
Example: How to get data from the store
|
9. Addition of metadata
Klayr SDK v6 introduces a new RPC endpoint to get all existing metadata related to a node. This includes metadata of all the modules which are registered on the node.
The module developer can now easily define which data should be returned by the endpoint for the particular module by adjusting the newly introduced metadata method.
Main benefits of this change
- Improved user experience
-
-
Users can now query all the relevant metadata about a module in a consistent manner.
-
- Improved modularity
-
-
Metadata for a module is now defined inside it.
-
The metadata to be returned can be defined for each module individually.
-
export class HelloModule extends BaseModule {
// [...]
public metadata(): ModuleMetadata {
return {
name: '',
endpoints: [],
commands: this.commands.map(command => ({
name: command.name,
params: command.schema,
})),
events: this.events.values().map(v => ({
name: v.name,
data: v.schema,
})),
assets: [],
};
}
// [...]
}
Use the RPC endpoint system_getMetadata
to retrieve the metadata of all modules registered to the blockchain client.
curl --location --request POST 'localhost:7887/rpc' \
--header 'Content-Type: application/json' \
--data-raw '{
"jsonrpc": "2.0",
"id": "1",
"method": "system_getMetadata",
"params": {}
}'
10. Module dependencies registration updates
The following changes were introduced to complement the improvements made in the module structure, see Methods replace reducers, Addition of blockchain events, and Migration of store from v5 to v6. |
In Klayr SDK v6, module dependencies can be registered in the following methods:
10.1. init()
init()
is a method that can be implemented inside a module and/or a command to register the required dependencies for the module.
The init()
method of the command can be called inside the init()
function of the module to pass config options to a command, if desired.
- Dependencies added inside the init() method
-
-
Configuration options for the module
-
The stores used by the module
-
The events emitted by the module
-
Stores and events can be registered in the constructor of the module alternatively. |
public async init(args: ModuleInitArgs): Promise<void> {
// registration of stores and events
this.stores.register(CounterStore, new CounterStore(this.name));
this.stores.register(MessageStore, new MessageStore(this.name));
this.events.register(NewHelloEvent, new NewHelloEvent(this.name));
// Get the module config defined in the config.json file
const { moduleConfig } = args;
// Overwrite the default module config with values from config.json, if set
const config = utils.objects.mergeDeep({}, defaultConfig, moduleConfig) as ModuleConfigJSON;
// Validate the provided config with the config schema
validator.validate<ModuleConfigJSON>(configSchema, config);
// Call the command init() method with config values as parameters
this.commands[0].init(config).catch(err => {
console.log("Error: ", err);
});
}
10.2. addDependencies()
addDependencies()
is a method that can be implemented inside a module and/or a command to register methods of other modules.
- Dependencies added inside the addDependencies() method
-
-
The methods of other modules used by the module
-
By registering them in addDependencies() , methods keep their type information which improves the development experience greatly.
|
public addDependencies(tokenMethod: TokenMethod) {
this._tokenMethod = tokenMethod;
}