Altcoin 101 — Create a Cryptonote Privacy Coin Clone in One Hour

Today we’re following a howto guide for making your own privacy coin network, fast and easy!

Why would we want to be forked?

We were seeing a lot of projects that had either already forked us or were trying to create a fork of TurtleCoin, and often the people forking were afraid to ask for help once they launched, or would make rookie mistakes like removing the licenses from the code, so we thought it was a good idea to make a guide on how to execute a fork properly.

Before you do anything, go to our GitHub page and click “Fork” in the upper right hand corner, and give it a ✪ if you’re feeling nice. It really helps us out.

We want you to fork our software. You have our permission. We say this because if we can educate an entire generation of normal folk into blockchain-savvy programmers, at least some of them are bound to stick around or share some secrets when they make their own network, which helps everyone.

Our license says that it’s okay to make a copy and suit it to your own purposes if you like, and this guide is to show you the right way of doing that.

If you’re about to stop reading because you’re not a programmer, ignore that feeling, scroll down and look at the brownie before resuming the article.

Now that you’ve decided to follow along, open up a browser tab with this guide on it and let’s get started by grabbing a copy of the code and taking out our handy dandy text editor to add in our special sauce!

Here is the link for Zpalmtree’s Wiki Guide: How To Fork TurtleCoin

Here is the link to the TurtleCoin code: Fork Me Here

This picture has absolutely nothing to do with the article, but when I did a search for “artistic blockchain vision” it was about 30 pages deep on Google Images.

Step Zero: The Vision (optional)

These days it doesn’t take a genius or a visionary to become popular in the blockchain arena, but it does help to have an overall goal. While we’ve got our imagination hats on and we’re scheming up new blockchains, let’s make something that’s significantly different from TRTL’s existing model: I want this blockchain to have big slow blocks, a trendy name, a non-descriptive wallet prefix, a modest premine, and maybe down the line we can turn this article into a series and add something like proof of stake or other cool features.

Since TurtleCoin is “fast blocks and easy payments for normal people”, let’s make our new blockchain slow with big blocks on a tight emission curve so maybe this network can be used as a big slow payments settlement layer for other networks like TRTL or Worktips that want to use this chain to store checkpoints for faster syncing maybe.

This sounds really good. Unbutton the top button, shine the shoes, straighten your pocket square. We’re going Wall Street, baby!

Step One: Pick a trendy name

What’s a good altcoin without a trendy name? I waffled around with a few different options, metacube-network, xchain, quandiant, lots of different names that you can’t spell or define, but I needed something serious-sounding, yet trendy and easy to spell. At the risk of having no available namespace, I settled with “Athena”. Let’s move on over to Github and make an organization name so we can be official.

Yes. This already feels like a winner.

Step Two: Fork TurtleCoin Repository

https://github.com/turtlecoin/turtlecoin/wiki/Forking-Turtlecoin#the-actual-forking-process

Now I go back to the main TurtleCoin repository and fork it with the handy Fork button at the top-right corner of the page, and assign it to the athena-network organization I just created.

Stars, Watches, and Forks give us extra points

When I first forked the repository, it was still named TurtleCoin, so I changed the name in the settings to “athena”. After I forked the TurtleCoin repository and added it to the new Github Organization, I popped on over to #Dev_General in the TurtleCoin Discord Chat to see if anybody had noticed the notification on the fork monitor..

Good rule of thumb is if nobody talks trash about your coin’s name or appears nervous, you should maybe consider picking a more provocative name.

See that nervous sweat bead of acknowledgement and respect? Athena was a good name choice.

Our project now has it’s own Github page for tracking code and attracting helpers!

Step Three: Economic Collapse and the Art of Emissions Logic

For those of you that are at home following along, we are in this section of the Forking TurtleCoin tutorial: CryptonoteConfig and we are working in the file src/cryptonoteConfig.h

About this point, we’ve got to a stopping point so I made some coffee and flipped through logos that were vaguely brownie related on Google Images for about a solid hour, I’ll admit.

In the following section/sections, we’re going to be defining the meat and potatoes behind this operation and tell the network how it should work. It’s a long one, so get a cup of coffee and a comfy chair.

Block Time

https://github.com/turtlecoin/turtlecoin/wiki/Forking-Turtlecoin#const-uint64_t-difficulty_target--30--seconds

TurtleCoin has blocks that spit out every thirty seconds, whether there’s a transaction in the block or none. Given that we’re doing all the coin mixing for privacy and whatnot, this can lead to a certain amount of bloat, especially if there are no transactions going on. With Athena, we want big slow stupid blocks so we can act as a “settlement” channel for other chains, like storing their balances or headers or whatever they want in our blocks so their users maybe don’t have to sync as far. Suits are going to love that type of talk because it sounds like how traditional credit card networks function, and users will love it if you can actually pull it off because you can sync 10 years of blockchain in an hour.

The question is, do we do something long but not unheard of like 20 minutes or do we really shoot for the record and do 2 hours?

Since DIFFICULTY_TARGET is measured in seconds, let’s do 3600 seconds for a total of 1 hour per block.

change this line: const uint64_t DIFFICULTY_TARGET = 30; // seconds

to this: const uint64_t DIFFICULTY_TARGET = 3600; // seconds

One thing that I didn’t know where to mention is how much this added up to as far as reward in each block mined. Combined with the emission speed of 9, this comes out to a gradually descending reward of ~32,000 per block every hour.

Wallet Address Prefix

https://github.com/turtlecoin/turtlecoin/wiki/Forking-Turtlecoin#const-uint64_t-cryptonote_public_address_base58_prefix--3914525

This really only has one requirement, and it’s pretty loose. Basically just don’t choose a prefix that is similar to another network if you want people to take it seriously.

I use the tools provided by CryptonoteStarter to generate the wallet prefix.

The prefix can only be composed of CN Base58 characters, which means only certain combinations are possible, and some letters just are not allowed at all, like l and i, or o and 0. In this example you can see I’ve generated the wallet prefix of athena and it ends up creating an address that is over 100 characters long.

change this line: const uint64_t CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = 3914525;

to this: const uint64_t CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = 0x18845CFCA;

Wikipedia says our logo should be an owl. called the Owl of Athena

Supply

https://github.com/turtlecoin/turtlecoin/wiki/Forking-Turtlecoin#const-uint64_t-money_supply--uint64_c100000000000000

With TRTL we decided on a trillion coins, with two decimal points, and that’s pretty scarce compared to other top 10 networks, but people still complained that it was “too many coins” whatever that means. Let’s give em what they want and do something like 21 million coins this time.

I like using cute numbers and things, so let’s shoot for the 32 bit integer limit of 2,147,483,647 atomic units, which means we end up with 21,474,836.47 Athena units.

change this line: const uint64_t MONEY_SUPPLY = UINT64_C(100000000000000);

to this: const uint64_t MONEY_SUPPLY = UINT64_C(2147483647);

Difficulty

https://github.com/turtlecoin/turtlecoin/wiki/Forking-Turtlecoin#const-uint32_t-zawy_difficulty_block_index--187000

I don’t really have much special flair to add here, so I’m going to go with the suggested parameters that Zpalmtree included and use block 0 for Zawy Algo 1, and block 1 for LWMA-2 switch.

Change these lines:

const uint32_t ZAWY_DIFFICULTY_BLOCK_INDEX = 187000;

const uint64_t LWMA_2_DIFFICULTY_BLOCK_INDEX = 620000;

to this:

const uint32_t ZAWY_DIFFICULTY_BLOCK_INDEX = 0;

const uint64_t LWMA_2_DIFFICULTY_BLOCK_INDEX = 1;

Supply, continued

Emission is a fine science to those who know how to use it best, and just another magic number to an aspiring shitcoin artisan. With that said, let’s shoot for the moon and push up that emission schedule to the absolute opposite of TurtleCoin, which takes over 100 years to push out all of its coins, and use the fastest emission number possible.

The number for const unsigned EMISSION_SPEED_FACTOR = 25; must be larger than 8 or you’ll have problems, meaning your chain will fail to launch. Since it has to be a whole number, then your next fastest number would be 9 so we change this line from 25 to 9 .

Decimals

https://github.com/turtlecoin/turtlecoin/wiki/Forking-Turtlecoin#const-size_t-cryptonote_display_decimal_point--2

I’ve always liked that TurtleCoin has two decimal points so this line will stay the same just to keep the math easy.

const size_t CRYPTONOTE_DISPLAY_DECIMAL_POINT = 2;

Fees

https://github.com/turtlecoin/turtlecoin/wiki/Forking-Turtlecoin#const-uint64_t-minimum_fee--uint64_c10

Fees are somewhat of an oddity in a network like this. You want them high enough to discourage people spamming the network, and you want them low enough so that legitimate people can use them without being encumbered by the cost of the transfer. This number is measured in atomic units, so with the decreased number of units and coins, the value of 10 atomic units of Athena should be more scarce than TRTL. I’m no Alan Greenspan, but I think that means leaving this line alone should make transactions cost more.

Alan Greenspan, Self described TurtleCoin “Whale”

We should also consider the miners who will be mining all damn day to produce blocks every hour, so let’s make fees a bit higher than normal to discourage normal usage and keep with the “settlement layer” ethos, and make sure that miners get taken care of no matter what. Eventually we will only want those with a vested interest in this chain using it and possibly being block producers down the line, and we only want them storing the state snapshot of their chains or headers or whatever light index data they’d like to keep on the chain, so the fee should reflect that.

change this: const uint64_t MINIMUM_FEE = UINT64_C(10);

to this: const uint64_t MINIMUM_FEE = UINT64_C(10000); // evil capitalist grin

Mixing

https://github.com/turtlecoin/turtlecoin/wiki/Forking-Turtlecoin#const-uint64_t-minimum_mixin_v1--0

Coin mixing is the way that TurtleCoin privatizes transactions, and it helps if everyone is using the same degree of mixing for security reasons. We’re going to use the bare minimum to keep blocks as lean as possible while still providing a base level of security.

Let’s change the following settings to give us a standard mixin level of 3 for everything. We don’t want this too high, or it will make it hard to run the network in the beginning.

If you’re curious why we do mixing a bit differently than other Cryptonote networks you’ve used, here’s an article that explains what’s going on:

Change these following lines to match the lines in the second block:

const uint64_t MINIMUM_MIXIN_V1 = 0;

const uint64_t MAXIMUM_MIXIN_V1 = 100;

const uint64_t MINIMUM_MIXIN_V2 = 7;

const uint64_t MAXIMUM_MIXIN_V2 = 7;



const uint32_t MIXIN_LIMITS_V1_HEIGHT = 440000;

const uint32_t MIXIN_LIMITS_V2_HEIGHT = 620000;

Use these values instead:

const uint64_t MINIMUM_MIXIN_V1 = 0;

const uint64_t MAXIMUM_MIXIN_V1 = 3;

const uint64_t MINIMUM_MIXIN_V2 = 3;

const uint64_t MAXIMUM_MIXIN_V2 = 3;



const uint32_t MIXIN_LIMITS_V1_HEIGHT = 0;

const uint32_t MIXIN_LIMITS_V2_HEIGHT = 1;

Dust Threshold

https://github.com/turtlecoin/turtlecoin/wiki/Forking-Turtlecoin#const-uint64_t-default_dust_threshold--uint64_c10

This value has less potential to flex your artistic muscle, so it’s best to just leave it at 0. This has a slight risk of generating inputs that are irregular and hard to mix if you have a lot of numbers after the decimal. Like Zpalmtree says, it’s best to leave it at 0.

Fork Heights

https://github.com/turtlecoin/turtlecoin/wiki/Forking-Turtlecoin#const-uint64_t-fork_heights-

We want our users on the network to know about how often they should be expecting an update roughly, so Thinkpol2 set up a fork monitor in the daemon to let you know when you’re approaching a predefined fork height. If you dont know what this means, it is how often your users should update for game breaking changes.

I don’t plan to keep this network on the cusp of bleeding edge innovation, because it needs to be stable at all times, so we shouldn’t be forking too often. Let’s shoot for one fork every 6 months. Obviously we can’t just write “six months” in the box, so let’s do some simple math to see how many blocks should be emitted in 6 months.

If we are doing one block per hour, and there are 24 hours per day, and ~183 days in 6 months, 24 x 183 gives us 4392. Since we plan to fork every 6 months, let’s assign a few fork heights like so:

const uint64_t FORK_HEIGHTS[] =

{

4392,

8684,

13176,

17568

};

This next part sounds somewhat complicated, but it really just means “which upgrade period are we in right now”

const uint8_t CURRENT_FORK_INDEX = FORK_HEIGHTS_SIZE == 0 ? 0 : 3;

change to this:

const uint8_t CURRENT_FORK_INDEX = FORK_HEIGHTS_SIZE == 0 ? 0 : 0;

Naming

https://github.com/turtlecoin/turtlecoin/wiki/Forking-Turtlecoin#const-char-cryptonote_name--turtlecoin

This is the first Athena ever mined.

Somehow this is near the end of the list, but we should change the name of our project here. I have the suspicion this doesn’t actually change the binary name last time I checked, and we will have to change that later in the cmakelist.txt but since we’re following the tutorial, we’re going to change this next line accordingly:

change this: const char CRYPTONOTE_NAME[] = "TurtleCoin";

to this: const char CRYPTONOTE_NAME[] = "Athena";

Wallet Config

https://github.com/turtlecoin/turtlecoin/wiki/Forking-Turtlecoin#walletconfigh

The great thing about using Zedwallet as opposed to Simplewallet is how modular it is. I basically random through this list of params in the WalletConfig.h file and filled them in as I went. They’re very well documented. https://github.com/turtlecoin/turtlecoin/wiki/Forking-Turtlecoin#walletconfigh

Seed Nodes

https://github.com/turtlecoin/turtlecoin/wiki/Forking-Turtlecoin#const-char-const-seed_nodes--

These are your first nodes that allow people to download the chain and get started. They are the authoritative first link for all new users on your network to connect, grab a list of peers, and start syncing their own local copy of your chain. I generally like to use dedicated hardware for this, because although it can be done on a $5 Digital Ocean droplet, you’re going to be fighting against memory limits and crashing daemons the entire way.

Do it right or do it twice. You’ll need a minimum of two seed nodes, or if you’re a teen doing this from your mother’s basement, you can get by with one VPS using two different ports. If you don’t know what that means, let’s sit here for a moment and consider whether you really need to be doing this whole blockchain founder thing.

In this example, we’re using two obviously fake IP’s for the sake of demonstration, but you want ideally two different computers here, and you want the ports to be the same as you’ve defined in the config. Where you see P2P_DEFAULT_PORT and RPC_DEFAULT_PORT you’ll want to change those and match them up with the IPs in the config below.

const char* const SEED_NODES[] =

{

"111.111.111.111:12000",

"222.222.222.222:12000",

};

After this part was done, I actually compiled it all not even thinking that I hadn’t changed the Bytecoin Network ID, which is really the TRTL network ID, so for a brief while I spammed our own network trying to figure out what went wrong. Never forget to change the network byte, even if by just one letter.

const static boost::uuids::uuid CRYPTONOTE_NETWORK =

{

{ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00 }

};

It looks like this, and you can change any of the hex bytes after the 0x part. For those of you who don’t know what that means, just take the pieces and rearrange their order.

Step Four: Premine

https://github.com/turtlecoin/turtlecoin/wiki/Forking-Turtlecoin#premine

Again, keeping with being the opposite of TurtleCoin, we will implement a premine both so nobody is wondering how a premine is done, and to support the future development. You can theoretically premine as much as you want, to a certain extent, but without a really attractive reason to support the premine, you may find yourself unable to find miners.

Scrooge Mcaffee

A typical premine ranges from 2% on the low end, to 60% on the high end. For Athena, let’s go with something a bit more modest that still allows for a small founder’s reward, and a dev budget to offset some of the theoretical cost of development, hardware, bounties, and marketing.

10% premine — 5% Founder reward, 5% Development & marketing budget

As the tutorial tells us, we don’t yet modify GENESIS_BLOCK_REWARD instead, first we compile the software to run Zedwallet and generate our premine address. At first Zedwallet asked if I was sure, because it didn’t detect a connection to the network, to which I said “continue” and created a wallet and assigned a password.

public address: athena1hZmcKXZXgui53gfPsAZXF1kLXN9ZWbw5hPqL4SzP2Lp64a2bMP83umLVKmpF4DzT3S8wHDXm4KW9U5sgMiFaa9oqcwHH2h wallet-name: athena-network.wallet password: hunter2

Premine Protip — Always copy your view key and spend key, and/or your mnemonic seed phrase, which is a long sequence of simple english words. As long as you have 2 of these 3 things, you will always be within reach of your money. Without them you have nothing. No matter what.

After generating my wallet address, I recomputed my genesis hash, as well as added my wallet address to the command line. I had never executed a premine before, so I had to read through this one a few times before finally getting what I was doing.

https://github.com/turtlecoin/turtlecoin/wiki/Forking-Turtlecoin#premine

Step Five: Going Live

https://github.com/turtlecoin/turtlecoin/wiki/Forking-Turtlecoin#setup

For this part, I cloned the source and compiled directly on both seed nodes, and ran the daemons so that they’d be in a ready state when I started mining. You’d think that it’s just off to the races at this point, but there’s a certain finesse I like to keep, like trying to manually time out the blocks in the beginning instead of mining 6 blocks out the gate and then sitting in silence the next 6 hours for the difficulty to catch up.

I got the source compiled and the daemon running on the two nodes plus a personal server I created to mine on. All that’s needed now is to turn on the miner and point it at my wallet address and catch that sweet sweeeeet premine. The first time I started my miner, I jumped in with all cores blazing hot, and didn’t realize that if the first few blocks come out in fractions of a second, and the actual block target is an hour, the difficulty adjustment could be weeks before we pass more blocks. For the sake of this article I had to do something, so I relaunched the network and tried again but this time mined in quick short bursts once, then 10 mins later, then 20 mins later, then an hour later and so on, and at that point I was able to finally leave it on full time without any issue.

Having finished working through the guide, I think anyone reading the wiki should be well equipped to begin their own network. If you do create your own network, please come to our chat and tell us about it and let us help you get the word out there :)