Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add smart contract turorial #1

Merged
merged 1 commit into from
Mar 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions smart-contract-tutorial/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<h1 align="center">Ontology Smart Contract</h1>
<h4 align="center">Version V0.6.0 </h4>

## What is a smart contract?

A smart contract is a set of commitments that are defined in digital form, including the agreement on how contract participants shall fulfill these commitments. Blockchain technology gives us a decentralized, non-tampering, highly reliable system in which smart contracts are extremely useful. Smart contracts is one of the most important characteristics of blockchain technologies and the reason why blockchains can be called disruptive technology. It is increasing the efficiency of our social structure by each passing day.

## Characteristics of Ontology smart contracts

//TODO

## Write smart contracts in any language

//TODO

## How to make a effective smart contract?

![Workflow of smart contract](https://s1.ax1x.com/2018/03/24/9q9vx1.png)

There are few things as below.

First, you should choose a language to write your smart contract, lets's suppose it's C#. Then you need to compile your code. At last, you can deploy your smart contract to the blockchain and invoke it.

Don't worry, we have built a simple tool to help you with all these things. It's a [online IDE]() for Ontology smart contract. You can write smart contract with popular languages on it, and deploy ,invoke contracts easily.

For more information, please check the [Smart Contract IDE user guide]().

### Step1 - Write & Compile

We now support smart contracts that run in **NEOVM** and **WASMVM**.


* **For NeoVM**, We supply you Smart Contract IDE to help your write, compile,deploy and invoke smart contracts.
* **For WASMVM**, Please enter [>> Wasm Smart Contract](README_wasm.md).

Firstly , you should create a project, and you can choose the language to write smart contract as you want.

![Select language](https://s1.ax1x.com/2018/03/24/9bxJYR.png)

Then you can see the main editor page.

The left side is the file structure of your smart contract.

The right side is the operation panel.

The middle area is the editor and the logs output box.

![](https://s1.ax1x.com/2018/03/24/9bzj2t.md.png)

#### Write smart contract

You can enjoy coding your smart contracts now. We also provide some userful contract templates for you to start writing easily.

You can check more specific examples here:

[ C# Smart Contract](docs/en/csharp.md)

[Python Smart Contract](docs/en/python.md)

#### Compile smart contract

After you have written your smart contract, you can click the **Compile** button on the right side to compile your code.

If your code is correct, your smart contract will be compiled to the ABI and AVM file , and display on the right side.



### Step2 - Deploy smart contract

Next, you can deploy the smart contract to the blockchain. This step costs some fee so you have to select one of your local wallet with enough balance. Then click the **Deploy** button to deploy the contract.

Besides IDE, you can use ONT SDK to deploy smart contract. Please check the sdks to see more detailed information.

[>> Java SDK](https://opendoc.ont.io/javasdk/en/chapter5/smartcontract.html)


![](https://s1.ax1x.com/2018/03/24/9qp10S.png)


### Step3 - Invoke smart contract

Last, you can run the method of your contract. The step costs some fee, too. You can select the method and input the params to invoke. The result will display on the right side.

![Invoke smart contract](https://s1.ax1x.com/2018/03/24/9qpLct.png)

Besides IDE, you can use [>> Java SDK](https://opendoc.ont.io/javasdk/en/chapter5/smartcontract.html) to invoke smart contract. Please check the sdks to see more detailed information.









229 changes: 229 additions & 0 deletions smart-contract-tutorial/README_wasm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
# Wasm Smart Contract

## Introduction
Wasm (WebAssembly) is a binary instruction format for stack-based virtual machines. Wasm is designed to be a portable target for compiling high-level languages such as C/C++/Rust, and supports deployment of client and server applications on the Web. Ontology supports smart contracts written in the wasm format.

![WASM](./images/WASM.png)

## Compilation

1. First, we will prepare a simple c language contract that calculates the sum of two integers or concatenates two strings.

```c
char * JsonMashal(void * val,char * types);
int strcmp(char *a,char *b);
int arrayLen(char *a);
void * malloc(int size);
int ReadInt32Param(char *addr);
char * ReadStringParam(char *addr);

int add(int a, int b ){
return a + b;
}

char * concat(char * a, char * b){
int lena = arrayLen(a);
int lenb = arrayLen(b);
char * res = (char *)malloc((lena + lenb)*sizeof(char));
for (int i = 0 ;i < lena ;i++){
res[i] = a[i];
}

for (int j = 0; j < lenb ;j++){
res[lenb + j] = b[j];
}
return res;
}

char * invoke(char * method,char * args){

if (strcmp(method ,"init")==0 ){
return "init success!";
}

if (strcmp(method, "add")==0){
int a = ReadInt32Param(args);
int b = ReadInt32Param(args);
int res = add(a,b);
char * result = JsonMashal(res,"int");
return result;
}

if(strcmp(method,"concat")==0){

char * a = ReadStringParam(args);
char * b = ReadStringParam(args);
char * res = concat(a,b);
char * result = JsonMashal(res,"string");
return result;
}

}


```

The following functions are provided by the virtual machine API and need to be declared at the head of the file.

```c
char * JsonMashal(void * val,char * types);
int strcmp(char *a,char *b);
int arrayLen(char *a);
void * malloc(int size);
int ReadInt32Param(char *addr);
char * ReadStringParam(char *addr);

```

The entry of WASM contract is unified as ```char * invoke(char * method, char * args)```.

**method** is the method’s name that needs to be called

**args** are the incoming parameters, raw bytes

API ```int strcmp(char *a,char *b)``` :String comparison function, which can be used to judge the method’s name that needs to be called

API ```char * JsonMashal(void * val,char * types)``` : It can serialize results to Json format

API ```int ReadInt32Param(char *addr)``` and ```char * JsonMashal(void * val,char * types);``` can read string or int param from input bytes



2. Compile the above C file into a smart contract in wasm format.
* Emscripten tool [http://kripken.github.io/emscripten-site/](http://http://kripken.github.io/emscripten-site/)
* Use the online compiler WasmFiddle [https://wasdk.github.io/WasmFiddle](https://wasdk.github.io/WasmFiddle)

Use WasmFiddle as an Example

Paste the C code into the edit window of "c". Please ignore the contents of the "JS" window and click the "Build" button. If the compilation is correct, you can see the compiled wast format code in the "Text Format" window. If the compilation is wrong, an error message will be displayed in the "output" window.

![fiddle](images/fiddle.png)

If you are familiar with [wast syntax](http://webassembly.org/docs/binary-encoding/),you can modify the wast file yourself.

And use the [wabt](https://github.com/WebAssembly/wabt) tool to compile the wast file into wasm format.


3. Click the "wasm" button to download the compiled wasm file


### Passing parameters in Json format

Incoming parameters can be in Json format:

```
void JsonUnmashal(void * addr,int size,char * arg);
char * JsonMashal(void * val,char * types);
int strcmp(char *a,char *b);
int arrayLen(void *a);
void * malloc(int size);

int add(int a, int b ){
return a + b;
}

char * concat(char * a, char * b){
int lena = arrayLen(a);
int lenb = arrayLen(b);
char * res = (char *)malloc((lena + lenb)*sizeof(char));
for (int i = 0 ;i < lena ;i++){
res[i] = a[i];
}

for (int j = 0; j < lenb ;j++){
res[lenb + j] = b[j];
}
return res;
}


int sumArray(int * a, int * b){

int res = 0;
int lena = arrayLen(a);
int lenb = arrayLen(b);

for (int i = 0;i<lena;i++){
res += a[i];
}
for (int j = 0;j<lenb;j++){
res += b[j];
}
return res;
}


char * invoke(char * method,char * args){

if (strcmp(method ,"init")==0 ){
return "init success!";
}

if (strcmp(method, "add")==0){
struct Params {
int a;
int b;
};
struct Params param;

JsonUnmashal(&param,sizeof(param),args);
int res = add(param.a,param.b);
char * result = JsonMashal(res,"int");
return result;
}

if(strcmp(method,"concat")==0){
struct Params{
char *a;
char *b;
};
struct Params param;
JsonUnmashal(&param,sizeof(param),args);
char * res = concat(param.a,param.b);
char * result = JsonMashal(res,"string");
return result;
}

if(strcmp(method,"sumArray")==0){
struct Params{
int *a;
int *b;
};
struct Params param;
JsonUnmashal(&param,sizeof(param),args);
int res = sumArray(param.a,param.b);
char * result = JsonMashal(res,"int");
return result;
}

}

```

This example adds the new API:
```
void JsonUnmashal(void * addr,int size,char * arg);
```

API ```void JsonUnmashal(void * addr,int size,char * arg)``` :It can parse the parameters in json format into defined structures.

Since webFiddle has problems with the compilation of the ```&``` operation of the C language, it needs to use Emscripten to compile it.

* For installation of Emscripten, please refer to [http://kripken.github.io/emscripten-site/](http://http://kripken.github.io/emscripten-site/)
* Use the command ```emcc cfiles/{file}.c -Os -s WASM=1 -s SIDE_MODULE=1 -o cfiles/{file}.wasm``` to compile the C file to a wasm format file.
* Install WABT [https://github.com/WebAssembly/wabt](https://github.com/WebAssembly/wabt)
* Use the wasm2wat {file}.wasm > {file}.wast command to view.


* You can see that the method names are compiled into names that start with ```_``` , which needs to be modified manually.

* We only want to export the ```invoke``` method and need to delete the other "export"
* ```(import "env" "memory" (memory (;0;) 256))``` memory size is set to 256 pages, according to Webassembly [spec](https://github.com/WebAssembly/design/blob/27ac254c854994103c24834a994be16f74f54186/Semantics.md#linear-memory), each page is 64K. Our contract does not require so much memory. So we can change 256 to 1.
* Use```wat2wasm {file}.wast ```to compile the wasm format file


### Get the binary contents of the wasm file
Use the online tool [http://tomeko.net/online_tools/file_to_hex.php?lang=en](http://tomeko.net/online_tools/file_to_hex.php?lang=en)
![hexadecimal](images/hexadecimal.png)
Loading