Skip to content

Commit

Permalink
Merge pull request #1 from xiaomin49/master
Browse files Browse the repository at this point in the history
add smart contract turorial
  • Loading branch information
xiaomin49 authored Mar 27, 2018
2 parents 37d2b68 + f73d5b6 commit 6c74326
Show file tree
Hide file tree
Showing 32 changed files with 2,054 additions and 0 deletions.
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

0 comments on commit 6c74326

Please sign in to comment.