GithubHelp home page GithubHelp logo

exonum / exonum-client Goto Github PK

View Code? Open in Web Editor NEW
65.0 65.0 33.0 3.78 MB

JavaScript client for Exonum blockchain

License: Apache License 2.0

JavaScript 88.85% Rust 10.48% Shell 0.68%
blockchain cryptography ed25519 exonum merkle-tree sha256

exonum-client's Introduction

Exonum

Status: CI dependency status codecov

Project info: Docs.rs License: Apache-2.0 LoC rust 1.55.0+ required

Community: Join the chat at https://gitter.im/exonum/exonum Join the chat at https://t.me/exonum_blockchain Join the chat at https://gitter.im/exonum/ruExonum Join the chat at https://t.me/ExonumRU Website

Exonum is an extensible open-source framework for creating blockchain applications. Exonum can be used to create cryptographically powered distributed ledgers in virtually any problem domain, including FinTech, GovTech, and LegalTech. The Exonum framework is oriented towards creating permissioned blockchains, that is, blockchains with the known set of blockchain infrastructure providers.

If you are using Exonum in your project and want to be listed on our website & GitHub list — write us a line to [email protected].

Contents

This is the main Exonum repository containing the bulk of Rust crates used in Exonum. Rust crates for Exonum are intended to be reasonably small and reusable, hence there is relatively large number of them.

Main Crates

Upstream Dependencies

Tools for Building Services

Services and Node Plugins

Examples

Versioning Policy

Exonum crates follow semantic versioning.

The exonum crate and its re-exported dependencies (exonum-crypto, exonum-merkledb and exonum-keys) are released at the same time; their version is considered the version of the Exonum framework. On the other hand, the crates downstream of exonum (e.g., exonum-node) or independent of it (e.g., exonum-api) may evolve at different speeds, including major releases not tied to a major Exonum release.

Throughout the Exonum codebase, certain APIs are described in the API docs as unstable or experimental. Such APIs may be removed or changed in a semantically non-breaking release (for example, a minor release) of the corresponding crate. Similarly, nominally public APIs that are hidden from the docs via #[doc(hidden)] are considered unstable and thus exempt from semantic versioning limitations.

Supported Rust Versions

The Exonum crates are built against a specific stable Rust version (1.45.0). Newer stable versions are supported as a result. (Feel free to file an issue if any Exonum crate does not build on a newer stable version.) Newer beta and nightly versions should be supported as well, but no specific effort is allocated into supporting them.

Due to at least some external dependencies not factoring the minimum supported Rust version into their semantic versioning policy, the Exonum crates effectively have no choice but to do the same. Namely, a bump of the minimum supported Rust version will not be considered a semantically breaking change. It is, however, guaranteed that the Exonum crates will build on some stable Rust.

Note that due to versioning policies of external dependencies, the effective minimum supported Rust version may increase as a result of the activities out of control of Exonum developers. The decision how to deal with this situation (pin the dependency or bump the minimum supported Rust version) will be made on the case-by-case basis.

Contributing

To contribute to Exonum, please see CONTRIBUTING.

See Also

Some Exonum stuff that is not in this repository:

exonum-client's People

Contributors

alexmarinenko avatar boguslavsky avatar bullet-tooth avatar dependabot-preview[bot] avatar dependabot[bot] avatar ilammy avatar katenegrienko avatar pepyakin avatar qvantor avatar slowli avatar stanislav-tkach avatar wingedfox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

exonum-client's Issues

Rework NewMessage

Issue: signature field is part of NewMessage entity.
Need to pass data as { body: ..., signature: ... }.

Fix Jshint

  • should probably specify ./src/**/*.js here; otherwise, only a single file is linted
  • fix jshint errors

Tracking issue for 0.1 release

@boguslavsky:

  • Bug fixes and style improvements. PR: #12
  • Rework modules export. Task: #5, PR: #13
  • Update format. Task: #20, PR: #24
  • Fix Jshint. Task: #15
  • Rework error handling: change console.error to throwing errors. Task: #16, PR: #28
  • Documentation refactoring. Task: #1, PR: #32
  • Publish as npm package. Task: #18
  • Publish as bower package. Task: #19
  • Coveralls code coverage + badge. Task: #22

Update transaction format

Add fields:

  • message_id
  • network_id
  • protocol_version
  • service_id

Example of precommit:

{
    “body”: {
        “block_hash”: “29a5b5797b1fcf3e32236440f5fa79c64662b8ba29c791d4ee4e0e498b11263c”,
        “height”: “4”,
        “propose_hash”: “90cc7ebb90e8873e98a6cb662471b3baae68eb5f1ab205f13a898037323edc76”,
        “round”: 4,
        “time”: {
            “nanos”: 804000000,
            “secs”: 1486720350
        },
        “validator”: 0
    },
    “message_id”: 4,
    “network_id”: 0,
    “protocol_version”: 0,
    “service_id”: 0,
    “signature”: “11380a7faf53dcfea888642d9027db417162e5f75939db7efd6e892abb8543f4c2b7922ec4689a0f096da3a3e50600cd78a7d28e49b89d0de43f8e92d53c490e”
}

Check library version

Make it possible to check library version via access to some built-in variable, like:

$.fn.jquery // "2.1.4"

Exonum v0.2 compatibility?

Hi

I am used this "template" and all works, but update of exonum-client breaks compatibility ("Unable to verify transaction") for all exonum versions (0.2, 0.1.1) (my code isn't changed)

With what version is the client compatible now?

exonum.MapProof.merkleRoot is inconsistent when the type of boolen in protobuf

platform: Ubuntu 18.04
rust: rustc 1.38.0-nightly (78ca1bda3 2019-07-08)
exonum: 0.11-master
exonum-client: 0.16.4

Hi, there is a strange situation when I add boolean data in cryptocurrency.proto under cryptocurrency-advance (diff below). After adding this field, the exonum.MapProof cannot get the correct Merkle root from the javascript client.

Could someone help to check whether it is an issue?

diff --git a/examples/cryptocurrency-advanced/backend/src/api.rs b/examples/cryptocurrency-advanced/backend/src/api.rs
index 8006eb7..c01cb1f 100644
--- a/examples/cryptocurrency-advanced/backend/src/api.rs
+++ b/examples/cryptocurrency-advanced/backend/src/api.rs
@@ -81,6 +81,13 @@ impl PublicApi {
         let to_table: MapProof<Hash, Hash> =
             general_schema.get_proof_to_service_table(CRYPTOCURRENCY_SERVICE_ID, 0);
 
+        let to_wallet =
+            currency_schema.wallets().get_proof(query.pub_key).check().unwrap();
+
+        println!("show entries {:?}", to_wallet.entries().collect::<Vec<_>>());
+        println!("show missing_keys {:?}", to_wallet.missing_keys().collect::<Vec<_>>());
+        println!("show merkle root {:?}", to_wallet.merkle_root());
+
         let to_wallet: MapProof<PublicKey, Wallet> =
             currency_schema.wallets().get_proof(query.pub_key);
 
diff --git a/examples/cryptocurrency-advanced/backend/src/proto/cryptocurrency.proto b/examples/cryptocurrency-advanced/backend/src/proto/cryptocurrency.proto
index 04252b0..7435e59 100644
--- a/examples/cryptocurrency-advanced/backend/src/proto/cryptocurrency.proto
+++ b/examples/cryptocurrency-advanced/backend/src/proto/cryptocurrency.proto
@@ -54,4 +54,6 @@ message Wallet {
   uint64 history_len = 4;
   // `Hash` of the transactions history.
   exonum.Hash history_hash = 5;
+  // test
+  bool test_fail = 6;
 }
diff --git a/examples/cryptocurrency-advanced/backend/src/wallet.rs b/examples/cryptocurrency-advanced/backend/src/wallet.rs
index 5a33dea..d4ed040 100644
--- a/examples/cryptocurrency-advanced/backend/src/wallet.rs
+++ b/examples/cryptocurrency-advanced/backend/src/wallet.rs
@@ -32,6 +32,8 @@ pub struct Wallet {
     pub history_len: u64,
     /// `Hash` of the transactions history.
     pub history_hash: Hash,
+    /// test
+    pub test_fail: bool,
 }
 
 impl Wallet {
@@ -49,6 +51,7 @@ impl Wallet {
             balance,
             history_len,
             history_hash,
+            test_fail: false,
         }
     }
     /// Returns a copy of this wallet with updated balance.
diff --git a/examples/cryptocurrency-advanced/frontend/src/plugins/blockchain.js b/examples/cryptocurrency-advanced/frontend/src/plugins/blockchain.js
index 8b084a0..f654c22 100644
--- a/examples/cryptocurrency-advanced/frontend/src/plugins/blockchain.js
+++ b/examples/cryptocurrency-advanced/frontend/src/plugins/blockchain.js
@@ -116,9 +116,12 @@ module.exports = {
               return Exonum.verifyBlock(data.block_proof, validators).then(() => {
                 // verify table timestamps in the root tree
                 const tableRootHash = Exonum.verifyTable(data.wallet_proof.to_table, data.block_proof.block.state_hash, SERVICE_ID, TABLE_INDEX)
-
+                console.log('tableRootHash: ' + tableRootHash)
                 // find wallet in the tree of all wallets
                 const walletProof = new Exonum.MapProof(data.wallet_proof.to_wallet, Exonum.PublicKey, Wallet)
+                console.log(walletProof.entries)
+                console.log(walletProof.missingKeys)
+                console.log('walletProof merkleRoot: ' + walletProof.merkleRoot)
                 if (walletProof.merkleRoot !== tableRootHash) {
                   throw new Error('Wallet proof is corrupted')
                 }

The results are below.
From the backend side:

show entries [(PublicKey(cf0c5b2c...), Wallet { pub_key: PublicKey(cf0c5b2c...), name: "ababa", balance: 100, history_len: 1, history_hash: Hash(416e9a05...), test_fail: false })]
show missing_keys []
show merkle root Hash(b6cb148d...)

From the frontend side:
Screen Shot 2019-07-10 at 11 43 12

You can see the result of merkleRoot is different from "b6cb148d..." (backend result and tableRootHash in the frontend side) and "336bb671...". (walletProof merkleRoot in the frontend side).

Merkle (Patricia) proof interface and implementation

Merkle (Patricia) tree proofs essentially prove that a certain element (or several elements) belongs to a certain data collection (list in the case of Merkle trees; map in the case of MPTs). Essentially, a MTs and MPTs are views of lists or maps, in which some elements are unknown. So, it could be logical to implement them as such.

Interface

Thus, it could be logical to have the following interface for MTs and MPTs:

  • constructor(json): creates an MT or MPT based on JSON retrieved from the server. Verifies the internal structure of the tree (see below) and throws TypeError if the provided JSON is invalid
  • hash(): returns the hash of the collection, calculated as per the current algorithm
  • [MT only?] length (read-only property): returns the length of the underlying collection
  • get(index): gets the element at the specified index (integer for MTs, Hash in the case of MPTs). Returns undefined if the element was not in the provided JSON
  • has(index): returns true if the requested index is in the collection view, false otherwise
  • [MPT only?] maybeHas(index): returns true if the specified index may be present in the collection (not necessarily in the current view). Hence, the proof of absence for index is !view.maybeHas(index).
  • Symbol.iterator and entries(): returns the iterator for [index, value] pairs in the view, like the JS Map (maybe, pull other methods from Map too, e.g., forEach, keys and values).

Internal construction

Merkle tree

Recursive definition:

MT<ItemType> = oneOf({
  stub: Hash, // "collapsed" part of the tree
  branch: { left: MT<ItemType>, right: MT<ItemType> },
  sprout: { child: MT<ItemType> }, // a non-branching intermediate node 
  val: ItemType, // value
});

ListView<ItemType> = {
  root: MT<ItemType>,
  length: Uint64
};

Consistency checks:

  • All values are at the depth expected by length
  • All stubs are at the depth not exceeding the same depth
  • The left child in any branch cannot be a sprout
  • (optional) The tree must be non-redundant, e.g., a branch cannot have both stub children

Methods:

  • get(index) can be implemented by traversing the tree from the root
  • hash() can be implemented by traversing the tree from the leaves

Merkle Patricia tree

Recursive definition:

MPT<ItemType> = {
  bits: BitSlice, // key bits connecting the node to its parent
  node: oneOf({
    stub: Hash, // "collapsed" part of the tree
    branch: { left: MPT<ItemType>, right: MPT<ItemType> },
    val: ItemType // value
  })
};

MapView<ItemType> = MPT<ItemType>;

bits may be woven into all type variants if deemed necessary.

Consistency checks:

  • bits may be empty only for the root node
  • For branches, left.bits must start with 0 and right.bits with 1
  • Key length of all values must be as expected (256 bits)
  • Key length of all stubs must not exceed 256 bits
  • (optional) The tree must be non-redundant, e.g., a branch cannot have both stub children

Methods:

  • get(index) and maybeHas(index) can be implemented by traversing the tree from the root
  • hash() can be implemented by traversing the tree from the leaves

Type specifications

Type specifications right now are quite redundant. While such specs might make sense in Rust, they could be improved in JavaScript to look like

[
  { name: 'foo', type: types.Uint8 },
  { name: 'bar', type: types.String },
  { name: 'bazz', type: SomeCustomType }
]

Future compatibility. Note that types declared in this way are sequences; besides them, we might define other compositions in the future (e.g., enums, optional types, arrays, and/or Any). They can be straightforwardly defined though related constructions, e.g.,

{
  oneOf: [
    types.Uint32,
    types.String
  ]
}

for enums, { array: types.Uint32 } for arrays, etc. Thus, we probably shouldn't worry about specification extensions right now.

Rework serialization

It could be better to calculate the length of the buffer needed for serialization, and use Uint8Array buffers for increased efficiency.
Implemented as a part of PR #8.

Use Flow type system?

Since we (supposedly) build secure software, we need to worry about type safety everywhere (including the client), and allow to take care of type safety for developers using the client. Flow seems like a straightforward way to accomplish this; although there are some alternatives (e.g., TypeScript or Elm, or even compiling Rust code directly to wasm or asm.js).

@deniskolodin Do you think Elm would be an optimal way to pursue? I'm a bit worried that a "fully" functional Elm's approach can have certain performance implications. For example, the tutorial on lists does not seem to unroll recursion, not even in the tail-form (i.e.,

length : List a -> Int
length list = length2 list 0

length2 : List a -> Int -> Int
length2 list acc =
  case list of
    [] ->
        acc
    first :: rest ->
        length2 rest 1 + acc

so it doesn't work with lists of length more than several thousand. Am I doing something wrong, or is this just how Elm rolls (heh)? Also, in general it seems Flow is a bit more supported than Elm, although I may be biased.

Make send headers for tx.send

Actual

Method tx.send(explorerBasePath, type, data, secretKey, attempts, timeout) don't have opportunity send request headers

Expected

Method tx.send(explorerBasePath, type, data, secretKey, attempts, timeout, headers) have opportunity send request headers

 return _axios2.default.post('' + explorerBasePath, {
    tx_body: txBody
  }, headers}).then...

Exonum datatypes interface and newType()

The current definition of Exonum datatypes works, but it can probably be improved as follows.

Each datatype has a set of methods

DataType.prototype = {
  serialize: function () {
    // serializes the value as Uint8Array
  },
  hash: function () {
    // calculates the hash of the serialized data
    // internally, simply calls nacl's hash on this.serialize()
  },
  isFixedLength: function () {
    // Whether the datatype has fixed byte length. It determines how the fields of this type
    // are (de)serialized as fields of other types
  }
};
Datatype.deserialize = function (bytes) {
  // deserializes the value from Uint8Array
};

Example:

// Built-in types
var x = new exonum.types.Uint8(120);
x.serialize(); // === Uint8Array([ 120 ])
x.hash(); // === exonum.types.Hash([ ... ])
var y = exonum.types.Uint8.deserialize(new Uint8Array([ 125 ]));
// Constructed types
var SomeType = exonum.types.newType({ /* type spec */ });
var z = new SomeType(/* initializer; TBD */);
z.serialize();
z.hash();
SomeType.deserialize(new Uint8Array([ /* ... */ ]));

This interface could be especially useful for datatypes constructed with newType(), but it could work for primitive/predefined datatypes for consistency.

Possible problems/topics for discussion:

  • Primitive integer datatypes cease to behave like integers. For example, x + y in the example above will cease working properly (although it could be partially brought back by defining the valueOf method). But it may be a good thing; we probably wouldn't want to allow arbitrary operations on datatypes. Raw values could be extracted from primitive types in a uniform fashion, e.g., via raw property.
  • deserialize may double as a constructor: If the constructor is supplied with a Uint8Array, then deserialization is performed. Note that this will work for hashes, pubkeys and signatures.
  • newType() should be discussed in detail in another issue; I feel that its interface is not optimal either

FixedBuffer serialization

Figure out about FixedBuffer serialization. It seems FixedBuffer should be serialized using pointer.

Source file structure

IMO, the package could definitely benefit from refining its structure:

/src
  index.js # exports exonum package with all dependencies
  /types
    index.js # reexports all datatypes
    primitive.js # primitive types: Uint8, Uint16, ...
    generic.js # newType()
    message.js # newMessage()
  /crypto
    index.js # hash, sign, verify, and keyPair
  /blockchain
    index.js # reexports blockchain datatypes
    merkle.js # MerkleProof
    merkle-patricia.js # MerklePatriciaProof
    block.js # Block

Corresponding package structure:

exonum
  types
    Uint8
    Uint16
    ...
    newType
    ...
  crypto
    hash
    sign
    verify
    keyPair
  blockchain
    Block
    Precommit
    MerkleProof
    MerklePatriciaProof

Notes:

  • blockchain will potentially contain other blockchain-related instances, such as Blockchain or Service
  • I'm not sure which is better: types or type
  • I wonder if Pubkey or Signature should be primitive datatypes, or just byte arrays with specific length

Drop unnecessary size field

Why we have to set size directly for JS library?

name: {type: Exonum.String, size: 8, from: 0, to: 8},

We can calculate size as to - from or use internal constants associated with type like we do in core library. Right?

Uniform coding style?

It could be beneficial to use a uniform coding style for all JS projects. I like semistandard (it is currently used in pwbox), although it is a subject of discussion. Such a tool can also be used as a linter, which is necessary for writing quality code.

Review code style

Reviewing defensive coding style (explicit type comparisons, === false, etc.)

BadRequest("Invalid 'hash' parameter: Odd number of digits")

Hey there!

I'm trying to submit transactions (and they do endup in the blockchain)!
But I'm getting this weird error printed on the server side...

Sat, 19 May 2018 15:32:15 +0100 ERROR iron::iron Error handling:
Request {
    url: Url { generic_url: "http://192.168.43.29:8000/api/explorer/v1/transactions/[object%20Object]" }
    method: Get
    remote_addr: V4(192.168.43.29:59393)
    local_addr: V4(0.0.0.0:8000)
}
Error was: Compat { error: BadRequest("Invalid \'hash\' parameter: Odd number of digits") }

Submitting the same signed transaction through curl works without any problems:

{
  "body": {
    "issuer": "fa7f9ee43aff70c879f80fa7fd15955c18b98c72310b09e7818310325050cf7a",
    "expiry": "never",
    "description": "print <3 Rust?"
  },
  "protocol_version": 0,
  "service_id": 1,
  "message_id": 0,
  "signature":"15011786453fafa2b432ae8fa1e41eb77ebdc1c831e694c0a362f1c0f51aff5d821f47a08d0f89872ff1a4a7ae7b297cc05f821f807b05e1d25632a457d03800"
}

The client code:

#!/usr/bin/env node
let Exonum = require('exonum-client')
const zeroPubKey = '0000000000000000000000000000000000000000000000000000000000000000'

let ServiceDelegate = Exonum.newType({
  fields: [
    { name: 'issuer', type: Exonum.PublicKey },
    { name: 'expiry', type: Exonum.String },
    { name: 'description', type: Exonum.String },
    { name: 'resolution', type: Exonum.PublicKey }
  ]
})

const keyPair = {
  publicKey: 'fa7f9ee43aff70c879f80fa7fd15955c18b98c72310b09e7818310325050cf7a',
  secretKey: '978e3321bd6331d56e5f4c2bdb95bf471e95a77a6839e68d4241e7b0932ebe2b' +
  'fa7f9ee43aff70c879f80fa7fd15955c18b98c72310b09e7818310325050cf7a'
}

const data_sd = {
  issuer: keyPair.publicKey,
  expiry: 'never',
  description: 'print <3 Rust?',
  resolution: zeroPubKey
}

////////////////////////////////////////////////
// Testing signing and signature verification //
////////////////////////////////////////////////

let signature_sd = Exonum.sign(keyPair.secretKey, data_sd, ServiceDelegate)

if (Exonum.verifySignature(signature_sd, keyPair.publicKey, data_sd, ServiceDelegate)) {
    console.log("OK, signature verified!")
} else {
    console.log("Nope")
}

/////////////////////////////////////
// Let's compose a transaction now //
/////////////////////////////////////

let createServiceDelegate = Exonum.newMessage({
  protocol_version: 0,
  service_id: 1,
  message_id: 0,
  fields: [
    { name: 'issuer', type: Exonum.PublicKey },
    { name: 'expiry', type: Exonum.String },
    { name: 'description', type: Exonum.String }
  ]
})

const data_create_sd = {
  issuer: keyPair.publicKey,
  expiry: 'never',
  description: 'print <3 Rust?'
}

let signature_create_sd = createServiceDelegate.sign(keyPair.secretKey, data_create_sd)
if (Exonum.verifySignature(signature_create_sd, keyPair.publicKey, data_create_sd, createServiceDelegate)) {
    console.log("OK, signature verified: "+signature_create_sd)
} else {
    console.log("Nope")
}

const transactionEndpoint = 'http://192.168.43.29:8000/api/services/empathy/v1/delegates'
const explorerBasePath = 'http://192.168.43.29:8000/api/explorer/v1/transactions/'

Exonum.send(transactionEndpoint, explorerBasePath, data_create_sd, signature_create_sd, createServiceDelegate)
  .then(tx => {
      console.log(tx)
  })
  .catch(err => {
      console.log(err)
  })

Exonum-client version: 0.8.0
Exonum version: 0.7.0

Documentation refactoring

It could be beneficial to split documentation from /README.md into several files and put them into the /doc folder, as per the npm spec, probably as tutorials (which can be later referenced from jsdocs via @tutorial tags). Each file could reference a specific section of the exonum module, e.g.:

  • Data types and messages
  • Cryptography
  • Merkle proofs
  • Work with blockchain

Main README could contain one or two examples how to use the lightweight client.

Also, there are several issues with the documentation contents, such as the repeated usage of bits instead of bytes in specifying datatype lengths. And sometimes the lengths of datatypes in examples is seemingly wrong. For example, in some cases signatures take 32 bytes, whereas they should take 64 bytes.

Travis CI

Travis CI integration should be enabled for the project. In order to do this, scripts.test should probably specified in package.json because Travis executes npm test for testing by default.

Make it work with Typescript

I'm making use of exonum-client using Typescript on NodeJS v10.
I did:
$ npm i @types/node --save
$ npm i exonum-client --save

Now TSLint is giving me this error:

[ts] Could not find a declaration file for module 'exonum-client'. '/Users/username/workarea/node_proj/project/node_modules/exonum-client/lib/index.js' implicitly has an 'any' type. Try 'npm install @types/exonum-client' if it exists or add a new declaration (.d.ts) file containing 'declare module 'exonum-client';'

I'd request that $ npm i @types/exonum-client is made available. If not, then kindly supply a exonum-client/index.d.ts with exports and declarations done properly.

Bugs in documentation & how to use the client with the rust server

Hey peeps,

Thanks for providing such great open source libraries. Found some issues.

Documentation has bugs e.g:

var SendFunds = Exonum.newMessage({
    size: 24,
    network_id: 0,
    protocol_version: 0,
    service_id: 0,
    message_id: 0,
    signature: '07038584a4a77510ea5eced45f54dc030f5864ab6a5a2190666b47c676bcf15a' +
     '1f2f07703c5bcafb5749aa735ce8b7c366752be882314f5bbbc9a6af2ae634fc',
    fields: {
        from: {type: Exonum.Hash, size: 8, from: 0, to: 8},
        to: {type: Exonum.Hash, size: 8, from: 8, to: 16},
        amount: {type: Exonum.Uint64, size: 8, from: 16, to: 24}
    }
});

Where Exonum.Hash seems to actually be 32-bytes rather than 8 and thus the actual size is wrong and causes a runtime error.

There is no mention of where the above signature actually comes from nor any mention of the primitives required to form a keyPair (even though it is mandatory to know that tweetnacl is the underlying cryptographic library being used). If you use Exonums default way of signing the body and follow the docs the result doesn't work:

         var keyA = Exonum.keyPair();

         var walletType = Exonum.newType({
             size: 40,
             fields: {
                 pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32},
                 name: {type: Exonum.String, size: 8, from: 32, to: 40}
             }
         });

         var walletData = {
             pub_key: keyA.publicKey,
             name: "Someone"
         };

         var walletSignature = Exonum.sign(keyA.secretKey, walletData, walletType);

         var walletJson = {
             body: walletData,
             network_id: 0,
             protocol_version: 0,
             service_id: 1,
             message_id: 1,
             signature: walletSignature
         };

         fetch('http://127.0.0.1:8000/api/services/some_chain/v1/wallets/transaction', {method: 'POST', body: JSON.stringify(walletJson)})
             .then(result => {
                 console.log(result);
             })
             .catch(error => {
                 console.log(error);
             });

Which begs the question how do you form the signature as per the curl requests in the documentation in order to match what is expected?

Can I disable check transaction status after send?

In some case, e.g. if we created long-timed block (5 - 10 min or min 100+ transaction per block), current client isn't good way to sending transaction. If big block (or long timeout) we haven't transaction status "committed" as long, as we collected data at mempool. But current logic create periodical check status.

May be we can disable query to explorer api? In example, set explorerBasePath (in send function) to Null or attempts counter to 0? With this we can send more transaction per second (and with less memory usage) from one client too.

Verify an error messages in tests

Verify not only error type but also message:
expect(() => Exonum.someMethod(params)).to.throw(Error);
to
expect(() => Exonum.someMethod(params)).to.throw(Error, 'Thrown error message...');

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.