bdcontract-doc/markdown/markdown_BDWare/YJSAPI.md
2022-01-04 13:26:25 +08:00

1137 lines
25 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# YJS SDK
## YJS Build-in API
### 内置对象 Global
### 内置对象 requester
该内置对象在export function里面会有值仅当合约调用签名验证通过。
### 执行合约 executeContract
参数:
``` bash
action:executeContract;
contractID:合约的id或名称均可
operation:调用合约的方法名;
arg: 参数格式为JSON字符串有action与arg两个字段。
```
可选参数:
```bash
requestID:字符串类型自行生成用于查询hash
```
使用示例:
```javascript
function testExecutorContract(arg){
var ret = JSON.parse(executeContract("ElemeProvider","queryDB",arg));
if (ret.status == "Success"){
return JSON.parse(ret.result);
}else return null;
}
```
### 订阅事件主题 subscribe
参数
``` bash
contractID字符串类型 合约id或名称均可。
event字符串类型
handler方法名该方法必须接受Event内含字段topic和content类型的唯一变量为参数可以不是export方法
```
使用示例:
```javascript
export function init(arg) {
YancloudUtil.subscribe("topic", handler);
print("Handler: " + handler);
}
function handler(e) {
print("topic: " + e.topic);
print("content: " + e.content);
}
```
## 发布事件 pubEvent
参数
``` bash
topic字符串类型发布的事件主题
content字符串类型发布的事件内容
```
使用示例:
```javascript
export function pub1(arg) {
YancloudUtil.pubEvent("topic", arg);
return "done";
}
```
也可以在合约开头定义事件,则事件名即为事件主题,此时可直接使用事件作为方法名发布事件
```javascript
event topic;
export function pub2(arg) {
topic(arg);
return "done";
}
```
该写法与上面的`pub1`等价。
### 访问资源文件
通过Global.Resources去加载ypk内部的资源文件。
#### loadAsInputStream
参数:
```bash
path字符串类型 需要加载文件的地址
```
使用示例:
```javascript
var file = Global.Resources.loadAsInputStream("/deleteit.txt");
```
#### loadAsScanner
参数:
```bash
path字符串类型 需要加载文件的地址
```
使用示例:
```javascript
var scanner = Global.Resources.loadAsScanner("/local.txt");
```
## YJS Build-in Annotation
### @Access
设置合约的调用是否需要签名,这里分为两种,需签名和无签名。
其中,"verified"表示需要签名。其他则表示无需签名。
```
@Access("verified")
export function easy(arg){
return "true";
}
```
### @LogType
LogType注解通过参数的方式声明合约或函数的需要记录的日志类型。
其中Arg表示日志中记录合约执行的参数Result表示记录合约执行的返回结果Branch表示记录合约执行分支。
例如 通过如下LogType注解来声明函数
```
@LogType("Arg","Result","Branch")
export function easy(arg){
Global.a = "a";
Global.b = "b";
if(arg > 0)
return Global.a;
else
return Global.b;
}
```
### @LogLocation
该注解可以修饰`contract`或`function`。
设置日志存储的位置。参数中指定为“dataware”则存储在账本和本地如果没有指定为“dataware”则仅存储在本地。
例如通过如下LogLocation设置存储位置。
在BaaS平台中可以指定账本名称BaaS平台默认账本为default,使用
`@LogLocation("bdledger:default")`。如想保存到自定义的账本,比如,"abc"账本,就使用
`@LogLocation("bdledger:abc")`
```
@LogLocation("dataware")
export function easy(arg){
Global.a = "a";
}
```
### @Permission
该注解只能修饰`contract`
设置合约中调用的工具类的权限包括File、Http、MySQL、MongoDB、RocksDB等工具类。如果合约中用到了以上工具类需要在注解中添加对应的授权字段默认只有YJS自带的YancloudUtil;如果没有添加则会抛出"未授权工具类"的异常。
这6种工具类的详细说明在本小节后续中有说明。
```
@Permission("Http","File")
contract HttpPermission {
export function main(args){
var http=HttpUtil.httpGet(args);
var dir="adf/adfas/";
var file=FileUtil.getDir(dir);
return YancloudUtil.currentTimeMillis();
}
}
```
### @Description
该注解可以修饰`contract`或`function`。
传入合约及函数的简介可用于生成说明文档中关于exported函数的介绍。
```
@Description("返回数据条目,无需参数")
export function count(args){
var sql = "select count(*) from data;";
var conn = getConn();
var statement = conn.createStatement();
var resultSet = statement.executeQuery(sql);
var c = {};
resultSet.next();
c.count = resultSet.getLong(1);
return JSON.stringify(c);
}
```
### @Param
该注解可以修饰`function`。
提供调用函数的参数示例,也为生成说明文档中的返回结果提供默认参数。
```
@Param({"offset":0,"count":100})
export function get(args){
var offset = args.offset;
var count = args.count;
...
}
```
### @MockTemplate
该注解可以修饰`function`。
提供函数的返回模拟数据模板,用于描述返回值的格式.若加此注解在debug方式调用时返回按照此格式生成的模拟数据。
####支持的字段类型
```
@integer
@string
@boolean
@date
@time
@datatime
/[a-z][A-Z][0-9]/ (正则表达式)
……
详细格式可以参考http://mockjs.com/examples.html
```
####注意:模板的格式为{result:模板}
```json
//返回一个1-100之间的整数
@MockTemplate({'result|1-100':1})
//返回
{'result':76}
//返回一个1-5个数的数组
@MockTemplate({'result|1-5':[{'value|1-100':1}]})
//返回
{"result":[{"value":34},{"value":8},{"value":48},{"value":50},{"value":43}]}
//返回一个对象包含如下字段
@MockTemplate({'result':{'id':'@integer','email':'@email','password':'@string','name':'@name'}})
//返回
{"password":"3ZLc","name":"William Young","id":36097783842688,"email":"d.fuunwe@gqnr.to"}
//返回元素个数为1-5个之间的一个数组数组的每个元素都是上述格式的一个对象
{'result|1-5':[{'id':'@integer','email':'@email','password':'@string','name':'@name'}]}
//返回
[
{"password":"dO]wW","name":"Jeffrey Lopez","id":1783453207480410,"email":"a.ckokgxrga@hgiesugi.bb"},
{"password":"BQYRL","name":"Brian Moore","id":4310212972071102,"email":"k.lbpxocydrh@msgnjtox.na"},
{"password":"Gw1","name":"Susan Jackson","id":7766580783668916,"email":"h.zjgusl@htce.cr"}
]
```
```
@MockTemplate({'result':{'id':'@integer','email':'@email','password':'@string','name':'@name'}})
export function count(args){
var sql = "select count(*) from data;";
var conn = getConn();
var statement = conn.createStatement();
var resultSet = statement.executeQuery(sql);
var c = {};
resultSet.next();
c.count = resultSet.getLong(1);
return JSON.stringify(c);
}
```
### @Result
该注解可以修饰`function`。
若没有模拟数据模板,则返回模拟数据时使用该注解的内容
提供函数的返回结果示例,若加此注解则生成说明文档时将直接返回此结果而不使用默认参数调用函数。
```
@Result(666)
export function count(args){
var sql = "select count(*) from data;";
var conn = getConn();
var statement = conn.createStatement();
var resultSet = statement.executeQuery(sql);
var c = {};
resultSet.next();
c.count = resultSet.getLong(1);
return JSON.stringify(c);
}
```
## IO工具类
### 概览
|IO工具类名称|说明|
|---|---|
| [FileUtil](./YJSAPI.html#fileutil) | 文件操作相关的类 |
| [LedgerUtil](./YJSAPI.html#ledgerutil) | 账本操作相关的类 |
| [HttpUtil](./YJSAPI.html#httputil) | Http接口相关的类 |
| [DOIPUtil](./YJSAPI.html#doiputil) | DoIP相关的类 |
| [MySQLUtil](./YJSAPI.html#mysqlutil) | 连接mysql数据库 |
| [MongoDBUtil](./YJSAPI.html#mongodbutil) | MongoDB连接相关的类 |
| [RocksDBUtil](./YJSAPI.html#rocksdbutil) | RocksDB基于本地文件的k-v数据库 |
| [BDWareTimeSeriesDBUtil](./YJSAPI.html#BDWareTimeSeriesDBUtil) | 基于本地文件的时间序列数据库 |
### FileUtil
可以使用@Permission("File")来引入FileUtil对象。
```
@Permission("File")
contract FileSample {
...
}
```
该对象支持以下方法:
#### copyTo
可以复制文件和目录。第一个参数是source第二个参数是destination。
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | src | 类型为String |
| 2 | dest | 类型为String |
##### 使用示例
```javascript
var ret = FileUtil.copyTo("./source.txt","./dest.txt");
```
#### getContent
获取文件的文本内容,当文件不存在时,返回```undefined```。
##### 参数
| 序号 | 参数 | 说明 |
| --- | --- | --- |
| 1 | path | 类型为String |
##### 使用示例
```javascript
var ret = FileUtil.getContent("./source.txt");
```
#### getDir
获取文件所在的文件夹名,输入参数为字符串。
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | path | 类型为String |
##### 使用示例
```javascript
var ret = FileUtil.getDir("./parent/src.txt");
// ret 为 "./parent/";
```
#### getFileName
获取文件名。输入参数为字符串。
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | path | 类型为String |
##### 使用示例
```javascript
var ret = FileUtil.getFileName("./parent/src.txt");
// ret 为 "src.txt"
```
#### openFileAsPrinter
以PrintStream的形式打开文件。
返回结果是```java.io.PrintStream```类型。
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | path | 文件名类型为String |
| 2 | isAppend| 类型为boolean表示是否往文件末尾添加 |
##### 使用示例
```javascript
var ret = FileUtil.openFileAsPrinter("./parent/src.txt",true);
ret.println("hello");
ret.close();
```
### LedgerUtil
可以使用@Permission("Ledger")来引入LedgerUtil对象。
```
@Permission("Ledger")
contract LedgerExample{
...
}
```
#### getClient
获取一个连接客户端,一个参数,为对象类型。
返回结果为LedgerClient类型用于后续的查询账本等操作。
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | address | 包含ip和端口两个字段 |
##### 使用示例
```javascript
var address = {};
address.ip = "127.0.0.1";
address.port = 18091;
var ledgerClient = LedgerUtil.getClient(address);
```
#### queryByHash
根据Hash查询Transaction。
返回结果为对象包含from、to、type和data四个字段均为String类型。
其中data为按utf-8编码解析字节数组如果存证时用的不是utf8编码可能返回乱码。
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | client | 通过getClient方法获得的对象 |
| 2 | info | 对象类型有两个字段ledger和hash均为字符串类型 |
##### 使用示例
```javascript
// ... ledgerClient = LedgerUtil.getClient(...);
var info = {};
info.ledger = "bdcontract";
info.hash = "4d3b75750835092a50085127702669615b602e53";
var ret = LedgerUtil.queryByHash(ledgerClient,info);
print(ret.from);
print(ret.to);
print(ret.type);
print(ret.data);
```
#### sendTransaction
存证数据。
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | client | 通过getClient方法获得的对象 |
| 2 | info | 对象类型有from\to\data三个字段均为String类型 |
##### 使用示例
```javascript
// ... ledgerClient = LedgerUtil.getClient(...);
var info = {};
info.ledger = "bdcontract";
info.from = "b60e8dd61c5d32be8058bb8eb970870f07233155";
info.to = "b60e8dd61c5d32be8058bb8eb970870f07233155";
info.data = "hello world";
var ret = LedgerUtil.sendTransaction(ledgerClient,info);
//ret为存证的哈希值
print(ret);
```
### HttpUtil
可以使用@Permission("Http")来引入HttpUtil对象。
```
@Permission("Http")
contract HttpExample{
...
}
```
#### createAPIGate
配合手机的元邦使用当手机安装元邦且安装了API 接口后,可成为数据来源。
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | ip | 字符串类型ip端口默认为6161 |
##### 使用示例
```javascript
var ret = HttpUtil.createAPIGate("192.168.4.4");
ret.get("com.tencent.mm","sendMsg","msg");
print(ret);
```
#### createAPIGate
配合手机的元邦使用当手机安装元邦且安装了API 接口后,可成为数据来源。
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | ip | 字符串类型ip|
| 2 | port | 字符串类型,端口 |
##### 使用示例
```javascript
var ret = HttpUtil.createAPIGate("192.168.4.4", "6161");
ret.get("com.tencent.mm","sendMsg","msg");
print(ret);
```
#### get
发起Http的get请求。
返回结果为对象类型包含response和responseCode两个字段。
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | url | 字符串表示url类型 |
##### 使用示例
```javascript
var ret = HttpUtil.get("https://www.baidu.com");
print(ret.responseCode);
print(ret.response);
```
#### post
发起Http的post请求。
返回结果为对象类型包含response和responseCode两个字段。
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | args | 对象类型有urlheaders和data三个字段。其中args.headers为对象类型。|
##### 使用示例
```javascript
var req = {};
req.url = "https://www.baidu.com";
req.data = "hello";
req.header = {};
req.header.Accept = "application/json";
req.header["Content-Type"] = "application/json";
var ret = HttpUtil.post(req);
print(ret.resposeCode);
print(ret.response);
```
### DOIPUtil
可以使用@Permission("DOIP")来引入DOIPUtil对象。
```
@Permission("DOIP")
contract DOIPExample{
...
}
```
#### call
调用一个DO
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | arg0 | 字符串类型, 目标DO标识|
| 2 | arg1 | 字符串类型, 输入参数字符串|
##### 使用示例
```javascript
var ret = DOIPUtil.call("86.5000.470/do.hello","inputString");
```
#### create
向一个Repository创建一个字符串类型DO
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | arg0 | 字符串类型, 目标Repo标识|
| 2 | arg1 | 对象类型,包括doID,doBody字段|
##### 使用示例
```javascript
var digitalObject = JSON.parse("{\"doID\":\"86.5000.470/do.hello\",\"doBody\":\"hello world\"}");
var ret = DOIPUtil.create("86.5000.470/repo.localTcpRepo",digitalObject);
```
#### delete
从一个Repository中删除DO
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | arg0 | 字符串类型 目标DO标识|
| 2 | arg1 | 字符串类型 目标Repo标识|
##### 使用示例
```javascript
var ret = DOIPUtil.delete("86.5000.470/do.hello","86.5000.470/repo.localTcpRepo");
```
#### hello
获取目标Repository的DOIP服务信息
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | arg0 | 字符串类型 目标Repo标识|
##### 使用示例
```javascript
var ret = DOIPUtil.hello("86.5000.470/repo.localTcpRepo");
```
#### listOperation
获取目标DO支持的DOIP操作
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | arg0 | 字符串类型 目标DO标识|
##### 使用示例
```javascript
var ret = DOIPUtil.listOperation("86.5000.470/do.hello");
```
#### register
向LHS注册一个DO返回分配的标识
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | arg0 | 字符串类型 DO所在Repo标识|
| 2 | arg1 | 字符串类型 DO格式描述字符串|
##### 使用示例
```javascript
var ret = DOIPUtil.register("86.5000.470/repo.localTcpRepo","String");
```
#### reregister
修改LHS中DO的注册信息
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | arg0 | 字符串类型 目标DO标识|
| 2 | arg1 | 字符串类型 DO所在Repo标识|
| 3 | arg2 | 字符串类型 DO格式描述字符串|
##### 使用示例
```javascript
var ret = DOIPUtil.reregister("86.5000.470/do.hello","86.5000.470/repo.localTcpRepo","String");
```
#### retrieve
获取一个DO
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | arg0 | 字符串类型 目标DO标识|
##### 使用示例
```javascript
var ret = DOIPUtil.retrieve("86.5000.470/do.hello");
```
### test
测试DOIPUtils是否可用
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | arg0 | 字符串类型 任意字符串|
##### 使用示例
```javascript
var ret = DOIPUtil.test("hello");
```
#### update
更新目标DO
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | arg0 | JS对象,包括doID,doBody字段|
##### 使用示例
```javascript
var digitalObject = JSON.parse("{\"doID\":\"86.5000.470/do.hello\",\"doBody\":\"hello world\"}");
var ret = DOIPUtil.update(digitalObject);
```
### MySQLUtil
可以使用@Permission("MySQL")来引入MySQLUtil对象。
```
@Permission("MySQL")
contract MySQLExample{
...
}
```
#### getConnection
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | URL | 字符串类型jdbc连接 |
| 2 | usrName | 字符串类型,用户名 |
| 3 | pwd | 字符串类型,密码 |
##### 使用示例
```javascript
var url = "jdbc:mysql://xx.xx.xx:port/tableName";
var usrName = "xxx";
var pwd = "xxx";
//配置好用户名和密码url格式为ip或域名+端口,中间以”:”隔开。
var conn = MySQLUtil.getConnection(url,usrName,pwd);
//获取数据库连接
var sql = "select * from newele.data";
//创建查询语句
var statement = conn.createStatement();
var resultSet = statement.executeQuery(sql);
var waimailist = [];
//解析查询结果
var meta = resultSet.getMetaData();
for (;resultSet.next();){
var line = {};
for (var j=1;j<=meta.getColumnCount();j++){
line[meta.getColumnName(j)] = resultSet.getString(j);
}
waimailist.push(line);
}
```
其中getConnection方法返回的对象通过反射机制绑定到了Java的一个java.util.Connection对象。因此可以查看
<https://docs.oracle.com/javase/7/docs/api/java/sql/Connection.html>
以了解如何进行Mysql数据库操作。
### MongoDBUtil
可以使用@Permission("MongoDB")来引入MongoDBUtil对象。
```
@Permission("MongoDB")
contract MongoDBExample{
...
}
```
#### getConnection
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | URL | 字符串类型 数据库的URL |
| 2 | port | 整数类型 端口号 |
| 3 | dbName | 字符串类型 数据库的名称 |
| 4 | usrName | 字符串类型 数据库的用户名 |
| 5 | pwd | 字符串类型 数据库的密码 |
##### 使用示例
**注意port为整型其他参数为String类型**
```javascript
var client = MongoDBUtil.getConnection(url,port,dbName,usrName,pwd);
//获取数据库对象
var db = client.getDatabase("yancloud");
var collection = db.getCollection("containers");
var iter = collection.find().iterator();
var ret ="";
for (;iter.hasNext();){
ret+=iter.next().toJson();
ret+="\n";
}
```
其中getMongoDBClient对象通过反射机制绑定到了Java的一个com.mongodb.MongoClient对象。因此可以查看
<https://mongodb.github.io/mongo-java-driver/3.4/javadoc/com/mongodb/MongoClient.html>
以了解该对象的更多方法和使用方式。
### RocksDBUtil
使用@Permission("RocksDB")来引入RocksDBUtil对象。
```
@Permission("RocksDB")
contract RocksDBSample {
...
}
```
#### loadDB
通过loadDB来加载一个RocksDB数据库。
加载后可进行get/delete/put等操作。
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | path | 字符串类型 数据库部署的路径 |
| 2 | readOnly | 布尔类型 数据库只读 |
##### 使用示例
```
@Permission("RocksDB")
@Description("这是个使用RocksDB的参考代码")
contract RocksDBSample{
function onCreate(){
Global.rocksdb = RocksDBUtil.loadDB("./dbdir/","false");
}
@Description("示例参数: {\"key\":\"abc\",\"value\":\"def\"}")
export function put(arg){
arg = JSON.parse(arg);
Global.rocksdb.put(arg.key,arg.value);
return "success";
}
@Description("示例参数: \"abc\"}")
export function get(arg){
return Global.rocksdb.get(arg);
return "failed";
}
@Description("示例参数: \"abc\"")
export function deleteKey(arg){
return Global.rocksdb.delete(arg);
}
@Description("遍历KV库无需参数")
export function iter(arg){
var iter = Global.rocksdb.newIterator();
var obj = undefined;
var ret = {
};
for (iter.seekToFirst();(obj=Global.rocksdb.getNext(iter))!=undefined;){
ret[obj.key]=obj.value;
}
return JSON.stringify(ret)
}
}
```
### BDWareTimeSeriesDBUtil
使用示例
```
@Permission("BDWareTimeSeriesDB")
contract BDWareTimeDBExample{
function onCreate(arg){
Global.dbutil = BDWareTimeSeriesDBUtil.getConnection();
}
export function put(arg){
//第一个参数为表名第二个参数为要放的value时间戳自动打。
Global.dbutil.put("defaultTable",arg);
return "success";
}
@Param
export function getCount(arg){
return Global.dbutil.getCount("defaultTable");
}
@Param(1617254937373)
export function queryByStartTime(arg){
var startDate = java.lang.Long.valueOf(arg);
//查询从开始时刻startDate到最新的数据
var list = Global.dbutil.query("defaultTable",startDate);
var ret=[];
print("DBUtil"+Global.dbutil+" list:"+list+" list.size"+list.size());
var i=0;
for (i=0;i<list.size();i++){
print(i+"-->"+list.get(i));
ret.push(list.get(i));
}
return ret;
}
@Description("示例参数: {\"offset\":1,\"len\":1}")
@Param({"offset":1,"len":1})
export function queryByOffset(arg){
var offsetLen = JSON.parse(arg);
//可配合getCount使用查询第offset至offset+len条数据
var list = Global.dbutil.queryByOffset("defaultTable",offsetLen.offset,offsetLen.len);
var ret=[];
print("DBUtil"+Global.dbutil+" list:"+list+" list.size"+list.size());
var i=0;
for (i=0;i<list.size();i++){
print(i+"-->"+list.get(i));
ret.push(list.get(i));
}
return ret;
}
}
```
## 加解密工具类
### SM2
可以使用@Permission("SM2")来引入SM2Util对象。
```
@Permission("SM2")
contract SM2Sample {
...
}
```
#### generateKeyPair
生成公私钥。
##### 参数
无参数。
##### 使用示例
```javascript
var ret = SM2Util.generateKeyPair();
print(ret.publicKey);
print(ret.privateKey);
return JSON.stringify(ret);
```
#### sign
签名。
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | content | 字符串类型 要进行签名的内容 |
| 2 | keyPair | sm2 |
##### 使用示例
```
var keypair = SM2Util.generateKeyPair();
var ret = SM2Util.sign("Hello",keypair);
print(ret.status);
//如果status是success
print(ret.signature);
//如果status是failed
print(ret.message);
```
#### verify
验签。
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | content | 字符串类型 待验签的内容 |
| 2 | signature | 字符串类型 签名 |
| 3 | publicKey | 字符串类型 公钥 |
##### 使用示例
```javascript
var ret = SM2Util.verify("Hello","....签名","...公钥");
// 验证通过时result为truestatus为success
// 失败时result为failedstatus为failed
print(ret.status);
print(ret.result);
```
## 多线程工具类
### AsyncUtil
可以使用@Permission("Async")来引入AsyncUtil对象。
```
@Permission("Async")
contract AsyncExample{
export function longTimeTask(arg){
var a = {
};
a.count = 100;
AsyncUtil.postFunction(taskFun,a);
}
function taskFun(arg){
Global.progress = 0;
for (var i=0;i<arg.count;i++){
AsyncUtil.sleep(100);
Global.progress++;
}
}
export function getProgress(arg){
return Global.progress;
}
}
```
#### postFunction
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | arg0 | ScriptFunction |
| 2 | arg1 | 对象 |
##### 使用示例
```javascript
var ret = AsyncUtil.postFunction(a,{"a":"b"});
```
#### setInterval
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | arg0 | ScriptFunction |
| 2 | arg1 | long |
| 3 | arg2 | long |
| 4 | arg3 | 对象 |
##### 使用示例
```javascript
var ret = AsyncUtil.setInterval(a,100,1000,"abc");
```
#### setTimeOut
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | arg0 | ScriptFunction |
| 2 | arg1 | long |
| 3 | arg2 | Object |
##### 使用示例
```javascript
var ret = AsyncUtil.setTimeOut(a,100,"abc");
```
#### sleep
##### 参数
| 序号 | 参数 | 说明 |
|---|---|---|
| 1 | arg0 | long |
##### 使用示例
```javascript
var ret = AsyncUtil.sleep();
```
## ECMA5 Build-in Objects
YJS支持ECMAScript6的部分内置对象
* String <https://www.w3schools.com/js/js_strings.asp>
* Number <https://www.w3schools.com/js/js_numbers.asp>
* Math <https://www.w3schools.com/js/js_math.asp>
* Date <https://www.w3schools.com/js/js_dates.asp>
* RegExp <https://www.w3schools.com/js/js_regexp.asp>
* Error <https://www.w3schools.com/js/js_errors.asp>
* JSON <https://www.w3schools.com/js/js_json.asp>