# nSPV
# Introduction
nSPV enhances the normal "Simple Payment Verification" (SPV) technology available for a Smart Chain. To learn more about regular SPV technology, read this entry on the Bitcoin wiki. (opens new window)
nSPV leverages the dPoW security mechanism of the Komodo Platform to enable secure and scalable super-lite "SPV" clients. An nSPV client network utilizes a smaller amount of computation and storage resources compared to a normal SPV network. For all Smart Chains, all the full nodes on the Smart Chain's network can serve the necessary data to nSPV clients for the latter to have full wallet functionality.
All Komodo-compatible Smart Chains, including the KMD main chain, can utilize this technology.
More details are available in the blog posts here (opens new window) and here. (opens new window)
# Installation
Follow the instructions below to set up an nSPV client.
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install build-essential pkg-config libc6-dev m4 libsodium-dev curl libevent-dev git cmake nano wget ntp ntpdate automake unzip autoconf libtool -y
git clone https://github.com/KomodoPlatform/libnspv
cd libnspv
./autogen.sh
./configure
./onetime # compiles cc support
make
# Enabling the nSPV Client
Copy the following code to the file named coins
(located at the root level of the source directory).
(Change each value as appropriate for the desired Smart Chain.)
{
"coin": "COIN",
"asset": "COIN",
"fname": "Coin",
"rpcport": 12345,
"mm2": 1,
"p2p": 12346,
"magic": "feb4cb23",
"nSPV": "5.9.102.210, 5.9.253.195, 5.9.253.196, 5.9.253.197, 5.9.253.198, 5.9.253.199, 5.9.253.200, 5.9.253.201, 5.9.253.202, 5.9.253.203"
}
# Property Descriptions
Name | Type | Description |
---|---|---|
coin | (string) | the ticker of the coin |
asset | (string) | the -ac_name parameter used to start the Smart Chain |
fname | (string) | the full name of the Smart Chain |
rpcport | (number) | the RPC port the Smart Chain's daemon uses to receive RPC commands |
mm2 | (number) | set this value to 1 if this coin has been tested and proves capable of functioning on MarketMaker 2.0 software |
p2p | (number) | the p2p port the Smart Chain's daemon uses to communicate with other nodes |
magic | (string) | the netmagic number for this Smart Chain. The decimal value of magic can be obtained by executing the getinfo RPC on a full node on the Smart Chain network. Convert the decimal value to hex and serialize it into 4 hexbytes; |
nSPV | (string) | the ip addresses of the full nodes on the Smart Chain network |
TIP
To start the nSPV client for a specific Smart Chain after its data has been added to the coins file, execute the following.
./nspv COIN
# Tips and Suggestions for Working with the Magic Number
The magic number is a unique number that the daemon uses for identification purposes.
If the direction of the magic
number appears to be incorrect, try reversing the order of the numbers.
The magic
number can also be found from the terminal as a stdout
printout when launching the daemon. Look for the line that starts with >>>>>>>>>>
, extract the hex portion of the string (magic.xxxxxxxx
), and reverse its byte order.
# Example
>>>>>>>>>> COIN: p2p.40264 rpc.40265 magic.fe1c3450 4263261264 350689 coins
The hex extracted is fe1c3450
.
Therefore the magic value for the coins file is 50341cfe
# Interacting with the nSPV Client
The port in each of these examples is the port on which the nSPV client listens for RPC commands.
For KMD, the port is 7771
. For any other Smart Chain, the port is the rpcport
specified in the coins
file.
This behaviour can be bypassed by setting the -p parameter.
# curl Commands Using Named Parameters
Use the example below as a template for creating new curl
commands for any RPCs available in the nSPV API.
curl --url "http://127.0.0.1:$port" --data "{\"userpass\":\"$userpass\",\"method\":\"spentinfo\",\"vout\":1,\"txid\":\"e07709088fa2690fdc71b43b5d7760689e42ca90f7dfb74b18bf47a1ad94c855\"}"
# curl Command Using the json2.0 Interface
When using this format for any RPC that requires parameters (also called "arguments"), provide the parameters in the order they are given in this documentation.
For example, the spentinfo RPC lists txid
as the first parameter and vout
as the second. Observe in the following example how the values in the "params"
key match this order.
Use quotation marks ""
for all strings.
curl --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "spentinfo", "params": ["e07709088fa2690fdc71b43b5d7760689e42ca90f7dfb74b18bf47a1ad94c855",1 ] }' -H 'content-type: text/plain;' http://127.0.0.1:$port/
# Accessing localhost in the Browser
To access an nSPV client's API using a browser, create a url that uses http://127.0.0.1:<insert_port>/api/
as the base url, and add the rpc_name/
and any relevant additional parameters/
as additional url directions. See the example below.
# Example
http://127.0.0.1:<port>/api/method/spentinfo/txid/e07709088fa2690fdc71b43b5d7760689e42ca90f7dfb74b18bf47a1ad94c855/vout/1
# Static HTML wallet in a browser
Simply visit the url http://127.0.0.1:<insert_port>/
to access the Static HTML wallet served by the nSPV binary.
# -p
Use this parameter at nSPV runtime to set the port on which the nSPV client should listen for RPC commands.
# Example
The following command starts the nSPV client for the KMD main chain and listens on port 3000
for RPC commands.
./nspv KMD -p 3000
# broadcast
broadcast hex
Use this method to broadcast the hex value returned by the spend method.
# Arguments
Name | Type | Description |
---|---|---|
hex | (string) | the transaction in hex format |
# Response
Name | Type | Description |
---|---|---|
result | (string) | whether the command was successful |
expected | (string) | the expected transaction id |
broadcast | (string) | the broadcasted transaction id |
retcode | (number) | the return code 0: no error -1,-2,-3: failure -200x: mostly OK, some of the inputs may not be notarized |
type | (string) | the type of the broadcast |
lastpeer | (string) | the last known peer |
# 📌 Examples
# Command
curl --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "broadcast", "params": ["0400008085202f890155c894ada147bf184bb7dff790ca429e6860775d3bb471dc0f69a28f080977e0010000006a47304402206774ff903a8a4b73bcd5a79fe5c744f34d2263160cd8877c198c2228c66a8a42022063e1d2d6403c395e3472a6a509f01cbff0b90e3413bc6f7bc492649302a4a64001210217a6aa6c0fe017f9e469c3c00de5b3aa164ca410e632d1c04169fd7040e20e06ffffffff0200e1f505000000001976a9144726f2838fc4d6ac66615e10604e18926e9b556e88ac48f804060000000023210217a6aa6c0fe017f9e469c3c00de5b3aa164ca410e632d1c04169fd7040e20e06ace77e395d000000000000000000000000000000"] }' -H 'content-type: text/plain;' http://127.0.0.1:$port/
# getinfo
getinfo [hdrheight]
Use this method to get the general information on the state of the blockchain at the moment.
# Arguments
Name | Type | Description |
---|---|---|
hdrheight | (number, optional) | supplies the height of the block for which the header data is required |
# Response
Name | Type | Description |
---|---|---|
result | (string) | whether the command was successful |
nSPV | (string) | the mode of nSPV |
address | (string) | the address corresponding to the wifkey |
pubkey | (string) | the pubkey corresponding to the wifkey |
wifexpires | (string) | the time in seconds till the login expires |
height | (number) | the current height of the blockchain |
chaintip | (string) | the blockhash of the last block |
notarization | (json) | a json object containing the notarization details |
notarized_height | (number) | the height of the latest block that has been notarized |
notarized_blockhash | (string) | the blockhash of the latest block that has been notarized |
notarization_txid | (string) | the id of the transaction in which the notarization data is included in the chain being dPoW'ed |
notarization_txidheight | (number) | the height of the block in which the notarization transaction is included |
notarization_desttxid | (string) | the id of the transaction in which the notarization data is included in the chain acting as the data store |
header | (string) | a json object containing the details of the header (of the current block by default / block of height specified by hdrheight if it is specified) |
height | (number) | the height of the block that has been queried |
blockhash | (string) | the blockhash of the block that has been queried |
hashPrevBlock | (string) | the blockhash of the block before the block that has been queried |
hashMerkleRoot | (string) | the merkleroot of the block that has been queried |
nTime | (number) | a timestamp recording when this block was created |
nBits | (number) | the calculated difficulty target being used for this block |
protocolversion | (string) | the version of the client; helps the nspv client disconnect from nodes that are out of date |
lastpeer | (string) | the last known peer |
# 📌 Examples
# Command
curl --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "getinfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:$port/
# getnewaddress
getnewaddress [lang]
Use this method to create a new address.
# Arguments
Name | Type | Description |
---|---|---|
lang | (string,optional) | the language in which the seed words are to be generated; can be one of: "english", "french", "italian", "japanese", "korean", "russian", "spanish", "chinese_simplified", "chinese_traditional" |
# Response
Name | Type | Description |
---|---|---|
seed | (string) | seed phrase of the generated address; currently generates a phrase with 23 seed words compatible with the other wallets in the Komodo Ecosystem |
wif | (string) | wifkey of the generated address |
address | (string) | the generated address |
pubkey | (string) | pubkey of the generated address |
wifprefix | (number) | prefix of the generated wifkey; depends on the network |
compressed | (number) | whether the wifkey generated is compressed |
# 📌 Examples
# Command (Without arguments)
curl --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "getnewaddress", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:$port/
# Command (To get the seed words in italian)
curl --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "getnewaddress", "params": ["italian"] }' -H 'content-type: text/plain;' http://127.0.0.1:$port/
# getpeerinfo
getpeerinfo
Use this method to get the information of all peers on the network.
# Arguments
Name | Type | Description |
---|---|---|
(none) |
# Response
Name | Type | Description |
---|---|---|
nodeid | (number) | the number given to a node by our instance of the nSPV client |
ipaddress | (string) | the ipaddress of the node |
port | (number) | the p2p port used to connect to this node |
lastping | (number) | the unix time at which this node was last pinged |
time_started_con | (number) | the unix time at which a connection to this node was established |
time_last_request | (number) | the unix time at which a connection was last requested |
services | (number) | this value encodes the available services from this node in decimal format; converted to HEX, 70000005 : nSPV support with both addressindex and spent index , 40000005 : nSPV support but neither addressindex nor spent index, 00000005 is the services value for a normal node |
missbehavescore | (number) | the score given to this node if the node was misbehaving |
bestknownheight | (number) | the height of the blockchain as best known by this node |
in_sync | (string) | the sync status of the node; synced indicates that the client has verified that the chain tip's block header from the node links back to the last notarization; after the client been running a while, all honest nodes should be synced to the same block |
# 📌 Examples
# Command
curl --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "getpeerinfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:$port/
# hdrsproof
hdrsproof prevheight nextheight
This method scans backwards from the prevheight
until the process encounters a notarization transaction, then forward from nextheight
until the process encounters another notarization transaction.
Then the process finds the notarized blocks corresponding to these two notarization transactions.
Then the process returns all the block headers between these two notarized blocks.
Now that both ends of this segment of blocks are notarized blocks, all block headers in this segment can be validated to see if they link back to each other.
# Arguments
Name | Type | Description |
---|---|---|
prevheight | (number) | the block number from which headers are required |
nextheight | (number) | the block number to which headers are required |
# Response
Name | Type | Description |
---|---|---|
result | (string) | whether the command was successful |
prevht | (string) | the height of the first notarized block below the height prevheight |
nextht | (string) | the height of the first notarized block above the height nextheight |
prevtxid | (string) | the id of the transaction that contains the notarization data of the block of height prevht |
prevtxidht | (string) | the height of the block in which the transaction with id prevtxid is present |
prevtxlen | (string) | the length of the transaction with id prevtxid |
nexttxid | (string) | the id of the transaction that contains the notarization data of the block of height nextht |
nexttxidht | (string) | the height of the block in which the transaction with id nexttxid is present |
nexttxlen | (string) | the length of the transaction with id nexttxid |
numhdrs | (string) | the number of headers being returned |
headers | (string) | a json object containing the details of the header (of the current block by default / block of height specified by hdrheight if it is specified) |
height | (number) | the height of the block that has been queried |
blockhash | (string) | the blockhash of the block that has been queried |
hashPrevBlock | (string) | the blockhash of the block before the block that has been queried |
hashMerkleRoot | (string) | the merkleroot of the block that has been queried |
nTime | (number) | a timestamp recording when this block was created |
nBits | (number) | the calculated difficulty target being used for this block |
lastpeer | (string) | the last known peer |
# 📌 Examples
# Command
curl --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "hdrsproof", "params": [1456692, 1456694 ] }' -H 'content-type: text/plain;' http://127.0.0.1:$port/
# help
help
This method returns the help output of all available methods.
# Arguments
Name | Type | Description |
---|---|---|
(none) |
# Response
Name | Type | Description |
---|---|---|
result | (string) | whether the command was successful |
methods | (array of jsons) | an array containing a json object for each method |
method | (string) | name of a method |
fields | (array) | an array conataining the description of parameters expected |
num | (number) | the number of methods available |
# 📌 Examples
# Command
curl --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "help", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:$port/
# listtransactions
listtransactions [address [isCC [skipcount [filter]]]]
This method returns a list of transactions for an address.
# Arguments
Name | Type | Description |
---|---|---|
address | (string, optional) | the address for which transactions are to be listed; if not specified, the current active address is used |
isCC | (number, optional) | only return transactions that are related to Antara modules |
skipcount | (number, optional) | skips the specified number of transactions starting from the oldest; always returns the latest transaction |
filter | (number, optional) | (in development) |
# Response
Name | Type | Description |
---|---|---|
result | (string) | whether the command was successful |
txids | (array of jsons) | an array containing jsons that describe the transactions |
height | (number) | the height of the block in which the transaction was included |
txid | (string) | the id of the transaction |
value | (number) | the amount of coins in the vin/vout (inputs and outputs) |
vin/vout | (number) | the index of vin/vout in the transaction |
address | (string) | the address for which the transactions are being returned |
isCC | (number) | whether the address belongs to an Antara module |
height | (number) | the height of the blockchain when this response was returned |
numtxids | (number) | number of vouts/vins being returned |
skipcount | (number) | the number of transactions that have been skipped, starting from the oldest transaction |
filter | (number) | (in development) |
lastpeer | (string) | the last known peer |
# 📌 Examples
# Command
curl --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "listtransactions", "params": ["RFmQiF4Zbzxchv9AG6dw6ZaX8PbrA8FXAb"] }' -H 'content-type: text/plain;' http://127.0.0.1:$port/
# listunspent
listunspent [address [isCC [skipcount [filter]]]]
Use this method to retrieve all unspent outputs belonging to an address.
# Arguments
Name | Type | Description |
---|---|---|
address | (string, optional) | the address for which transactions are to be listed; if not specified, the current active address is used |
isCC | (number, optional) | only return transactions that are related to Antara modules |
skipcount | (number, optional) | skips the specified number of transactions starting from the oldest; always returns the latest transaction |
filter | (number, optional) | (in development) |
# Response
Name | Type | Description |
---|---|---|
result | (string) | whether the command was successful |
utxos | (array of jsons) | an array containing jsons that describe the outputs |
height | (number) | the height of the block in which the output was created |
txid | (string) | the id of the transaction in which the output is present |
vout | (number) | the index of the vout (output) in the transaction |
value | (number) | the amount of coins in the vout (output) |
rewards | (number) | the amount of active user rewards claimable by the output |
address | (string) | the address for which the transactions are being returned |
isCC | (number) | whether the address belongs to an Antara module |
height | (number) | the height of the blockchain when this response was returned |
numutxos | (number) | number of vouts(outputs) being returned |
balance | (number) | the total balance available for the address |
rewards | (number) | the total rewards claimable by the address |
skipcount | (number) | the number of utoxs that have been skipped; from the oldest |
filter | (number) | (in development) |
lastpeer | (string) | the last known peer |
# 📌 Examples
# Command
curl --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "listunspent", "params": ["RFmQiF4Zbzxchv9AG6dw6ZaX8PbrA8FXAb"] }' -H 'content-type: text/plain;' http://127.0.0.1:$port/
# login
login wif
Use this method to log in to an address using its wifkey.
# Arguments
Name | Type | Description |
---|---|---|
wif | (string) | the wifkey (wallet import format of the privatekey) |
# Response
Name | Type | Description |
---|---|---|
result | (string) | whether the command was successful |
status | (string) | the time till the expiry of the login |
address | (string) | the address corresponding to the wifkey |
pubkey | (string) | the pubkey corresponding to the wifkey |
wifprefix | (number) | the prefix of the wifkey (indicates the intended network for the wifkey) |
compressed | (boolean) | indicates whether the wifkey is compressed |
# 📌 Examples
# Command
curl --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "login", "params": ["Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"] }' -H 'content-type: text/plain;' http://127.0.0.1:$port/
# logout
logout
Use this method to log out of the current active address.
# Arguments
Name | Type | Description |
---|---|---|
(none) |
# Response
Name | Type | Description |
---|---|---|
result | (string) | whether the command succeeded |
# 📌 Examples
# Command
curl --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "logout", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:$port/
# mempool
mempool address isCC memfunc [txid vout evalcode ccfunc]
This method returns the current transactions in the mempool. The various parameters can be used to filter the transactions.
# Arguments
Name | Type | Description |
---|---|---|
address | (string, optional) | if the transactions should belong to the address |
isCC | (number, optional) | if the transactions should belong to any Antara module |
memfunc | (number, optional) | (in development) |
txid | (string, optional) | (in development) |
vout | (number, optional) | (in development) |
evalcode | (number, optional) | (in development) |
ccfunc | (number, optional) | (in development) |
# Response
Name | Type | Description |
---|---|---|
result | (string) | whether the command was successful |
txids | (array of strings) | the ids of the transactions in the mempool |
address | (string) | the address that was used to filter the mempool |
isCC | (number) | if the transactions returned belong to an Antara Module |
height | (number) | the height of the blockchain when this response was returned |
numtxids | (number) | the number of transaction ids that are being returned |
txid | (string) | (in development) |
vout | (number) | (in development) |
memfunc | (number) | (in development) |
type | (string) | the type of the filter apploed to the mempool |
lastpeer | (string) | the last known peer |
# 📌 Examples
# Command
curl --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "mempool", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:$port/
# notarizations
notarizations height
This method returns the notarization data for a given height.
# Arguments
Name | Type | Description |
---|---|---|
height | (number) | the height at which notarization data is required |
# Response
Name | Type | Description |
---|---|---|
result | (string) | whether the command was successful |
prev | (json) | the details of the previous notarization |
notarized_height | (number) | the height of the latest block that has been notarized |
notarized_blockhash | (string) | the blockhash of the latest block that has been notarized |
notarization_txid | (string) | the id of the transaction in which the notarization data is included in the chain being dPoW'ed |
notarization_txidheight | (number) | the height of the block in which the notarization transaction is included |
notarization_desttxid | (string) | the id of the transaction in which the notarization data is included in the chain acting as the data store |
next | (json) | the details of the next notarization |
lastpeer | (string) | the last known peer |
# 📌 Examples
# Command
curl --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "notarizations", "params": [145677] }' -H 'content-type: text/plain;' http://127.0.0.1:$port/
# spend
spend address amount
This method can be used to spend coins from the current active address to any other address.
# Arguments
Name | Type | Description |
---|---|---|
address | (string) | the address of the recipient |
amount | (number) | the amount to be sent |
# Response
Name | Type | Description |
---|---|---|
rewards | (string) | the rewards being claimed by this spend transaction |
validated | (string) | (in development) |
tx | (json) | a json object containing details of the transaction |
nVersion | (number) | version of the komodo daemon |
vin | (array of jsons) | the inputs being consumed by the transaction |
txid | (string) | the id of the transaction whose input is being spent |
vout | (number) | the output number in the above transaction |
scriptSig | (string) | the redeem script that satisfies the scriptPubkey of the above output |
sequenceid | (number) | the sequence number that has been set |
vout | (array of jsons) | the outputs being created by the transaction |
value | (string) | the value in the output |
scriptPubKey | (string) | the locking script placed on the above value |
nLockTime | (number) | the locktime that has been set |
nExpiryHeight | (number) | the block height after which the transaction will be removed from the mempool if it has not been mined |
valueBalance | (number) | (in development) |
result | (string) | whether the command succeeded |
hex | (string) | the transaction in hex format; this should be broadcast to the network using the broadcast method |
retcodes | (number) | the return codes; an indication of the success or failure of the creation of the transaction |
lastpeer | (string) | the last known peer |
# 📌 Examples
# Command
curl --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "spend", "params": ["RFmQiF4Zbzxchv9AG6dw6ZaX8PbrA8FXAb",1 ] }' -H 'content-type: text/plain;' http://127.0.0.1:$port/
# spentinfo
spentinfo txid vout
This method returns the spent info of the output specified by the arguments.
# Arguments
Name | Type | Description |
---|---|---|
txid | (string) | the id of the transaction whose spent info is required |
vout | (number) | the vout number in the above transaction whose spent info is required |
# Response
Name | Type | Description |
---|---|---|
result | (string) | whether the command succeeded |
txid | (string) | the id of the transaction whose spent info is returned |
vout | (string) | the vout number in the above transaction whose spent info is required |
spentheight | (string) | the block height at which the output has been spent |
spenttxid | (string) | the id of the transaction that spent this output |
spentvini | (string) | the input number of this output in the transaction that spent it |
spenttxlen | (string) | the length of the transaction that spent this output |
spenttxprooflen | (string) | the length of proof of the transaction that spent this output |
lastpeer | (string) | the last known peer |
# 📌 Examples
# Command
curl --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "spentinfo", "params": ["e07709088fa2690fdc71b43b5d7760689e42ca90f7dfb74b18bf47a1ad94c855",1 ] }' -H 'content-type: text/plain;' http://127.0.0.1:$port/
# stop
stop
Stops the nSPV instance associated with the port specified in the curl command.
# Arguments
Name | Type | Description |
---|---|---|
(none) |
# Response
Name | Type | Description |
---|---|---|
result | (string) | whether the command was successful |
# 📌 Examples
# Command
curl --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "stop", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:$port/
# txproof
txproof txid vout [height]
This method is an internal function used by the gettransaction method.
# Arguments
Name | Type | Description |
---|---|---|
txid | (string) | the id of the transaction whose proof is requested |
vout | (number) | the number of the output in the above transaction |
height | (number, optional) |
# Response
Name | Type | Description |
---|---|---|
txid | (string) | the id of the transaction whose proof is returned |
height | (string) | the height at which the proof of the transaction is returned |
txlen | (string) | the length of the transaction |
txprooflen | (string) | the length of the proof for the transaction |
lastpeer | (string) | the last known peer |
# 📌 Examples
# Command
curl --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "txproof", "params": ["e07709088fa2690fdc71b43b5d7760689e42ca90f7dfb74b18bf47a1ad94c855",0,1453881 ] }' -H 'content-type: text/plain;' http://127.0.0.1:$port/