get started intro - SkycoinWikis/CXChains GitHub Wiki

CXCHAINS HOME » CX » CXCHAINS » GET STARTED - INTRO

Introduction to CX chains

This text gives you an introduction to running CX program "on the blockchain". This means that you will write programs in the CX language that are stored on a Skycoin Fiber blockchain. It is assumed that the reader of this text has a basic understanding of CX itself, as well as a number of key components in the Skycoin universe such as Fiber blockchains.

Getting Started

A blockchain is a distributed ledger secured by cryptographic methods. The Skycoin blockchain, and most other blockchains like e.g. Bitcoin, contains records that represent an amount of a digital asset. Such an asset is normally a crypto coin like Skycoin or Bitcoin.

However, a blockchain can also store many other types of data. A CX chain is a blockchain that contains a CX program and everything that is necessary to run it in a series of updates. A CX chain works by separating a CX program into two parts: its program code and the so called transaction code. The program state is stored on the blockchain, and it is updated every time a transaction is run. In this case, "update" means that the new state is stored in a new block in the blockchain.

Consider the code below:

package main

func main() {

}

One could think that this CX program represents an empty program state, but this is not the case. The program state consists of the following parts:

  • a code segment
  • a stack segment
  • a data segment
  • a heap segment

This is exactly like any CX program, but in this case the running state represented by the segments listed above will be stored on a blockchain instead of in RAM.

In the case of the example above, it would represent a code segment containing a single package (main) with a single function (main). As the main function is empty, nothing will run and the stack and heap segments will be empty. Furthermore, as we do not have any global variables, the data segment will be empty too.

Now, let's have a look at a slightly more complex example:

package main

var name str = "Richard"

func main() {

}

In this case, we have a code segment similar to the previous example and we have two pieces of data in the data segment: a global string variable and the string value "Richard". The variable points to the string value so that the value can be accessed by using the name of the variable in the code.

In order to store the CX program on the Skycoin blockchain, we need to serialize it. To serialize a program, all the packages, structs, functions, globals, etc. of the CX program are converted to a series of bytes, called a slice. The same happens to the stack, the data and the heap memory segments. These slices are stored in a transaction on the blockchain, which results in a "CX chain". (You can look at cx/serialize.go in the CX source code if you are curious about the details.)

As a consequence, if a program with many packages, functions, etc. is used to initiate a CX chain, the program state stored on the blockchain will be big, even if the program is not creating any heap objects or using deep function calls that fill the stack. Just to make it clearer, the following rather simple code would result in a very big program state:

package main

var foo [1000][1000]i32

func main() {

}

It is important to bear this in mind, as there are hardcoded limits to how big the program state of a CX chain can be, as well as how big a transaction can be.

We now know how and where the program state of a CX chain is going to be stored, but we also need to know how to use it. The program state will never be executed or mutated by itself. In order to modify its state, we need to run a transaction against it. Consider the following pieces of code:

package bc

func PlusOne(indata i32) (result i32) {
	result = indata + 1
}

package main

func main() {

}

and

package main
import "bc"

func main() {
	var num i32
	num = bc.PlusOne(5)
	i32.print(num)
}

The first code snippet is our blockchain code and the second snippet is our transaction code. As can be seen in the blockchain code, there are two packages: bc and main. Then, if we pay attention to the transaction code, we can see that its main package is importing bc. The blockchain code (which defines the CX chain's program state) can be seen as a code library that can store mutable state, and the transaction code can be seen as a program that is importing the blockchain code -- which is exactly what is happening.

"But that's not useful, I can just create another file with that code and import it" you might be thinking. However, remember that you can also store state and that state can be mutated. Consider this case:

package bc

var numTransactions i32

func LogTransaction() {
	numTransactions++
	i32.print(numTransactions)
}

package main

func main() {

}

and

package main
import "bc"

func main() {
	bc.LogTransaction()
}

In the example above, we can see that we have a global variable called numTransactions, which is increased by one if LogTransaction is called. This simple program can help us track how many times a transaction has been created and broadcasted.

As you may have noticed, the main function in the blockchain code is empty. The whole main package and any function that is in that package will be destroyed once the program state is created and stored on the blockchain. This does not mean that the main package is useless though, as it can be used to initialize the program state. For example, have a look at the following blockchain and transaction codes:

package bc

var matrix [10][10]i32

func initMatrix() {
	for y := 0; y < 10; y++ {
		for x := 0; x < 10; x++ {
			matrix[x][y] = 1
		}
	}
}

func PrintMatrix() {
	for i := 0; i < 10; i++ {
		for j := 0; j < 10; j++ {
			printf("%d", matrix[i][j])
		}
		printf("\n")
	}
}

func FlipBit(x i32, y i32) {
	if matrix[x][y] == 1 {
		matrix[x][y] = 0
	} else {
		matrix[x][y] = 1
	}
}

package main
import "bc"

func main() {
	bc.initMatrix()
}

and

package main
import "bc"

func main() {
	bc.FlipBit(3, 4)
	bc.PrintMatrix()
}

We use bc.initMatrix to initialize matrix to 1s, and the transaction code uses bc.FlipBit to change one of the cells of the matrix to 0.

Now, this should be enough to give you a quick introduction to what you can do. Now, let us go into the details of how to set up a development environment and create your own CX blockchain.

Continue with the Setup Process for your OS: Windows 10 / macOS / *nix