freecoin is a fully-functional cryptocurrency I'm making for fun. Unlike most cryptocurrencies which followed Bitcoin (litecoin, dogecoin), freecoin uses no Bitcoin source code.
A cryptocurrency is a currency that is functionally possible because of cryptography. Mathematics and cryptographic principles allow a user to prove they were the recipient of a past transaction.
With banks that deal with regular currencies, all regulation happens in one place. Storing the amount of money each person has along with the processing of transactions all happens on a few servers. Though they probably take backups and security very seriously, banks (and the governments that regulate them) represent a central authority over a vastly powerful resource. With decentralized currencies, transactions are processed and balances are stored by the people. Everyone agrees on how things should work, so it works.
#####Revision 5.0 - 6/4/16 All freecoin communication is done over TCP. Because data must be able to permeate the network quickly, most functions are designed with the purpose of data request and exchange.
All messages have the following 7B header.
[4][2][1]
[body_len][version][CTYPE]
0 <reject>
[1][1][<=255]
[ETYPE][info_size][info]
Sent in response to invalid data.
1 <gethighest>
[]
Requests an inv of a peer's highest chained block.
2 <getchain>
[32][1]
[start_block][count]
Requests an inv of the [count] blocks that proceed [start_block].
3 <gettxs>
[]
Requests an inv of all orphan transactions a peer knows about.
4 <getpeers>
[]
Requests all of a peer's peers.
5 <inv>
[1][1][count*32]
[DTYPE][count][hashes..]
Informs a peer about the existence of data.
Should only include *orphan* transactions and *chain-valid* blocks.
6 <getdata>
[1][1][count*32..]
[DTYPE][count][hashes..]
Requests blocks or transactions.
7 <block>
[?]
A block. Should only be sent when solicited by getdata.
8 <tx>
[?]
A full transaction. Should only be sent when solicited by getdata.
9 <peer>
[1][1][addr_len]
[port][addr_len][addr]
Information about a peer.
10 <alert>
[1][48]([1][4][msg_len])
[msg_len][sig]([ATYPE][time][msg])
Notifies peer about network emergency. Only valid if signed by admin_key.
11 <ping>
[]
Requests that a peer respond with a <pong>.
12 <pong>
[]
Solicited by <ping>.
1 bad_version
2 message_malformed
3 bad_ctype
4 bad_dtype
5 bad_atype
0 blocks
1 transactions
2 peers
0 warnuser
1 forceupdate
Note: See the source for info on handling received messages.
In order for the network to remain functional, all clients must abide by the following three rules:
- Stay as informed as possible
- Keep others as informed as you are
- Strive to have the highest possible chain.
-
Try connecting to known nodes until one works. This is peer0 .
-
For
(0 <= n < 8):- Ask peern what peers they are connected to. Select a node randomly from this pool (excluding ourself, peer[0,n-1] and any nodes we've failed to connect to). This is peern+1.
- If peern for
n>0has less than 8 peers, send them a list of all our peers. - If peern for
n>0has no nodes that are valid to us (according to above exclusions), select another node from the same pool we selected peern from.
- Send all peers a
<gethighest>. - If you have less than 8 peers, send each peer a
<getpeers>until you do.
It's important to test the validity of data we receive. Although there are certain traits a block or transaction may have that make them blatantly invalid, there are certain types of validity that can't be tested for until we have a complete picture. To remedy this, there are two tiers of validity: pseudo-valid and chain-valid. Data can be confirmed to be pseudo-valid at first glance. However, it's only until we know about the entire chain of a block or the block of a transaction that we may deem data to be chain-valid.
- sha256(block_header) <=
targetfield versionfield matches that of the current clientmerkle_rootmust be merkle root of transactions in body, in order- The body must contain
tx_counttransactions, all of which must be pseudo-valid.
- if
height== 0:- Block hash must be equal to
ONE_TRUE_ROOT
- Block hash must be equal to
- elif
height> 0:timefield >timefield of previous blockheightfield == 1 +heightof previous block- If
height<CHAIN_RECALC_INTERVAL:targetmust be equal to the previous block'starget
- else:
targetmust be correct in terms of the previous block and the blockCHAIN_RECALC_INTERVALblocks prior to it
- The body's transactions must all be chain-valid.
versionfield matches that of the current client- If [transaction_size] > 1000 bytes, this transaction's outputs' combined output surplus must be >= [transaction_size] *
TX_FEE_PER_1K - The body must contain
in_counttx_inputs andout_counttx_outputs. All inputs must be pseudo-valid.
- If this is the first transaction in the block and (
in_count== 0) (coinbase transaction):- The combined output amount <= (
MINING_REWARD+ the combinedtx_outputsurplus from other transactions in the transaction's block).
- The combined output amount <= (
- Else:
in_count> 0- The the sum of the
amounts corresponding to eachtx_inputmust be >= than the sum of theamounts corresponding to eachtx_output. - The body's inputs must all be chain-valid.
- The
sigfield must contain a signature (corresponding to thepubkey) of the sha256 of the input's transaction, minus the parts where the signatures would go.
- The
out_indexth output of theref_txmust not have been spent in this block or one prior (within the same chain).
- ipv6
- fast_mine: C API, and the first 64B chunk of every hash need not be calculated on each iteration.