Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
ethereumjs-client
Advanced tools
This is the work repository for the EthereumJS client project targetting both Node.js and the browser as a platform.
See Technical Guidelines if you directly want to dive into development info.
Current development stage: EARLY DEVELOPMENT
Project summary from this document is currently outdated. Please refer to our communication channels for some information on the current state of client development.
Installing the Client
npm install ethereumjs-client
For the ethereumjs
CLI command to work run:
npm link
Note: you can also fallback to invoking the client by using ./bin/cli.js
.
Running the Client
Some building blocks for the client have already been implemented or outlined to further build upon.
You can run the current state of the client with:
ethereumjs --network=mainnet [--loglevel=debug]
For development you might want to connect to rinkeby
as the network with the currently
most reliable connection:
ethereumjs --network rinkeby
The help can be shown with:
ethereumjs --help
If you want to have verbose logging output for the p2p communication you can use...
DEBUG=*,-babel [CLIENT_START_COMMAND]
for all output or something more targeted by listing the loggers like
DEBUG=devp2p:rlpx,devp2p:eth,-babel [CLIENT_START_COMMAND]
See also this diagram for an overview of the client structure with the initialization and message flow.
Overview
You can expose a JSON-RPC interface along a client run with:
ethereumjs --rpc
To run just the server without syncing:
ethereumjs --rpc --maxPeers=0
Currently only a small subset of RPC
methods are implemented.(*) You can have a look at the
./lib/rpc/modules/ source folder or the tracking issue
#17 for an overview.
(*) Side note: implementing RPC methods is actually an extremely thankful task for a first-time contribution on the project hint hint. 😄
API Examples
You can use cURL
to request data from an API endpoint. Here is a simple example for
web3_clientVersion:
curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","id":1,"method":"web3_clientVersion", "params": []}' http://localhost:8545
Note that "params": []
can also be omitted in this case.
Or - somewhat more convenient and with formatted output - with a tool like httpie:
http POST http://localhost:8545 jsonrpc=2.0 id=1 method=web3_clientVersion params:=[]
Note the :=
separator for the params
parameter to
indicate raw JSON
as an input.
This will give you an output like the following:
{
"id": "1",
"jsonrpc": "2.0",
"result": "EthereumJS/0.0.5/darwin/node12.15.0"
}
Here an example for a call on an endpoint with the need for parameters. The following call uses
the eth_getBlockByNumer endpoint
to request data for block number 436 (you can use an tool like
RapidTables for conversion to hex
):
curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x1b4", true],"id":1}' http://127.0.0.1:8545
Same with httpie
:
http POST http://localhost:8545 jsonrpc=2.0 id=1 method=eth_getBlockByNumber params:='["0x1b4",true]'
Output:
{
"id": "1",
"jsonrpc": "2.0",
"result": {
"header": {
"bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0xbb7b8287f3f0a933474a79eae42cbca977791171",
"difficulty": "0x04ea3f27bc",
"extraData": "0x476574682f4c5649562f76312e302e302f6c696e75782f676f312e342e32",
"gasLimit": "0x1388",
"gasUsed": "0x",
"mixHash": "0x4fffe9ae21f1c9e15207b1f472d5bbdd68c9595d461666602f2be20daf5e7843",
"nonce": "0x689056015818adbe",
"number": "0x01b4",
"parentHash": "0xe99e022112df268087ea7eafaf4790497fd21dbeeb6bd7a1721df161a6657a54",
"receiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot": "0xddc8b0234c2e0cad087c8b389aa7ef01f7d79b2570bccb77ce48648aa61c904d",
"timestamp": "0x55ba467c",
"transactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
"transactions": [],
"uncleHeaders": []
}
}
In this example, we will run two ethereumjs-clients. The first will be a fast sync client that will connect to the rinkeby network and start downloading the blockchain. The second will be a light client that connects to the first client and syncs headers as they are downloaded.
The first client will use RLPx to connect to the rinkeby network, but will also provide a libp2p listener. The second client will use libp2p to connect to the first client.
Run the first client and start downloading blocks:
ethereumjs --syncmode fast --lightserv true --datadir first --network rinkeby --transports rlpx libp2p:multiaddrs=/ip4/127.0.0.1/tcp/50505/ws
Output:
... INFO [10-24|11:42:26] Listener up transport=rlpx url=enode://1c3a3d70e9fb7c274355b7ffbbb34465576ecec7ab275947fd4bdc7ddcd19320dfb61b210cbacc0702011aea6971204d4309cf9cc1856fce4887145962281907@[::]:30303 INFO [10-24|11:37:48] Listener up transport=libp2p url=/ip4/127.0.0.1/tcp/50505/ws/ipfs/QmYAuYxw6QX1x5aafs6g3bUrPbMDifP5pDun3N9zbVLpEa ...
Copy the libp2p URL from the output. In this example, the url is /ip4/127.0.0.1/tcp/50505/ws/ipfs/QmYAuYxw6QX1x5aafs6g3bUrPbMDifP5pDun3N9zbVLpEa
but it will be different in your case.
Wait until a few thousand blocks are downloaded and then run the second client in a new terminal, using the url above to connect to the first client:
ethereumjs --syncmode light --network rinkeby --datadir second --transports libp2p:multiaddrs=/ip4/0.0.0.0/tcp/50506,bootnodes=/ip4/127.0.0.1/tcp/50505/ws/ipfs/QmYAuYxw6QX1x5aafs6g3bUrPbMDifP5pDun3N9zbVLpEa
Notice that we have to run the second client on port 50506 using the multiaddrs=/ip4/0.0.0.0/tcp/50506
libp2p option to avoid port conflicts.
In this example, we will again perform a light sync by connecting to the first client from above. However, this time we will connect directly to the first client from within a browser window using libp2p websockets.
First, let's set up the browserify bundle:
git clone https://github.com/ethereumjs/ethereumjs-client
cd ethereumjs-client
npm i
npm run build
This will create a new file (dist/bundle.js
) in your source tree. Now, we will create an index.html
file that loads dist/bundle.js
and then serves it up on http://localhost:8080
.
echo '<script src="/dist/bundle.js"></script>' > index.html
npm i -g http-server
http-server
Now, open a new browser window and navigate to http://localhost:8080
. Open the developer console in your browser and run the following command to start syncing to the first client. Again, remember to change the value of bootnodes to match the url of the first client from above:
ethereumjs.run({ network: 'rinkeby', syncmode: 'light', bootnodes: '/ip4/127.0.0.1/tcp/50505/ws/ipfs/QmYAuYxw6QX1x5aafs6g3bUrPbMDifP5pDun3N9zbVLpEa' })
That's it! Now, you should start seeing headers being downloaded to the local storage of your browser. Since IndexDB is being used, even if you close and re-open the browser window, the headers you'll already downloaded will be saved.
Goals
Contributors should aim to achieve the following goals when making design decisions:
The current design tries to achieves the goals of loose coupling and ease of testing by using an event-driven architecture where possible. Readability is improved by using features of JavaScript ES6 such as classes, async/await, promises, arrow functions, for...of, template literals and destructuring assignment among others. Shorter names are used when possible and long functions are broken up into smaller helpers, along with JSDoc annotations for most methods and parameters. Documentation is auto-generated from JSDoc comments and many examples of usage are provided (TO DO).
We will now briefly describe the directory structure and main components of the Ethereumjs client to help contributors better understand how the project is organized.
Directory structure
/bin
Contains the CLI script for the ethereumjs
command/docs
Contains auto-generated API docs as well as other supporting documentation/lib/blockchain
Contains the Chain
class./lib/net
Contains all of the network layer classes including Peer
, Protocol
and its subclasses,
Server
and its subclasses, and PeerPool
./lib/service
Contains the main Ethereum services (FastEthereumService
and LightEthereumService
)/lib/rpc
Contains the RPC server (optionally) embedded in the client./lib/sync
Contains the various chain synchronizers and Fetcher
helpers./tests
Contains test cases, testing helper functions, mocks and test dataComponents
Chain
[In Progress] This class represents the blockchain and is a wrapper around
ethereumjs-blockchain
. It handles creation of the data directory, provides basic blockchain operations
and maintains an updated current state of the blockchain, including current height, total difficulty, and
latest block.Server
This class represents a server that discovers new peers and handles incoming and dropped
connections. When a new peer connects, the Server
class will negotiate protocols and emit a connected
event with a new Peer
instance. The peer will have properties corresponding to each protocol. For example,
if a new peer understands the eth
protocol, it will contain an eth
property that provides all eth
protocol methods (for example: peer.eth.getBlockHeaders()
)
RlpxServer
[In Progress] Subclass of Server
that implements the devp2p/rlpx
transport.Libp2pServer
[In Progress] Subclass of Server
that implements the libp2p
transport.Peer
Represents a network peer. Instances of Peer
are generated by the Server
subclasses and contain instances of supported protocol classes as properties. Instances of Peer
subclasses can also be used to directly connect to other nodes via the connect()
method. Peers emit message
events
whenever a new message is received using any of the supported protocols.
RlpxPeer
[In Progress] Subclass of Peer
that implements the devp2p/rlpx
transport.Libp2pPeer
[In Progress] Subclass of Peer
that implements the libp2p
transport.Protocol
[In Progress] This class and subclasses provide a user-friendly wrapper around the
low level ethereum protocols such as eth/62
, eth/63
and les/2
. Subclasses must define the messages provided by the protocol.
EthProtocol
[In Progress] Implements the eth/62
and eth/63
protocols.LesProtocol
[In Progress] Implements the les/2
protocol.ShhProtocol
[Not Started] Implements the whisper protocol.PeerPool
[In Progress] Represents a pool of network peers. PeerPool
instances emit added
and removed
events when new peers are added and removed and also emit the message
event whenever
any of the peers in the pool emit a message. Each Service
has an associated PeerPool
and they are used primarily by Synchronizer
s to help with blockchain synchronization.Synchronizer
Subclasses of this class implements a specific blockchain synchronization strategy. They
also make use of subclasses of the Fetcher
class that help fetch headers and bodies from pool peers. The fetchers internally make use of streams to handle things like queuing and backpressure.
FastSynchronizer
[In Progress] Implements fast syncing of the blockchainLightSynchronizer
[In Progress] Implements light syncing of the blockchainHandler
Subclasses of this class implements a protocol message handler. Handlers respond to incoming requests from peers.
EthHandler
[In Progress] Handles incoming ETH requestsLesHandler
[In Progress] Handles incoming LES requestsService
Subclasses of Service
will implement specific functionality of a Node
. For example, the EthereumService
subclasses will synchronize the blockchain using the fast or light sync protocols. Each service must specify which protocols it needs and define a start()
and stop()
function.
FastEthereumService
[In Progress] Implementation of ethereum fast sync.LightEthereumService
[In Progress] Implementation of ethereum light sync.WhisperService
[Not Started] Implementation of an ethereum whisper node.Node
[In Progress] Represents the top-level ethereum node, and is responsible for managing the lifecycle of included services.RPCManager
[In Progress] Implements an embedded JSON-RPC server to handle incoming RPC requests.To update the structure diagram files in the root folder open the client.drawio
file in draw.io, make your changes, and open a PR with the updated files. Export svg
and png
with border
width=20
and transparency=false
. For png
go to "Advanced" and select 300 DPI
.
EthereumJS Ecosystem
This project will be embedded in the EthereumJS ecosystem and many submodules already exist and can be used within the project, have a look e.g. at ethereumjs-block, ethereumjs-vm, the merkle-patricia-tree or the ethereumjs-devp2p implementation. Work needs to be done both within this repos and related libraries.
Related issues are labelled with the ethereumjs-client
label, see here for an org-wide search.
See our organizational documentation for an introduction to EthereumJS
as well as information on current standards and best practices.
If you want to join for work or do improvements on the libraries have a look at our contribution guidelines.
[0.0.6] - 2020-06-19
After a longer period of stalled development this release brings the EthereumJS
client back
to life respectively a usable state by doing necessary dependency updates and modernizing CI.
It also comes with an updated documentation and user-facing improvements like a more reliable
and better communicated sync mechanism.
Most notable for development is the upgrade of the ethereumjs-devp2p
dependency to v3.0.1
.
The devp2p library is now TypeScript
based and comes with an improved debugging experience
which will be helpful when working on further improving the sync reliability of the client and
hunting for networking bugs.
To ease jumping into the code base there is now a new structure diagram showing the relations between the main components as well as the initialization and message flow.
Dependencies, CI and Docs
level
and ethereumjs-common
dependency,
PR #111ethereumjs-util
to v7.0.2
,
PR #129README
, Outdated
notice for the project summary,
PR #114JSON-RPC
documentation to README
,
PR #124Bug Fixes and Maintenance
RPC
test method cleanup,
PR #126consensus
and finality
,
PR #120New Features
FAQs
EthereumJS client implementation
The npm package ethereumjs-client receives a total of 7 weekly downloads. As such, ethereumjs-client popularity was classified as not popular.
We found that ethereumjs-client demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.