From 6c01d375768d46d16486449835e230595dfa9412 Mon Sep 17 00:00:00 2001 From: michielmulders Date: Tue, 26 Sep 2017 16:05:25 +0200 Subject: [PATCH 01/10] Solved throw payload message at baserequest --- src/baseRequest.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/baseRequest.js b/src/baseRequest.js index e75e92a..0b5a829 100644 --- a/src/baseRequest.js +++ b/src/baseRequest.js @@ -74,7 +74,11 @@ export default function baseRequest(url, { jsonBody, query, urlTemplateSpec, ... // If status is not a 2xx (based on Response.ok), assume it's an error // See https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/fetch if (!(res && res.ok)) { - throw res + throw { + message: "HTTP Error: Couldn't reach requested webpage", + status: res.status + " " + res.statusText, + requestURI: res.url + } } return res }) From 823d340d6102edd166c92c8f499086efb90c3f15 Mon Sep 17 00:00:00 2001 From: michielmulders Date: Tue, 26 Sep 2017 16:19:36 +0200 Subject: [PATCH 02/10] Updated errorObject to match TravisCI criteria --- src/baseRequest.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/baseRequest.js b/src/baseRequest.js index 0b5a829..3f53370 100644 --- a/src/baseRequest.js +++ b/src/baseRequest.js @@ -74,11 +74,12 @@ export default function baseRequest(url, { jsonBody, query, urlTemplateSpec, ... // If status is not a 2xx (based on Response.ok), assume it's an error // See https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/fetch if (!(res && res.ok)) { - throw { - message: "HTTP Error: Couldn't reach requested webpage", - status: res.status + " " + res.statusText, + let errorObject = { + message: 'HTTP Error: Requested page not reachable', + status: '${res.status} ${res.statusText}', requestURI: res.url } + throw errorObject } return res }) From 42c037c6aca8010fa4195150b6818021a9608bc5 Mon Sep 17 00:00:00 2001 From: michielmulders Date: Tue, 26 Sep 2017 16:25:07 +0200 Subject: [PATCH 03/10] Trying to match TravisCI Criteria --- src/baseRequest.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/baseRequest.js b/src/baseRequest.js index 3f53370..99d7fc4 100644 --- a/src/baseRequest.js +++ b/src/baseRequest.js @@ -74,9 +74,9 @@ export default function baseRequest(url, { jsonBody, query, urlTemplateSpec, ... // If status is not a 2xx (based on Response.ok), assume it's an error // See https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/fetch if (!(res && res.ok)) { - let errorObject = { + const errorObject = { message: 'HTTP Error: Requested page not reachable', - status: '${res.status} ${res.statusText}', + status: (res.status) + ' ' + (res.statusText), requestURI: res.url } throw errorObject From ce9e88bac3ccf80911774f4b6e2cac8971470b31 Mon Sep 17 00:00:00 2001 From: michielmulders Date: Tue, 26 Sep 2017 16:29:52 +0200 Subject: [PATCH 04/10] Fixed for TravisCI --- src/baseRequest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/baseRequest.js b/src/baseRequest.js index 99d7fc4..90ce3b2 100644 --- a/src/baseRequest.js +++ b/src/baseRequest.js @@ -76,7 +76,7 @@ export default function baseRequest(url, { jsonBody, query, urlTemplateSpec, ... if (!(res && res.ok)) { const errorObject = { message: 'HTTP Error: Requested page not reachable', - status: (res.status) + ' ' + (res.statusText), + status: `${res.status} ${res.statusText}`, requestURI: res.url } throw errorObject From 6703fd88396f538ca2ffd72bb46f8b70da3d4961 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Wed, 27 Sep 2017 05:09:47 +0000 Subject: [PATCH 05/10] chore(package): update release-it to version 3.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e190554..48f7732 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "husky": "^0.14.0", "lint-staged": "^4.0.0", "nyc": "^11.0.2", - "release-it": "^2.7.3", + "release-it": "^3.0.0", "rimraf": "^2.5.4", "sinon": "^3.0.0", "webpack": "^3.0.0" From f82cbd652645a9191968e5cc94ae7fec38e97f21 Mon Sep 17 00:00:00 2001 From: michielmulders Date: Wed, 27 Sep 2017 15:37:49 +0200 Subject: [PATCH 06/10] Writing test for baserequest --- test/connection/test_connection.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/connection/test_connection.js b/test/connection/test_connection.js index 8e7e495..83a82b3 100644 --- a/test/connection/test_connection.js +++ b/test/connection/test_connection.js @@ -7,6 +7,16 @@ import { Connection } from '../../src' const API_PATH = 'http://localhost:9984/api/v1/' const conn = new Connection(API_PATH) +test('payload thrown at incorrect API_PATH', t => { + const path = 'http://localhost:9984/api/wrong/' + const conn = new Connection(path) + const target = { + message: 'HTTP Error: Requested page not reachable', + status: '404 NOT FOUND', + requestURI: 'http://localhost:9984/api/wrong/transactionId' + } + t.deepEqual(target, conn.getTransaction("transactionId")) +}) test('generate API URLS', t => { const endpoints = { From b77d2960695f218b66c87526760bd1157e3ceec2 Mon Sep 17 00:00:00 2001 From: michielmulders Date: Wed, 27 Sep 2017 15:38:52 +0200 Subject: [PATCH 07/10] Writing test for baserequest --- test/connection/test_connection.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/connection/test_connection.js b/test/connection/test_connection.js index 83a82b3..5c16baa 100644 --- a/test/connection/test_connection.js +++ b/test/connection/test_connection.js @@ -9,13 +9,13 @@ const conn = new Connection(API_PATH) test('payload thrown at incorrect API_PATH', t => { const path = 'http://localhost:9984/api/wrong/' - const conn = new Connection(path) + const connection = new Connection(path) const target = { message: 'HTTP Error: Requested page not reachable', status: '404 NOT FOUND', requestURI: 'http://localhost:9984/api/wrong/transactionId' } - t.deepEqual(target, conn.getTransaction("transactionId")) + t.deepEqual(target, connection.getTransaction('transactionId')) }) test('generate API URLS', t => { From 2fa812940a6bab401ff0655df7befd2716f07ac9 Mon Sep 17 00:00:00 2001 From: michielmulders Date: Thu, 28 Sep 2017 16:08:41 +0200 Subject: [PATCH 08/10] Added information and code about spent vs unspent transactions --- docs/source/usage.rst | 130 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/docs/source/usage.rst b/docs/source/usage.rst index 4b958bb..15f5efc 100644 --- a/docs/source/usage.rst +++ b/docs/source/usage.rst @@ -357,6 +357,136 @@ Recap: Asset Creation & Transfer .then(() => conn.searchAssets('Bicycle Inc.')) .then(assets => console.log('Found assets with serial number Bicycle Inc.:', assets)) +Difference unspent and spent output +----------------------------------- +An unspent output is simply an output of a transaction which isn't yet an input of another transaction. +So, if we transfer an asset, the output becomes spent, because it becomes the input of the transfer transaction. +The transfer transactions its output becomes unspent now until he transfers the asset again to somebody else. + +We will demonstrate this with a piece of code where we transfer a bicycle from Alice to Bob, +and further we transfer it from Bob to Chris. Expectations: + +* Output for Alice is spent +* Output for Bob is spent +* Output for Chris is unspent (he is the last person in transaction chain) + +.. code-block:: js + + const driver = require('bigchaindb-driver') + const API_PATH = 'http://localhost:9984/api/v1/' + const conn = new driver.Connection(API_PATH) + + const alice = new driver.Ed25519Keypair() + const bob = new driver.Ed25519Keypair() + const chris = new driver.Ed25519Keypair() + + console.log('Alice: ', alice.publicKey) + console.log('Bob: ', bob.publicKey) + console.log('Chris: ', chris.publicKey) + + // Define the asset to store, in this example + // we store a bicycle with its serial number and manufacturer + assetdata = { + 'bicycle': { + 'serial_number': 'cde', + 'manufacturer': 'Bicycle Inc.', + } + } + + var txTransferBobSigned; + + // Construct a transaction payload + const txCreateAliceSimple = driver.Transaction.makeCreateTransaction( + assetdata, + {'meta': 'meta'}, + // A transaction needs an output + [ driver.Transaction.makeOutput( + driver.Transaction.makeEd25519Condition(alice.publicKey)) + ], + alice.publicKey + ) + + // Sign the transaction with private keys of Alice to fulfill it + const txCreateAliceSimpleSigned = driver.Transaction.signTransaction(txCreateAliceSimple, alice.privateKey) + console.log('\n\nPosting signed create transaction for Alice:\n', txCreateAliceSimpleSigned) + + conn.postTransaction(txCreateAliceSimpleSigned) + // Check status of transaction every 0.5 seconds until fulfilled + .then(() => conn.pollStatusAndFetchTransaction(txCreateAliceSimpleSigned.id)) + + // Transfer bicycle from Alice to Bob + .then(() => { + const txTransferBob = driver.Transaction.makeTransferTransaction( + txCreateAliceSimpleSigned, + {'newOwner': 'Bob'}, + [driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(bob.publicKey))], + 0) + + // Sign with alice's private key + txTransferBobSigned = driver.Transaction.signTransaction(txTransferBob, alice.privateKey) + console.log('\n\nPosting signed transaction to Bob:\n', txTransferBobSigned) + + // Post and poll status + return conn.postTransaction(txTransferBobSigned) + }) + .then(res => conn.pollStatusAndFetchTransaction(res.id)) + + // Second transfer of bicycle from Bob to Chris + .then(tx => { + const txTransferChris = driver.Transaction.makeTransferTransaction( + txTransferBobSigned, + {'newOwner': 'Chris'}, + [driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(chris.publicKey))], + 0) + + // Sign with bob's private key + let txTransferChrisSigned = driver.Transaction.signTransaction(txTransferChris, bob.privateKey) + console.log('\n\nPosting signed transaction to Chris:\n', txTransferChrisSigned) + + // Post and poll status + return conn.postTransaction(txTransferChrisSigned) + }) + .then(res => conn.pollStatusAndFetchTransaction(res.id)) + .then(() => conn.listOutputs(alice.publicKey, true)) + .then(listSpentOutputs => { + console.log("\nSpent outputs for Alice: ", listSpentOutputs.length) // Spent outputs: 1 + return conn.listOutputs(alice.publicKey, false) + }) + .then(listUnspentOutputs => { + console.log("Unspent outputs for Alice: ", listUnspentOutputs.length) // Unspent outputs: 0 + return conn.listOutputs(bob.publicKey, true) + }) + .then(listSpentOutputs => { + console.log("\nSpent outputs for Bob: ", listSpentOutputs.length) // Spent outputs: 1 + return conn.listOutputs(bob.publicKey, false) + }) + .then(listUnspentOutputs => { + console.log("Unspent outputs for Bob: ", listUnspentOutputs.length) // Unspent outputs: 0 + return conn.listOutputs(chris.publicKey, true) + }) + .then(listSpentOutputs => { + console.log("\nSpent outputs for Chris: ", listSpentOutputs.length) // Spent outputs: 0 + return conn.listOutputs(chris.publicKey, false) + }) + .then(listUnspentOutputs => { + console.log("Unspent outputs for Chris: ", listUnspentOutputs.length) // Unspent outputs: 1 + }) + .catch(res => {console.log(res)}) + +Output of above code looks like this. As you can see, Chris has no spent output, but one unspent output. + +.. code-block:: js + + Spent outputs for Alice: 1 + Unspent outputs for Alice: 0 + + Spent outputs for Bob: 1 + Unspent outputs for Bob: 0 + + Spent outputs for Chris: 0 + Unspent outputs for Chris: 1 + + Divisible Assets ---------------- From f4333a92c1cb0f24289fa16bac6a428784e32fe2 Mon Sep 17 00:00:00 2001 From: michielmulders Date: Sat, 30 Sep 2017 19:18:50 +0200 Subject: [PATCH 09/10] Test added for testing payload thrown at incorrect API_PATH --- test/connection/test_connection.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test/connection/test_connection.js b/test/connection/test_connection.js index 5c16baa..435e38b 100644 --- a/test/connection/test_connection.js +++ b/test/connection/test_connection.js @@ -7,18 +7,21 @@ import { Connection } from '../../src' const API_PATH = 'http://localhost:9984/api/v1/' const conn = new Connection(API_PATH) -test('payload thrown at incorrect API_PATH', t => { +test('Payload thrown at incorrect API_PATH', t => { const path = 'http://localhost:9984/api/wrong/' const connection = new Connection(path) const target = { message: 'HTTP Error: Requested page not reachable', status: '404 NOT FOUND', - requestURI: 'http://localhost:9984/api/wrong/transactionId' + requestURI: 'http://localhost:9984/api/wrong/transactions/transactionId' } - t.deepEqual(target, connection.getTransaction('transactionId')) + connection.getTransaction('transactionId') + .catch(error => { + t.deepEqual(target, error) + }) }) -test('generate API URLS', t => { +test('Generate API URLS', t => { const endpoints = { 'blocks': 'blocks', 'blocksDetail': 'blocks/%(blockId)s', From df484832edc72ec7c82007fec999a1a7a8adcc31 Mon Sep 17 00:00:00 2001 From: Michiel Mulders Date: Thu, 12 Oct 2017 13:40:23 +0200 Subject: [PATCH 10/10] added const for declaring objects --- docs/source/usage.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/source/usage.rst b/docs/source/usage.rst index 15f5efc..9f64498 100644 --- a/docs/source/usage.rst +++ b/docs/source/usage.rst @@ -64,7 +64,7 @@ that represents a bicycle: .. code-block:: js - assetdata = { + const assetdata = { 'bicycle': { 'serial_number': 'abcd1234', 'manufacturer': 'Bicycle Inc.', @@ -86,7 +86,7 @@ For example, the bicycle will be transferred on earth which is metadata: .. code-block:: js - metadata = {'planet': 'earth'} + const metadata = {'planet': 'earth'} Asset Creation -------------- @@ -288,7 +288,7 @@ Recap: Asset Creation & Transfer // Define the asset to store, in this example // we store a bicycle with its serial number and manufacturer - assetdata = { + const assetdata = { 'bicycle': { 'serial_number': 'cde', 'manufacturer': 'Bicycle Inc.', @@ -298,7 +298,7 @@ Recap: Asset Creation & Transfer // Metadata contains information about the transaction itself // (can be `null` if not needed) // E.g. the bicycle is fabricated on earth - metadata = {'planet': 'earth'} + const metadata = {'planet': 'earth'} // Construct a transaction payload const txCreateAliceSimple = driver.Transaction.makeCreateTransaction( @@ -495,4 +495,4 @@ Yet to come! .. TODO: .. - Add lexer: https://stackoverflow.com/questions/4259105/which-sphinx-code-block-language-to-use-for-json .. - Add divisible assets example -.. - Add more readable code with promises possibly. \ No newline at end of file +.. - Add more readable code with promises possibly.