[关闭]
@zhenxi 2017-10-09T07:46:02.000000Z 字数 7596 阅读 3309

Asch SDK API 使用说明

Asch


1. 数据库

1.1 aync app.sdb.load(model, fields, indices)

无返回值, 出现错误时抛异常
将指定模型的数据加载到内存并建立索引, 这样可以提高查询和更新一个状态的效率
当一个数据模型需要频繁更新和查询时, 建议使用这个接口, 比如系统内置的账户余额、自增ID都使用了这个功能

示例:

  1. await app.sdb.load('Balance', app.model.Balance.fields(), [['address', 'currency']])
  2. await app.sdb.load('Variable', ['key', 'value'], ['key'])

1.2 app.sdb.get(model, cond)

返回一个数据项, 包含的字段为load时指定的字段
按指定条件查询内存中的数据, 如果该模型没有被载入内存, 会抛出异常; 查询条件包换未建索引的字段时也会抛出异常

示例:

  1. app.sdb.get('Variable', { key: 'foo' })
  2. /* output:
  3. {
  4. key: 'foo',
  5. value: 'bar'
  6. }
  7. */
  8. let balance = app.sdb.get('Balance', { address: 'foo', currency: 'XAS' })
  9. /* output:
  10. {
  11. address: 'foo',
  12. currency: 'XAS',
  13. balance: '1000000'
  14. }
  15. */

1.3 app.sdb.keys(model)

返回一个数据模型的全部索引字段

示例:

  1. let keys = app.sdb.keys('Variable')
  2. for (let i of keys) {
  3. console.log(i)
  4. }
  5. /* output:
  6. foo
  7. foo1
  8. foo2
  9. */

1.4 app.sdb.entries(model)

返回一个数据模型的所有缓存项

示例:

  1. let entries = app.sdb.entries('Variable')
  2. for (let [key, value] of entries) {
  3. console.log(key, value)
  4. }
  5. /* output:
  6. foo bar
  7. foo1 bar1
  8. foo2 bar2
  9. */

1.5 ap.sdb.lock(key)

无返回值
对一个key进行加锁, 有效期为一个区块间隔, 在同一个区块生命周期内不允许对一个key二次加锁, 否则会抛异常
该功能主要是为了解决对未确认数据的依赖问题。比如, 一个合约中需要对某账户设置昵称, 在这个合约调用被确认之前, 我们需要防止再次调用, 这种情况下可以使用加锁功能

示例:

  1. app.sdb.lock('AC3pinmvz9qX9cj6c7VrGigq7bpPxVJq85@nickname'

1.6 app.sdb.create(model, values)

无返回值
创建一个数据项, 如果该模型有缓存, 会实时更新缓存. 在区块确认后, 持久化到磁盘数据库

示例:

  1. app.sdb.create('Article', {
  2. title: 'This is an article title',
  3. content: 'article contents',
  4. author: 'qingfeng',
  5. tag: 'Science'
  6. })

1.7 app.sdb.replace(model, values)

无返回值
创建或更新一个数据项, 如果数据库中无此项则创建, 否则更新. 模型必须包含主键, values必须包含主键

示例:

  1. app.sdb.replace('Account', {
  2. address: 'AC3pinmvz9qX9cj6c7VrGigq7bpPxVJq85',
  3. nickname: 'Nakamoto'
  4. })

1.8 app.sdb.update(model, modifier, cond)

无返回值
按指定条件更新一个模型的若干个数据项

示例:

  1. app.sdb.update('Account', { nickname: 'Nakamoto' }, { nickname: 'Satoshi' })

1.9 app.sdb.increment(model, modifier, cond)

按指定条件增量更新一个模型的若干个数据项, 只能用于更新整数类型

示例:

  1. app.sdb.increment('Article', { votes: -10 }, { id: '10000' })
  2. app.sdb.increment('Article', { comments: 1 }, { id: '10000' })

1.10 app.sdb.del(model, cond)

无返回值
按条件删除一个模型中的数据项
删除操作的底层实现目前是标记为deleted, 默认的查询接口都会过滤掉被标记的数据, 但非标准接口或协议仍然可以获取到这些已经被删除的数据

示例:

  1. app.sdb.del('Article', { id: '100001' })

2. 余额

2.1 app.balances.get(address, currency)

获取指定账户、指定币种的余额

示例:

  1. app.balances.get('AC3pinmvz9qX9cj6c7VrGigq7bpPxVJq85', 'XAS')
  2. /* output:
  3. {
  4. address: 'AC3pinmvz9qX9cj6c7VrGigq7bpPxVJq85',
  5. currency: 'XAS',
  6. balance: '10000000'
  7. }
  8. */

2.2 app.balances.increase(address, currency, amount)

无返回值
增加指定账户、指定币种的余额

示例:

  1. app.balances.increase('AC3pinmvz9qX9cj6c7VrGigq7bpPxVJq85', 'XAS', '100000')

2.3 app.balances.decrease(address, currency, amount)

无返回值
减少指定账户、指定币种的余额

示例:

  1. app.balances.decrease('AC3pinmvz9qX9cj6c7VrGigq7bpPxVJq85', 'XAS', '100000')

2.4 app.balances.transfer(currency, amount, from, to)

无返回值
两个账户之间转移资产

示例:

  1. app.balances.transfer('XAS', '100000', 'AC3pinmvz9qX9cj6c7VrGigq7bpPxVJq85', 'A4MFPoF3c9vCzZ3GGf9sNQ3rDy2q8aXuVF')

3 数据模型

3.1 app.model[name]

返回一个模型的实例, 主要用于查询已确认的数据

3.2 fields()

返回该模型所有字段

3.3 count(cond)

返回Number
表示指定条件的数据项总数

示例:

  1. app.model.Block.count({ height: { $lt: 100 } })
  2. /* output:
  3. 99
  4. /*

3.4 exists(cond)

返回Boolean
表示指定条件的数据项是否存在

示例:

  1. app.model.Transaction.exists({ id: '9a5ec0669c79b9f5a1d5a4dbb2c200bc28c9ea829dbff71f41cbb2ad5a7d9b01' })
  2. /* output:
  3. false
  4. /*
  5. app.model.Account.exists({ nickname: 'Nakamoto' })
  6. /* output:
  7. true
  8. */

3.5 findOne(options)

options是一个对象, 包含以下元素

查询一个指定条件的数据项

示例:

  1. app.model.Account.findOne({ nickname: 'Nakamoto' })
  2. /* output:
  3. {
  4. address: 'AC3pinmvz9qX9cj6c7VrGigq7bpPxVJq85',
  5. nickname: 'Nakamoto',
  6. ...other values
  7. }
  8. */

3.6 findAll(options)

options是一个对象, 包含以下元素

查询指定条件的所有数据项

示例:

  1. app.model.Transfer.findAll({ senderId: 'AC3pinmvz9qX9cj6c7VrGigq7bpPxVJq85'})
  2. /* output:
  3. [
  4. {
  5. tid: "50e062f25946d220b924cb5ec6e52e260e44c9417d9f3c8ea041b704e06895f7",
  6. senderId: "AFnwUuET2XddPtqpFb2ns78CQEqc7KZ6vD",
  7. recipientId: "asdasdasd",
  8. currency: "CCTime.XCT",
  9. amount: "100000000",
  10. t_timestamp: 38660145,
  11. t_type: 3,
  12. t_height: 93953
  13. },
  14. {
  15. tid: "f15ce92add809b4a132936d514dce7fa7bdc15e850e7c026a001625b48595af3",
  16. senderId: "AFnwUuET2XddPtqpFb2ns78CQEqc7KZ6vD",
  17. recipientId: "asdasd",
  18. currency: "CCTime.XCT",
  19. amount: "100000000",
  20. t_timestamp: 38660096,
  21. t_type: 3,
  22. t_height: 93948
  23. }
  24. ]
  25. */

4. 路由

4.1 app.route.get(path, handler)

注册一个get类型的http请求处理函数

4.2 app.route.post(path, handler)

注册一个post类型的http请求处理函数

4.3 app.route.put(path, handler)

注册一个put类型的http请求处理函数

5. 费用池

5.1 app.feePool.add(currency, amount)

无返回值
将资产加入费用池(在每一个round结尾平均分给记账人)

示例:

  1. app.feelPool.add('XAS', '10000000')

6. 自增ID

6.1 app.autoID.get(name)

返回String
获取一个类型的当前最大ID

6.2 app.autoID.increment(name)

返回String
对指定类型的ID增加1并以字符串形式返回更新后的数值, 相当于原子的++1, 超大数也适用

示例:

  1. const AID = 'article_id'
  2. app.autoID.get(AID) === '0'
  3. app.autoID.increment(AID) === '1'
  4. app.autoID.get(AID) === '1'

7. 日志

7.1 app.logger.setLevel(level)

7.2 app.logger.log()

7.3 app.logger.trace()

7.4 app.logger.debug()

7.5 app.logger.info()

7.6 app.logger.warn()

7.7 app.logger.error()

示例:

  1. app.logger.setLevel('debug')
  2. app.logger.setLevel('info')
  3. logger.log('hello');
  4. logger.trace('hello', 'world');
  5. logger.debug('hello %s', 'world', 123);
  6. logger.info('hello %s %d', 'world', 123, {foo:'bar'});
  7. logger.warn('hello %s %d %j', 'world', 123, {foo:'bar'});
  8. logger.error('hello %s %d %j', 'world', 123, {foo:'bar'}, [1, 2, 3, 4], Object);

8. 工具类

8.1 app.validate(type, value)

验证一个数据是否符合规范, 不符合则抛出异常

示例:

  1. app.validate('amount', '10000') // pase
  2. app.validate('amount', 10000) // throws
  3. app.validate('amount', 'abc') // throws
  4. app.validate('amount', '1e10') // throws

8.2 app.registerContract(type, name)

无返回值
为合约注册一个数字类型, 未注册的合约无法被外部调用

示例:

  1. app.registerContract(1001, 'cctime.postArticle')

8.3 app.getContractName(type)

根据合约编号查询名称

示例:

  1. app.getContractName(1001) === 'cctime.postArticle'

8.4 app.registerFee(type, min, currency)

为一个合约注册最小费用, 不固定资产, 可通过currency参数指定收哪种资产作为手续费
min表示最小费用, 实际调用合约的时候, 费用不能小于min, 但可以大于, 超过的部分自动放入费用池

示例:

  1. app.registerFee(1001, '100000', 'XAS')

8.5 app.getFee(type)

获取指定合约的费用设定

示例:

  1. app.getFee(1001)
  2. /* output:
  3. {
  4. min: '100000',
  5. currency: 'XAS'
  6. }
  7. */

8.6 app.setDefaultFee(min, currency)

为系统的所有合约设置默认手续费

示例:

  1. app.setDefaultFee('10000', 'XAS')

8.7 app.getRealTime(epochTime)

返回完整的时间戳, 即区块创世时间加上偏移量, 单位为毫秒
Asch系统中底层存储和上层查询的时间戳均为一个偏移量, 并非实际时间戳, 可以调用这个函数转换为真实的时间戳

示例:

  1. app.getRealTime(4353634)

8.8 app.registerHook

// TBD

8.9 app.custom[]

应用的名字空间, 可用来保存应用本身自定义的一些全局变量, 主要是为了与系统级的全局变量进行隔离

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注