1.1.41 • Published 5 years ago

incubed v1.1.41

Weekly downloads
13
License
in3
Repository
github
Last release
5 years ago

INCUBED

The Minimal Verification Client

INCUBED = A trustless INcentivized remote Node Network = IN3

Getting started

INCUBED can be used in different ways

StackSizeCode BaseUse Case
TS/ JavaScript2.7MBhttps://github.com/slockit/in3WebApplication (decentralized RPC-Client in the Browser) or Mobile Applications
C/C++210kBhttps://github.com/slockit/in3-coreIoT-Devices, can be integrated nicely on many micro controllers (like zephyr-supported boards ) or anny other C/C++ -Application
Java360kBhttps://github.com/slockit/in3-coreJava-Implementation of a native-wrapper
Docker67MBhttps://github.com/slockit/in3For replacing existing clients with this docker and connect to incubed via localhost:8545 without the need to change the architecture
bash368kBhttps://github.com/slockit/in3-corethe in3-commandline utils can be used directly as executable within bash-script or on the shell

other Languages (like C#, Python, Go, Rust) will be supported soon (until then you can simply use the shared library directly).

TypeScript/JavaScript

Installing incubes is as easy as installing any other module:

npm install --save in3

Using web3

// import in3-Module
import In3Client from 'in3'
import * as web3 from 'web3'

// use the In3Client as Http-Provider
const web3 = new Web3(new In3Client({
    proof         : 'standard',
    signatureCount: 1,
    requestCount  : 2,
    chainId       : 'mainnet'
}).createWeb3Provider())

// use the web3
const block = await web.eth.getBlockByNumber('latest')
...

Without web3 (Direct API)

Incubed includes a light API, allowinng not only to use all RPC-Methods in a typesafe way, but also to sign transactions and call funnctions of a contract without the web3-library.

For more details see the API-Doc

// import in3-Module
import In3Client from 'in3'

// use the In3Client
const in3 = new In3Client({
    proof         : 'standard',
    signatureCount: 1,
    requestCount  : 2,
    chainId       : 'mainnet'
})

// use the api to call a funnction..
const myBalance = await in3.eth.callFn(myTokenContract, 'balanceOf(address):uint', myAccount)

// ot to send a transaction..
const receipt = await in3.eth.sendTransaction({ 
  to           : myTokenContract, 
  method       : 'transfer(address,uint256)',
  args         : [target,amount],
  confirmations: 2,
  pk           : myKey
})

...

C - Implementation

The C-Implemetation will be released soon!

#include <stdio.h>
#include <in3/client.h>  // the core client
#include <eth_full.h>    // the full ethereum verifier containing the EVM
#include <in3/eth_api.h> // wrapper for easier use
#include <in3_curl.h>    // transport implementation

int main(int argc, char* argv[]) {

  // register a chain-verifier for full Ethereum-Support
  in3_register_eth_full();

  // create new incubed client
  in3_t* c        = in3_new();

  // set your config
  c->transport    = send_curl; // use curl to handle the requests
  c->requestCount = 1;         // number of requests to send
  c->chainId      = 0x1;       // use main chain

  // use a ethereum-api instead of pure JSON-RPC-Requests
  eth_block_t* block = eth_getBlockByNumber(c, atoi(argv[1]), true);
  if (!block)
    printf("Could not find the Block: %s", eth_last_error());
  else {
    printf("Number of verified transactions in block: %i", block->tx_count);
    free(block);
  }

  ...
}

More Details are comming soon...

Java

The Java-Implementation uses a wrapper of the C-Implemenation. That's why you need to make sure the libin3.so or in3.dll or libin3.dylib can be found in the java.library.path, like

java -Djava.library.path="path_to_in3;${env_var:PATH}" HelloIN3.class

import org.json.*;
import in3.IN3;

public class HelloIN3 {  
   // 
   public static void main(String[] args) {
       String blockNumber = args[0]; 
       IN3 in3 = new IN3();
       JSONObject result = new JSONObject(in3.sendRPC("eth_getBlockByNumber",{ blockNumberm ,true})));
       ....
   }
}

Commandline Tool

Based on the C-Implementation a Commandline-Util is build, which executes a JSON-RPC-Request and only delivers the result. This can be used within bash-scripts:

CURRENT_BLOCK = `in3 -c kovan eth_blockNumber`

#or to send a transaction

IN3_PK=`cat mysecret_key.txt` in3 eth_sendTransaction '{"from":"0x5338d77B5905CdEEa7c55a1F3A88d03559c36D73", "to":"0xb5049E77a70c4ea06355E3bcbfcF8fDADa912481", "value":"0x10000"}'

Features

  • Failsafe Connection - The Incubed client will connect to any ethereum-blockchain (providing in3-servers) by randomly selecting nodes within the incubed-network and automatically retry with different nodes, if the node cannot be reached or deliver verifiable responses.
  • Reputation Management - Nodes which are not available will automatically temporarily blacklisted and loose reputation. The selection of a node is based on the weight (or performance) of the node and their availability.
  • Automatic Nodelist Updates - ALl incubed nodes are registered in smart contracts on chain and will trigger events if the nodelist changes. Each request will always return the blocknumber of the last event, so client knows when to update its nodelist.
  • Partial Nodelist - In order to support small devices, the nodelist can be limited and still be fully verified by basing the selection of nodes deterministicly on a client generated seed.
  • MultiChain Support - Incubed is currently supporting any ethereum-based chain. The client can run even parallel requests to different networks without the need to synchronize first.
  • Preconfigured Boot Nodes - While you can configure any registry-contract, the standard version contains configuration with boot nodes for mainnet, kovan, goerli, evan, tobalaba and ipfs.
  • Full Verification of JSON-RPC-Methods - Incubed is able to fully verify all important JSPN-RPC-Methods. This even includes calling functions in smart contract and verifying their return-value (eth_call), which means executing each opcode locally in the client in order to confirm the result.
  • IPFS-Support - Incubed is able to write and read IPFS-content and verify the data by hashing and creating the the multihash.
  • Caching Support - a optional cache allows to store the result of rpc-requests and automatically use it within again within a configurable timespan or if the client if offline. This also includes RPC-Requests, blocks, code and nodelists)
  • Custom Configuration - The client is highly customizable. For each single request a configuration can be explicitly passed or by adjusting it through events (client.on('beforeRequest',...)). This allows to optimize proof-level or number of requests to be send depending in the context.
  • Proof-Levels Incubed support different proof-levels: none - for no verification, standard - for verifying only relevant properties and full - for complete vertification including uncle blocks or previous Transaction (higher payload) )
  • Security-Levels - configurable number of signatures (for PoW) and minimal deposit stored.
  • PoW-Support - For PoW blocks are verified based on blockhashes signed by incubed nodes storing a deposit which they would lose if this blockhash is not correct.
  • PoA-Support - For PoA-Chains blockhashes are verified by extracting the signature from the sealed fields of the blockheader and using the aura-algorithm to determine the signer from the Validatorlist ( with static Validatorlist or contract based validators )
  • Finality-Support - For PoA-Chains the client can require a configurable number of signatures (in percent) to accept it as final.
  • Flexible Transport-layer - The communication-layer between clients and nodes can be overriden, but already support different transport-formats (json/cbor/in3)
  • Replace Latest-Blocks - Since most application per default always ask request for the latest block, which can not be considered as final in a PoW-Chain, a configuration allows to automatically use a certain blockheight to run the request. (like 6 blocks)
  • Light Ethereum API - Incubed comes with a typesafe simple API, which covers all standard JSON-RPC-Requests ( in3.eth.getBalance('0x52bc44d5378309EE2abF1539BF71dE1b7d7bE3b5') ). This API also includes support for signing and sending transactions as well as calling methods in smart contracts without a complete ABI by simply passing the signature of thr method as argument.
  • TypeScript Support - as Incubed is written 100% in typescript, you get all the advantages of a typesafe blockchain.
  • Integrations - Incubes has been successfully tested in all major Browsers, nodejs and even react-native.
  • Signed Requests - Incubed supports the Incentivisation-Layer which requires signed requests in order to assign client-request to certain nodes.

Docker

In order to start the incubed-client as a standalone client (allowing others none-js-application to connect to it), you can start the container as

docker run -d -p 8545:8545  slockit/in3:latest --chainId=mainnet

The application would then accept the following arguments:

paramdescription
--nodeLimitthe limit of nodes to store in the client.
--keepIn3if true, the in3-section of the response will be kept. Otherwise it will be removed after validating the data. This is useful for debugging or if the proof should be used afterwards.
--formatthe format for sending the data to the client. Default is json, but using cbor means using only 30-40% of the payload since it is using binary encoding
--autoConfigif true the config will be adjusted depending on the request
--retryWithoutProofif true the request may be handled without proof in case of an error. (use with care!)
--includeCodeif true, the request should include the codes of all accounts. otherwise only the codeHash is returned. In this case the client may ask by calling eth_getCode() afterwards
--maxCodeCachenumber of max bytes used to cache the code in memory
--maxBlockCachenumber of number of blocks cached in memory
--proof'none' for no verification, 'standard' for verifying all important fields, 'full' verifying all fields even if this means a high payload.
--signatureCountnumber of signatures requested
--finalitypercenage of validators signed blockheaders - this is used for PoA (aura)
--minDepositmin stake of the server. Only nodes owning at least this amount will be chosen.
--replaceLatestBlockif specified, the blocknumber latest will be replaced by blockNumber- specified value
--requestCountthe number of request send when getting a first answer
--timeoutspecifies the number of milliseconds before the request times out. increasing may be helpful if the device uses a slow connection.
--chainIdservers to filter for the given chain. The chain-id based on EIP-155.
--chainRegistrymain chain-registry contract
--mainChainmain chain-id, where the chain registry is running.
--autoUpdateListif true the nodelist will be automatically updated if the lastBlock is newer
--loggerUrla url of RES-Endpoint, the client will log all errors to. The client will post to this endpoint JSON like { id?, level, message, meta? }

Documentation

The following documentations are available:

Chains

Currently incubed is deployed on the following chains:

Mainnet

Registry : 0x2736D225f85740f42D17987100dc8d58e9e16252
ChainId : 0x1 (alias mainnet)
Status : https://in3.slock.it?n=mainnet
NodeList: https://in3.slock.it/mainnet/nd-3

Kovan

Registry : 0x27a37a1210df14f7e058393d026e2fb53b7cf8c1
ChainId : 0x2a (alias kovan)
Status : https://in3.slock.it?n=kovan
NodeList: https://in3.slock.it/kovan/nd-3

Tobalaba

Registry : 0x845E484b505443814B992Bf0319A5e8F5e407879
ChainId : 0x44d (alias tobalaba)
Status : https://in3.slock.it?n=tobalaba
NodeList: https://in3.slock.it/tobalaba/nd-3

Evan

Registry : 0x85613723dB1Bc29f332A37EeF10b61F8a4225c7e
ChainId : 0x4b1 (alias evan)
Status : https://in3.slock.it?n=evan
NodeList: https://in3.slock.it/evan/nd-3

Görli

Registry : 0x85613723dB1Bc29f332A37EeF10b61F8a4225c7e
ChainId : 0x5 (alias goerli)
Status : https://in3.slock.it?n=goerli
NodeList: https://in3.slock.it/goerli/nd-3

IPFS

Registry : 0xf0fb87f4757c77ea3416afe87f36acaa0496c7e9
ChainId : 0x7d0 (alias ipfs)
Status : https://in3.slock.it?n=ipfs
NodeList: https://in3.slock.it/ipfs/nd-3

Registering a own in3-node

If you want to participate in this network and also register a node, you need to send a transaction to the registry-contract calling registerServer(string _url, uint _props).

ABI of the registry:

[{"constant":true,"inputs":[],"name":"totalServers","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_serverIndex","type":"uint256"},{"name":"_props","type":"uint256"}],"name":"updateServer","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_url","type":"string"},{"name":"_props","type":"uint256"}],"name":"registerServer","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"servers","outputs":[{"name":"url","type":"string"},{"name":"owner","type":"address"},{"name":"deposit","type":"uint256"},{"name":"props","type":"uint256"},{"name":"unregisterTime","type":"uint128"},{"name":"unregisterDeposit","type":"uint128"},{"name":"unregisterCaller","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_serverIndex","type":"uint256"}],"name":"cancelUnregisteringServer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_serverIndex","type":"uint256"},{"name":"_blockhash","type":"bytes32"},{"name":"_blocknumber","type":"uint256"},{"name":"_v","type":"uint8"},{"name":"_r","type":"bytes32"},{"name":"_s","type":"bytes32"}],"name":"convict","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_serverIndex","type":"uint256"}],"name":"calcUnregisterDeposit","outputs":[{"name":"","type":"uint128"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_serverIndex","type":"uint256"}],"name":"confirmUnregisteringServer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_serverIndex","type":"uint256"}],"name":"requestUnregisteringServer","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"url","type":"string"},{"indexed":false,"name":"props","type":"uint256"},{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"deposit","type":"uint256"}],"name":"LogServerRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"url","type":"string"},{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"caller","type":"address"}],"name":"LogServerUnregisterRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"url","type":"string"},{"indexed":false,"name":"owner","type":"address"}],"name":"LogServerUnregisterCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"url","type":"string"},{"indexed":false,"name":"owner","type":"address"}],"name":"LogServerConvicted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"url","type":"string"},{"indexed":false,"name":"owner","type":"address"}],"name":"LogServerRemoved","type":"event"}]

To run a incubed node, you simply use docker-compose:

version: '2'
services:
  incubed-server:
    image: slockit/in3-server:latest
    volumes:
    - $PWD/keys:/secure                                     # directory where the private key is stored
    ports:
    - 8500:8500/tcp                                         # open the port 8500 to be accessed by public
    command:
    - --privateKey=/secure/myKey.json                       # internal path to the key
    - --privateKeyPassphrase=dummy                          # passphrase to unlock the key
    - --chain=0x1                                           # chain (kovan)
    - --rpcUrl=http://incubed-parity:8545                   # url of the kovan-client
    - --registry=0xFdb0eA8AB08212A1fFfDB35aFacf37C3857083ca # url of the incubed-registry
    - --autoRegistry-url=http://in3.server:8500             # check or register this node for this url
    - --autoRegistry-deposit=2                              # deposit to use when registering

  incubed-parity:
    image: slockit/parity-in3:v2.2                          # parity-image with the getProof-function implemented
    command:
    - --auto-update=none                                    # do not automatically update the client
    - --pruning=archive
    - --pruning-memory=30000                                # limit storage