# Writing a smart contract in C

### Sample contract functionality

The sample contract serves as a demonstration of general QVM logic.

It is capable of:

* registering users into the database
* storing the last registered user's name in the database
* echoing the previous user's name to STDOUT
* incrementing the total registered user count
* storing above counter in the database

### Sample code

```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static int envAtoi(const char* env) {
  const char* val = getenv(env);
  if (val == NULL) {
    return 0;
  }
  return atoi(val);
}

int main(int argc, char *argv[]) {

  // THIS SAMPLE ONLY SUPPORTS THE "register" FUNCTION
  if (argc == 3 && strcmp(argv[1], "register") == 0) {

    // GET THE CURRENT USER'S NAME
    const char *previousName = getenv("DB_USER_CURRENT");

    // OR DEFAULT TO "unknown" IF THIS IS THE FIRST CALL
    if (previousName == NULL || strlen(previousName) == 0) {
      previousName = "unknown";
    }

    // GET THE TOTAL USER COUNT
    int totalUserCount = envAtoi("DB_TOTALUSERS");

    // WRITE PREVIOUS USER NAME TO STDOUT
    printf("OUT=prevname: %s\n", previousName);

    // UPDATE CURRENT USER NAME BY WRITING IT TO DB
    printf("DBW=USER_CURRENT=%s\n", argv[2]);

    // STORE USER NAME UNDER A STORAGE SLOT FOR PERSISTENCE (CURRENT GETS OVERWRITTEN ON EACH CALL)
    printf("DBW=USER_%d=%s\n", totalUserCount, argv[2]);

    // INCREMENT THE TOTAL USER COUNT
    printf("DBW=TOTALUSERS=%d\n", totalUserCount+1);
    return 0;
  }
  if (argc >= 2) {
    fprintf(stderr, "Wrong CMD: %s\n", argv[1]);
    exit(1);
  }
  fprintf(stderr, "Wrong args!\n");
  exit(1);
}
```

### Save the contract

Open a text editor and save above sample contract as `main.c` file.

{% content-ref url="compiling-a-smart-contract-in-c" %}
[compiling-a-smart-contract-in-c](https://learn.qanplatform.com/developers/qvm-multi-language-smart-contracts/docs-for-supported-languages/c-smart-contract/compiling-a-smart-contract-in-c)
{% endcontent-ref %}
