To build a distributable version of komodo then run the makeDistrib.sh script after building.
When you are done building, you need to do a few things in the [Configuration](https://github.com/zcash/zcash/wiki/1.0-User-Guide#configuration) section of the Zcash User Guide differently because we are on the Mac. All instances of `~/.zcash` need to be replaced by `~/Library/Application\ Support/Zcash`
The fetch-params.sh script, however, has already been altered to fetch the proving keys into the correct directory to conform to Mac specific naming conventions.
When you are done building, you need to create `Komodo.conf` the Mac way.
This version of Komodo contains Bitcore support for komodo and all its assetchains.
## Komodod
This software is Komodo client, generally you will use this if you want to mine KMD or setup a full node.
It downloads and stores the entire history of Komodo transactions; depending on the speed of your computer and network connection, the synchronization process could take a day or more once the blockchain has reached a significant size.
- Jumblr - Decentralized tumbler for KMD and other cryptocurrencies
- Assetchains - Easy way to fork Komodo coin
- Pegged Assets - Chains that maintain a peg to fiat currencies
- Peerchains - Scalability solution where sibling chains form a network of blockchains
- More in depth covered [here](https://docs.google.com/document/d/1AbhWrtagu4vYdkl-vsWz-HSNyNvK-W-ZasHCqe7CZy0)
- Also note you receive 5% APR on your holdings.
[See this article for more details](https://komodoplatform.atlassian.net/wiki/spaces/KPSD/pages/20480015/Claim+KMD+Interest+in+Agama)
## Tech Specification
Max Supply: 200 million KMD.
Block Time: 1M 2s
Block Reward: 3KMD
Mining Algorithm: Equihash
- Max Supply: 200 million KMD.
- Block Time: 1M 2s
- Block Reward: 3KMD
- Mining Algorithm: Equihash
## About this Project
Komodo is based on Zcash and has been by our innovative consensus algorithm called dPoW which utilizes Bitcoin's hashrate to store Komodo blockchain information into the Bitcoin blockchain. Other new and native Komodo features are the privacy technology called JUMBLR or our assetchain capabilities (one click plug and play blockchain solutions). More details are available under https://komodoplatform.com/.
There is a small chance that an outbound transaction will give an error due to mismatched values in wallet calculations. There is a -exchange option that you can run komodod with, but make sure to have the entire transaction history under the same -exchange mode. Otherwise you will get wallet conflicts.
To change modes:
a) backup all privkeys (launch komodod with -exportdir=<path> and dumpwallet)
b) start a totally new sync including wallet.dat, launch with same exportdir
c) stop it before it gets too far and import all the privkeys from a) using komodo-cli importwallet filename
**To change modes:**
a) backup all privkeys (launch komodod with `-exportdir=<path>` and `dumpwallet`)
b) start a totally new sync including `wallet.dat`, launch with same `exportdir`
c) stop it before it gets too far and import all the privkeys from a) using `komodo-cli importwallet filename`
komodod now has jumblr_deposit and jumblr_secret RPC calls.
```
## JUMBLR
komodod now has `jumblr_deposit` and `jumblr_secret` RPC calls.
Jumblr works like described previously where all the nodes with jumblr active synchronize their tx activity during the same block to maximize the mixing effect. However, unlike all other mixers/tumblers, you never give up control of your coins to anybody else. JUMBLR uses a one to many allocation of funds, ie. one deposit address and many secret addresses. You can always run multiple komodod daemons to get multiple active deposit addresses.
JUMBLR implements t -> z, z -> z and z -> t transactions to maximize privacy of the destination t (transparent) address. So while it is transparent, its first activity is funds coming from an untracable z address.
Which of the three stages is done is randomly selected at each turn. Also when there is more than one possible transaction at the selected stage, a random one is selected. This randomization prevents analyzing incoming z ->t transactions by its size to correlate it to the originating address.
jumblr_deposit <depositaddr> designates the deposit address as the jumblr deposit address for that session. You can select an address that already has funds in it and it will immediately start jumblr process. If there are no funds, it will wait until you send funds to it.
There are three sizes of a jumblr transaction: 10 KMD, 100 KMD and 1000 KMD. There is also a fixed interval of blocks where all jumblr nodes are active. Currently it is set to be 10, but this is subject to change. Only during every 10*10 blocks are the largest 1000 KMD transactions processed, so this concentrates all the large transactions every N*N blocks.
jumblr_secret <secretaddress> notifies JUMBLR where to send the final z -> t transactions. In order to allow larger accounts to obtain privacy, up to 777 secret addresses are supported. Whenever a z -> t stage is activated, a random secret address from the list of the then active secret addresses is selected.
Practical Advice:
`jumblr_deposit <depositaddr>` designates the deposit address as the jumblr deposit address for that session. You can select an address that already has funds in it and it will immediately start jumblr process. If there are no funds, it will wait until you send funds to it.
There are three sizes of a jumblr transaction: 10 KMD, 100 KMD and 1000 KMD. There is also a fixed interval of blocks where all jumblr nodes are active. Currently it is set to be 10, but this is subject to change. Only during every 10*10 blocks are the largest 1000 KMD transactions processed, so this concentrates all the large transactions every N*N blocks.
`jumblr_secret <secretaddress>` notifies JUMBLR where to send the final z -> t transactions. In order to allow larger accounts to obtain privacy, up to 777 secret addresses are supported. Whenever a z -> t stage is activated, a random secret address from the list of the then active secret addresses is selected.
#### Practical Advice:
Obtaining privacy used to be very difficult. JUMBLR makes it as simple as issuing two command line calls. Higher level layers can be added to help manage the addresses, ie. linking them at the passphrase level. Such matters are left to each implementation.
Once obtained, it is very easy to lose all the privacy. With a single errant transaction that combines some previously used address and the secretaddress, well, the secretaddress is no longer so private.
The advice is to setup a totally separate node!
This might seem a bit drastic, but if you want to maintain privacy, it is best to make it look like all the transactions are coming from a different node. The easiest way for most people to do this is to actually have a different node.
It can be a dedicated laptop (recommended) or a VPS (for smaller amounts) with a totally fresh komodod wallet. Generate an address on this wallet and use that as the jumblr_secret address on your main node. As the JUMBLR operates funds will teleport into your secret node's address. If you are careful and never use the same IP address for both your nodes, you will be able to maintain very good privacy.
It can be a dedicated laptop (recommended) or a VPS (for smaller amounts) with a totally fresh komodod wallet. Generate an address on this wallet and use that as the jumblr_secret address on your main node. As the JUMBLR operates funds will teleport into your secret node's address. If you are careful and never use the same IP address for both your nodes, you will be able to maintain very good privacy.
Of course, don't send emails that link the two accounts together! Dont use secret address funds for home delivery purchases! Etc. There are many ways to lose the privacy, just think about what linkages can be dont at the IP and blockchain level and that should be a useful preparation.
What if you have 100,000 KMD and you dont want others to know you are such a whale?
Instead of generating 1 secret address, generate 100 and make a script file with:
```shell
./komodo-cli jumblr_secret <addr0>
./komodo-cli jumblr_secret <addr1>
...
./komodo-cli jumblr_secret <addr99>
```
And make sure to delete all traces of this when the JUMBLR is finished. You will end up with 100 addresses that have an average of 1000 KMD each. So as long as you are careful and dont do a 10,000 KMD transaction (that will link 10 of your secret addresses together), you can appear as 100 different people each with 1000 KMD.
fprintf(stderr,"%s FORK detected. notarized.%d %s not in this chain! last notarization %d -> rewindtarget.%d\n",ASSETCHAINS_SYMBOL,notarized_height,srchash.ToString().c_str(),sp->NOTARIZED_HEIGHT,rewindtarget);
fprintf(stderr,"%s FORK detected. notarized.%d %s not in this chain! last notarization %d -> rewindtarget.%d\n",ASSETCHAINS_SYMBOL,*notarizedheightp,srchash.ToString().c_str(),sp->NOTARIZED_HEIGHT,rewindtarget);
fprintf(stderr,"komodo_is_PoSblock PoS failure ht.%d eligible.%u vs blocktime.%u, lag.%d -> check to see if it is PoW block\n",height,eligible,(uint32_t)pblock->nTime,(int32_t)(eligible-pblock->nTime));
}elseisPoS=1;
}
elseif(slowflag==0)// maybe previous block is not seen yet, do the best approx
printf("out of order detected? SKIP CC_data ht.%d/txi.%d vs ht.%d/txi.%d\n",CC_data->MoMdata.height,CC_data->MoMdata.txi,ccdata->MoMdata.height,ccdata->MoMdata.txi);
printf("[%s] error validating notarization ht.%d notarized_height.%d, if on a pruned %s node this can be ignored\n",ASSETCHAINS_SYMBOL,height,notarizedheight,dest);
fprintf(stderr,"PoS failure ht.%d eligible.%u vs blocktime.%u, lag.%d -> check to see if it is PoW block\n",height,eligible,(uint32_t)block.nTime,(int32_t)(eligible-block.nTime));
}elseisPoS=1;
}
if(isPoS==0&&height>100)
{
if(ASSETCHAINS_STAKED==100)
{
fprintf(stderr,"ht.%d 100%% PoS after height 100 rule violated for -ac_staking=100\n",height);
printf("not proper vout with opreturn format %s ht.%d cmp.%d %d\n",ASSETCHAINS_SYMBOL,height,script[offset]==opcode,(int32_t)block.vtx[0].vout[n-1].scriptPubKey.size());
printf("pathA current interest %.8f vs new %.8f for ht.%d %.8f locktime.%u tiptime.%u\n",dstr(interest),dstr(interestnew),txheight,dstr(nValue),nLockTime,tiptime);
printf("pathB current interest %.8f vs new %.8f for ht.%d %.8f locktime.%u tiptime.%u\n",dstr(interest),dstr(interestnew),txheight,dstr(nValue),nLockTime,tiptime);
fprintf(stderr,"pathC current interest %.8f vs new %.8f for ht.%d %.8f locktime.%u tiptime.%u\n",dstr(interest),dstr(interestnew),txheight,dstr(nValue),nLockTime,tiptime);
/** Return the time it would take to redo the work difference between from and to, assuming the current hashrate corresponds to the difficulty at tip, in seconds. */
// If we expected this to work, don't silently ignore failures, because that would hide the problem and incur an unnecessarily system-call overhead. So if we ever observe this exception, we should probably add a suitable #ifdef .
//TODO: clock_gettime(CLOCK_PROCESS_CPUTIME_ID) is not supported by native Windows. What about Cygwin? Should we #ifdef on CLOCK_PROCESS_CPUTIME_ID or on __linux__?
#endif
returnts.tv_sec*1000000000ll+ts.tv_nsec;
}
longlongstart_time,last_time;
longlongstart_cpu_time,last_cpu_time;
int64_tstart_time,last_time;
int64_tstart_cpu_time,last_cpu_time;
voidstart_profiling()
{
@ -57,20 +74,20 @@ void start_profiling()
}
std::map<std::string,size_t>invocation_counts;
std::map<std::string,longlong>enter_times;
std::map<std::string,longlong>last_times;
std::map<std::string,longlong>cumulative_times;
std::map<std::string,int64_t>enter_times;
std::map<std::string,int64_t>last_times;
std::map<std::string,int64_t>cumulative_times;
//TODO: Instead of analogous maps for time and cpu_time, use a single struct-valued map
"\nReturns a new Komodo address for receiving payments.\n"
"\nReturns a new "+strprintf("%s",komodo_chainname())+" address for receiving payments.\n"
"\nArguments:\n"
"1. \"account\" (string, optional) DEPRECATED. If provided, it MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"\nResult:\n"
"\"zcashaddress\" (string) The new Zcash address\n"
"\""+strprintf("%s",komodo_chainname())+"_address\" (string) The new "+strprintf("%s",komodo_chainname())+" address\n"
"\nDEPRECATED. Returns the current Komodo address for receiving payments to this account.\n"
"\nDEPRECATED. Returns the current "+strprintf("%s",komodo_chainname())+" address for receiving payments to this account.\n"
"\nArguments:\n"
"1. \"account\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"\nResult:\n"
"\"zcashaddress\" (string) The account Zcash address\n"
"\""+strprintf("%s",komodo_chainname())+"_address\" (string) The account "+strprintf("%s",komodo_chainname())+" address\n"
"\nDEPRECATED. Sets the account associated with the given address.\n"
"\nArguments:\n"
"1. \"zcashaddress\" (string, required) The Zcash address to be associated with an account.\n"
"1. \""+strprintf("%s",komodo_chainname())+"_address\" (string, required) The "+strprintf("%s",komodo_chainname())+" address to be associated with an account.\n"
"2. \"account\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"1. \"account\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"\nResult:\n"
"[ (json array of string)\n"
"\"zcashaddress\" (string) a Zcash address associated with the given account\n"
"\""+strprintf("%s",komodo_chainname())+"_address\" (string) a "+strprintf("%s",komodo_chainname())+" address associated with the given account\n"
"\nSign a message with the private key of an address"
+HelpRequiringPassphrase()+"\n"
"\nArguments:\n"
"1. \"zcashaddress\" (string, required) The Zcash address to use for the private key.\n"
"1. \""+strprintf("%s",komodo_chainname())+" address\" (string, required) The "+strprintf("%s",komodo_chainname())+" address to use for the private key.\n"
"2. \"message\" (string, required) The message to create a signature of.\n"
"\nResult:\n"
"\"signature\" (string) The signature of the message encoded in base 64\n"
"\nReturns the total amount received by the given "+strprintf("%s",komodo_chainname())+" address in transactions with at least minconf confirmations.\n"
"\nArguments:\n"
"1. \"zcashaddress\" (string, required) The Zcash address for transactions.\n"
"1. \""+strprintf("%s",komodo_chainname())+"_address\" (string, required) The "+strprintf("%s",komodo_chainname())+" address for transactions.\n"
"2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
"\nResult:\n"
"amount (numeric) The total amount in "+CURRENCY_UNIT+" received at this address.\n"
"amount (numeric) The total amount in "+strprintf("%s",komodo_chainname())+" received at this address.\n"
"\nExamples:\n"
"\nThe amount from transactions with at least 1 confirmation\n"
"1. \"account\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
"\nResult:\n"
"amount (numeric) The total amount in "+CURRENCY_UNIT+" received for this account.\n"
"amount (numeric) The total amount in "+strprintf("%s",komodo_chainname())+" received for this account.\n"
"\nExamples:\n"
"\nAmount received by the default account with at least 1 confirmation\n"
"1. \"fromaccount\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"2. \"toaccount\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"3. amount (numeric) Quantity of "+CURRENCY_UNIT+" to move between accounts.\n"
"3. amount (numeric) Quantity of "+strprintf("%s",komodo_chainname())+" to move between accounts.\n"
"4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
"5. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n"
"\nResult:\n"
"true|false (boolean) true if successful.\n"
"\nExamples:\n"
"\nMove 0.01 "+CURRENCY_UNIT+" from the default account to the account named tabby\n"
"\nMove 0.01 "+strprintf("%s",komodo_chainname())+" from the default account to the account named tabby\n"
+HelpExampleCli("move","\"\"\"tabby\" 0.01")+
"\nMove 0.01 "+CURRENCY_UNIT+" timotei to akiko with a comment and funds have 6 confirmations\n"
"\nMove 0.01 "+strprintf("%s",komodo_chainname())+" timotei to akiko with a comment and funds have 6 confirmations\n"
"\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a "+strprintf("%s",komodo_chainname())+" address.\n"
"The amount is a real and is rounded to the nearest 0.00000001."
+HelpRequiringPassphrase()+"\n"
"\nArguments:\n"
"1. \"fromaccount\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"2. \"tozcashaddress\" (string, required) The Zcash address to send funds to.\n"
"3. amount (numeric, required) The amount in "+CURRENCY_UNIT+" (transaction fee is added on top).\n"
"2. \"to"+strprintf("%s",komodo_chainname())+"address\" (string, required) The "+strprintf("%s",komodo_chainname())+" address to send funds to.\n"
"3. amount (numeric, required) The amount in "+strprintf("%s",komodo_chainname())+" (transaction fee is added on top).\n"
"4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
"5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
" This is not part of the transaction, just kept in your wallet.\n"
"1. \"fromaccount\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"2. \"amounts\" (string, required) A json object with addresses and amounts\n"
" {\n"
"\"address\":amount (numeric) The Zcash address is the key, the numeric amount in "+CURRENCY_UNIT+" is the value\n"
"\"address\":amount (numeric) The "+strprintf("%s",komodo_chainname())+" address is the key, the numeric amount in "+strprintf("%s",komodo_chainname())+" is the value\n"
" ,...\n"
" }\n"
"3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n"
"4. \"comment\" (string, optional) A comment\n"
"5. subtractfeefromamount (string, optional) A json array with addresses.\n"
" The fee will be equally deducted from the amount of each selected address.\n"
" Those recipients will receive less Zcash than you enter in their corresponding amount field.\n"
" Those recipients will receive less "+strprintf("%s",komodo_chainname())+" than you enter in their corresponding amount field.\n"
" If no addresses are specified here, the sender pays the fee.\n"
" [\n"
"\"address\" (string) Subtract fee from this address\n"
"\nAdd a nrequired-to-sign multisignature address to the wallet.\n"
"Each key is a Komodo address or hex-encoded public key.\n"
"Each key is a "+strprintf("%s",komodo_chainname())+" address or hex-encoded public key.\n"
"If 'account' is specified (DEPRECATED), assign address to that account.\n"
"\nArguments:\n"
"1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
"2. \"keysobject\" (string, required) A json array of Zcash addresses or hex-encoded public keys\n"
"2. \"keysobject\" (string, required) A json array of "+strprintf("%s",komodo_chainname())+" addresses or hex-encoded public keys\n"
" [\n"
"\"address\" (string) Zcash address or hex-encoded public key\n"
"\"address\" (string) "+strprintf("%s",komodo_chainname())+" address or hex-encoded public key\n"
" ...,\n"
" ]\n"
"3. \"account\" (string, optional) DEPRECATED. If provided, MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
"\nResult:\n"
"\"zcashaddress\" (string) A Zcash address associated with the keys.\n"
"\""+strprintf("%s",komodo_chainname())+"_address\" (string) A "+strprintf("%s",komodo_chainname())+" address associated with the keys.\n"
"\"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n"
" It will be \"\" for the default account.\n"
"\"address\":\"zcashaddress\", (string) The Zcash address of the transaction. Not present for \n"
"\"address\":\""+strprintf("%s",komodo_chainname())+"_address\", (string) The "+strprintf("%s",komodo_chainname())+" address of the transaction. Not present for \n"
" move transactions (category = move).\n"
"\"category\":\"send|receive|move\", (string) The transaction category. 'move' is a local (off blockchain)\n"
" transaction between accounts, and not associated with an address,\n"
" transaction id or block. 'send' and 'receive' transactions are \n"
" associated with an address, transaction id and block details\n"
"\"amount\": x.xxx, (numeric) The amount in "+CURRENCY_UNIT+". This is negative for the 'send' category, and for the\n"
"\"amount\": x.xxx, (numeric) The amount in "+strprintf("%s",komodo_chainname())+". This is negative for the 'send' category, and for the\n"
" 'move' category for moves outbound. It is positive for the 'receive' category,\n"
" and for the 'move' category for inbound funds.\n"
"\"vout\" : n, (numeric) the vout value\n"
"\"fee\": x.xxx, (numeric) The amount of the fee in "+CURRENCY_UNIT+". This is negative and only available for the \n"
"\"fee\": x.xxx, (numeric) The amount of the fee in "+strprintf("%s",komodo_chainname())+". This is negative and only available for the \n"
" 'send' category of transactions.\n"
"\"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n"
"\"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n"
"\"address\":\"zcashaddress\", (string) The Zcash address of the transaction. Not present for move transactions (category = move).\n"
"\"address\":\""+strprintf("%s",komodo_chainname())+"_address\", (string) The "+strprintf("%s",komodo_chainname())+" address of the transaction. Not present for move transactions (category = move).\n"
"\"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n"
"\"amount\": x.xxx, (numeric) The amount in "+CURRENCY_UNIT+". This is negative for the 'send' category, and for the 'move' category for moves \n"
"\"amount\": x.xxx, (numeric) The amount in "+strprintf("%s",komodo_chainname())+". This is negative for the 'send' category, and for the 'move' category for moves \n"
" outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n"
"\"vout\" : n, (numeric) the vout value\n"
"\"fee\": x.xxx, (numeric) The amount of the fee in "+CURRENCY_UNIT+". This is negative and only available for the 'send' category of transactions.\n"
"\"fee\": x.xxx, (numeric) The amount of the fee in "+strprintf("%s",komodo_chainname())+". This is negative and only available for the 'send' category of transactions.\n"
"\"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n"
"\"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
"\"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
"\"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n"
"\"address\" : \"zcashaddress\", (string) The Zcash address involved in the transaction\n"
"\"address\" : \""+strprintf("%s",komodo_chainname())+"_address\", (string) The "+strprintf("%s",komodo_chainname())+" address involved in the transaction\n"
"\"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n"
"\"amount\" : x.xxx (numeric) The amount in "+CURRENCY_UNIT+"\n"
"\"amount\" : x.xxx (numeric) The amount in "+strprintf("%s",komodo_chainname())+"\n"