# YJS语法

- - -

## 概述

YJS源文件包括任意数量的**import声明**和一个**contract定义**。

- - -

## import声明

与JavaScript（ES6）类似，YJS也支持import声明语句，在全局层面，开发者可以使用如下import声明来导入其他文件。

```
import "filename";
```

### 内容

import声明语句将包含在“filename”文件中的所有全局符号（单元）导入到当前文件，且全局范围内有效。

### 路径

**filename**通常用**/**做目录分隔符来表示文件的路径，例如，从同一目录下导入**x.yjs**文件到当前文件，可以使用**import "x.yjs"**语句；从其他目录下导入**x.yjs**使用**import "lib/x.yjs"**语句。

- - -

## Contract定义

### 示例

以下是一个合约示例，用于JSON处理，此YJS源文件以合约名称命名。

```
contract ScoreAdder{
	//arg =  {"action":"main","arg":"[{\"score\":20},{\"score\":20}]"}
	export function main(arg){
		//JSON is a build-in object.
		var point = JSON.parse(arg);
		var s = 0;
		print(point[0].score);
		print(point.length);
		for (var i=0;i<point.length;i++){
			s+=point[i].score/1.0;
		}
		print("total score= "+s);
		return s;
	}
}
```

### 注释

YJS源文件支持以（**//**）表示的单行注释和以（**/\*...\*/**）表示的多行注释，如下所示：

```
// 这是一个单行注释
/*
 * 这是一个
 * 多行注释
 */
```

### 注解
与Java类似，YJS也支持注解声明合约和函数。


在YJS中，有几种内建注解：LogType、LogLocation、Access、Permission。
当然，可以自定义注解。
内建注解的详细使用方式可以通过YJS内置API文档查看。
开发者可以使用如下注解来声明合约和函数。

```
@LogType("Arg","Result","Branch")
@SelfDefinedAnntation("dad",1)
@Access
function xxx(){}
```
 
### 结构

YJS中的合约类似于Java中的类。每个合约都定义了一定数量的**变量**、**函数**和**事件**。

#### 变量

YJS中的变量类似于JavaScript（ES6）中的变量，分为**全局变量**和**局部变量**。

全局变量:

```
judge =  true;
```

局部变量:

```
var vs = "This is a string";
```

所有的变量都是**动态类型**，因为变量的具体类型是根据变量值来决定的。如上示例中，全局变量judge是bool类型，局部变量vs是字符串类型。

#### 函数

函数是合约中的可执行单元。YJS中有两种类型的函数：普通函数和用**export**关键字修饰的exported函数。

以下是exported函数和普通函数的区别：

1. 只有exported函数能被其他合约调用。
2. exported函数只能有一个参数且参数类型必须为String。
3. exported函数的返回类型必须是String。
4. 内置对象requester（请求者的公钥）只能存在于exported函数或onCreate函数，因为onCreate()虽然没被**export**关键字修饰，但它自带requester对象且该函数可以自动执行。

#### 事件

YJS中的事件类似于Solidity中的事件。

**发布者**定义一个包含事件发布函数的事件，然后通过调用事件发布函数发布事件。

**订阅者**订阅并处理事件。

事件示例如下：

EventPuber.yjs

```
contract EventPuber{
	event abcEvent;
  	export function pub(arg){
		abcEvent(arg);
  		return "done!";
	}
}
```

EventSuber.yjs

```
contract EventSuber{
  	export function init(arg){
		YancloudUtil.subscribe("EventPuber","abcEvent",handler);
        print("Handler:"+handler);
	}
  	function handler(e){
        var ret = "ReceiveEvent:"+(e.type)+" "+(e.content);
		print(ret);
	}
}
```


- - -

## YJS项目

除了只包含一个contract定义的YJS源文件，YJS引擎还支持**YJS项目**。

每个YJS project包含了合约执行过程中需用到的各种文件，包括yjs源文件**".yjs"**和其他资源文件，如**"mainfest.json"**, **".js"**, **".txt"**,**".jar"**,  ...

### Manifest.json

每个YJS项目在项目的根目录下必须有一个**mainfest.json**文件，此文件描述了合约对于YJS的编译工具（YJS引擎）所需的必要信息。

#### Manifest结构

manifest文件需包含以下信息：

1. **main**: 项目中将要被执行的合约文件。
2. **type**: 合约的类型，如数据合约/算法合约...
3. **builder**: 构建YJS项目的开发者姓名。
4. **insnLimit**: 运行合约需要消耗的值。
5. **pyDependences**: 项目所需的Python依赖。

#### Manifest示例

```
{
	"main": "contract.js",
	"type": "Data",
	"builder": "caihq",
	"permissions": 0L,
	"pyDependences": [
        {
            "name": "yjsexample",
            "modules": [
                {
                    "name": "sample"
                }
            ]
        }
    ]
}
```

### YJS-Java

Jar文件实现了YJS与其他编程语言间的**跨语言调用**，如YJS-Java, YJS-Python, ... 通过将Java文件包成jar包的方式，使得合约可直接调用Java中的方法。


Java class:

```java
package your.own.pkg;
public class HelloWorld {
 public static int fun(String arg){
  return arg.length;
 }
 public int fun2(String arg){
  return arg.length;
 }
}
```

InvokeJava.yjs

```javascript
contract InvokeJava{
 export function main(arg){
  var Hello = Java.type("your.own.package.HelloWorld");
  var hello = new Hello();
  return Hello.fun(arg)+hello.fun2(arg);
 }
}
```

### YJS-前端

使用数瑞客户端来访问智能合约支持从智能合约中获取html/js/css等资源文件，
并在[BDWareWebClient](./_static/BDWareWebClient.zip)中渲染。
首先在合约中import以下模块。

```javascript
module Viewable{
  export function loadResource(arg){
    return Global.Resources.loadAsString(arg);
  }
  export function needRender(arg){
    return true;
  }
}
```

同时，import以后，定义一个getMainFrame方法，以便数瑞客户端识别主页：

```javascript
export function getMainFrame(arg){
  return "/html/main.html";
}
```

该方法的返回结果为一个资源文件的路径。
示例的资源文件"/html/main.html"如下：

```html
<div>
<button onclick="queryDataFromContract()">Hello,</button> Data from contract:
<span id="resultText"></span>
<script fromContract="/html/hello.js"></script>
<link fromContract="/html/hello.css"/>
</div>
```
示例的资源文件"/html/hello.js"如下：

```javascript
var queryDataFromContract = function(){
    //第一个参数为函数名，第二个为参数，第三个参数为回调。
	var data = executeCurrentContract("query","abc",function(argg){
    	$("#resultText")[0].innerHTML = argg.result;
    });
}
```

参考示例：




### YJS-Python

TODO

