本文共 6164 字,大约阅读时间需要 20 分钟。
BigNumber 模块构建于 之上,用来处理任意精度的十进制和非十进制运算。合约可以直接使用 BigNumber 来处理交易和其他转账操作中涉及到的数值计算。
var value = new BigNumber(0);value.plus(1);…
storage 模块用来支持Nebulas上的数据持久化存储。功能上类似于传统的键值存储系统,当然存储不是免费的,需要消耗一定的 GAS。LocalContractStorage 是可以直接在合约中使用的内置storage对象,可存储的数据类型包括数字、字符串和 JavaScript 对象(需要序列化为字符串)。链上数据只能被存储它们的合约访问和修改。
LocalContractStorage 支持三个操作:set、get`和 del,分别实现存储、读取和删除数据功能:“use strict”;var BankVaultContract = function () { // nothing};BankVaultContract.prototype = { init: function() { // nothing }, set: function(name, value) { // name=”robin”, value=10000 LocalContractStorage.set(“name”, name); // put 操作相当于 set LocalContractStorage.put(“value”, value); }, get: function() { var name = LocalContractStorage.get(“name”); console.log(name); // 打印 ‘robin’ var value = LocalContractStorage.get(“value”); console.log(value); // 打印 ‘10000’ }, del: function() { var result = LocalContractStorage.del(“name”); console.log(result); // 打印 ‘robin’ // delete 操作相当于 del result = LocalContractStorage.delete(“value”); console.log(result); // 打印 ‘10000’ // 删除操作之后数据就不能被读取 }};module.exports = BankVaultContract;
除上述基本用法之外,LocalContractStorage还支持绑定以下两类链上存储空间到合约属性上:单值类型(storage property)和Map类型(storage map)。
只能存放一个值,对被绑定合约属性的读写都直接作用到LocalContractStorage 上。有两种方法可以定义这种绑定:
// 绑定一个单值存储空间到`obj` 上名为 `fieldName` 的属性 ,// descriptor定义了这个属性的序列化方法。//// 默认的 descriptor实现是 JSON.parse() 和 JSON.stringify()。// descriptor 为 ‘null’ 或 ‘undefined’时,默认 descriptor 将被使用。// return thisdefineProperty(obj, fieldName, [descriptor]);// 批量绑定多个单值存储空间到 `obj`// return thisdefineProperties(obj, { fieldName1: descriptor1, fieldName2: descriptor2});
通常我们会在初始化操作里完成绑定,如下所示:
“use strict”;var BankVaultContract = function () { // 因为传值为 ‘null’,将会使用默认的 descriptor实现(序列化方法) LocalContractStorage.defineProperty(this, “name1”, null); // 一个自定义的 `descriptor` 实现 // 在解析的时候返回 BigNumber 对象 LocalContractStorage.defineProperty(this, “value1”, { stringify: function (obj) { return obj.toString(); }, parse: function (str) { return new BigNumber(str); } }); // 用默认的序列化实现批量绑定 LocalContractStorage.defineProperties(this, { name2: null, value2: null });};module.exports = BankVaultContract;
之后,读写绑定的属性就如同直接访问LocalContractStorage:
BankVaultContract.prototype = { init: function(name, value) { // name=”robin”, value=1 this.name1 = name; this.value1 = value; }, testStorage: function(name, value) { // name=”ROBIN”, value=2 this.name2 = name; this.value2 = value; bool r = this.value1.lessThan(new BigNumber(0)); console.log(this.name1 + “:” + r); // robin:false console.log(this.name2 + “:” + this.value2); // ROBIN:2 }};
Nebulas 存储支持Map数据结构,有 del/delete、get 和 set/put这些操作,在遇到某些需要存储键值数据的场景时,就可以使用它。同样地,有两个方法来定义Map:
// 绑定单个map存储空间到名为`mapName`的合约属性,默认的 descriptor 实现和 defineProperty一样// 返回 thisdefineMapProperty(obj, mapName, [descriptor]);// 批量绑定// 返回 thisdefineMapProperties(obj, { mapName1: descriptor1, mapName2: descriptor2});
来看一个如何使用Map的例子:
‘use strict’;var BankVaultContract = function () { LocalContractStorage.defineMapProperty(this, “userMap”); LocalContractStorage.defineMapProperty(this, “userBalanceMap”, { stringify: function (obj) { return obj.toString(); }, parse: function (str) { return new BigNumber(str); } }); LocalContractStorage.defineMapProperties(this,{ key1Map: null, key2Map: null });};BankVaultContract.prototype = { init: function () { }, testStorage: function () { this.userMap.set(“robin”, “1”); this.userBalanceMap.set(“robin”,new BigNumber(1)); }, testRead: function () { // 读取和存储数据 var balance = this.userBalanceMap.get(“robin”); this.key1Map.set(“robin”, balance.toString()); this.key2Map.set(“robin”, balance.toString()); }};module.exports = BankVaultContract;
Blockchain 模块用来获取当前正在执行的合约内的交易和区块信息。另外,还提供了若干有用的方法,诸如从合约账户中转出 NAS,进行地址格式验证等。
返回:1 – 地址有效,0 – 地址无效
下面是用这个模块实现的简单实例:
‘use strict’;var BankVaultContract = function () {};BankVaultContract.prototype = { init: function () { console.log(‘init: Blockchain.block.height = ‘ + Blockchain.block.height); console.log(‘init: Blockchain.transaction.from = ‘ + Blockchain.transaction.from); }, transfer: function (address, value) { var result = Blockchain.transfer(address, value); console.log(“transfer result:”, result); }, verifyAddress: function (address) { var result = Blockchain.verifyAddress(address); console.log(“verifyAddress result:”, result); }};module.exports = BankVaultContract;
Event 模块用来记录在合约执行过程中产生的事件。被记录的事件存储在链上的事件Trie结构中,可以通过事件查询方法 获取所有事件。通过Event
模块输出的事件其最终Topic由用户自定义topic加固定前缀 chain.contract. 两部分构成 。使用方法如下:
Event.Trigger(topic, obj);· topic:用户定义的topic· obj:JSON 对象下面是示例:‘use strict’;var BankVaultContract = function () {};BankVaultContract.prototype = { init: function () {},testEvent: function() { // 实际被存储的topic是“chain.contract.topic” Event.Trigger(“topic“, { Data: {value: “Event test.” } }); }};module.exports = BankVaultContract;
console 模块提供了一个简单的调试控制台,类似于网页浏览器提供的 JavaScript 控制台。console 将把所有接收到的 args 以指定级别打印到 Nebulas Logger 上。
转载于:https://blog.51cto.com/634435/2117168