├── .gitignore
├── lib
├── base58check
│ ├── bs58.js
│ ├── index.js
│ └── base-x.js
├── constants.js
├── options.js
├── transactions
│ ├── delegate.js
│ ├── basic.js
│ ├── vote.js
│ ├── signature.js
│ ├── multisignature.js
│ ├── transfer.js
│ ├── uia.js
│ ├── dapp.js
│ ├── transaction.js
│ └── crypto.js
├── address.js
└── time
│ ├── slots.js
│ └── format.js
├── .travis.yml
├── index.js
├── package.json
├── README.md
└── test
└── tests.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .idea
3 | node_modules
4 | npm-debug.log
5 | package-lock.json
6 |
--------------------------------------------------------------------------------
/lib/base58check/bs58.js:
--------------------------------------------------------------------------------
1 | var basex = require('./base-x.js')
2 | var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
3 |
4 | module.exports = basex(ALPHABET)
--------------------------------------------------------------------------------
/lib/constants.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | fees:{
3 | send: 10000000,
4 | vote: 10000000,
5 | delegate: 10000000000,
6 | secondsignature: 500000000,
7 | multisignature: 500000000,
8 | dapp: 10000000000
9 | },
10 | coin: 100000000
11 | }
12 |
--------------------------------------------------------------------------------
/lib/options.js:
--------------------------------------------------------------------------------
1 | var optionMap = {
2 | clientDriftSeconds: 5
3 | }
4 |
5 | module.exports = {
6 | set: function (key, val) {
7 | optionMap[key] = val
8 | },
9 | get: function (key) {
10 | return optionMap[key]
11 | },
12 | getAll: function () {
13 | return optionMap
14 | }
15 | }
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | os:
2 | - linux
3 | language: node_js
4 | env:
5 | - CXX=g++-4.8
6 | node_js:
7 | - "6.0.0"
8 | - "7"
9 | notifications:
10 | recipients:
11 | - sqf1225@foxmail.com
12 | - i@yanyiwu.com
13 | email:
14 | on_success: change
15 | on_failure: always
16 | addons:
17 | apt:
18 | sources:
19 | - ubuntu-toolchain-r-test
20 | packages:
21 | - g++-4.8
22 |
--------------------------------------------------------------------------------
/lib/transactions/delegate.js:
--------------------------------------------------------------------------------
1 | var crypto = require("./crypto.js")
2 | var constants = require("../constants.js")
3 | var slots = require("../time/slots.js")
4 | var options = require('../options')
5 | var transaction = require('./transaction')
6 |
7 | function createDelegate(secret, secondSecret) {
8 | return transaction.createTransactionEx({
9 | type: 10,
10 | fee: 100 * 1e8,
11 | args: [],
12 | secret: secret,
13 | secondSecret: secondSecret
14 | })
15 | }
16 |
17 | module.exports = {
18 | createDelegate : createDelegate
19 | }
20 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | basic: require("./lib/transactions/basic.js"),
3 | crypto : require("./lib/transactions/crypto.js"),
4 | dapp: require("./lib/transactions/dapp.js"),
5 | transfer: require("./lib/transactions/transfer.js"),
6 | delegate : require("./lib/transactions/delegate.js"),
7 | signature : require("./lib/transactions/signature.js"),
8 | transaction : require("./lib/transactions/transaction.js"),
9 | vote : require("./lib/transactions/vote.js"),
10 | uia: require("./lib/transactions/uia.js"),
11 | options: require("./lib/options.js"),
12 | utils: {
13 | slots: require("./lib/time/slots.js"),
14 | format: require("./lib/time/format.js")
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/lib/transactions/basic.js:
--------------------------------------------------------------------------------
1 | var transaction = require('./transaction.js')
2 |
3 | function calculateFee(username){
4 | let len = username.length
5 | if (len === 2) {
6 | return 200
7 | } else if (len === 3) {
8 | return 100
9 | } else if (len === 4) {
10 | return 80
11 | } else if (len === 5) {
12 | return 40
13 | } else if (len <= 10) {
14 | return 10
15 | }
16 | return 1
17 | }
18 |
19 | function setName(username, secret, secondSecret) {
20 | return transaction.createTransactionEx({
21 | type: 2,
22 | fee: calculateFee(username) * 1e8,
23 | secret: secret,
24 | secondSecret: secondSecret,
25 | args: [username]
26 | })
27 | }
28 |
29 | module.exports = {
30 | setName: setName
31 | }
32 |
--------------------------------------------------------------------------------
/lib/transactions/vote.js:
--------------------------------------------------------------------------------
1 | var crypto = require("./crypto.js")
2 | var constants = require("../constants.js")
3 | var slots = require("../time/slots.js")
4 | var options = require('../options')
5 | var transaction = require('./transaction')
6 |
7 | function createVote(keyList, secret, secondSecret) {
8 | return transaction.createTransactionEx({
9 | type: 11,
10 | fee: 0.1 * 1e8,
11 | args: keyList,
12 | secret: secret,
13 | secondSecret: secondSecret
14 | })
15 | }
16 |
17 | function deleteVote(keyList, secret, secondSecret) {
18 | return transaction.createTransactionEx({
19 | type: 12,
20 | fee: 0.1 * 1e8,
21 | args: keyList,
22 | secret: secret,
23 | secondSecret: secondSecret
24 | })
25 | }
26 |
27 | module.exports = {
28 | createVote: createVote,
29 | deleteVote: deleteVote
30 | }
31 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "asch-js",
3 | "version": "1.4.2",
4 | "description": "asch javascript library",
5 | "main": "index.js",
6 | "directories": {
7 | "test": "test"
8 | },
9 | "scripts": {
10 | "test": "mocha test",
11 | "build": "browserify build.js -o browserify-asch.js && uglifyjs browserify-asch.js > browserify-asch-min.js"
12 | },
13 | "keywords": [
14 | "asch",
15 | "js",
16 | "library"
17 | ],
18 | "author": "sqf1225@foxmail.com",
19 | "license": "ISC",
20 | "dependencies": {
21 | "JSONStream": "=1.3.1",
22 | "browserify-bignum": "=1.3.0-2",
23 | "buffer": "=4.7.0",
24 | "bytebuffer": "=5.0.1",
25 | "fast-sha256": "=1.0.0",
26 | "ripemd160": "=2.0.1",
27 | "through2": "=2.0.3",
28 | "tweetnacl": "=1.0.0"
29 | },
30 | "devDependencies": {
31 | "browserify": "^13.1.0",
32 | "mocha": "^3.4.2",
33 | "should": "^9.0.2",
34 | "uglify-es": "github:mishoo/UglifyJS2#harmony"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/lib/transactions/signature.js:
--------------------------------------------------------------------------------
1 | var crypto = require("./crypto.js")
2 | var constants = require("../constants.js")
3 | var slots = require("../time/slots.js")
4 | var options = require('../options')
5 |
6 | function newSignature(secondSecret) {
7 | var keys = crypto.getKeys(secondSecret);
8 |
9 | var signature = {
10 | publicKey: keys.publicKey
11 | };
12 |
13 | return signature;
14 | }
15 |
16 | function createSignature(secret, secondSecret) {
17 | var keys = crypto.getKeys(secret);
18 |
19 | var signature = newSignature(secondSecret);
20 | var transaction = {
21 | type: 1,
22 | amount: 0,
23 | fee: constants.fees.secondsignature,
24 | recipientId: null,
25 | senderPublicKey: keys.publicKey,
26 | timestamp: slots.getTime() - options.get('clientDriftSeconds'),
27 | asset: {
28 | signature: signature
29 | }
30 | };
31 |
32 | crypto.sign(transaction, keys);
33 | transaction.id = crypto.getId(transaction);
34 |
35 | return transaction;
36 | }
37 |
38 | module.exports = {
39 | createSignature: createSignature
40 | }
41 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/AschPlatform/asch-js)
2 | [](http://github.com/AschPlatform)
3 | [](http://AschPlatform.mit-license.org)
4 | [](https://www.npmjs.org/package/asch-js)
5 | [](https://www.npmjs.org/package/asch-js)
6 | - - -
7 |
8 | # Asch Javascript Library
9 |
10 | ## Install
11 |
12 | ```
13 | npm install asch-js
14 | ```
15 |
16 | ## Import
17 |
18 | CommonJS
19 |
20 | ```
21 | var AschJS = require('asch-js');
22 | ```
23 |
24 | Front end
25 |
26 | ```
27 |
28 | # or
29 |
30 |
31 | console.log(window.AschJS)
32 | ```
33 |
34 |
35 |
36 | ## Usage
37 |
38 | Please reference the [asch http interface documents](https://github.com/AschPlatform/asch/blob/master/docs/asch_http_interface.md)
39 |
--------------------------------------------------------------------------------
/lib/address.js:
--------------------------------------------------------------------------------
1 | var sha256 = require('fast-sha256')
2 | var RIPEMD160 = require('ripemd160')
3 | var base58check = require('./base58check')
4 |
5 | const NORMAL_PREFIX = 'A' // A
6 |
7 | module.exports = {
8 | isAddress: function (address) {
9 | if (typeof address !== 'string') {
10 | return false
11 | }
12 | if (!/^[0-9]{1,20}$/g.test(address)) {
13 | if (!base58check.decodeUnsafe(address.slice(1))) {
14 | return false
15 | }
16 | if (['A'].indexOf(address[0]) == -1) {
17 | return false
18 | }
19 | }
20 | return true
21 | },
22 |
23 | isBase58CheckAddress: function (address) {
24 | if (typeof address !== 'string') {
25 | return false
26 | }
27 | if (!base58check.decodeUnsafe(address.slice(1))) {
28 | return false
29 | }
30 | if (['A'].indexOf(address[0]) == -1) {
31 | return false
32 | }
33 | return true
34 | },
35 |
36 | generateBase58CheckAddress: function (publicKey) {
37 | if (typeof publicKey === 'string') {
38 | publicKey = Buffer.from(publicKey, 'hex')
39 | }
40 | var h1 = sha256.hash(publicKey)
41 | var h2 = new RIPEMD160().update(Buffer.from(h1)).digest()
42 | return NORMAL_PREFIX + base58check.encode(h2)
43 | },
44 | }
--------------------------------------------------------------------------------
/lib/transactions/multisignature.js:
--------------------------------------------------------------------------------
1 | var crypto = require("./crypto.js")
2 | var constants = require("../constants.js")
3 | var slots = require("../time/slots.js")
4 | var options = require('../options')
5 |
6 | function signTransaction(trs, secret) {
7 | var keys = crypto.getKeys(secret);
8 | var signature = crypto.sign(trs, keys);
9 |
10 | return signature;
11 | }
12 |
13 | function createMultisignature(keysgroup, lifetime, min, secret, secondSecret) {
14 | var keys = crypto.getKeys(secret);
15 |
16 | var transaction = {
17 | type: 4,
18 | amount: 0,
19 | fee: constants.fees.multisignature,
20 | recipientId: null,
21 | senderPublicKey: keys.publicKey,
22 | timestamp: slots.getTime() - options.get('clientDriftSeconds'),
23 | asset: {
24 | multisignature: {
25 | min: min,
26 | lifetime: lifetime,
27 | keysgroup: keysgroup
28 | }
29 | }
30 | };
31 |
32 | crypto.sign(transaction, keys);
33 |
34 | if (secondSecret) {
35 | var secondKeys = crypto.getKeys(secondSecret);
36 | crypto.secondSign(transaction, secondKeys);
37 | }
38 |
39 | transaction.id = crypto.getId(transaction);
40 | return transaction;
41 | }
42 |
43 | module.exports = {
44 | createMultisignature : createMultisignature,
45 | signTransaction: signTransaction
46 | }
47 |
--------------------------------------------------------------------------------
/lib/transactions/transfer.js:
--------------------------------------------------------------------------------
1 | var crypto = require("./crypto.js")
2 | var constants = require("../constants.js")
3 | var slots = require("../time/slots.js")
4 | var options = require('../options')
5 | var transaction = require('./transaction')
6 |
7 | function createInTransfer(dappName, currency, amount, secret, secondSecret) {
8 | return transaction.createTransactionEx({
9 | type: 204,
10 | fee: 0.1 * 1e8,
11 | args: [dappName, currency, amount],
12 | secret,
13 | secondSecret: secondSecret
14 | })
15 | }
16 |
17 | function createOutTransfer(address, chain, recipient, currency, amount, wid, seq) {
18 | var transaction = {
19 | type: 205,
20 | fee: 10000000,
21 | senderId: address,
22 | timestamp: slots.getTime() - options.get('clientDriftSeconds'),
23 | args: [
24 | chain,
25 | recipient,
26 | currency,
27 | amount,
28 | wid,
29 | seq
30 | ]
31 | };
32 | return transaction;
33 | }
34 |
35 | function signOutTransfer(transaction, secret) {
36 | var keys = crypto.getKeys(secret);
37 | var signature = crypto.sign(transaction, keys);
38 |
39 | return keys.publicKey + signature;
40 | }
41 |
42 | module.exports = {
43 | createInTransfer: createInTransfer,
44 | createOutTransfer: createOutTransfer,
45 | signOutTransfer: signOutTransfer
46 | }
--------------------------------------------------------------------------------
/lib/base58check/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | var sha256 = require('fast-sha256')
4 | var base58 = require('./bs58.js')
5 |
6 | // SHA256(SHA256(buffer))
7 | function sha256x2(buffer) {
8 | return Buffer.from(sha256.hash(sha256.hash(buffer)))
9 | }
10 |
11 | // Encode a buffer as a base58-check encoded string
12 | function encode(payload) {
13 | var checksum = sha256x2(payload)
14 | return base58.encode(Buffer.concat([
15 | payload,
16 | checksum
17 | ], payload.length + 4))
18 | }
19 |
20 | function decodeRaw(buffer) {
21 | var payload = buffer.slice(0, -4)
22 | var checksum = buffer.slice(-4)
23 | var newChecksum = sha256x2(payload)
24 |
25 | if (checksum[0] ^ newChecksum[0] |
26 | checksum[1] ^ newChecksum[1] |
27 | checksum[2] ^ newChecksum[2] |
28 | checksum[3] ^ newChecksum[3]) return
29 |
30 | return payload
31 | }
32 |
33 | // Decode a base58-check encoded string to a buffer, no result if checksum is wrong
34 | function decodeUnsafe(string) {
35 | var buffer = base58.decodeUnsafe(string)
36 | if (!buffer) return
37 |
38 | return decodeRaw(buffer)
39 | }
40 |
41 | function decode(string) {
42 | var buffer = base58.decode(string)
43 | var payload = decodeRaw(buffer)
44 | if (!payload) throw new Error('Invalid checksum')
45 | return payload
46 | }
47 |
48 | module.exports = {
49 | encode: encode,
50 | decode: decode,
51 | decodeUnsafe: decodeUnsafe
52 | }
53 |
--------------------------------------------------------------------------------
/lib/time/slots.js:
--------------------------------------------------------------------------------
1 | function getEpochTime(time) {
2 | if (time === undefined) {
3 | time = (new Date()).getTime();
4 | }
5 | var d = beginEpochTime();
6 | var t = d.getTime();
7 | return Math.floor((time - t) / 1000);
8 | }
9 |
10 | function beginEpochTime() {
11 | var d = new Date(Date.UTC(2016, 5, 27, 20, 0, 0, 0))
12 |
13 | return d;
14 | }
15 |
16 | var interval = 10,
17 | delegates = 101;
18 |
19 | function getTime(time) {
20 | return getEpochTime(time);
21 | }
22 |
23 | function getRealTime(epochTime) {
24 | if (epochTime === undefined) {
25 | epochTime = getTime()
26 | }
27 | var d = beginEpochTime();
28 | var t = Math.floor(d.getTime() / 1000) * 1000;
29 | return t + epochTime * 1000;
30 | }
31 |
32 | function getSlotNumber(epochTime) {
33 | if (epochTime === undefined) {
34 | epochTime = getTime()
35 | }
36 |
37 | return Math.floor(epochTime / interval);
38 | }
39 |
40 | function getSlotTime(slot) {
41 | return slot * interval;
42 | }
43 |
44 | function getNextSlot() {
45 | var slot = getSlotNumber();
46 |
47 | return slot + 1;
48 | }
49 |
50 | function getLastSlot(nextSlot) {
51 | return nextSlot + delegates;
52 | }
53 |
54 | module.exports = {
55 | interval: interval,
56 | delegates: delegates,
57 | getTime: getTime,
58 | getRealTime: getRealTime,
59 | getSlotNumber: getSlotNumber,
60 | getSlotTime: getSlotTime,
61 | getNextSlot: getNextSlot,
62 | getLastSlot: getLastSlot,
63 | beginEpochTime: beginEpochTime
64 | }
65 |
--------------------------------------------------------------------------------
/lib/transactions/uia.js:
--------------------------------------------------------------------------------
1 | var ByteBuffer = require('bytebuffer')
2 | var crypto = require("./crypto.js")
3 | var constants = require("../constants.js")
4 | var slots = require("../time/slots.js")
5 | var options = require('../options')
6 | var transaction = require('./transaction')
7 |
8 | function createIssuer (name, desc, secret, secondSecret) {
9 | return transaction.createTransactionEx({
10 | type: 100,
11 | fee: 100 * 1e8,
12 | args: [ name, desc ],
13 | secret: secret,
14 | secondSecret: secondSecret
15 | })
16 | }
17 |
18 | function createAsset(name, desc, maximum, precision, secret, secondSecret) {
19 | return transaction.createTransactionEx({
20 | type: 101,
21 | fee: 500 * 1e8,
22 | args: [ name, desc, maximum, precision ],
23 | secret: secret,
24 | secondSecret: secondSecret
25 | })
26 | }
27 |
28 |
29 | function createIssue(currency, amount, secret, secondSecret) {
30 | return transaction.createTransactionEx({
31 | type: 102,
32 | fee: 0.1 * 1e8,
33 | args: [ currency, amount ],
34 | secret: secret,
35 | secondSecret: secondSecret
36 | })
37 | }
38 |
39 | function createTransfer(currency, amount, recipientId, message, secret, secondSecret) {
40 | return transaction.createTransactionEx({
41 | type: 103,
42 | fee: 0.1 * 1e8,
43 | args: [currency, amount, recipientId],
44 | secret,
45 | secondSecret,
46 | message
47 | })
48 | }
49 |
50 | module.exports = {
51 | createIssuer: createIssuer,
52 | createAsset: createAsset,
53 | createIssue: createIssue,
54 | createTransfer: createTransfer
55 | }
56 |
--------------------------------------------------------------------------------
/lib/transactions/dapp.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert')
2 | var ByteBuffer = require('bytebuffer')
3 | var crypto = require("./crypto.js")
4 | var constants = require("../constants.js")
5 | var slots = require("../time/slots.js")
6 | var globalOptions = require('../options.js')
7 | var transaction = require('./transaction.js')
8 |
9 | function createDApp(options, secret, secondSecret) {
10 | return transaction.createTransactionEx({
11 | type: 200,
12 | fee: 100 * 1e8,
13 | secret: secret,
14 | secondSecret: secondSecret,
15 | args: [
16 | options.name,
17 | options.desc,
18 | options.link,
19 | options.icon,
20 | options.delegates,
21 | options.unlockDelegates
22 | ]
23 | })
24 | }
25 |
26 | function getDAppTransactionBytes(trs, skipSignature) {
27 | var bb = new ByteBuffer(1, true);
28 | bb.writeInt(trs.timestamp);
29 | bb.writeString(trs.fee)
30 |
31 | var senderPublicKeyBuffer = new Buffer(trs.senderPublicKey, 'hex');
32 | for (var i = 0; i < senderPublicKeyBuffer.length; i++) {
33 | bb.writeByte(senderPublicKeyBuffer[i]);
34 | }
35 |
36 | bb.writeInt(trs.type)
37 |
38 | assert(Array.isArray(trs.args))
39 | bb.writeString(JSON.stringify(trs.args))
40 |
41 | if (!skipSignature && trs.signature) {
42 | var signatureBuffer = new Buffer(trs.signature, 'hex');
43 | for (var i = 0; i < signatureBuffer.length; i++) {
44 | bb.writeByte(signatureBuffer[i]);
45 | }
46 | }
47 | bb.flip();
48 | return bb.toBuffer()
49 | }
50 |
51 | function createInnerTransaction(options, secret) {
52 | var keys = crypto.getKeys(secret)
53 | var args = options.args
54 | if (typeof args === 'string') args = JSON.parse(args)
55 | var trs = {
56 | fee: options.fee,
57 | timestamp: slots.getTime() - globalOptions.get('clientDriftSeconds'),
58 | senderPublicKey: keys.publicKey,
59 | type: options.type,
60 | args: args
61 | }
62 | trs.signature = crypto.signBytes(getDAppTransactionBytes(trs), keys)
63 | return trs
64 | }
65 |
66 | module.exports = {
67 | createDApp: createDApp,
68 | createInnerTransaction: createInnerTransaction
69 | }
70 |
--------------------------------------------------------------------------------
/lib/time/format.js:
--------------------------------------------------------------------------------
1 | var slots = require('./slots.js');
2 |
3 | function timeAgo(time) {
4 | var d = slots.beginEpochTime();
5 | var t = parseInt(d.getTime() / 1000);
6 |
7 | time = new Date((time + t) * 1000);
8 |
9 | var currentTime = new Date().getTime();
10 | var diffTime = (currentTime - time.getTime()) / 1000;
11 |
12 | if (diffTime < 60) {
13 | return Math.floor(diffTime) + ' sec ago';
14 | }
15 | if (Math.floor(diffTime / 60) <= 1) {
16 | return Math.floor(diffTime / 60) + ' min ago';
17 | }
18 | if ((diffTime / 60) < 60) {
19 | return Math.floor(diffTime / 60) + ' mins ago';
20 | }
21 | if (Math.floor(diffTime / 60 / 60) <= 1) {
22 | return Math.floor(diffTime / 60 / 60) + ' hour ago';
23 | }
24 | if ((diffTime / 60 / 60) < 24) {
25 | return Math.floor(diffTime / 60 / 60) + ' hours ago';
26 | }
27 | if (Math.floor(diffTime / 60 / 60 / 24) <= 1) {
28 | return Math.floor(diffTime / 60 / 60 / 24) + ' day ago';
29 | }
30 | if ((diffTime / 60 / 60 / 24) < 30) {
31 | return Math.floor(diffTime / 60 / 60 / 24) + ' days ago';
32 | }
33 | if (Math.floor(diffTime / 60 / 60 / 24 / 30) <= 1) {
34 | return Math.floor(diffTime / 60 / 60 / 24 / 30) + ' month ago';
35 | }
36 | if ((diffTime / 60 / 60 / 24 / 30) < 12) {
37 | return Math.floor(diffTime / 60 / 60 / 24 / 30) + ' months ago';
38 | }
39 | if (Math.floor((diffTime / 60 / 60 / 24 / 30 / 12)) <= 1) {
40 | return Math.floor(diffTime / 60 / 60 / 24 / 30 / 12) + ' year ago';
41 | }
42 |
43 | return Math.floor(diffTime / 60 / 60 / 24 / 30 / 12) + ' years ago';
44 | }
45 |
46 | function fullTimestamp(time) {
47 | var d = slots.beginEpochTime();
48 | var t = parseInt(d.getTime() / 1000);
49 |
50 | d = new Date((time + t) * 1000);
51 | var month = d.getMonth() + 1;
52 |
53 | if (month < 10) {
54 | month = "0" + month;
55 | }
56 |
57 | var day = d.getDate();
58 |
59 | if (day < 10) {
60 | day = "0" + day;
61 | }
62 |
63 | var h = d.getHours();
64 | var m = d.getMinutes();
65 | var s = d.getSeconds();
66 |
67 | if (h < 10) {
68 | h = "0" + h;
69 | }
70 |
71 | if (m < 10) {
72 | m = "0" + m;
73 | }
74 |
75 | if (s < 10) {
76 | s = "0" + s;
77 | }
78 |
79 | return d.getFullYear() + "/" + month + "/" + day + " " + h + ":" + m + ":" + s;
80 | }
81 |
82 | module.exports = {
83 | timeAgo: timeAgo,
84 | fullTimestamp: fullTimestamp
85 | }
--------------------------------------------------------------------------------
/lib/base58check/base-x.js:
--------------------------------------------------------------------------------
1 | // base-x encoding
2 | // Forked from https://github.com/cryptocoinjs/bs58
3 | // Originally written by Mike Hearn for BitcoinJ
4 | // Copyright (c) 2011 Google Inc
5 | // Ported to JavaScript by Stefan Thomas
6 | // Merged Buffer refactorings from base58-native by Stephen Pair
7 | // Copyright (c) 2013 BitPay Inc
8 |
9 | module.exports = function base (ALPHABET) {
10 | var ALPHABET_MAP = {}
11 | var BASE = ALPHABET.length
12 | var LEADER = ALPHABET.charAt(0)
13 |
14 | // pre-compute lookup table
15 | for (var z = 0; z < ALPHABET.length; z++) {
16 | var x = ALPHABET.charAt(z)
17 |
18 | if (ALPHABET_MAP[x] !== undefined) throw new TypeError(x + ' is ambiguous')
19 | ALPHABET_MAP[x] = z
20 | }
21 |
22 | function encode (source) {
23 | if (source.length === 0) return ''
24 |
25 | var digits = [0]
26 | for (var i = 0; i < source.length; ++i) {
27 | for (var j = 0, carry = source[i]; j < digits.length; ++j) {
28 | carry += digits[j] << 8
29 | digits[j] = carry % BASE
30 | carry = (carry / BASE) | 0
31 | }
32 |
33 | while (carry > 0) {
34 | digits.push(carry % BASE)
35 | carry = (carry / BASE) | 0
36 | }
37 | }
38 |
39 | var string = ''
40 |
41 | // deal with leading zeros
42 | for (var k = 0; source[k] === 0 && k < source.length - 1; ++k) string += ALPHABET[0]
43 | // convert digits to a string
44 | for (var q = digits.length - 1; q >= 0; --q) string += ALPHABET[digits[q]]
45 |
46 | return string
47 | }
48 |
49 | function decodeUnsafe (string) {
50 | if (string.length === 0) return Buffer.allocUnsafe(0)
51 |
52 | var bytes = [0]
53 | for (var i = 0; i < string.length; i++) {
54 | var value = ALPHABET_MAP[string[i]]
55 | if (value === undefined) return
56 |
57 | for (var j = 0, carry = value; j < bytes.length; ++j) {
58 | carry += bytes[j] * BASE
59 | bytes[j] = carry & 0xff
60 | carry >>= 8
61 | }
62 |
63 | while (carry > 0) {
64 | bytes.push(carry & 0xff)
65 | carry >>= 8
66 | }
67 | }
68 |
69 | // deal with leading zeros
70 | for (var k = 0; string[k] === LEADER && k < string.length - 1; ++k) {
71 | bytes.push(0)
72 | }
73 |
74 | return Buffer.from(bytes.reverse())
75 | }
76 |
77 | function decode (string) {
78 | var buffer = decodeUnsafe(string)
79 | if (buffer) return buffer
80 |
81 | throw new Error('Non-base' + BASE + ' character')
82 | }
83 |
84 | return {
85 | encode: encode,
86 | decodeUnsafe: decodeUnsafe,
87 | decode: decode
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/lib/transactions/transaction.js:
--------------------------------------------------------------------------------
1 | var crypto = require("./crypto.js")
2 | var constants = require("../constants.js")
3 | var slots = require("../time/slots.js")
4 | var options = require('../options')
5 |
6 | function calculateFee(amount) {
7 | var min = constants.fees.send;
8 | var fee = parseFloat((amount * 0.0001).toFixed(0));
9 | return fee < min ? min : fee;
10 | }
11 |
12 | function createTransaction(recipientId, amount, message, secret, secondSecret) {
13 | return createTransactionEx({
14 | type: 1,
15 | fee: 0.1 * 1e8,
16 | args: [amount, recipientId],
17 | secret,
18 | secondSecret: secondSecret,
19 | message
20 | })
21 | }
22 |
23 | function createLock(height, amount, secret, secondSecret) {
24 | return createTransactionEx({
25 | type: 4,
26 | fee: 0.1 * 1e8,
27 | args: [height, amount],
28 | secret: secret,
29 | secondSecret: secondSecret
30 | })
31 | }
32 |
33 | function unlock(secret, secondSecret) {
34 | return createTransactionEx({
35 | type: 5,
36 | fee: 0,
37 | args: [],
38 | secret: secret,
39 | secondSecret: secondSecret
40 | })
41 | }
42 |
43 | function createTransactionEx(params) {
44 | if (!params.secret) throw new Error('Secret needed')
45 | let keys = crypto.getKeys(params.secret)
46 | let transaction = {
47 | type: params.type,
48 | timestamp: slots.getTime() - options.get('clientDriftSeconds'),
49 | fee: params.fee,
50 | message: params.message,
51 | args: params.args,
52 | senderPublicKey: keys.publicKey,
53 | senderId: crypto.getAddress(keys.publicKey),
54 | signatures: []
55 | }
56 | transaction.signatures.push(crypto.sign(transaction, keys))
57 | if (params.secondSecret) {
58 | let secondKeys = crypto.getKeys(params.secondSecret);
59 | transaction.secondSignature = crypto.secondSign(transaction, secondKeys);
60 | }
61 | transaction.id = crypto.getId(transaction)
62 | return transaction
63 | }
64 |
65 | function createMultiSigTransaction(params) {
66 | var transaction = {
67 | type: params.type,
68 | fee: params.fee,
69 | senderId: params.senderId,
70 | requestId: params.requestId,
71 | mode: params.mode,
72 | timestamp: slots.getTime() - options.get('clientDriftSeconds'),
73 | args: params.args
74 | };
75 | return transaction;
76 | }
77 |
78 | function signMultiSigTransaction(transaction, secret) {
79 | var keys = crypto.getKeys(secret);
80 | var signature = crypto.sign(transaction, keys);
81 |
82 | return keys.publicKey + signature;
83 | }
84 |
85 | module.exports = {
86 | createTransaction: createTransaction,
87 | createTransactionEx: createTransactionEx,
88 | calculateFee: calculateFee,
89 | createLock: createLock,
90 | unlock: unlock,
91 | createMultiSigTransaction: createMultiSigTransaction,
92 | signMultiSigTransaction: signMultiSigTransaction
93 | }
94 |
--------------------------------------------------------------------------------
/lib/transactions/crypto.js:
--------------------------------------------------------------------------------
1 | var sha256 = require("fast-sha256");
2 | var addressHelper = require('../address.js')
3 |
4 | if (typeof Buffer === "undefined") {
5 | Buffer = require("buffer/").Buffer;
6 | }
7 |
8 | var ByteBuffer = require("bytebuffer");
9 | var bignum = require("browserify-bignum");
10 | var nacl = require('tweetnacl')
11 |
12 | var fixedPoint = Math.pow(10, 8);
13 |
14 | function getSignatureBytes(signature) {
15 | var bb = new ByteBuffer(32, true);
16 | var publicKeyBuffer = new Buffer(signature.publicKey, "hex");
17 |
18 | for (var i = 0; i < publicKeyBuffer.length; i++) {
19 | bb.writeByte(publicKeyBuffer[i]);
20 | }
21 |
22 | bb.flip();
23 | return new Uint8Array(bb.toArrayBuffer());
24 | }
25 |
26 | function toLocalBuffer(buf) {
27 | if (typeof window !== 'undefined') {
28 | return new Uint8Array(buf.toArrayBuffer())
29 | } else {
30 | return buf.toBuffer()
31 | }
32 | }
33 |
34 | function sha256Bytes(data) {
35 | return sha256.hash(data)
36 | }
37 |
38 | function sha256Hex(data) {
39 | return Buffer.from(sha256.hash(data)).toString('hex')
40 | }
41 |
42 | function getDAppBytes(dapp) {
43 | try {
44 | var buf = new Buffer([]);
45 | var nameBuf = new Buffer(dapp.name, "utf8");
46 | buf = Buffer.concat([buf, nameBuf]);
47 |
48 | if (dapp.description) {
49 | var descriptionBuf = new Buffer(dapp.description, "utf8");
50 | buf = Buffer.concat([buf, descriptionBuf]);
51 | }
52 |
53 | if (dapp.tags) {
54 | var tagsBuf = new Buffer(dapp.tags, "utf8");
55 | buf = Buffer.concat([buf, tagsBuf]);
56 | }
57 |
58 | if (dapp.link) {
59 | buf = Buffer.concat([buf, new Buffer(dapp.link, "utf8")]);
60 | }
61 |
62 | if (dapp.icon) {
63 | buf = Buffer.concat([buf, new Buffer(dapp.icon, "utf8")]);
64 | }
65 |
66 | var bb = new ByteBuffer(1, true);
67 | bb.writeInt(dapp.type);
68 | bb.writeInt(dapp.category);
69 | bb.writeString(dapp.delegates.join(','));
70 | bb.writeInt(dapp.unlockDelegates);
71 | bb.flip();
72 |
73 | buf = Buffer.concat([buf, bb.toBuffer()]);
74 | } catch (e) {
75 | throw Error(e.toString());
76 | }
77 |
78 | return buf;
79 | }
80 |
81 | function getInTransferBytes(inTransfer) {
82 | try {
83 | var buf = new Buffer([]);
84 | var dappId = new Buffer(inTransfer.dappId, "utf8");
85 | var currency = new Buffer(inTransfer.currency, "utf8")
86 | buf = Buffer.concat([buf, dappId, currency]);
87 | if (inTransfer.currency !== 'XAS') {
88 | var amount = new Buffer(inTransfer.amount, "utf8")
89 | buf = Buffer.concat([buf, amount])
90 | }
91 | } catch (e) {
92 | throw Error(e.toString());
93 | }
94 |
95 | return buf;
96 | }
97 |
98 | function getOutTransferBytes(outTransfer) {
99 | try {
100 | var buf = new Buffer([]);
101 | var dappIdBuf = new Buffer(outTransfer.dappId, 'utf8');
102 | var transactionIdBuff = new Buffer(outTransfer.transactionId, 'utf8');
103 | var currencyBuff = new Buffer(outTransfer.currency, 'utf8')
104 | var amountBuff = new Buffer(outTransfer.amount, 'utf8')
105 | buf = Buffer.concat([buf, dappIdBuf, transactionIdBuff, currencyBuff, amountBuff]);
106 | } catch (e) {
107 | throw Error(e.toString());
108 | }
109 |
110 | return buf;
111 | }
112 |
113 | function getBytes(trs, skipSignature, skipSecondSignature) {
114 | var bb = new ByteBuffer(1, true);
115 | bb.writeInt(trs.type);
116 | bb.writeInt(trs.timestamp);
117 | bb.writeLong(trs.fee);
118 | bb.writeString(trs.senderId)
119 | if (trs.requestorId) {
120 | bb.writeString(trs.requestorId)
121 | }
122 | if (trs.mode) {
123 | bb.writeInt(trs.mode)
124 | }
125 |
126 | if (trs.message) bb.writeString(trs.message);
127 | if (trs.args) {
128 | let args
129 | if (typeof trs.args === 'string') {
130 | args = trs.args
131 | } else if (Array.isArray(trs.args)) {
132 | args = JSON.stringify(trs.args)
133 | }
134 | bb.writeString(args)
135 | }
136 |
137 | if (!skipSignature && trs.signatures) {
138 | for (let signature of trs.signatures) {
139 | var signatureBuffer = new Buffer(signature, 'hex');
140 | for (var i = 0; i < signatureBuffer.length; i++) {
141 | bb.writeByte(signatureBuffer[i]);
142 | }
143 | }
144 | }
145 |
146 | if (!skipSecondSignature && trs.secondSignature) {
147 | var signSignatureBuffer = new Buffer(trs.secondSignature, 'hex');
148 | for (var i = 0; i < signSignatureBuffer.length; i++) {
149 | bb.writeByte(signSignatureBuffer[i]);
150 | }
151 | }
152 |
153 | bb.flip();
154 | return toLocalBuffer(bb);
155 | }
156 |
157 | function getId(transaction) {
158 | return sha256Hex(getBytes(transaction))
159 | }
160 | function getHash(transaction, skipSignature, skipSecondSignature) {
161 | return sha256Bytes(getBytes(transaction, skipSignature, skipSecondSignature))
162 | }
163 |
164 | function getFee(transaction) {
165 | switch (transaction.type) {
166 | case 0: // Normal
167 | return 0.1 * fixedPoint;
168 | break;
169 |
170 | case 1: // Signature
171 | return 100 * fixedPoint;
172 | break;
173 |
174 | case 2: // Delegate
175 | return 10000 * fixedPoint;
176 | break;
177 |
178 | case 3: // Vote
179 | return 1 * fixedPoint;
180 | break;
181 | }
182 | }
183 |
184 | function sign(transaction, keys) {
185 | var hash = getHash(transaction, true, true);
186 | var signature = nacl.sign.detached(hash, keys.keypair.secretKey);
187 |
188 | return new Buffer(signature).toString("hex");
189 | }
190 |
191 | function secondSign(transaction, keys) {
192 | var hash = getHash(transaction, true, true);
193 | var signature = nacl.sign.detached(hash, keys.keypair.secretKey);
194 | return new Buffer(signature).toString("hex")
195 | }
196 |
197 | function signBytes(bytes, keys) {
198 | var hash = sha256Bytes(new Buffer(bytes, 'hex'))
199 | var signature = nacl.sign.detached(hash, keys.keypair.secretKey);
200 | return new Buffer(signature).toString("hex");
201 | }
202 |
203 | function verify(transaction) {
204 | var remove = 64;
205 |
206 | if (transaction.signSignature) {
207 | remove = 128;
208 | }
209 |
210 | var bytes = getBytes(transaction);
211 | var data2 = new Buffer(bytes.length - remove);
212 |
213 | for (var i = 0; i < data2.length; i++) {
214 | data2[i] = bytes[i];
215 | }
216 |
217 | var hash = sha256Bytes(data2)
218 |
219 | var signatureBuffer = new Buffer(transaction.signature, "hex");
220 | var senderPublicKeyBuffer = new Buffer(transaction.senderPublicKey, "hex");
221 | var res = nacl.sign.detached.verify(hash, signatureBuffer, senderPublicKeyBuffer);
222 |
223 | return res;
224 | }
225 |
226 | function verifySecondSignature(transaction, publicKey) {
227 | var bytes = getBytes(transaction);
228 | var data2 = new Buffer(bytes.length - 64);
229 |
230 | for (var i = 0; i < data2.length; i++) {
231 | data2[i] = bytes[i];
232 | }
233 |
234 | var hash = sha256Bytes(data2)
235 |
236 | var signSignatureBuffer = new Buffer(transaction.signSignature, "hex");
237 | var publicKeyBuffer = new Buffer(publicKey, "hex");
238 | var res = nacl.sign.detached.verify(hash, signSignatureBuffer, publicKeyBuffer);
239 |
240 | return res;
241 | }
242 |
243 | function verifyBytes(bytes, signature, publicKey) {
244 | var hash = sha256Bytes(new Buffer(bytes, 'hex'))
245 | var signatureBuffer = new Buffer(signature, "hex");
246 | var publicKeyBuffer = new Buffer(publicKey, "hex");
247 | var res = nacl.sign.detached.verify(hash, signatureBuffer, publicKeyBuffer);
248 | return res
249 | }
250 |
251 | function getKeys(secret) {
252 | var hash = sha256Bytes(new Buffer(secret))
253 | var keypair = nacl.sign.keyPair.fromSeed(hash);
254 |
255 | return {
256 | keypair,
257 | publicKey: new Buffer(keypair.publicKey).toString("hex"),
258 | privateKey: new Buffer(keypair.secretKey).toString("hex")
259 | }
260 | }
261 |
262 | function getAddress(publicKey) {
263 | return addressHelper.generateBase58CheckAddress(publicKey)
264 | }
265 |
266 | module.exports = {
267 | getBytes: getBytes,
268 | getHash: getHash,
269 | getId: getId,
270 | getFee: getFee,
271 | sign: sign,
272 | secondSign: secondSign,
273 | getKeys: getKeys,
274 | getAddress: getAddress,
275 | verify: verify,
276 | verifySecondSignature: verifySecondSignature,
277 | fixedPoint: fixedPoint,
278 | signBytes: signBytes,
279 | toLocalBuffer: toLocalBuffer,
280 | verifyBytes: verifyBytes,
281 | isAddress: addressHelper.isAddress,
282 | isBase58CheckAddress: addressHelper.isBase58CheckAddress
283 | }
284 |
--------------------------------------------------------------------------------
/test/tests.js:
--------------------------------------------------------------------------------
1 | var Buffer = require("buffer/").Buffer;
2 | var crypto_lib = require("crypto-browserify");
3 | var should = require("should");
4 | var asch = require("../index.js");
5 |
6 | describe("Asch JS", function () {
7 |
8 | it("should be ok", function () {
9 | (asch).should.be.ok;
10 | });
11 |
12 | it("should be object", function () {
13 | (asch).should.be.type("object");
14 | });
15 |
16 | it("should have properties", function () {
17 | var properties = ["transaction", "signature", "vote", "delegate", "dapp", "crypto"];
18 |
19 | properties.forEach(function (property) {
20 | (asch).should.have.property(property);
21 | });
22 | });
23 |
24 | describe("crypto.js", function () {
25 | var crypto = asch.crypto;
26 |
27 | it("should be ok", function () {
28 | (crypto).should.be.ok;
29 | });
30 |
31 | it("should be object", function () {
32 | (crypto).should.be.type("object");
33 | });
34 |
35 | it("should has properties", function () {
36 | var properties = ["getBytes", "getHash", "getId", "getFee", "sign", "secondSign", "getKeys", "getAddress", "verify", "verifySecondSignature", "fixedPoint"];
37 | properties.forEach(function (property) {
38 | (crypto).should.have.property(property);
39 | });
40 | });
41 |
42 | describe("#getBytes", function () {
43 | var getBytes = crypto.getBytes;
44 | var bytes = null;
45 |
46 | it("should be ok", function () {
47 | (getBytes).should.be.ok;
48 | });
49 |
50 | it("should be a function", function () {
51 | (getBytes).should.be.type("function");
52 | });
53 |
54 | it("should return Buffer of simply transaction and buffer most be 117 length", function () {
55 | var transaction = {
56 | type: 0,
57 | amount: 1000,
58 | recipientId: "58191285901858109",
59 | timestamp: 141738,
60 | asset: {},
61 | senderPublicKey: "5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09",
62 | signature: "618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a",
63 | id: "13987348420913138422"
64 | };
65 |
66 | bytes = getBytes(transaction);
67 | (bytes).should.be.ok;
68 | (bytes).should.be.type("object");
69 | (bytes.length).should.be.equal(117);
70 | });
71 |
72 | it("should return Buffer of transaction with second signature and buffer most be 181 length", function () {
73 | var transaction = {
74 | type: 0,
75 | amount: 1000,
76 | recipientId: "58191285901858109",
77 | timestamp: 141738,
78 | asset: {},
79 | senderPublicKey: "5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09",
80 | signature: "618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a",
81 | signSignature: "618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a",
82 | id: "13987348420913138422"
83 | };
84 |
85 | bytes = getBytes(transaction);
86 | (bytes).should.be.ok;
87 | (bytes).should.be.type("object");
88 | (bytes.length).should.be.equal(181);
89 | });
90 | });
91 |
92 | describe("#getHash", function () {
93 | var getHash = crypto.getHash;
94 |
95 | it("should be ok", function () {
96 | (getHash).should.be.ok;
97 | });
98 |
99 | it("should be a function", function () {
100 | (getHash).should.be.type("function");
101 | })
102 |
103 | it("should return Buffer and Buffer most be 32 bytes length", function () {
104 | var transaction = {
105 | type: 0,
106 | amount: 1000,
107 | recipientId: "58191285901858109",
108 | timestamp: 141738,
109 | asset: {},
110 | senderPublicKey: "5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09",
111 | signature: "618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a",
112 | id: "13987348420913138422"
113 | };
114 |
115 | var result = getHash(transaction);
116 | (result).should.be.ok;
117 | (result).should.be.type("object");
118 | (result.length).should.be.equal(32);
119 | });
120 | });
121 |
122 | describe("#getId", function () {
123 | var getId = crypto.getId;
124 |
125 | it("should be ok", function () {
126 | (getId).should.be.ok;
127 | });
128 |
129 | it("should be a function", function () {
130 | (getId).should.be.type("function");
131 | });
132 |
133 | it("should return string id and be equal to 13987348420913138422", function () {
134 | var transaction = {
135 | type: 0,
136 | amount: 1000,
137 | recipientId: "58191285901858109",
138 | timestamp: 141738,
139 | asset: {},
140 | senderPublicKey: "5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09",
141 | signature: "618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a"
142 | };
143 |
144 | var id = getId(transaction);
145 | (id).should.be.type("string").and.equal("f60a26da470b1dc233fd526ed7306c1d84836f9e2ecee82c9ec47319e0910474");
146 | });
147 | });
148 |
149 | describe("#getFee", function () {
150 | var getFee = crypto.getFee;
151 |
152 | it("should be ok", function () {
153 | (getFee).should.be.ok;
154 | })
155 |
156 | it("should be a function", function () {
157 | (getFee).should.be.type("function");
158 | });
159 |
160 | it("should return number", function () {
161 | var fee = getFee({ amount: 100000, type: 0 });
162 | (fee).should.be.type("number");
163 | (fee).should.be.not.NaN;
164 | });
165 |
166 | it("should return 10000000", function () {
167 | var fee = getFee({ amount: 100000, type: 0 });
168 | (fee).should.be.type("number").and.equal(10000000);
169 | });
170 |
171 | it("should return 10000000000", function () {
172 | var fee = getFee({ type: 1 });
173 | (fee).should.be.type("number").and.equal(10000000000);
174 | });
175 |
176 | it("should be equal 1000000000000", function () {
177 | var fee = getFee({ type: 2 });
178 | (fee).should.be.type("number").and.equal(1000000000000);
179 | });
180 |
181 | it("should be equal 100000000", function () {
182 | var fee = getFee({ type: 3 });
183 | (fee).should.be.type("number").and.equal(100000000);
184 | });
185 | });
186 |
187 | describe("fixedPoint", function () {
188 | var fixedPoint = crypto.fixedPoint;
189 |
190 | it("should be ok", function () {
191 | (fixedPoint).should.be.ok;
192 | })
193 |
194 | it("should be number", function () {
195 | (fixedPoint).should.be.type("number").and.not.NaN;
196 | });
197 |
198 | it("should be equal 100000000", function () {
199 | (fixedPoint).should.be.equal(100000000);
200 | });
201 | });
202 |
203 | describe("#sign", function () {
204 | var sign = crypto.sign;
205 |
206 | it("should be ok", function () {
207 | (sign).should.be.ok;
208 | });
209 |
210 | it("should be a function", function () {
211 | (sign).should.be.type("function");
212 | });
213 | });
214 |
215 | describe("#secondSign", function () {
216 | var secondSign = crypto.secondSign;
217 |
218 | it("should be ok", function () {
219 | (secondSign).should.be.ok;
220 | });
221 |
222 | it("should be a function", function () {
223 | (secondSign).should.be.type("function");
224 | });
225 | });
226 |
227 | describe("#getKeys", function () {
228 | var getKeys = crypto.getKeys;
229 |
230 | it("should be ok", function () {
231 | (getKeys).should.be.ok;
232 | });
233 |
234 | it("should be a function", function () {
235 | (getKeys).should.be.type("function");
236 | });
237 |
238 | it("should return two keys in hex", function () {
239 | var keys = getKeys("secret");
240 |
241 | (keys).should.be.ok;
242 | (keys).should.be.type("object");
243 | (keys).should.have.property("publicKey");
244 | (keys).should.have.property("privateKey");
245 | (keys.publicKey).should.be.type("string").and.match(function () {
246 | try {
247 | new Buffer(keys.publicKey, "hex");
248 | } catch (e) {
249 | return false;
250 | }
251 |
252 | return true;
253 | });
254 | (keys.privateKey).should.be.type("string").and.match(function () {
255 | try {
256 | new Buffer(keys.privateKey, "hex");
257 | } catch (e) {
258 | return false;
259 | }
260 |
261 | return true;
262 | });
263 | });
264 | });
265 |
266 | describe("#getAddress", function () {
267 | var getAddress = crypto.getAddress;
268 |
269 | it("should be ok", function () {
270 | (getAddress).should.be.ok;
271 | })
272 |
273 | it("should be a function", function () {
274 | (getAddress).should.be.type("function");
275 | });
276 |
277 | it("should generate address by publicKey", function () {
278 | var keys = crypto.getKeys("secret");
279 | var address = getAddress(keys.publicKey);
280 |
281 | (address).should.be.ok;
282 | (address).should.be.type("string");
283 | (address).should.be.equal("AFkctfgZFkaATGRhGbj72wzJqACvMyzQ1U");
284 | });
285 | });
286 |
287 | describe("#verify", function () {
288 | var verify = crypto.verify;
289 |
290 | it("should be ok", function () {
291 | (verify).should.be.ok;
292 | })
293 |
294 | it("should be function", function () {
295 | (verify).should.be.type("function");
296 | });
297 | });
298 |
299 | describe("#verifySecondSignature", function () {
300 | var verifySecondSignature = crypto.verifySecondSignature;
301 |
302 | it("should be ok", function () {
303 | (verifySecondSignature).should.be.ok;
304 | });
305 |
306 | it("should be function", function () {
307 | (verifySecondSignature).should.be.type("function");
308 | });
309 | });
310 | });
311 |
312 | describe("dapp.js", function () {
313 | var dapp = asch.dapp;
314 |
315 | it("should be object", function () {
316 | (dapp).should.be.type("object");
317 | });
318 |
319 | it("should have properties", function () {
320 | (dapp).should.have.property("createDApp");
321 | })
322 |
323 | describe("#createDApp", function () {
324 | var createDApp = dapp.createDApp;
325 | var trs = null;
326 |
327 | var options = {
328 | "name": "asch-dapp-cctime",
329 | "link": "https://github.com/AschPlatform/asch-dapp-cctime/archive/master.zip",
330 | "category": 1,
331 | "description": "Decentralized news channel",
332 | "tags": "asch,dapp,demo,cctime",
333 | "icon": "http://o7dyh3w0x.bkt.clouddn.com/hello.png",
334 | "type": 0,
335 | "delegates": [
336 | "8b1c24a0b9ba9b9ccf5e35d0c848d582a2a22cca54d42de8ac7b2412e7dc63d4",
337 | "aa7dcc3afd151a549e826753b0547c90e61b022adb26938177904a73fc4fee36",
338 | "e29c75979ac834b871ce58dc52a6f604f8f565dea2b8925705883b8c001fe8ce",
339 | "55ad778a8ff0ce4c25cb7a45735c9e55cf1daca110cfddee30e789cb07c8c9f3",
340 | "982076258caab20f06feddc94b95ace89a2862f36fea73fa007916ab97e5946a"
341 | ],
342 | "unlockDelegates": 3
343 | }
344 |
345 | it("should be a function", function () {
346 | (createDApp).should.be.type("function");
347 | });
348 |
349 | it("should create dapp without second signature", function () {
350 | trs = createDApp(options, "secret", null);
351 | (trs).should.be.ok;
352 | });
353 |
354 | it("should create delegate with second signature", function () {
355 | trs = createDApp(options, "secret", "secret 2");
356 | (trs).should.be.ok;
357 | });
358 |
359 | describe("returned dapp", function () {
360 | var keys = asch.crypto.getKeys("secret");
361 | var secondKeys = asch.crypto.getKeys("secret 2");
362 |
363 | it("should be object", function () {
364 | (trs).should.be.type("object");
365 | });
366 |
367 | it("should have id as string", function () {
368 | (trs.id).should.be.type("string");
369 | });
370 |
371 | it("should have type as number and equal 9", function () {
372 | (trs.type).should.be.type("number").and.equal(5);
373 | });
374 |
375 | it("should have amount as number and eqaul 0", function () {
376 | (trs.amount).should.be.type("number").and.equal(0);
377 | });
378 |
379 | it("should have fee as number and equal 10000000000", function () {
380 | (trs.fee).should.be.type("number").and.equal(10000000000);
381 | });
382 |
383 | it("should have null recipientId", function () {
384 | trs.should.have.property("recipientId").equal(null);
385 | });
386 |
387 | it("should have senderPublicKey as hex string", function () {
388 | (trs.senderPublicKey).should.be.type("string").and.match(function () {
389 | try {
390 | new Buffer(trs.senderPublicKey, "hex")
391 | } catch (e) {
392 | return false;
393 | }
394 |
395 | return true;
396 | })
397 | });
398 |
399 | it("should have timestamp as number", function () {
400 | (trs.timestamp).should.be.type("number").and.not.NaN;
401 | });
402 |
403 | it("should have dapp inside asset", function () {
404 | (trs.asset).should.have.property("dapp");
405 | });
406 |
407 | describe("dapp asset", function () {
408 | it("should be ok", function () {
409 | (trs.asset.dapp).should.be.ok;
410 | })
411 |
412 | it("should be object", function () {
413 | (trs.asset.dapp).should.be.type("object");
414 | });
415 |
416 | it("should have category property", function () {
417 | (trs.asset.dapp).should.have.property("category").and.equal(options.category);
418 | });
419 |
420 | it("should have name property", function () {
421 | (trs.asset.dapp).should.have.property("name").and.equal(options.name);
422 | });
423 |
424 | it("should have tags property", function () {
425 | (trs.asset.dapp).should.have.property("tags").and.equal(options.tags);
426 | });
427 |
428 | it("should have type property", function () {
429 | (trs.asset.dapp).should.have.property("type").and.equal(options.type);
430 | });
431 |
432 | it("should have link property", function () {
433 | (trs.asset.dapp).should.have.property("link").and.equal(options.link);
434 | });
435 |
436 | it("should have icon property", function () {
437 | (trs.asset.dapp).should.have.property("icon").and.equal(options.icon);
438 | });
439 | });
440 |
441 | it("should have signature as hex string", function () {
442 | (trs.signature).should.be.type("string").and.match(function () {
443 | try {
444 | new Buffer(trs.signature, "hex")
445 | } catch (e) {
446 | return false;
447 | }
448 |
449 | return true;
450 | })
451 | });
452 |
453 | it("should have second signature in hex", function () {
454 | (trs).should.have.property("signSignature").and.type("string").and.match(function () {
455 | try {
456 | new Buffer(trs.signSignature, "hex");
457 | } catch (e) {
458 | return false;
459 | }
460 |
461 | return true;
462 | });
463 | });
464 |
465 | it("should be signed correctly", function () {
466 | var result = asch.crypto.verify(trs);
467 | (result).should.be.ok;
468 | });
469 |
470 | it("should not be signed correctly now", function () {
471 | trs.amount = 10000;
472 | var result = asch.crypto.verify(trs);
473 | (result).should.be.not.ok;
474 | });
475 |
476 | it("should be second signed correctly", function () {
477 | trs.amount = 0;
478 | var result = asch.crypto.verifySecondSignature(trs, secondKeys.publicKey);
479 | (result).should.be.ok;
480 | });
481 |
482 | it("should not be second signed correctly now", function () {
483 | trs.amount = 10000;
484 | var result = asch.crypto.verifySecondSignature(trs, secondKeys.publicKey);
485 | (result).should.be.not.ok;
486 | });
487 |
488 | it("should be ok to verify bytes", function () {
489 | var data1 = 'a1b2c3d4'
490 | var secret = 'secret1'
491 | var keys = asch.crypto.getKeys(secret)
492 | var signature = asch.crypto.signBytes(data1, keys)
493 | var result = asch.crypto.verifyBytes(data1, signature, keys.publicKey)
494 | result.should.be.ok
495 |
496 | var data2 = new Buffer('a1b2c3d4', 'hex')
497 | signature = asch.crypto.signBytes(data2, keys)
498 | result = asch.crypto.verifyBytes(data2, signature, keys.publicKey)
499 | result.should.be.ok
500 | })
501 | });
502 | });
503 | });
504 |
505 | describe("delegate.js", function () {
506 | var delegate = asch.delegate;
507 |
508 | it("should be ok", function () {
509 | (delegate).should.be.ok;
510 | });
511 |
512 | it("should be function", function () {
513 | (delegate).should.be.type("object");
514 | });
515 |
516 | it("should have property createDelegate", function () {
517 | (delegate).should.have.property("createDelegate");
518 | });
519 |
520 | describe("#createDelegate", function () {
521 | var createDelegate = delegate.createDelegate;
522 | var trs = null;
523 |
524 | it("should be ok", function () {
525 | (createDelegate).should.be.ok;
526 | });
527 |
528 | it("should be function", function () {
529 | (createDelegate).should.be.type("function");
530 | });
531 |
532 | it("should create delegate", function () {
533 | trs = createDelegate("delegate", "secret", "secret 2");
534 | });
535 |
536 | describe("returned delegate", function () {
537 | var keys = asch.crypto.getKeys("secret");
538 | var secondKeys = asch.crypto.getKeys("secret 2");
539 |
540 | it("should be ok", function () {
541 | (trs).should.be.ok;
542 | });
543 |
544 | it("should be object", function () {
545 | (trs).should.be.type("object");
546 | });
547 |
548 | it("should have recipientId equal null", function () {
549 | (trs).should.have.property("recipientId").and.type("object").and.be.empty;
550 | })
551 |
552 | it("shoud have amount equal 0", function () {
553 | (trs).should.have.property("amount").and.type("number").and.equal(0);
554 | })
555 |
556 | it("should have type equal 0", function () {
557 | (trs).should.have.property("type").and.type("number").and.equal(2);
558 | });
559 |
560 | it("should have timestamp number", function () {
561 | (trs).should.have.property("timestamp").and.type("number");
562 | });
563 |
564 | it("should have senderPublicKey in hex", function () {
565 | (trs).should.have.property("senderPublicKey").and.type("string").and.match(function () {
566 | try {
567 | new Buffer(trs.senderPublicKey, "hex");
568 | } catch (e) {
569 | return false;
570 | }
571 |
572 | return true;
573 | }).and.equal(keys.publicKey);
574 | });
575 |
576 | it("should have signature in hex", function () {
577 | (trs).should.have.property("signature").and.type("string").and.match(function () {
578 | try {
579 | new Buffer(trs.signature, "hex");
580 | } catch (e) {
581 | return false;
582 | }
583 |
584 | return true;
585 | });
586 | });
587 |
588 | it("should have second signature in hex", function () {
589 | (trs).should.have.property("signSignature").and.type("string").and.match(function () {
590 | try {
591 | new Buffer(trs.signSignature, "hex");
592 | } catch (e) {
593 | return false;
594 | }
595 |
596 | return true;
597 | });
598 | });
599 |
600 | it("should have delegate asset", function () {
601 | (trs).should.have.property("asset").and.type("object");
602 | (trs.asset).should.have.have.property("delegate");
603 | })
604 |
605 | it("should be signed correctly", function () {
606 | var result = asch.crypto.verify(trs, keys.publicKey);
607 | (result).should.be.ok;
608 | });
609 |
610 | it("should be second signed correctly", function () {
611 | var result = asch.crypto.verifySecondSignature(trs, secondKeys.publicKey);
612 | (result).should.be.ok;
613 | });
614 |
615 | it("should not be signed correctly now", function () {
616 | trs.amount = 100;
617 | var result = asch.crypto.verify(trs, keys.publicKey);
618 | (result).should.be.not.ok;
619 | });
620 |
621 | it("should not be second signed correctly now", function () {
622 | trs.amount = 100;
623 | var result = asch.crypto.verify(trs, secondKeys.publicKey);
624 | (result).should.be.not.ok;
625 | });
626 |
627 | describe("delegate asset", function () {
628 | it("should be ok", function () {
629 | (trs.asset.delegate).should.be.ok;
630 | });
631 |
632 | it("should be object", function () {
633 | (trs.asset.delegate).should.be.type("object");
634 | });
635 |
636 | it("should be have property username", function () {
637 | (trs.asset.delegate).should.have.property("username").and.be.type("string").and.equal("delegate");
638 | });
639 | });
640 | });
641 | });
642 | });
643 |
644 | describe("multisignature.js", function () {
645 | });
646 |
647 | describe("signature.js", function () {
648 | var signature = asch.signature;
649 | it("should be ok", function () {
650 | (signature).should.be.ok;
651 | });
652 |
653 | it("should be object", function () {
654 | (signature).should.be.type("object");
655 | });
656 |
657 | it("should have properties", function () {
658 | (signature).should.have.property("createSignature");
659 | });
660 |
661 | describe("#createSignature", function () {
662 | var createSignature = signature.createSignature;
663 | var sgn = null;
664 |
665 | it("should be function", function () {
666 | (createSignature).should.be.type("function");
667 | });
668 |
669 | it("should create signature transaction", function () {
670 | sgn = createSignature("secret", "second secret");
671 | (sgn).should.be.ok;
672 | (sgn).should.be.type("object");
673 | });
674 |
675 | describe("returned signature transaction", function () {
676 | it("should have empty recipientId", function () {
677 | (sgn).should.have.property("recipientId").equal(null);
678 | });
679 |
680 | it("should have amount equal 0", function () {
681 | (sgn.amount).should.be.type("number").equal(0);
682 | });
683 |
684 | it("should have asset", function () {
685 | (sgn.asset).should.be.type("object");
686 | (sgn.asset).should.be.not.empty;
687 | });
688 |
689 | it("should have signature inside asset", function () {
690 | (sgn.asset).should.have.property("signature");
691 | });
692 |
693 | describe("signature asset", function () {
694 | it("should be ok", function () {
695 | (sgn.asset.signature).should.be.ok;
696 | })
697 |
698 | it("should be object", function () {
699 | (sgn.asset.signature).should.be.type("object");
700 | });
701 |
702 | it("should have publicKey property", function () {
703 | (sgn.asset.signature).should.have.property("publicKey");
704 | });
705 |
706 | it("should have publicKey in hex", function () {
707 | (sgn.asset.signature.publicKey).should.be.type("string").and.match(function () {
708 | try {
709 | new Buffer(sgn.asset.signature.publicKey);
710 | } catch (e) {
711 | return false;
712 | }
713 |
714 | return true;
715 | });
716 | });
717 |
718 | it("should have publicKey in 32 bytes", function () {
719 | var publicKey = new Buffer(sgn.asset.signature.publicKey, "hex");
720 | (publicKey.length).should.be.equal(32);
721 | });
722 | });
723 | });
724 | });
725 | });
726 |
727 | describe("slots.js", function () {
728 | var slots = require("../lib/time/slots.js");
729 |
730 | it("should be ok", function () {
731 | (slots).should.be.ok;
732 | });
733 |
734 | it("should be object", function () {
735 | (slots).should.be.type("object");
736 | });
737 |
738 | it("should have properties", function () {
739 | var properties = ["interval", "delegates", "getTime", "getRealTime", "getSlotNumber", "getSlotTime", "getNextSlot", "getLastSlot"];
740 | properties.forEach(function (property) {
741 | (slots).should.have.property(property);
742 | });
743 | });
744 |
745 | describe(".interval", function () {
746 | var interval = slots.interval;
747 |
748 | it("should be ok", function () {
749 | (interval).should.be.ok;
750 | });
751 |
752 | it("should be number and not NaN", function () {
753 | (interval).should.be.type("number").and.not.NaN;
754 | });
755 | });
756 |
757 | describe(".delegates", function () {
758 | var delegates = slots.delegates;
759 |
760 | it("should be ok", function () {
761 | (delegates).should.be.ok;
762 | });
763 |
764 | it("should be number and not NaN", function () {
765 | (delegates).should.be.type("number").and.not.NaN;
766 | });
767 | });
768 |
769 | describe("#getTime", function () {
770 | var getTime = slots.getTime;
771 |
772 | it("should be ok", function () {
773 | (getTime).should.be.ok;
774 | });
775 |
776 | it("should be a function", function () {
777 | (getTime).should.be.type("function");
778 | });
779 |
780 | it("should return epoch time as number, equal to 2764800", function () {
781 | var d = 1469822400000;
782 | var time = getTime(d);
783 | (time).should.be.ok;
784 | (time).should.be.type("number").and.equal(2764800);
785 | });
786 | });
787 |
788 | describe("#getRealTime", function () {
789 | var getRealTime = slots.getRealTime;
790 |
791 | it("should be ok", function () {
792 | (getRealTime).should.be.ok;
793 | });
794 |
795 | it("should be a function", function () {
796 | (getRealTime).should.be.type("function");
797 | });
798 |
799 | it("should return return real time, convert 196144 to 1467253744000", function () {
800 | var d = 196144;
801 | var real = getRealTime(d);
802 | (real).should.be.ok;
803 | (real).should.be.type("number").and.equal(1467253744000);
804 | });
805 | });
806 |
807 | describe("#getSlotNumber", function () {
808 | var getSlotNumber = slots.getSlotNumber;
809 |
810 | it("should be ok", function () {
811 | (getSlotNumber).should.be.ok;
812 | });
813 |
814 | it("should be a function", function () {
815 | (getSlotNumber).should.be.type("function");
816 | });
817 |
818 | it("should return slot number, equal to 19614", function () {
819 | var d = 196144;
820 | var slot = getSlotNumber(d);
821 | (slot).should.be.ok;
822 | (slot).should.be.type("number").and.equal(19614);
823 | });
824 | });
825 |
826 | describe("#getSlotTime", function () {
827 | var getSlotTime = slots.getSlotTime;
828 |
829 | it("should be ok", function () {
830 | (getSlotTime).should.be.ok;
831 | });
832 |
833 | it("should be function", function () {
834 | (getSlotTime).should.be.type("function");
835 | });
836 |
837 | it("should return slot time number, equal to ", function () {
838 | var slot = 19614;
839 | var slotTime = getSlotTime(19614);
840 | (slotTime).should.be.ok;
841 | (slotTime).should.be.type("number").and.equal(196140);
842 | });
843 | });
844 |
845 | describe("#getNextSlot", function () {
846 | var getNextSlot = slots.getNextSlot;
847 |
848 | it("should be ok", function () {
849 | (getNextSlot).should.be.ok;
850 | });
851 |
852 | it("should be function", function () {
853 | (getNextSlot).should.be.type("function");
854 | });
855 |
856 | it("should return next slot number", function () {
857 | var nextSlot = getNextSlot();
858 | (nextSlot).should.be.ok;
859 | (nextSlot).should.be.type("number").and.not.NaN;
860 | });
861 | });
862 |
863 | describe("#getLastSlot", function () {
864 | var getLastSlot = slots.getLastSlot;
865 |
866 | it("should be ok", function () {
867 | (getLastSlot).should.be.ok;
868 | });
869 |
870 | it("should be function", function () {
871 | (getLastSlot).should.be.type("function");
872 | });
873 |
874 | it("should return last slot number", function () {
875 | var lastSlot = getLastSlot(slots.getNextSlot());
876 | (lastSlot).should.be.ok;
877 | (lastSlot).should.be.type("number").and.not.NaN;
878 | });
879 | });
880 | });
881 |
882 | describe("transaction.js", function () {
883 | var transaction = asch.transaction;
884 |
885 | it("should be object", function () {
886 | (transaction).should.be.type("object");
887 | });
888 |
889 | it("should have properties", function () {
890 | (transaction).should.have.property("createTransaction");
891 | })
892 |
893 | describe("#createTransaction", function () {
894 | var createTransaction = transaction.createTransaction;
895 | var trs = null;
896 |
897 | it("should be a function", function () {
898 | (createTransaction).should.be.type("function");
899 | });
900 |
901 | it("should create transaction without second signature", function () {
902 | trs = createTransaction("58191285901858109", 1000, "", "secret");
903 | (trs).should.be.ok;
904 | });
905 |
906 | describe("returned transaction", function () {
907 | it("should be object", function () {
908 | (trs).should.be.type("object");
909 | });
910 |
911 | it("should have id as string", function () {
912 | (trs.id).should.be.type("string");
913 | });
914 |
915 | it("should have type as number and eqaul 0", function () {
916 | (trs.type).should.be.type("number").and.equal(0);
917 | });
918 |
919 | it("should have timestamp as number", function () {
920 | (trs.timestamp).should.be.type("number").and.not.NaN;
921 | });
922 |
923 | it("should have senderPublicKey as hex string", function () {
924 | (trs.senderPublicKey).should.be.type("string").and.match(function () {
925 | try {
926 | new Buffer(trs.senderPublicKey, "hex")
927 | } catch (e) {
928 | return false;
929 | }
930 |
931 | return true;
932 | })
933 | });
934 |
935 | it("should have recipientId as string and to be equal 58191285901858109", function () {
936 | (trs.recipientId).should.be.type("string").and.equal("58191285901858109");
937 | });
938 |
939 | it("should have amount as number and eqaul to 1000", function () {
940 | (trs.amount).should.be.type("number").and.equal(1000);
941 | });
942 |
943 | it("should have empty asset object", function () {
944 | (trs.asset).should.be.type("object").and.empty;
945 | });
946 |
947 | it("should does not have second signature", function () {
948 | (trs).should.not.have.property("signSignature");
949 | });
950 |
951 | it("should have signature as hex string", function () {
952 | (trs.signature).should.be.type("string").and.match(function () {
953 | try {
954 | new Buffer(trs.signature, "hex")
955 | } catch (e) {
956 | return false;
957 | }
958 |
959 | return true;
960 | })
961 | });
962 |
963 | it("should be signed correctly", function () {
964 | var result = asch.crypto.verify(trs);
965 | (result).should.be.ok;
966 | });
967 |
968 | it("should not be signed correctly now", function () {
969 | trs.amount = 10000;
970 | var result = asch.crypto.verify(trs);
971 | (result).should.be.not.ok;
972 | });
973 | });
974 | });
975 |
976 | describe("#createTransaction with second secret", function () {
977 | var createTransaction = transaction.createTransaction;
978 | var trs = null;
979 | var secondSecret = "second secret";
980 | var keys = asch.crypto.getKeys(secondSecret);
981 |
982 | it("should be a function", function () {
983 | (createTransaction).should.be.type("function");
984 | });
985 |
986 | it("should create transaction without second signature", function () {
987 | trs = createTransaction("58191285901858109", 1000, "", "secret", secondSecret);
988 | (trs).should.be.ok;
989 | });
990 |
991 | describe("returned transaction", function () {
992 | it("should be object", function () {
993 | (trs).should.be.type("object");
994 | });
995 |
996 | it("should have id as string", function () {
997 | (trs.id).should.be.type("string");
998 | });
999 |
1000 | it("should have type as number and eqaul 0", function () {
1001 | (trs.type).should.be.type("number").and.equal(0);
1002 | });
1003 |
1004 | it("should have timestamp as number", function () {
1005 | (trs.timestamp).should.be.type("number").and.not.NaN;
1006 | });
1007 |
1008 | it("should have senderPublicKey as hex string", function () {
1009 | (trs.senderPublicKey).should.be.type("string").and.match(function () {
1010 | try {
1011 | new Buffer(trs.senderPublicKey, "hex")
1012 | } catch (e) {
1013 | return false;
1014 | }
1015 |
1016 | return true;
1017 | })
1018 | });
1019 |
1020 | it("should have recipientId as string and to be equal 58191285901858109", function () {
1021 | (trs.recipientId).should.be.type("string").and.equal("58191285901858109");
1022 | });
1023 |
1024 | it("should have amount as number and eqaul to 1000", function () {
1025 | (trs.amount).should.be.type("number").and.equal(1000);
1026 | });
1027 |
1028 | it("should have empty asset object", function () {
1029 | (trs.asset).should.be.type("object").and.empty;
1030 | });
1031 |
1032 | it("should have second signature", function () {
1033 | (trs).should.have.property("signSignature");
1034 | });
1035 |
1036 | it("should have signature as hex string", function () {
1037 | (trs.signature).should.be.type("string").and.match(function () {
1038 | try {
1039 | new Buffer(trs.signature, "hex")
1040 | } catch (e) {
1041 | return false;
1042 | }
1043 |
1044 | return true;
1045 | })
1046 | });
1047 |
1048 | it("should have signSignature as hex string", function () {
1049 | (trs.signSignature).should.be.type("string").and.match(function () {
1050 | try {
1051 | new Buffer(trs.signSignature, "hex");
1052 | } catch (e) {
1053 | return false;
1054 | }
1055 |
1056 | return true;
1057 | });
1058 | });
1059 |
1060 | it("should be signed correctly", function () {
1061 | var result = asch.crypto.verify(trs);
1062 | (result).should.be.ok;
1063 | });
1064 |
1065 | it("should be second signed correctly", function () {
1066 | var result = asch.crypto.verifySecondSignature(trs, keys.publicKey);
1067 | (result).should.be.ok;
1068 | });
1069 |
1070 | it("should not be signed correctly now", function () {
1071 | trs.amount = 10000;
1072 | var result = asch.crypto.verify(trs);
1073 | (result).should.be.not.ok;
1074 | });
1075 |
1076 | it("should not be second signed correctly now", function () {
1077 | trs.amount = 10000;
1078 | var result = asch.crypto.verifySecondSignature(trs, keys.publicKey);
1079 | (result).should.be.not.ok;
1080 | });
1081 | });
1082 | });
1083 | });
1084 |
1085 | describe("transfer.js", function () {
1086 | });
1087 |
1088 | describe("vote.js", function () {
1089 | var vote = asch.vote;
1090 |
1091 | it("should be ok", function () {
1092 | (vote).should.be.ok;
1093 | });
1094 |
1095 | it("should be object", function () {
1096 | (vote).should.be.type("object");
1097 | });
1098 |
1099 | it("should have createVote property", function () {
1100 | (vote).should.have.property("createVote");
1101 | });
1102 |
1103 | describe("#createVote", function () {
1104 | var createVote = vote.createVote,
1105 | vt = null,
1106 | publicKey = asch.crypto.getKeys("secret").publicKey,
1107 | publicKeys = ["+" + publicKey];
1108 |
1109 | it("should be ok", function () {
1110 | (createVote).should.be.ok;
1111 | });
1112 |
1113 | it("should be function", function () {
1114 | (createVote).should.be.type("function");
1115 | });
1116 |
1117 | it("should create vote", function () {
1118 | vt = createVote(publicKeys, "secret", "second secret");
1119 | });
1120 |
1121 | describe("returned vote", function () {
1122 | it("should be ok", function () {
1123 | (vt).should.be.ok;
1124 | });
1125 |
1126 | it("should be object", function () {
1127 | (vt).should.be.type("object");
1128 | });
1129 |
1130 | it("should have recipientId string equal to sender", function () {
1131 | (vt).should.have.property("recipientId").equal(null);;
1132 | });
1133 |
1134 | it("should have amount number eaul to 0", function () {
1135 | (vt).should.have.property("amount").and.be.type("number").and.equal(0);
1136 | });
1137 |
1138 | it("should have type number equal to 3", function () {
1139 | (vt).should.have.property("type").and.be.type("number").and.equal(3);
1140 | });
1141 |
1142 | it("should have timestamp number", function () {
1143 | (vt).should.have.property("timestamp").and.be.type("number");
1144 | });
1145 |
1146 | it("should have senderPublicKey hex string equal to sender public key", function () {
1147 | (vt).should.have.property("senderPublicKey").and.be.type("string").and.match(function () {
1148 | try {
1149 | new Buffer(vt.senderPublicKey, "hex");
1150 | } catch (e) {
1151 | return false;
1152 | }
1153 |
1154 | return true;
1155 | }).and.equal(publicKey);
1156 | });
1157 |
1158 | it("should have signature hex string", function () {
1159 | (vt).should.have.property("signature").and.be.type("string").and.match(function () {
1160 | try {
1161 | new Buffer(vt.signature, "hex");
1162 | } catch (e) {
1163 | return false;
1164 | }
1165 |
1166 | return true;
1167 | });
1168 | });
1169 |
1170 | it("should have second signature hex string", function () {
1171 | (vt).should.have.property("signSignature").and.be.type("string").and.match(function () {
1172 | try {
1173 | new Buffer(vt.signSignature, "hex");
1174 | } catch (e) {
1175 | return false;
1176 | }
1177 |
1178 | return true;
1179 | });
1180 | });
1181 |
1182 | it("should be signed correctly", function () {
1183 | var result = asch.crypto.verify(vt);
1184 | (result).should.be.ok;
1185 | });
1186 |
1187 | it("should be second signed correctly", function () {
1188 | var result = asch.crypto.verifySecondSignature(vt, asch.crypto.getKeys("second secret").publicKey);
1189 | (result).should.be.ok;
1190 | });
1191 |
1192 | it("should not be signed correctly now", function () {
1193 | vt.amount = 100;
1194 | var result = asch.crypto.verify(vt);
1195 | (result).should.be.not.ok;
1196 | });
1197 |
1198 | it("should not be second signed correctly now", function () {
1199 | vt.amount = 100;
1200 | var result = asch.crypto.verifySecondSignature(vt, asch.crypto.getKeys("second secret").publicKey);
1201 | (result).should.be.not.ok;
1202 | });
1203 |
1204 | it("should have asset", function () {
1205 | (vt).should.have.property("asset").and.not.empty;
1206 | });
1207 |
1208 | describe("vote asset", function () {
1209 | it("should be ok", function () {
1210 | (vt.asset.vote).should.have.property("votes").and.be.ok;
1211 | });
1212 |
1213 | it("should be object", function () {
1214 | (vt.asset.vote.votes).should.be.type("object");
1215 | });
1216 |
1217 | it("should be not empty", function () {
1218 | (vt.asset.vote.votes).should.be.not.empty;
1219 | });
1220 |
1221 | it("should contains one element", function () {
1222 | (vt.asset.vote.votes.length).should.be.equal(1);
1223 | });
1224 |
1225 | it("should have public keys in hex", function () {
1226 | vt.asset.vote.votes.forEach(function (v) {
1227 | (v).should.be.type("string").startWith("+").and.match(function () {
1228 | try {
1229 | new Buffer(v.substring(1, v.length), "hex");
1230 | } catch (e) {
1231 | return false;
1232 | }
1233 |
1234 | return true;
1235 | });
1236 | });
1237 | });
1238 |
1239 | it("should be equal to sender public key", function () {
1240 | var v = vt.asset.vote.votes[0];
1241 | (v.substring(1, v.length)).should.be.equal(publicKey);
1242 | });
1243 | })
1244 | });
1245 | });
1246 | });
1247 |
1248 | describe('crypto sha256 and address', function () {
1249 | it('should be equal to the expected address', function () {
1250 | asch.crypto.getAddress('7a91b9bfc0ea185bf3ade9d264da273f7fe19bf71008210b1d7239c82dd3ad20').should.be.equal('AFbYJhiJb3DXzHy5ZP24mKw21M2dCBJCXP')
1251 | var publicKeyBuffer = new Buffer('7a91b9bfc0ea185bf3ade9d264da273f7fe19bf71008210b1d7239c82dd3ad20', 'hex')
1252 | asch.crypto.getAddress(publicKeyBuffer).should.be.equal('AFbYJhiJb3DXzHy5ZP24mKw21M2dCBJCXP')
1253 | })
1254 | })
1255 |
1256 | });
1257 |
--------------------------------------------------------------------------------