Skip to main content

Task Tutorial


The main function of the task is to submit "Hello, World!" to K2.

Update task() with the code block below to fulfill the task's logic:

async task() {
try {
const value = "Hello, World!";

if (value) {
// store value on NeDB
await namespaceWrapper.storeSet("value", value);
} catch (err) {
console.log("ERROR IN EXECUTING TASK", err);


The fetchSubmission method will fetch and return the submission value from NeDB using the namespaceWrapper.storeGet() method.

Update fetchSubmission() with the code block below:

async fetchSubmission() {
const value = await namespaceWrapper.storeGet("value"); // retrieves the value
console.log("VALUE", value);
return value;


The submitTask method calls fetchSubmission() to retrieve the submission value from NeDB and submits it to K2 along with the current roundNumber.

async submitTask(roundNumber) {
try {
const submission = await this.fetchSubmission();
console.log("SUBMISSION", submission);
await namespaceWrapper.checkSubmissionAndUpdateRound(
} catch (error) {
console.log("error in submission", error);


This method verifies that a node submitted the correct value, "Hello, World!" This method returns true if the value is correct, otherwise false.

Update validateNode() with the code block below:

async validateNode(submission_value, round) {
let vote;
console.log("SUBMISSION VALUE", submission_value, round);

try {
if (submission_value == "Hello, World!") {
vote = true;
} else {
vote = false;
} catch (e) {
vote = false;

return vote;


The Task Template contains a sample logic for the generateDistributionList(), which rewards 1 KOII to all the nodes with valid submissions for that round. We'd retain the logic for the Hello World project.

In the sample code:

  • An empty distribution list is initialized
  • The task's data is retrieved using the getTaskState helper function
  • All submissions are fetched from the task's data
  • The submissions_audit_trigger is also retrieved from the task's data; this object contains information about the audited submissions
  • An empty distribution list is returned if submissions is null. Otherwise, the keys and values of submissions are grouped separately, and in a loop, it calculates the audits on each submission and the number of votes on the audit and then generates a distribution list based on that.


In the sample code present in the template:

  • The distribution list is fetched
  • If the distribution list is not null, it is parsed and stored in the variable fetchedDistributionList
  • The distribution list is re-generated by calling the generateDistributionList method with the current round number and task state as parameters
  • The generated distribution list is stored in the variable generatedDistributionList
  • Finally, fetchedDistributionList and generatedDistributionList are compared to see if they are equal. If they are, this method returns true, otherwise false.

When creating a task using the Task Template, there's usually no need to edit the following methods: auditTask(), auditDistribution(), and submitDistributionList().