Giter Club home page Giter Club logo

neo-js's Introduction

City of Zion logo

neo-js

Running NEO blockchain full node with Node.js and MongoDB.

npm version

Overview

neo-js package is designed to interface with the NEO blockchain in a number of different ways that are configured by options that are used to initialize a node. A few examples of these different interaction mechanics are defined in the quickstart below as well as in the examples.

This is not a SDK library for interacting with NEO blockchain. You are looking for neon-js.

Getting Started

Preparations

Currently this module only support MongoDB for synchronizing the blockchain. You are expect to be connected to an instance of MongoDB 3.2+ to use most of its features.

System Recommendations

  • NodeJS 8+
  • MongoDB 3.2+

Installation

Install the package using:

$ npm install --save @cityofzion/neo-js

Alternatively, to access to the latest available code, you can reference to the git repository directly:

$ npm install --save git://github.com/CityOfZion/neo-js.git#develop

Quick Start

More comprehensive examples can be found at neo-js-examples repository.

const Neo = require('@cityofzion/neo-js').Neo

To create a new blockchain instance:

// Create a neo instances to interface with RPC methods
const testnetNeo = new Neo({ network: 'testnet' })

// Wait for mesh to be ready before attempt to fetch block information
testnetNeo.mesh.on('ready', () => {
  testnetNeo.api.getBlockCount()
    .then((res) => {
      console.log('Testnet getBlockCount:', res)
    })
})

// To connect to the mainnet:
const mainnetNeo = new Neo({ network: 'mainnet' })

mainnetNeo.mesh.on('ready', () => {
  mainnetNeo.api.getBlock(1000)
    .then((res) => {
      console.log('Mainnet getBlock(1000).hash:', res.hash)
    })
})

This will create a new node instance and configure it to sync the blockchain to the defined mongoDB collections:

const options = {
  network: 'testnet',
  storageType: 'mongodb',
  storageOptions: {
    connectionString: 'mongodb://localhost/neo_testnet',
  },
}

// Create a neo instance
const neo = new Neo(options)

// Get block height
neo.storage.on('ready', () => {
  neo.storage.getHighestBlockHeight()
    .then((res) => {
      console.log('Block height:', res)
    })
})

Documentation

Documentation for the project can be found at:

You can find more code examples at repository:

Blockchain Bootstrap Files

Please refer to Bootstrap Files document

Options

Please refer to Optional Parameters document

Events

Please refer to Event Emitters document

Contribution

neo-js always encourages community code contribution. Before contributing please read the contributor guidelines and search the issue tracker as your issue may have already been discussed or fixed. To contribute, fork neo-js, commit your changes and submit a pull request.

By contributing to neo-js, you agree that your contributions will be licensed under its MIT license.

License

neo-js's People

Contributors

hmcq6 avatar iryusa avatar rockacola avatar slipo avatar thomaslobker avatar tudorconstantin 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  avatar  avatar  avatar  avatar  avatar

Watchers

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

neo-js's Issues

Proposal for neo-js version 0.5

A major refactor and formalisation proposal for neo-js. This is to set a formal step towards version 1, catering for in-browser scripting purpose or as node background service.

What 0.5 provides

  • Isolation on major components such as enum, rpc, neo where user can choose their level of utilisation for their purpose.
  • Finer optional controls and dependency injections for customisation capability.
  • Remove concept of light/full node, instead, finer options (convention over configurations) will be available..
  • Introduce data access layer, provides possibility for different types of data storage methods: currently only supports MongoDB, with intention to implement for LevelDB.

What 1.0 aim to provide

  • Formal system requirement definitions.
  • Developer/contributor’s guideline
  • Adequate unit/integration testings and code coverage
  • CI
  • Modularised node packages
  • Complete generated documentations
  • Thorough example usages (as a form of manual documentation)
  • Semi-formal milestone for future versions

What’s not within consideration before 1.0

  • Semantic versioning
  • Legacy system/browser support
  • Smart contract compilation

Getting error: neo is not a function

I followed the instructions:

var neo = require('neo-js-blockchain'); var neoBlockchain = neo('full', 'mainnet');

I'm getting error:

TypeError: neo is not a function at Object.<anonymous> (/home/NEO/index.js:2:21) at Module._compile (module.js:635:30) at Object.Module._extensions..js (module.js:646:10) at Module.load (module.js:554:32) at tryModuleLoad (module.js:497:12) at Function.Module._load (module.js:489:3) at Function.Module.runMain (module.js:676:10) at startup (bootstrap_node.js:187:16) at bootstrap_node.js:608:3

Please help.

Thank you.

TypeError: x is not a function

I am trying to follow the instruction and run the code below.

var neo = require('neo-js-blockchain');
var neoBlockchain = neo('light', 'mainnet');
neoBlockchain.sync.start();

var node = require('./neo.blockchain.node.js');
var n = node({'domain': 'http://seed1.neo.org', 'port': 10332});
node.getBestBlockHash();

but I got TypeError: x is not a function error. Can anyone give me a hint?

var neoBlockchain = neo('light', 'mainnet');
                    ^
TypeError: neo is not a function

n.getBestBlockHash();
  ^
TypeError: n.getBestBlockHash is not a function

Event-driven or observer pattern

Introduce optional, pass forward EventEmitter instance to components.

This is to allow higher customisable event bindings that leads to granulate user control and decoupling of components.

neo.storage.getAssetBalance err

neo.storage.getAssetBalance(addr, kacHash)
https://github.com/CityOfZion/neo-js/blob/develop/examples/smoke-test/asset.js

05:53:00.234 Storage error: getExpandedTX Promise.all err: TypeError: Cannot read property 'vout' of null
    at tx.vin._.map (C:\atest\neo-js\dist\node\storage.js:314:48)
    at arrayMap (C:\atest\neo-js\node_modules\lodash\lodash.js:631:23)
    at Function.map (C:\atest\neo-js\node_modules\lodash\lodash.js:9546:14)
    at Promise.all.then (C:\atest\neo-js\dist\node\storage.js:314:26)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)
05:59:14.478 examples:rpc-endpoints info: assetBalance: { asset: '0x602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7',
  balance: 72411.84199755987,
  index: 148065,
  type: 'a' }

System asset support

Code to support asset handling on the blockchain including parsing of the invoke script for relevant metadata

dynamic seed registration rpc method

Extension of core rpc methods to enable dynamic node registration.

This method will be invoked with inputs containing the requestor's contact information as its configuration information (what type of node it is etc..)

When invoked, this method should return a dump off all the nodes that the node instance is tracking with their most recent states. This information will be used to integrate a new node into the mesh.

Missing .gitignore

Propose starting with following ignores:

node_modules
package-lock.json

refactor and break out models into separate libraries

neo.blockchain.db currently contains all the schema and connection information for the full node.

Refactor neo.blockchain.db -> neo.node.storage

Break out the mongoDB model and implementation into its own library(s) which is optionally imported by neo.node.storage based on an input set of options.

Misleading error when network endpoints invalid

I added an endpoint with the wrong port, got an odd error, when it's actually a wrong network endpoint passed in via the options

Error: index not defined

node.js:72 while ((this.blockWritePointer < this.mesh.highestNode().index) &&

This originates in the setInterval loop in node.js - deferredUpdateLoop

Turns out Promise rejections from the rpc function getBlockCount are ignored, in rpc.js the call function returns a Promise.reject when there is an HTTP error, but there is no promise.catch in getBlockCount.

Then mesh.highestNode() returns undefined since that error caused the node's active flag to be set to false.

Unhandled exception when there are no valid nodes

Context (Environment)

  • neo-js Version: 0.8.1
  • node Version: v10.2.1
  • Operation System: Ubuntu 18.04 LTS
  • MongoDB Version (if applicable): version v3.6.3

Expected behavior

When all nodes are unavailable I'm expecting the synchronization to stop temporarily until nodes become available again.

Actual behavior

First I'm getting a clean error message notifying that there are no more valid nodes, then the whole script is crashing with the following error message:

/usr/local/src/neo-js/node_modules/@cityofzion/neo-js/dist/strategy/sync-strategy.js:224
    const max = node.index || index
                     ^

TypeError: Cannot read property 'index' of undefined
    at SyncStrategy.enqueueBlock (/usr/local/src/neo-js/node_modules/@cityofzion/neo-js/dist/strategy/sync-strategy.js:224:22)
    at Timeout.setTimeout [as _onTimeout] (/usr/local/src/neo-js/node_modules/@cityofzion/neo-js/dist/strategy/sync-strategy.js:115:18)
    at ontimeout (timers.js:427:11)
    at tryOnTimeout (timers.js:289:5)
    at listOnTimeout (timers.js:252:5)
    at Timer.processTimers (timers.js:212:10)

Steps to reproduce the behavior

  1. Run neo-js as a full node
  2. Wait for a day or so, until there is a moment where no more nodes are responsive
  3. Or disconnect your network (haven't tried it, but I assume this will trigger it as well)

smart contract support

smart contract support for the nodes including parsing of script invocations for relevant metadata as well as high level events for transactions on the blockchain using the rpc methods

merge node class instances

There are currently two node class instances (one for rpc/light nodes and one for local/full nodes). They need to be joined into a single class.

deployment of multiple node instances with rpc support for development use

One of the primary goals of the neo-js project is to implement a network of nodes which enable 'full-node' levels of functionality without synchronizing the entire blockchain. This task will include the development and deployment of multiple neo-js nodes which expose the functionality of the module via rpc methods.

Primary entry point missing in npm package

Primary entry point missing in npm package

  • neo-js Version: 0.8.0
  • node Version: 10
  • Operation System: Ubuntu
  • MongoDB Version (if applicable): any

Expected behavior

Being able to require @cityofzion/neo-js after npm i @cityofzion/neo-js
const Node = require('@cityofzion/neo-js');

Actual behavior

    throw err;
    ^

Error: Cannot find module '@cityofzion/neo-js'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:571:15)
    at Function.Module._load (internal/modules/cjs/loader.js:497:25)
    at Module.require (internal/modules/cjs/loader.js:626:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at Object.<anonymous> (index.js:1:76)
    at Module._compile (internal/modules/cjs/loader.js:678:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)
    at Module.load (internal/modules/cjs/loader.js:589:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:528:12)
    at Function.Module._load (internal/modules/cjs/loader.js:520:3)

Steps to reproduce the behavior

  1. npm i @cityofzion/neo-js
  2. echo "const Node = require('@cityofzion/neo-js');" > index.js
  3. nodejs index.js

LoggerService

Introduce LoggerService that able to configure verbose level of components.

This in turn will phase out traditional console.log usages and allows user to set the desirable verbose level for his usage.

ECONNREFUSED 47.94.164.49:10332

usign this Code

const Node = require('@cityofzion/neo-js');
const nodeT = new Node({ network: 'testnet' })

nodeT.mesh.getBlock(10).then(res=>{

console.log(res);

}).catch(err=>{

console.log(err);
});

Error: connect ECONNREFUSED 47.94.164.49:10332
at Object.exports._errnoException (util.js:1020:11)
at exports._exceptionWithHostPort (util.js:1043:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1090:14)
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect',
address: '47.94.164.49',
port: 10332,
config:
{ adapter: [Function: httpAdapter],
transformRequest: { '0': [Function: transformRequest] },
transformResponse: { '0': [Function: transformResponse] },
timeout: 10000,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
headers:
{ Accept: 'application/json, text/plain, /',
'Content-Type': 'application/json;charset=utf-8',
'User-Agent': 'axios/0.16.2',
'Content-Length': 60 },
method: 'post',
url: 'http://seed1.neo.org:10332',
data: '{"jsonrpc":"2.0","method":"getblock","params":[10,1],"id":0}' },
request:
Writable {
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
needDrain: false,
ending: false,
ended: false,
finished: false,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: true,
bufferProcessing: false,
onwrite: [Function],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: false,
errorEmitted: false,
bufferedRequestCount: 0,
corkedRequestsFree: [Object] },
writable: true,
domain: null,
_events:
{ response: [Function: handleResponse],
error: [Function: handleRequestError] },
_eventsCount: 2,
_maxListeners: undefined,
_options:
{ protocol: 'http:',
maxRedirects: 21,
maxBodyLength: 10485760,
hostname: 'seed1.neo.org',
port: '10332',
path: '/',
method: 'post',
headers: [Object],
agent: undefined,
auth: undefined,
nativeProtocols: [Object],
pathname: '/' },
_redirectCount: 0,
_requestBodyLength: 60,
_requestBodyBuffers: [ [Object] ],
_onNativeResponse: [Function],
_currentRequest:
ClientRequest {
domain: null,
_events: [Object],
_eventsCount: 6,
_maxListeners: undefined,
output: [],
outputEncodings: [],
outputCallbacks: [],
outputSize: 0,
writable: true,
_last: true,
upgrading: false,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedHeader: [Object],
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: false,
_headerSent: true,
socket: [Object],
connection: [Object],
_header: 'POST / HTTP/1.1\r\nAccept: application/json, text/plain, /\r\nContent-Type: application/json;charset=utf-8\r\nUser-Agent: axios/0.16.2\r\nContent-Length: 60\r\nHost: seed1.neo.org:10332\r\nConnection: close\r\n\r\n',
_headers: [Object],
_headerNames: [Object],
_onPendingData: null,
agent: [Object],
socketPath: undefined,
timeout: undefined,
method: 'POST',
path: '/',
_ended: false,
_redirectable: [Circular],
parser: null },
_currentUrl: 'http://seed1.neo.org:10332/' },
response: undefined }

refactor neo.blockchain.db and break out models

neo.blockchain.db currently contains all the schema and connection information for the full node.

Refactor neo.blockchain.db -> neo.node.storage

Break out the mongoDB model and implementation into its own library(s) which is optionally imported by neo.node.storage based on an input set of options.

Basic example in docs doesn't work in node 8.9.1-LTS

Hi there,

I believe I'm following the documentation correctly. I installed neo-blockchain-js using the line:

npm install neo-js-blockchain --save

It installed without any errors, but with some warnings (note, I've redacted the path):

npm WARN saveError ENOENT: no such file or directory, open '/Users/[ ... ]/neo/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/Users/[ ... ]/neo/package.json'
npm WARN neo No description
npm WARN neo No repository field.
npm WARN neo No README data
npm WARN neo No license field.

+ [email protected]
added 37 packages in 2.432s

Then I try the following examples from the docs in the node REPL:

> var neo = require('neo-js-blockchain');
undefined
> var neoBlockchain = neo('light', 'mainnet');
TypeError: neo is not a function
    at repl:1:21
    at ContextifyScript.Script.runInThisContext (vm.js:50:33)
    at REPLServer.defaultEval (repl.js:240:29)
    at bound (domain.js:301:14)
    at REPLServer.runBound [as eval] (domain.js:314:12)
    at REPLServer.onLine (repl.js:441:10)
    at emitOne (events.js:121:20)
    at REPLServer.emit (events.js:211:7)
    at REPLServer.Interface._onLine (readline.js:282:10)
    at REPLServer.Interface._line (readline.js:631:8)
> neo
{ neo: [Function: neo] }
>

What's wrong here?

Opinions on JavaScript transpiler and preprocessor usages

I would like to yield interests and opinions on pushing the project a step closer to defacto-standard, at a cost of increasing learning curve. There are potential we can result in even better coding practises and decrease environment requirements (particularly browsers).

Detailed logging

Now that LoggerService (PR #94) is complete, we'll to add comprehensive log messages through out all modules for readabilities.

neo-js experimental branch

During the period of neo-js inactive period, there were some concerns raised in NEO blockchain leads to re-prioritise short term goals for this project to better fit with real world needs:

  • Several nodes has been hit with high traffic causing transaction delay and overall performance. Consideration of adding pure bookkeeping node to potentially off load from consensus nodes.
  • Heavy dependence on availability of neoscan API, also lack of alternative or self hosted solutions especially for analysing privatenet.
  • A better mean to health check/benchmark nodes. ie/ An alternative approach to http://monitor.cityofzion.io/

An experiment (orphan) branch is in motion as a ground up redevelopment with following emphasis (some has already been put in place since 0.8):

  • Project will be written in TypeScript, enforcing strict typing as a measurement of bug/edge case mitigation during rapid developments.
  • Heavy logging and highly configurable.
  • Heavy event emitting allows better application customizations.
  • Validator pattern usage, project is now more likely to throw errors when appropriate.
  • Delegators and duck typing usages for forward compatibility for variations of certain components.

Continuous development of neo-js will start off with smaller set of features and its progress will be roughly partitioned into following phases:

  • Phase 1: Synchronizer for whole blockchain, or as per configured.
  • Phase 2: A RESTful API act as RPC delegates on ‘read only’ endpoints.
  • Phase 3: Provide neoscan equivalent REST API endpoints

The project will be released as 1.0 once it able to define itself as a minimal viable product. From that point on, Semver will be used for its continuous development.

Technical features to be implemented within foreseeable future as follow:

  • Block ignore list
  • Seamless RPC-JSON API endpoints
  • Block inconsistent (ie/ fork) alert mechanism

New features may be proposed throughout the development, hence this is issue ticket should be treated as a reference for direction of the project, please refers to proper project milestones are they become available.

Error: timeout of 10000ms exceeded

const Node = require('@cityofzion/neo-js');

const nodeT = new Node({ network: 'testnet' });

nodeT.mesh.rpc('getBlock', 1000).then(res=>{
console.log(res);
}).catch(err=>{

console.log(err);
});

Just installed the package and followed the example in docs and got error Error: timeout of 10000ms exceeded

getAssetBalance issue

There seems to be an issue with balance checking when the address is in the vin part of the transaction.

Even though the pull request #161 addresses this, the issue persists if the transaction is not expanded because it doesn't contain the address in this case.
For example, the following vin record may refer to the address for which we're trying to get the balance but it will not be returned since there's no address:

{
    "vout" : 9998,
    "txid" : "0x3e17f0897f1dcd322476c8c1f5bfd8ac74f3e8d48353b8c87baf7bbcc4783b3f"
}

I tried to do a workaround for it by calling storage.getExpandedTX() when the transaction is saved to DB but it doesn't work because the save process is async so the referred tx may not be saved yet.

Project code refactor proposal

Excerpt

This code refactor proposal contains 3 parts, but since they are closely intertwined I decided to have them in the same issue ticket where discussions, suggestions and feedbacks are most welcome.

Shall the community able to reach consensus partially or fully, a developer to be designated on making the refactorization PRs.

Progress

  • uniform code style (following standard), mostly aligning spacings
  • ES6 adaptations (this opens up talks for developer's guide and formal system requirements)
  • separation of concerns (relevant to #32), enum pattern, utils/helper classes
  • feature toggle, adaptation of optional parameters and dependencies injection (this may indirectly result in increase of performance)

Proposals

1. Language and dependencies:

1.1. Project to be coded in JavaScript ES6 format + await/async usage.

1.2. No transpilers to be used. Although this will reduce supporting environments, my vote goes toward debuggability and reducing complexity.

1.3. Adapt Moment handling datetime related implementations.

2. System requirements:

2.1. Minimum Node Node 8+ for async/await support and taking advantage of its LTS.

2.2. Minimum browser requirement is to be browsers that supports await/async. That is: Edge 15+, Firefox 52+, Chrome 55+, Safari 10.1+.

3. Coding style guide:

3.1. Follow JavaScript Standard Style as guidance . Developers are recommend to install Standard package globally as Node command line program and perform style checks before submitting PR.

3.2. Allow optional dependency injection of axios library. This is the pre-requisite to support unit testing within the project.

3.3. Separate and modularize magic numbers and strings into a static object.

3.4. Expose axios and lodash and other 3rd party libraries as included utilities. This is to give neo-js package users option to utilise these libraries instead of separate reference(s).

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.