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:

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

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中渲染。 首先在合约中import以下模块。

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

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

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

该方法的返回结果为一个资源文件的路径。 示例的资源文件“/html/main.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”如下:

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

参考示例:

YJS-Python

TODO