Realization

This is the general scheme of Elight platform work:

When developing the smart contract, we wanted to use all the advantages of C# language, so we've split our Smart Contract into small pieces/components. It allowed us to build a scalable and complex application, which is easy to understand, test and extend. There are a diagram and detailed explanation of all the components used in our smart contract.

Main.cs

The starting point of our contract. It has a method for invoking contracts:

public static bool Invoke(string carrierHash, BigInteger i, byte[] arg)

It invokes early created contracts. You should specify the index of contract, the hash script of carrier and arguments represented as the byte array.

Interpreter.cs

It's very expensive to create a smart NEO contract (about 490 gas) for each cargo delivery (as it can be done in Ethereum, for example). So we decided to write byte code programs which are interpreted by smart contract. So Interpreter.cs file represents interpreter for executing a very simple set of programs. It's possible to implement more complex one. For example, we could implement the interpreter for stack language like forth to enhance contract's functionality.

Interpreter class has two methods...

It accepts contract object with bytecode program in it and executes it with specified parameters (args variable):

//note: you can write another byte code program in args
public static Interpreter Run(Interpreter interpreter, Contract contract, byte[] arg)

After execution is completed you can get an output by calling GetResult method. Its signature looks like this:

public static Int32 GetResult(Interpreter Interpreter)

It gives you the last element from stack.

Stack.cs

Interpreter uses stack data structure for executing programs. It's a very famous data structure, so we don't want to dive into it.

Stack class operates with 4 byte signed numbers (Int32)

public static Stack Pop(Stack stack)            //remove element from stack
public static Stack Push(Stack stack, Int32 v)  //push element onto stack
public static Int32 Top(Stack stack)            //get copy of element that lays onto stack

Contract.cs

It represents a contract between contractors. It consists of information in JSON format and a program that written in byte code. Interpreter understands this code and it's able to execute it.

So there're two main methods:

public static Contract Init(byte[] info, byte[] source)

source is a byte code, available at the moment opcodes are described below

public enum OPCODES
{
    NEG  = 0x7FFFFFFF, // MULTIPLY BY -1
    SUM  = 0x7FFFFFFE, // a, b => a + b
    SUB  = 0x7FFFFFFD, // a, b => a - b
    MUL  = 0x7FFFFFFC, // a, b => a * b 
    ACC  = 0x7FFFFFFB, // a => acc_register + a
    CMP  = 0x7FFFFFFA, // a, b, c => b < a < c 
};

info represents an additional contract data, usually this data is represented in JSON format like so ...

{
    "Name": "...",
    "Description": "...",
    "From": "...",        
    "To": "...",
    "Goods": ""
}

Also it's possible to add deposit to the contract. It brings guarantee and security to contractors.

public static Contract InitDeposit(Contract contract, byte[] carrierHash, byte[] clientHash, BigInteger amount)

It has the same signature as Init method except two additional parameters: hash of client and amount to freeze as a deposit.

Deposit.cs

It represents guarantee between contractors. It stores hash their hash addresses and amounts of deposits.

When Contract.cs is initialized, the deposit is frozen.

When some particular conditions are met. The sensor is arrived with cargo and submits all the measurements to the blockchain, tokens are releasing in favor of client or carrier. It depends on the measurements and conditions, that was written in the contract before sending.

public static bool Freeze(Deposit deposit)

public static bool Unfreeze(Deposit deposit, bool isOk) //isOk determines reciever

Token.cs

It represents our currency which is used mainly for making deposits and adding them to contracts.

It has a couple of useful methods...

For transferring Elight Coin (EC) between contractors...

public static bool Transfer(byte[] from, byte[] to, BigInteger value) //'from' and 'to' are script hashes

For exchanging EC on NEO tokens...

public static bool MintTokens()

Also there are some helper methods. They help us to add and remove specific amount of tokens from address without proving an identity. It mainly used for freezing and unfreezing deposits.

ForceAdd(byte[] from, BigInteger amount)
ForceSub(byte[] from, BigInteger amount)

Prefixes.cs

All the keys, that store any data in blockchain are computed like so...

private static string GetContractKey(string carrierHash, BigInteger index)
{
    string main = Prefixes.CONTRACT_PREFIX + carrierHash;
    return main + index;
}

Every key has its own prefix, so it's important to store all the prefixes in one place, otherwise it may lead to Runtime errors which are very hard to find and debug.

For these purposes we created Prefixes.cs file. It stores all the prefixes.

results matching ""

    No results matching ""