mirror of
https://github.com/bigchaindb/js-bigchaindb-driver.git
synced 2024-11-22 01:36:56 +01:00
Merge branch 'master' into feature/styling-functional
This commit is contained in:
parent
8702e4c6f2
commit
0b275cc6be
405
README.md
405
README.md
@ -1,60 +1,129 @@
|
|||||||
# JavaScript quickstart for BigchainDB
|
# JavaScript Driver for BigchainDB
|
||||||
|
|
||||||
> :bangbang: High chance of :fire: and :rage: ahead if you expect this to be production-ready.
|
> Inspired by [`js-bigchaindb-quickstart`](https://github.com/sohkai/js-bigchaindb-quickstart) of @sohkhai [thanks]
|
||||||
|
|
||||||
> :bangbang: **ONLY** (and I mean **_only_**) supports BigchainDB Server 0.9
|
> Supports BigchainDB Server v0.10
|
||||||
|
|
||||||
Some naive helpers to get you on your way to making some transactions :boom:, if you'd like to use
|
Some naive helpers to get you on your way to making some transactions, if you'd like to use
|
||||||
[BigchainDB](https://github.com/bigchaindb/bigchaindb) with JavaScript.
|
[BigchainDB](https://github.com/bigchaindb/bigchaindb) with JavaScript.
|
||||||
|
|
||||||
Aimed to support usage in browsers or node; if it doesn't, well, I don't know what to say except
|
Aimed to support usage in browsers or node and ES∞+, so
|
||||||
it's probably you :smirk:. Use at your own risk :rocket:. At least I can tell you it's ES∞+, so
|
|
||||||
you'll probably need a babel here and a bundler there (or use [one of the built versions](./dist)),
|
you'll probably need a babel here and a bundler there (or use [one of the built versions](./dist)),
|
||||||
of which I expect you'll know quite well ([otherwise, go check out js-reactor :wink:](https://github.com/bigchaindb/js-reactor)).
|
of which I expect you'll know quite well ([otherwise, go check out js-reactor](https://github.com/bigchaindb/js-reactor)).
|
||||||
|
|
||||||
|
## Contents
|
||||||
|
|
||||||
|
- [Getting Started](#getting-started)
|
||||||
|
- [Usage](#usage)
|
||||||
|
- [Speed Optimizations](#speed-optimizations)
|
||||||
|
- [Warnings](#warnings)
|
||||||
|
- [API](#api)
|
||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
Srs, just read through [index.js](./index.js) and see if you can make any sense of it.
|
### Install from npm
|
||||||
|
|
||||||
You may also be interested in a [long-form example with actual code](#example).
|
```
|
||||||
|
npm install js-bigchaindb-driver
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Install from GitHub
|
||||||
|
|
||||||
|
Depending on your GitHub login credentials
|
||||||
|
|
||||||
|
- ssh
|
||||||
|
```
|
||||||
|
npm install git+ssh://github.com/bigchaindb/js-bigchaindb-driver.git
|
||||||
|
```
|
||||||
|
|
||||||
|
- https
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install git+https://github.com/bigchaindb/js-bigchaindb-driver.git
|
||||||
|
```
|
||||||
|
|
||||||
|
### Browser / ES6
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import * as driver from 'js-bigchaindb-driver';
|
||||||
|
```
|
||||||
|
|
||||||
|
### Browser / require
|
||||||
|
```javascript
|
||||||
|
let driver = require('js-bigchaindb-driver');
|
||||||
|
```
|
||||||
|
|
||||||
|
### CommonJS / node
|
||||||
|
```javascript
|
||||||
|
let driver = require('js-bigchaindb-driver/dist/node');
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import * as driver from 'js-bigchaindb-driver';
|
||||||
|
|
||||||
|
// http(s)://<bigchaindb-API-url>/ (e.g. http://localhost:9984/api/v1/)
|
||||||
|
const API_PATH = 'http://localhost:9984/api/v1/';
|
||||||
|
|
||||||
|
// create a new user with a public-private keypair
|
||||||
|
const alice = new driver.Ed25519Keypair();
|
||||||
|
|
||||||
|
// Create a transation
|
||||||
|
const tx = driver.Transaction.makeCreateTransaction(
|
||||||
|
{ assetMessage: 'My very own asset...' },
|
||||||
|
{ metaDataMessage: 'wrapped in a transaction' },
|
||||||
|
[ driver.Transaction.makeOutput(
|
||||||
|
driver.Transaction.makeEd25519Condition(alice.publicKey))
|
||||||
|
],
|
||||||
|
alice.publicKey
|
||||||
|
);
|
||||||
|
|
||||||
|
// sign/fulfill the transaction
|
||||||
|
const txSigned = driver.Transaction.signTransaction(tx, alice.privateKey);
|
||||||
|
|
||||||
|
// send it off to BigchainDB
|
||||||
|
driver.Connection
|
||||||
|
.postTransaction(txSigned, API_PATH)
|
||||||
|
.then((res) => {
|
||||||
|
// request the status of the transaction
|
||||||
|
driver.Connection
|
||||||
|
.getStatus(txSigned.id, API_PATH)
|
||||||
|
.then((res) => console.log('Transaction status:', res.status))});
|
||||||
|
```
|
||||||
|
|
||||||
|
You may also be interested in some [long-form tutorials with actual code](https://github.com/bigchaindb/kyber).
|
||||||
|
|
||||||
The expected flow for making transactions:
|
The expected flow for making transactions:
|
||||||
|
|
||||||
1. Go get yourself some keypairs! Just make a `new Keypair()` (or a whole bunch of them, nobody's
|
1. Go get yourself some keypairs! (or a whole bunch of them, nobody's
|
||||||
counting :sunglasses:).
|
counting)
|
||||||
1. Go get yourself a condition! `makeEd25519Condition()` should do the trick :sparkles:.
|
- `new driver.Ed25519Keypair()`
|
||||||
1. Go wrap that condition as an output (don't worry about the *why*)! `makeOutput()` no sweat
|
1. Construct a transaction payload that you can send of to BigchainDB:
|
||||||
:muscle:.
|
- `driver.Transaction.makeCreateTransaction()` for creating a new asset or
|
||||||
1. (**Optional**) You've got everyting you need, except for an asset. Maybe define one (any
|
- `driver.Transaction.makeTransferTransaction()` for transfering an existing asset
|
||||||
|
1. A transaction needs an output (\*):
|
||||||
|
- `driver.Transaction.makeOutput()` still requires a crypto-condition
|
||||||
|
- `driver.Transaction.makeEd25519Condition()` should do the trick for a simple public key output.
|
||||||
|
1. (**Optional**) You've got everything you need, except for an asset and metadata. Maybe define them (any
|
||||||
JSON-serializable object will do).
|
JSON-serializable object will do).
|
||||||
1. Time to get on the rocket ship, baby. `makeCreateTransaction()` your way to lifelong glory and
|
1. Ok, now you've got a transaction, but we need you to *sign* it cause, you
|
||||||
fame :clap:!
|
know... cryptography and `¯\_(ツ)_/¯`:
|
||||||
1. Ok, now you've got a transaction, but we need you to *sign* (`signTransaction()`) it cause, you
|
- `driver.Transaction.signTransaction()` allows you to sign with private keys.
|
||||||
know... cryptography and `¯\_(ツ)_/¯`.
|
1. Final step is to send the transaction off to BigchainDB:
|
||||||
1. Alright, sick dude, you've *finally* got everything you need to `POST` to a server. Phew
|
- `driver.Connection.postTransaction()`
|
||||||
:sweat_drops:. Go `fetch()` your way to business, start:point_up:life4evar!
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
Alright, alright, so you've made a couple transactions. Now what? Do I hear you saying
|
(\*) If you're not sure what any of this means (and you're as
|
||||||
"<sub>Transfer them??</sub>" No problem, brotha, I gotcha covered :neckbeard:.
|
|
||||||
|
|
||||||
1. Go get some more outputs (wrapping conditions), maybe based on some new made-up friends (i.e.
|
|
||||||
keypairs).
|
|
||||||
1. Go make a transfer transaction, using the transaction you want to *spend* (i.e. you can fulfill)
|
|
||||||
in `makeTransferTransaction()` :v:. *If you're not sure what any of this means (and you're as
|
|
||||||
confused as I think you are right now), you might wanna go check out [this](https://docs.bigchaindb.com/projects/server/en/latest/data-models/crypto-conditions.html)
|
confused as I think you are right now), you might wanna go check out [this](https://docs.bigchaindb.com/projects/server/en/latest/data-models/crypto-conditions.html)
|
||||||
and [this](https://docs.bigchaindb.com/projects/py-driver/en/latest/usage.html#asset-transfer)
|
and [this](https://docs.bigchaindb.com/projects/py-driver/en/latest/usage.html#asset-transfer)
|
||||||
and [this](https://tools.ietf.org/html/draft-thomas-crypto-conditions-01) first.*
|
and [this](https://tools.ietf.org/html/draft-thomas-crypto-conditions-01) first.
|
||||||
1. Sign that transaction with `signTransaction()`!
|
|
||||||
1. `POST` to the server, and watch the :dollar:s drop, man.
|
|
||||||
|
|
||||||
## Needs for speeds
|
## Speed Optimizations
|
||||||
|
|
||||||
This implementation plays "safe" by using JS-native (or downgradable) libraries for its
|
This implementation plays "safe" by using JS-native (or downgradable) libraries for its
|
||||||
crypto-related functions to keep compatabilities with the browser. If that makes you :unamused: and
|
crypto-related functions to keep compatibilities with the browser. If you do want some more speed, feel free to explore the following:
|
||||||
you'd rather go :godmode: with some :zap: :zap:, you can try using some of these to go as fast as a
|
|
||||||
:speedboat: --:surfing_man: :
|
|
||||||
|
|
||||||
* [chloride](https://github.com/dominictarr/chloride), or its underlying [sodium](https://github.com/paixaop/node-sodium)
|
* [chloride](https://github.com/dominictarr/chloride), or its underlying [sodium](https://github.com/paixaop/node-sodium)
|
||||||
library
|
library
|
||||||
@ -62,13 +131,13 @@ you'd rather go :godmode: with some :zap: :zap:, you can try using some of these
|
|||||||
if [the FIPS 202 upgrade](https://github.com/phusion/node-sha3/pull/25) hasn't been merged
|
if [the FIPS 202 upgrade](https://github.com/phusion/node-sha3/pull/25) hasn't been merged
|
||||||
(otherwise, you'll run into all kinds of hashing problems)
|
(otherwise, you'll run into all kinds of hashing problems)
|
||||||
|
|
||||||
## :rotating_light: WARNING WARNING WARNING :rotating_light:
|
## Warnings
|
||||||
|
|
||||||
> Crypto-conditions
|
> Crypto-conditions
|
||||||
|
|
||||||
Make sure you keep using a crypto-conditions implementation that implements the older v1 draft (e.g.
|
Make sure you keep using a crypto-conditions implementation that implements the older v1 draft (e.g.
|
||||||
[`five-bells-condition@v3.3.1`](https://github.com/interledgerjs/five-bells-condition/releases/tag/v3.3.1)).
|
[`five-bells-condition@v3.3.1`](https://github.com/interledgerjs/five-bells-condition/releases/tag/v3.3.1)).
|
||||||
BigchainDB Server 0.9 does not implement the newer version of the spec and **WILL** fail if you to
|
BigchainDB Server 0.10 does not implement the newer version of the spec and **WILL** fail if you to
|
||||||
use a newer implementation of crypto-conditions.
|
use a newer implementation of crypto-conditions.
|
||||||
|
|
||||||
> SHA3
|
> SHA3
|
||||||
@ -78,255 +147,33 @@ Otherwise, the hashes you generate **WILL** be invalid in the eyes of the Bigcha
|
|||||||
|
|
||||||
> Ed25519
|
> Ed25519
|
||||||
|
|
||||||
If you do end up replacing `tweetnacl` with `chloride` (or any other Ed25519 package), you might
|
If you do end up replacing `tweetnacl` with `chloride` (or any other `Ed25519` package), you might
|
||||||
want to double check that it gives you a correct public/private (or verifying/signing, if they use
|
want to double check that it gives you a correct public/private (or verifying/signing, if they use
|
||||||
that lingo) keypair.
|
that lingo) keypair.
|
||||||
|
|
||||||
An example BigchainDB Server-generated keypair (encoded in base58):
|
An example BigchainDB Server-generated keypair (encoded in `base58`):
|
||||||
|
|
||||||
- Public: "DjPMHDD9JtgypDKY38mPz9f6owjAMAKhLuN1JfRAat8C"
|
- Public: `DjPMHDD9JtgypDKY38mPz9f6owjAMAKhLuN1JfRAat8C`
|
||||||
- Private: "7Gf5YRch2hYTyeLxqNLgTY63D9K5QH2UQ7LYFeBGuKvo"
|
- Private: `7Gf5YRch2hYTyeLxqNLgTY63D9K5QH2UQ7LYFeBGuKvo`
|
||||||
|
|
||||||
Your package should be able to take in the decoded version of the **private** key and return you the
|
Your package should be able to take in the decoded version of the **private** key and return you the
|
||||||
same **public** key (once you encode that to base58).
|
same **public** key (once you encode that to `base58`).
|
||||||
|
|
||||||
-------
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
OK, OK, I gotcha, you'd rather see some *actual* code rather than a giant list of steps that don't
|
|
||||||
mean anything. :point_down: is for you.
|
|
||||||
|
|
||||||
```js
|
|
||||||
import {
|
|
||||||
Ed25519Keypair,
|
|
||||||
makeEd25519Condition,
|
|
||||||
makeOutput,
|
|
||||||
makeCreateTransaction,
|
|
||||||
makeTransferTransaction,
|
|
||||||
signTransaction,
|
|
||||||
} from 'js-bigchaindb-quickstart'; // Or however you'd like to import it
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* CREATE transaction *
|
|
||||||
**********************/
|
|
||||||
// First, create a keypair for our new friend, Ash (let's be real--who would you rather catch some
|
|
||||||
// Pokemon: Alice or the Ketchum man himself?)
|
|
||||||
const ash = new Ed25519Keypair();
|
|
||||||
|
|
||||||
console.log(ash.publicKey); // something like "DjPMHDD9JtgypDKY38mPz9f6owjAMAKhLuN1JfRAat8C"
|
|
||||||
console.log(ash.privateKey); // something like "7Gf5YRch2hYTyeLxqNLgTY63D9K5QH2UQ7LYFeBGuKvo"
|
|
||||||
|
|
||||||
// Let's get an output and condition that lets Ash be the recipient of the new asset we're creating
|
|
||||||
const ashCondition = new makeEd25519Condition(ash.publicKey);
|
|
||||||
const ashOutput = new makeOutput(ashCondition);
|
|
||||||
|
|
||||||
console.log(ashOutput);
|
|
||||||
/* Something like
|
|
||||||
{
|
|
||||||
"amount": 1,
|
|
||||||
"condition": {
|
|
||||||
"details": {
|
|
||||||
"signature": null,
|
|
||||||
"type_id": 4,
|
|
||||||
"type": "fulfillment",
|
|
||||||
"bitmask": 32,
|
|
||||||
"public_key": "DjPMHDD9JtgypDKY38mPz9f6owjAMAKhLuN1JfRAat8C"
|
|
||||||
},
|
|
||||||
"uri": "cc:4:20:vSfobaaMSP52nxnVkPiLMysCTR-t8JpjbWIdU6SvRYU:96"
|
|
||||||
},
|
|
||||||
"public_keys": [
|
|
||||||
"DjPMHDD9JtgypDKY38mPz9f6owjAMAKhLuN1JfRAat8C"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Let's make an asset, to pretend this isn't boring.
|
|
||||||
const pokeAsset = {
|
|
||||||
'name': 'Pikachu',
|
|
||||||
'trait': 'Will never, ever, EVAARRR leave your back'
|
|
||||||
};
|
|
||||||
|
|
||||||
const noMetadata = null; // Let's ignore that meta-stuff for now
|
|
||||||
|
|
||||||
// Now let's go give Ash his beloved Pikachu
|
|
||||||
const createPokeTx = makeCreateTransaction(pokeAsset, noMetadata, [ashOutput], ash.publicKey);
|
|
||||||
|
|
||||||
console.log(createPokeTx);
|
|
||||||
/* Something like
|
|
||||||
{
|
|
||||||
"id": "38acf7a938a39be335afc8e7300468b981a29813d52938104ba3badfe21470c9",
|
|
||||||
"operation": "CREATE",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"amount": 1,
|
|
||||||
"condition": {
|
|
||||||
"details": {
|
|
||||||
"signature": null,
|
|
||||||
"type_id": 4,
|
|
||||||
"type": "fulfillment",
|
|
||||||
"bitmask": 32,
|
|
||||||
"public_key": "DjPMHDD9JtgypDKY38mPz9f6owjAMAKhLuN1JfRAat8C"
|
|
||||||
},
|
|
||||||
"uri": "cc:4:20:vSfobaaMSP52nxnVkPiLMysCTR-t8JpjbWIdU6SvRYU:96"
|
|
||||||
},
|
|
||||||
"public_keys": [
|
|
||||||
"DjPMHDD9JtgypDKY38mPz9f6owjAMAKhLuN1JfRAat8C"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"fulfillment": null,
|
|
||||||
"fulfills": null,
|
|
||||||
"owners_before": [
|
|
||||||
"DjPMHDD9JtgypDKY38mPz9f6owjAMAKhLuN1JfRAat8C"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"metadata": null,
|
|
||||||
"asset": {
|
|
||||||
"data": {
|
|
||||||
"name": "Pikachu",
|
|
||||||
"trait": "Will never, ever, EVAARRR leave your back"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"version": "0.9"
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Let's sign this thing to make it legit! (Let's call Ash the "issuer", but a registered PokeCorp
|
|
||||||
// could be the one issuing instead)
|
|
||||||
const signedCreateTx = signTransaction(createPokeTx, ash.privateKey);
|
|
||||||
|
|
||||||
console.log(signedPokeTx);
|
|
||||||
/* Something like
|
|
||||||
{
|
|
||||||
"id": "38acf7a938a39be335afc8e7300468b981a29813d52938104ba3badfe21470c9",
|
|
||||||
"operation": "CREATE",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"amount": 1,
|
|
||||||
"condition": {
|
|
||||||
"details": {
|
|
||||||
"signature": null,
|
|
||||||
"type_id": 4,
|
|
||||||
"type": "fulfillment",
|
|
||||||
"bitmask": 32,
|
|
||||||
"public_key": "DjPMHDD9JtgypDKY38mPz9f6owjAMAKhLuN1JfRAat8C"
|
|
||||||
},
|
|
||||||
"uri": "cc:4:20:vSfobaaMSP52nxnVkPiLMysCTR-t8JpjbWIdU6SvRYU:96"
|
|
||||||
},
|
|
||||||
"public_keys": [
|
|
||||||
"DjPMHDD9JtgypDKY38mPz9f6owjAMAKhLuN1JfRAat8C"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"fulfillment": "cf:4:vSfobaaMSP52nxnVkPiLMysCTR-t8JpjbWIdU6SvRYWj-cp1qb1vsTSt_775cGe-NQFxgyUQvcPx1nWkJRgXhMvTk2vN2QJU_nd2DgeTbIcWBF-8-N1SH2WqQLsXJLcP",
|
|
||||||
"fulfills": null,
|
|
||||||
"owners_before": [
|
|
||||||
"DjPMHDD9JtgypDKY38mPz9f6owjAMAKhLuN1JfRAat8C"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"metadata": null,
|
|
||||||
"asset": {
|
|
||||||
"data": {
|
|
||||||
"name": "Pikachu",
|
|
||||||
"trait": "Will never, ever, EVAARRR leave your back"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"version": "0.9"
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Alright, now you've got yourself a valid transaction and you can do some crazy thing like send it
|
|
||||||
// over to a BigchainDB node. I'll leave that as an exercise for you ;).
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* TRANSFER transaction *
|
|
||||||
************************/
|
|
||||||
// Alright, let's get Ash some imaginary friends (remember Brock? Neither do I)
|
|
||||||
const brock = new Ed25519Keypair(); // public: "H8ZVy61CCKh5VQV9nzzzggNW8e5CyTbSiegpdLqLSmqi", private: "5xoYuPP92pznaGZF9KLsyAdR5C7yDU79of1KA9UK4qKS"
|
|
||||||
|
|
||||||
// Let's pretend that, for the sake of this example, Ash can actually part with Pikachu. Let's trade
|
|
||||||
// Pikachu to Brock (we won't be getting anything back, but if it helps, you can pretend Brock'll
|
|
||||||
// give Ash some help with his love life).
|
|
||||||
const brockCondition = new makeEd25519Condition(brock.publicKey);
|
|
||||||
const brockOutput = new makeOutput(brockCondition);
|
|
||||||
|
|
||||||
// Let's create the TRANSFER transaction cementing this trade. We'll use the "unspent" CREATE
|
|
||||||
// transaction that assigned Pikachu to Ash as an input to this TRANSFER.
|
|
||||||
// Note that we'll keep ignoring that metadata stuff.
|
|
||||||
// Also note that we could use either `createPokeTx` (unsigned) or `signedCreateTx` (signed) here
|
|
||||||
// for the input transaction. Either way, we'll be fulfilling the first (and only) output set in it.
|
|
||||||
const fulfilledOutputIndex = 0;
|
|
||||||
const transferPokeTx = makeTransferTransaction(createPokeTx, noMetadata, [brockOutput], fulfilledOutputIndex);
|
|
||||||
|
|
||||||
// OK, let's sign this TRANSFER (Ash has to, as he's the one currently in "control" of Pikachu)
|
|
||||||
const signedTransferTx = signTransaction(transferPokeTx, ash.privateKey);
|
|
||||||
|
|
||||||
console.log(signedTransferTx);
|
|
||||||
/* If everything went well, you should get something like this
|
|
||||||
{
|
|
||||||
"id": "0876962a40479e171135cd92dbae7f0216f2691561b56a579cff631371d4d128",
|
|
||||||
"operation": "TRANSFER",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"amount": 1,
|
|
||||||
"condition": {
|
|
||||||
"details": {
|
|
||||||
"signature": null,
|
|
||||||
"type_id": 4,
|
|
||||||
"type": "fulfillment",
|
|
||||||
"bitmask": 32,
|
|
||||||
"public_key": "H8ZVy61CCKh5VQV9nzzzggNW8e5CyTbSiegpdLqLSmqi"
|
|
||||||
},
|
|
||||||
"uri": "cc:4:20:76rNv-DAIjZC0-68Gl0KEuDpcJRpCAAQXxvVbTvQAxE:96"
|
|
||||||
},
|
|
||||||
"public_keys": [
|
|
||||||
"H8ZVy61CCKh5VQV9nzzzggNW8e5CyTbSiegpdLqLSmqi"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"fulfillment": "cf:4:vSfobaaMSP52nxnVkPiLMysCTR-t8JpjbWIdU6SvRYU8UJKi0Oq7QoCXIHuiWEYzxfgVEYs9HHtDIWBSkq1uvMX6l7VKwUCrK93k6JMNVBA8djOa5UGfDDF49xLVEgQI",
|
|
||||||
"fulfills": {
|
|
||||||
"output": 0,
|
|
||||||
"txid": "38acf7a938a39be335afc8e7300468b981a29813d52938104ba3badfe21470c9"
|
|
||||||
},
|
|
||||||
"owners_before": [
|
|
||||||
"DjPMHDD9JtgypDKY38mPz9f6owjAMAKhLuN1JfRAat8C"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"metadata": null,
|
|
||||||
"asset": {
|
|
||||||
"id": "38acf7a938a39be335afc8e7300468b981a29813d52938104ba3badfe21470c9"
|
|
||||||
},
|
|
||||||
"version": "0.9"
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Assuming you figured out how to send a transaction to a BigchainDB node, and that the federation
|
|
||||||
// you sent it to has validated the CREATE transaction you sent, you should now be able to cement
|
|
||||||
// the TRANSFER of Pikachu to Brock by sending `signedTransferTx` to a node in the same federation.
|
|
||||||
|
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
=========================================================================================================
|
### Keypairs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************
|
|
||||||
* *
|
|
||||||
* ~~~ CHALLENGE ~~~ *
|
|
||||||
* *
|
|
||||||
* So who's making the decentralized version of Pokemon? *
|
|
||||||
* (cause I want in) *
|
|
||||||
* *
|
|
||||||
*************************************************************/
|
|
||||||
```
|
```
|
||||||
|
new Ed25519Keypair(secret)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Transaction
|
||||||
|
|
||||||
|
```
|
||||||
|
Transaction(secret)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Connection
|
Loading…
Reference in New Issue
Block a user