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

30 KiB
Raw Blame History

YJS SDK

YJS Build-in API

内置对象 Global

内置对象 requester

该内置对象在export function里面会有值仅当合约调用签名验证通过。

执行合约 executeContract

参数:

action:executeContract; 
contractID:合约的id或名称均可
operation:调用合约的方法名;
arg: 参数格式为JSON字符串有action与arg两个字段。

可选参数:

requestID:字符串类型自行生成用于查询hash

使用示例:


 function testExecutorContract(arg){
    var ret = JSON.parse(executeContract("ElemeProvider","queryDB",arg));
    if (ret.status == "Success"){
      return JSON.parse(ret.result);
    }else return null;
  }

订阅事件主题 subscribe

参数

contractID字符串类型 合约id或名称均可。
event字符串类型
handler方法名该方法必须接受Event内含字段topic和content类型的唯一变量为参数可以不是export方法

使用示例:

export function init(arg) {
    YancloudUtil.subscribe("topic", handler);
    print("Handler: " + handler);
}

function handler(e) {
    print("topic: " + e.topic);
    print("content: " + e.content);
}

发布事件 pubEvent

参数

topic字符串类型发布的事件主题
content字符串类型发布的事件内容

使用示例:

export function pub1(arg) {
    YancloudUtil.pubEvent("topic", arg);
    return "done";
}

也可以在合约开头声明事件,则事件名即为事件主题,此时可直接使用事件作为方法名发布事件

event topic;
export function pub2(arg) {
    topic(arg);
    return "done";
}

该写法与上面的pub1等价。

发布带语义事件 pubEventConstraint

参数

topic字符串类型发布的事件主题
content字符串类型发布的事件内容
semantics枚举类型作为字符串输入事件语义

事件语义参数

  • AT_LEAST_ONCE至少一次默认语义
  • AT_MOST_ONCE至多一次
  • ONLY_ONCE只有一次

使用示例:

export function pub1(arg) {
    YancloudUtil.pubEventConstraint("topic", arg, "AT_MOST_ONCE");
    return "done";
}

也可以在合约开头声明事件,则事件名即为事件主题,此时可直接使用事件作为方法名按声明的语义发布事件

event AT_MOST_ONCE topic;
export function pub2(arg) {
    topic(arg);
    return "done";
}

该写法与上面的pub1等价。

事先声明的事件无论是否声明语义都可以用后缀s作为方法名的方式调用发布任意语义的事件

event topic;
export function pub3(arg) {
    topics(arg, "AT_MOST_ONCE");
    return "done";
}

该写法与上面的pub1, pub2等价。

不带事件语义声明事件时语义默认为至少一次AT_LEAST_ONCE

访问资源文件

通过Global.Resources去加载ypk内部的资源文件。

loadAsInputStream

参数:

path字符串类型 需要加载文件的地址

使用示例:

var file = Global.Resources.loadAsInputStream("/deleteit.txt");

loadAsScanner

参数:

path字符串类型 需要加载文件的地址

使用示例:

var scanner = Global.Resources.loadAsScanner("/local.txt");

YancloudUtil

提供了一些内置的工具方法。

getKeyPair

参数:

使用示例:

var keyPair = YancloudUtil.getKeyPair();
//该类型为SM2KeyPair类型
print(keyPair.getPublicKeyStr());
print(keyPair.getPrivateKeyStr());
print(keyPair.toJson());

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

该注解可以修饰contractfunction。 设置日志存储的位置。参数中指定为“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

该注解可以修饰contractfunction。 传入合约及函数的简介可用于生成说明文档中关于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 
@word 单词  @cword 中文单词
@first @last 英文姓,名
@cfirst @clast @cname 中文姓,名,全名
@url @domin @ip @email 
@region @province @city @county 地区,省,市,县
……
详细格式可以参考http://mockjs.com/examples.html

####注意:模板的格式为{result:模板}

//返回一个对象包含如下字段
@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);
}

@Cost

该注解可以修饰function。 提供函数的cpu计量功能。

@Cost({"countGas":true})
export function ....


IO工具类

概览

IO工具类名称 说明
FileUtil 文件操作相关的类
LedgerUtil 账本操作相关的类
HttpUtil Http接口相关的类
DOIPUtil DoIP相关的类
MySQLUtil 连接mysql数据库
MongoDBUtil MongoDB连接相关的类
RocksDBUtil RocksDB基于本地文件的k-v数据库
BDWareTimeSeriesDBUtil 基于本地文件的时间序列数据库

FileUtil

可以使用@Permission("File")来引入FileUtil对象。

@Permission("File")
contract FileSample {
...
}

该对象支持以下方法:

copyTo

可以复制文件和目录。第一个参数是source第二个参数是destination。

参数
序号 参数 说明
1 src 类型为String
2 dest 类型为String
使用示例
var ret = FileUtil.copyTo("./source.txt","./dest.txt");

getContent

获取文件的文本内容,当文件不存在时,返回undefined

参数
序号 参数 说明
1 path 类型为String
使用示例
var ret = FileUtil.getContent("./source.txt");

getDir

获取文件所在的文件夹名,输入参数为字符串。

参数
序号 参数 说明
1 path 类型为String
使用示例
var ret = FileUtil.getDir("./parent/src.txt");
// ret 为 "./parent/";

getFileName

获取文件名。输入参数为字符串。

参数
序号 参数 说明
1 path 类型为String
使用示例
var ret = FileUtil.getFileName("./parent/src.txt");
// ret 为 "src.txt"

openFileAsPrinter

以PrintStream的形式打开文件。 返回结果是java.io.PrintStream类型。

参数
序号 参数 说明
1 path 文件名类型为String
2 isAppend 类型为boolean表示是否往文件末尾添加
使用示例
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和端口两个字段
使用示例
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均为字符串类型
使用示例
// ... 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类型
使用示例
// ... 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
使用示例
var ret = HttpUtil.createAPIGate("192.168.4.4");
ret.get("com.tencent.mm","sendMsg","msg");
print(ret);

createAPIGate

配合手机的元邦使用当手机安装元邦且安装了API 接口后,可成为数据来源。

参数
序号 参数 说明
1 ip 字符串类型ip
2 port 字符串类型,端口
使用示例
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类型
使用示例
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为对象类型。
使用示例
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 字符串类型, 输入参数字符串
使用示例
var ret = DOIPUtil.call("86.5000.470/do.hello","inputString");

create

向一个Repository创建一个字符串类型DO

参数
序号 参数 说明
1 arg0 字符串类型, 目标Repo标识
2 arg1 对象类型,包括doID,doBody字段
使用示例
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标识
使用示例
var ret = DOIPUtil.delete("86.5000.470/do.hello","86.5000.470/repo.localTcpRepo");

hello

获取目标Repository的DOIP服务信息

参数
序号 参数 说明
1 arg0 字符串类型 目标Repo标识
使用示例
var ret = DOIPUtil.hello("86.5000.470/repo.localTcpRepo");

listOperation

获取目标DO支持的DOIP操作

参数
序号 参数 说明
1 arg0 字符串类型 目标DO标识
使用示例
var ret = DOIPUtil.listOperation("86.5000.470/do.hello");

register

向LHS注册一个DO返回分配的标识

参数
序号 参数 说明
1 arg0 字符串类型 DO所在Repo标识
2 arg1 字符串类型 DO格式描述字符串
使用示例
var ret = DOIPUtil.register("86.5000.470/repo.localTcpRepo","String");

reregister

修改LHS中DO的注册信息

参数
序号 参数 说明
1 arg0 字符串类型 目标DO标识
2 arg1 字符串类型 DO所在Repo标识
3 arg2 字符串类型 DO格式描述字符串
使用示例
var ret = DOIPUtil.reregister("86.5000.470/do.hello","86.5000.470/repo.localTcpRepo","String");

retrieve

获取一个DO

参数
序号 参数 说明
1 arg0 字符串类型 目标DO标识
使用示例
var ret = DOIPUtil.retrieve("86.5000.470/do.hello");

test

测试DOIPUtils是否可用

参数
序号 参数 说明
1 arg0 字符串类型 任意字符串
使用示例
var ret = DOIPUtil.test("hello");

update

更新目标DO

参数
序号 参数 说明
1 arg0 JS对象,包括doID,doBody字段
使用示例
var digitalObject = JSON.parse("{\"doID\":\"86.5000.470/do.hello\",\"doBody\":\"hello world\"}");
var ret = DOIPUtil.update(digitalObject);

SQLUtil

可以使用@Permission("SQL")来引入SQLUtil对象。 可支持MySQL/PostgreSQL/Oracle/GuassDB200等SQL数据库。 需要将对应的jdbc的jar上传到项目中。 例如要使用mysql可上传mysql-connector-java-8.0.24.jar

@Permission("SQL")
oracle MySQLExample{
...
}

initDriver

参数
序号 参数 说明
1 driverClass 字符串类型
使用示例
    //使用mysql
    SQLUtil.initDriver("com.mysql.cj.jdbc.Driver");
    //使用postgresql
    SQLUtil.initDriver("org.postgresql.Driver");
    //使用oracle
    SQLUtil.initDriver("oracle.jdbc.OracleDriver");

getConnection

参数
序号 参数 说明
1 URL 字符串类型jdbc连接
2 usrName 字符串类型,用户名
3 pwd 字符串类型,密码
使用示例
var url = "jdbc:mysql://xx.xx.xx:port/tableName";
var usrName = "xxx";
var pwd = "xxx";
//配置好用户名和密码url格式为ip或域名+端口,中间以”:”隔开。
var conn = SQLUtil.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类型

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

生成公私钥。

参数

无参数。

使用示例
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 字符串类型 公钥
使用示例
var ret = SM2Util.verify("Hello","....签名","...公钥");
// 验证通过时result为truestatus为success
// 失败时result为failedstatus为failed
print(ret.status);
print(ret.result);

encrypt

sm2加密。

参数
序号 参数 说明
1 content 字符串类型 待验签的内容
3 publicKey 字符串类型 公钥
使用示例
var ret = SM2Util.encrypt("Hello","...公钥");
print(ret);

decrypt

sm2解密。

参数
序号 参数 说明
1 content 字符串类型 待验签的内容
3 privateKey 字符串类型 公钥
使用示例
var ret = SM2Util.decrypt("Hello","...私钥");
print(ret);

多线程工具类

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 对象
使用示例
var ret = AsyncUtil.postFunction(a,{"a":"b"});

setInterval

参数
序号 参数 说明
1 arg0 ScriptFunction
2 arg1 long
3 arg2 long
4 arg3 对象
使用示例
var ret = AsyncUtil.setInterval(a,100,1000,"abc");

setTimeOut

参数
序号 参数 说明
1 arg0 ScriptFunction
2 arg1 long
3 arg2 Object
使用示例
var ret = AsyncUtil.setTimeOut(a,100,"abc");

sleep

参数
序号 参数 说明
1 arg0 long
使用示例
var ret = AsyncUtil.sleep();

ECMA5 Build-in Objects

YJS支持ECMAScript6的部分内置对象

YJS应用框架

ypk项目组成

如之前描述ypk中可存放静态资源文件html/css/js)在智能合约中声明loadResource方法可返回静态资源文件。 基于loadResource本项目提供了一个yjs应用框架。 该框架可以将合约ypk中的(html/css/js)文件通过executeContract调用加载至前端并展示。

函数约定

序号 合约函数名 说明
1 needRender 不会被调用,有该函数表示需要渲染前端
2 getMainFrame 无参数返回结果为String类型表示主页的html文件路径
3 loadResource 参数为String以文本形式返回相对路径下的静态资源文件

加载流程

前端加载的参数会解析至global.urlparam。 包括以下参数:

//global.urlparam对象示例
{
    "contract":"TrustedStorage0899",   //表示合约ID或是合约的名称
   
    "keys":{  //表示当前登录者的密钥对
        "privateKey":"ff38dd04710...",
        "publicKey":"04fc228..."
    },
    "nodeAddr":"022.node.internetapi.cn:21030" //节点的ip+端口
}

加载前会先建立与nodeAddr的websocket连接。 连接建立后,加载流程分为两步: 第一步是用当前的publickey-privatekey登录。登录过程详见BDContract SDK合约节点WebSocket接口 登录之后,会获取合约的信息。 并存放于global.currentContract对象。

第二步是根据global.currentContract对象中是否有needRender方法 如果有,就会进入加载前端代码的流程。 具体为1.执行executeCurrentContract("getMainFrame") 获取页面的htmlappend至mainDIV之后 会解析所有<script>,<link>等标签。2.会以标签中的fromContract属性去调用executeCurrentContract("loadResources")方法。 典型的yjs的loadResources方法如下。3.获取所有script会进行eval,link会当css加载。

//在某个yjs文件中声明。
  export function loadResource(arg){
    return Global.Resources.loadAsString(arg);
  }

前端加载流程图

前端框架预置函数说明

前端的javascript在html中已加载了jquery(使用$.)和vue2。 为避免冲突本版不支持再加载vue2/vue3脚本。 前端通过executeContract/executeCurrentContract与后端交互。

executeContract

调用某个合约的某个函数。会自动使用当前的global.sm2Key进行签名。参数说明及示例

executeContract(contracID,operation,arg,callback);
//其中contractID为string类型为被调用的合约名称/合约ID。
//operation为string类型合约函数
//arg为string类型表示参数
//callback为函数类型接受返回结果的回调函数。

executeCurrentContract

执行当前合约的某个函数。会自动使用当前的global.sm2Key进行签名。参数说明及示例

executeContract(operation,arg,callback);
//operation为string类型合约函数
//arg为string类型表示参数
//callback为函数类型接受返回结果的回调函数。