Getting Started¶
INCUBED can be used in different ways.
table
Stack | Size | Code Base | Use Case |
---|---|---|---|
TS/JS | 2.7MB (browserified) | TypeScript | WebApplication (Client in the Browser) or Mobile Applications |
C/C++ | 200kB | C | IoT-Devices, can be integrated nicely on many micro controllers (like [zephyr-supported boards] (https://docs.zephyrproject.org/latest/boards/index.html) ) or anny other C/C++ -Application |
Java | 205kB | C | Java-Implementation of a native-wrapper |
Docker | 74MB | TypeScript | For replacing existing clients with this docker and connect to incubed via localhost:8545 without the need to change the architecture |
bash | 200kB | C | the commandline utils can be used directly as executable within bash-script or on the shell |
other Languages will be supported soon (or can simply use the shared library directly).
TypeScript/JavaScript¶
Installing incubes is as easy as installing any other module:
npm install --save in3
As Provider in Web3¶
The Incubed Client also implements the Provider-Interface used in the web3-Library and can be used directly.
// 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')
...
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
})
...
As Docker-Container¶
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:
- –nodeLimit
- the limit of nodes to store in the client.
- –keepIn3
- if true, the in3-section of thr 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.
- –format
- the 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.
- –autoConfig
- if true the config will be adjusted depending on the request
- –retryWithoutProof
- if true the request may be handled without proof in case of an error. (use with care!)
- –includeCode
- if 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
- –maxCodeCache
- number of max bytes used to cache the code in memory
- –maxBlockCache
- number of number of blocks cached in memory
- –proof
- ‘none’ for no verification, ‘standard’ for verifying all important fields, ‘full’ veryfying all fields even if this means a high payload.
- –signatureCount
- number of signatures requested
- –finality
- percenage of validators signed blockheaders - this is used for PoA (aura)
- –minDeposit
- min stake of the server. Only nodes owning at least this amount will be chosen.
- –replaceLatestBlock
- if specified, the blocknumber latest will be replaced by blockNumber- specified value
- –requestCount
- the number of request send when getting a first answer
- –timeout
- specifies the number of milliseconds before the request times out. increasing may be helpful if the device uses a slow connection.
- –chainId
- servers to filter for the given chain. The chain-id based on EIP-155.
- –chainRegistry
- main chain-registry contract
- –mainChain
- main chain-id, where the chain registry is running.
- –autoUpdateList
- if true the nodelist will be automaticly updated if the lastBlock is newer
- –loggerUrl
- a url of RES-Endpoint, the client will log all errors to. The client will post to this endpoint JSON like { id?, level, message, meta? }
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"}'
Supported 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 automaticly update the client
- --pruning=archive
- --pruning-memory=30000 # limit storage