RFC 57: Safecoin Revised

I see that as entirely a front-end/SAFE Client Libs API issue. The fact that the network can provide that higher level of divisibility doesn’t mean it needs to be presented to human users. If an app decides to only support humans entering safecoin values to two decimal places, then it can enforce that. We may even only present the option to use nano safecoin at the SAFE Client Libs API where most app devs will be interfacing. That still doesn’t mean there’s any drawback to having the greater level of coin division within the type the network uses.

I believe it makes the code clearer. If that turns out to not be the case, or we find it’s worthwhile to optimise this, then we can certainly change over to use a u64. But this seems like a tiny detail to me.


Thanks @lubinew, my fault! Looking at it from that angle it might not be a bad idea to introduce divisability after all. :smiley: Only time will tell if it will be really necessary, but having the possibility at least might not be too bad.


There is a reason why financial programs used fixed point integer for storing and expressing financial data for well over 50-60 years. Please oh please understand there is very good reason to have the very variables used be a fixed point decimal. Yes it is a lot more than just a front end issue.

I can write a small book about it if you want but examining decades of practise should be a compelling adviser. Hint it never goes as you think it will when a multitude of programmers use a mixed binary/decimal system. And even in the back end there will be issues that will bite you in the butt after launch. Basically do it the right way from the start using fixed point integer for financial data and not try to mix it up and writing work arounds with carrying in/out values to/from units&parts and then trying to account for not using all the bits with binary rather than fixed point integers.


Yes, data on SAFE is mostly encrypted but that is beyond the point here. z-base-32 would be used for representing random bytes, e.g. an XOR address or a public key (like suggested in the RFC).

z-base-32 is designed for random bytes. From the specification:

The rationale for our encoding is different – it is to represent arbitrary sequences of octets in a form that is as convenient as possible for human users to manipulate.

Some of the alphabet characters will appear more frequently than others in the final position of the encoded strings, assuming an even distribution of binary inputs.

From the specification:

#bits base-2                           base32     base64     z-base-32
----- ------                           ------     ------     ---------
1     0                                AA======   AA==       y
1     1                                QA======   gA==       o
2     01                               IA======   QA==       e
2     11                               QA======   gA==       a
10    0000000000                       AAAA====   AAA=       yy
10    1000000010                       QCAA====   gIA=       on
20    10001011100010001000             BC4IQ===   CLiI       tqre
24    111100001011111111000111         6C74O===   8L/H       6n9hq
24    110101000111101000000100         2R5AI===   1HoE       4t7ye
30    111101010101011110111101000011   HVK66QY=   PVXvQw==   6im5sd

Well - then the specification simply lies… If you replace the characters




You end up having you data base32 encoded - not that strange thing in the table you cite there… Base32z is base32 where the meanings of the characters have been shuffled around… No more…

Sure - base32, hex, base64 all are… That’s why the claim of base32z to be better readable than base32 imo doesn’t make sense… And I haven’t seen an argument yet that would support this claim…

Ps: oh - I’m sorry - okay - there really seem to be more often appearing characters - you are right

Some of the alphabet characters will appear more frequently than others in the final position of the encoded strings, assuming an even distribution of binary inputs.

Thx for pointing this out @bzee =) so we are talking about the last character of the sequence to be ‘better readable’ (if the theory is correct)

This is how the examples would look correct:


#bits base-2                           base32     base64     z-base-32
----- ------                           ------     ------     ---------
1     0                                a          AA==       y
1     1                                q          gA==       o
2     01                               i          QA==       e
2     11                               y          gA==       a
10    0000000000                       aa         AAA=       yy
10    1000000010                       qc         gIA=       on
20    10001011100010001000             roei       CLiI       tqre
24    111100001011111111000111         6c74o      8L/H       6n9hq
24    110101000111101000000100         2r5ai      1HoE       4t7ye
30    111101010101011110111101000011   6vl3wd     PVXvQw==   6im5sd

Ps: and yes please correct me if I’m wrong
Pps: sorry for not clarifying earlier… I somehow thought it would be obvious…


I’m pretty sure it’s referring to this:


@neo few of us have much if any experience of these problems. I did write my own accounts program in, um probably basic, back in the eighties, mainly to tot up VAT but it was very, er, basic :grinning:

Could you give one or two of the most compelling kind of examples? I think it would help us to understand your concerns.

Right now I see both sides of this argument and not much to choose between them. I guess one point is rounding errors? I used to encounter my own form of those :wink: and just wrote them off each period.


There are only 10 types of people in the world: those who understand binary, and those who do not :wink:

And there are also 10 other types of people in the world: those who understand hexadecimal and F the rest.


@Lindsey can we do this, please.


StoreCost = 1/G + F/N

What exactly is a StoreCost ? Is it number of SafeCoin per one PUT ?

For 0% of full nodes we would get
SC 0,0001 for 10 000nodes
SC 0,00001 for 100 000nodes

For 1% of full nodes we would get
SC 0,0101 for 10 000nodes
SC 0,01 for 100 000nodes

For 50% of full nodes we would get
SC 0,5 for 10 000nodes
SC 0,5 for 100 000nodes

It looks that 1% of full nodes is not healty for price and network.

1 Like

I just don’t think there is a need to complicate matters. To quote the rfc:

The parts field represents a multiple of “250 pico-safecoins”, i.e. the number of 250 * 10^-12 -th parts of a single safecoin. The total value of the parts field will be required to be less than a single safecoin, i.e. it will always be less than 4 billion.

Is it worth having a counter intuitive system just to give us a little extra precision?

So, to run some numbers:

  • 0.5 safecoin is 2,000,000,000 parts
  • 0.1 safecoin is 400,000,000 parts
  • 0.99 safecoin is 3,960,000,000 parts
  • 0.000067 safecoin is 268,000 parts

It may only be internal, but it means having to do the maths every time to get the right value.

If we ‘just’ have 1,000,000,000 parts, we get the following:

  • 0.5 safecoin is 500,000,000 parts
  • 0.1 safecoin is 100,000,000 parts
  • 0.99 safecoin is 990,000,000 parts
  • 0.000067 safecoin is 67,000 parts

It is relatively trivial maths, that you can work out in your head. We haven’t lost much either, with the smallest unit being:

  • 0.000000000250 safecoin is 1 parts (but only 0.0000000005 =2, 0.000000000750 = 3 and 0.000000001 = 4 are available)
  • 0.000000001 safecoin is 1 parts

Is is really worth it? I say no it isn’t. Just ignore everything over 1,000,000,000 parts, treat as decimal and keep it simple.

(P.s I think I have the maths right, lol)


This seems like practical reasoning based off real world experience, Maidsafe could use their outside/ university links to verify what is being said here. Small detail with huge implications by the sounds of it.


The first thing to consider is that COBOL was (mostly) designed for the financial programming world and the financial world used COBOL almost exclusively so examples are not always frequent since they used fixed point integers anyhow and did not have to program around binary-decimal issues.

  1. Rounding,
    If you use binary then specific decimal values can never be sent. What happens is that you get cases when a specific value is requested but the actual value is 0.000000001 less. In these cases the front end does the expected rounding and shows the specific decimal value but it is not quite that. For instance you request 0.3 for each item you sell and after 4 items you expect to have 1.20 since that is what all the front programs have told you because that is the expected and normal function of them.
    Now you try and buy something worth 1.20 and so arrange everything (delivery addresses etc) and go to pay for the item only to have the receiver say you are short OR your wallet refuses to send 1.20 since you only have 1.199999997 and the front end wallet is set for 2 or 3 or 6 decimal places and continues to say you have 1.20 but cannot send 1.20 because you don’t have it.
    The fix for this is not as simple as saying the wallet front end should show all the places in this case. What we have is the back end causing confusion, anger, disgust, etc because the front end program can only work with what it has.
  2. Split units-parts
    Are these stored as integer? That would be the sensible way, but since its been split then we cannot assume common sense has been used. Is the parts variable some sort ???
  • 1/(parts-value) is what it represents? ie fractions of a coin
  • a variant of fixed point value? Cannot be fixed point ever since there is non decimal value stored but units of 250 pico. May seem to be that but in fact is a 250 pico unit.
    • parts value of 1 == 250 pico,
    • 2=500 pico and so on
  • some sort a binary representation of a number less than 1. 1/2^32 is the base unit rounded to 250 pico? This is worse than straight binary
  • which method is important and the best would be the 1=250pico, 2=500pico etc.
  1. split units-parts problems
    With a split units-parts we then have to do to 2 separate operations whenever 2 values have to be added or subtracted. Worse for front end that needs to work out how much 5 items cost using multiplication.
    This means that the back end has to over complicate the process of working with safecoin for both the back and front ends and gives no benefit whatsoever. Do you dig that ditch with 2 spoons or 1 shovel.
    It is yet another avenue for bugs to be introduced into the one thing that cannot afford any bugs at all - the backend handling of safecoin.
  • Considering the lack of definition of how the parts value is stored and even the best method of 1=250pico 2 = 500 pico and 3,999,999,999 = 0.999999999750, we still have the issue of double handling the calculation.
  • It introduces additional CPU time for safecoin calculations due to adding additional steps to simply add/subtract two safecoin amounts. Over a world wide network adding CPU cycles just because the initial homework was not done is bad programming practise.
  • No financial program does this splitting off of dollars and cents simply because it is inefficient, bad programming practise, and prone to introducing bugs.
  • It is unnecessary when the programming language provides the variables to allow for using a single value. The number of places can be 9, 18, 27 by choosing the variable size. There is no downside to providing for the maximum decimal places up front. The additional 64 bits to store value, while adding up on a global scale is still insignificant to the overall storage. Whereas additional operations for a split value is heat, electricity cost, time that adds up on a global scale and any savings here is worth “gold”.
    • so the question should not be whether to use split variable or not, but to choose the maximum number of decimal places we think we could ever need. Discuss number of decimal places and use that, or add a version flag so that we can upgrade later and have both working together forever if necessary.
  • the sort of problems with split values is that you have to have code accounting for overflowing the parts and adding/subtracting the overflow from the units. Now in the old days of assembler programming (mainframes or microprocessors) this was routine stuff when writing maths or values requiring more than the word size because the max word size for storage was 36 bits for mainframes or 8 bits for micros. Once languages were used then the variables were available and easy to have 16 or 32 or 36bit integers, but still had to have split values that needed more then that. So with modern day languages this issue is no longer a problem with 64 bit or greater variables and wanting fixed point integers to handle numbers up to 4,294,967,296,000,000,000 and fixed point makes this 4,294,967,296.000000000
  • why introduce complexity when not needed?
  1. Front-end potential problems
  • front end is not under the control of back end people
  • Bad programming practise by the back end people lead to bad programming practise by the front end people. It creates additional avenue for bugs to be introduced in the front end code.
  • If you allow down to 250pico then front end programs will advertise themselves as to showing the user the full amount in their wallet, so the argument of the user will only see 2 or 3 or 6 decimal places is only good for a certain %age of the population (maybe 50 or maybe 75%). Its the others that will cause all the noise and complaints which in turn gets the others worried and an increasingly larger number will then look into it.
    • you will have wallets that show the 250 pico and people will be questioning why they cannot send 1 pico for that comment tip. 1/4 decimal place is against all the financial training that we get from primary school onwards. Yea I know the USA has a quarter, but that is 25 whole, not 1/4 of the 10th decimal place. We (Maidsafe/forum users) live in a bubble of relative intelligent people who can accommodate perhaps 250pico, but most adults will go sh*t what is this crap when they install wallets that show the whole balance on request. Especially when the wallet show 1.20 safecoin but will not allow then to send 1.20 safecoin to someone because the balance is really 1.199999999750 and they say to themselves well I cannot send down to 0.000000000001 (1 pico) and try to do so when tipping or donating.
  • it only takes 1 in 10,000 people to complain to destroy confidence in safecoin and dramatically slow the adoption of safecoin and consequently SAFE. Thats 0.01% and in a world of social media that is more then enough to create problems simply because of one back end bad decision - money talks guys, get it right first time, especially when you’ve been told about it.


  • the issues with 250pico is both human and additional issues with front end programming by people not as talented as people in Maidsafe and in the forum.
  • the parts variable is not defined how the value is stored
  • units-parts goes against decades of good programming practise for financial and complete number storage when there are variables already in the language that can handle the full number.
  • unit-parts adds complexity for adding & subtracting within the backend and provides an avenue for introducing bugs now or later on with fixes or additional features
  • A single fixed point integer variable removes any need for the backend to do additional coding for split values and can reduce coding since the back end can work in say nano safecoin for everything it does and thus does not even have to know the value is a fixed point integer To the backend it just thinks the coin has 2^32*10^9 units.

Overall this is great to see.

It will take a long time to digest.

What exactly is a StoreCost ? Is it number of SafeCoin per one PUT ?

Agreed, please please please put units on this in the RFC. Maybe a short worked example could be handy. A simple change but imo very important.

My assumption is storecost units would be “SAFE per PUT” (smaller number means cheaper PUTs)

“This formula [for storecost] will very likely need to be refined”

Yes for sure it will need to change.

StoreCost is tied to section size, which is basically constant (between 100 and 200, as described in Future Enhancements). Section size is never going to get ‘really big’ so storage will never be ‘really cheap’. That’s a mistake.

If full nodes (F) is zero most of the time (a fair assumption considering the incentives of the network) then StoreCost is effectively 1/N.

Maybe introducing prefix length to the formula would help since that would allow a large network (total vaults) to be considered, rather than just section size which doesn’t say anything about the actual available space on the network.

I realise this sounds quite critical, but I’m just pushing for cheap storage as much as possible since that’s potentially a unique feature for SAFE.

Probably a lot more to delve into here but that’s my surface impression of the formula.

“The Core Developers of the SAFE Network are awarded 5% of the total”


This is way too much.

If this happened in bitcoin, MaidSafe would have received 826,150 btc by now. I can’t see how that’s justified. Especially since SAFE will overall be worth a lot more than BTC.

Maybe if there was a plan for spending, or plan for the governance of these coins, or the far-future implications then I’d be a bit more ok with it. But if spending from the core pool of funds ever drops then that 5% will start to accumulate really fast.

It’s great to have a mechanism sustainability of development and stimulus for economic activity - that’s awesome - but I’m needing quite a bit of convincing this technique is the right one.

Let’s compare to Visa… a fee of approx 2% per transaction gives them US$18 billion revenue. Can MaidSafe spend $18 billion per year? I guess so but it’s a fairly big question I feel.


Is PUT Balance no longer there? ie all PUT will result in direct deduction of safecoin from the uploader CoinBalance (using the current StoreCost calculated for the PUT)?

There seems to be an incentive for users to have multiple CoinAccounts spread fairly evenly across XOR space for large accounts. This way no single section controls all the funds for that user. Makes for an interesting bit of whale wallet design optimisation perhaps?!

I support @neo with fixed point integers. No amount of hiding the details will prevent people from trying to abuse them and burning themselves or others. A single u64 is my preference (decimal point can go wherever probably no decimal is better!). Not a super strong preference, since I appreciate the engineering desire to maximise the use of digital space.

But usability cannot be ignored, and libraries or abstractions won’t fix, say, ‘advanced’ excel users.


Its not Maidsafe that will receive all the core dev. It will be the likes of you, @tfa, and many others including ex-Maidsafe developers, and Maidsafe too.

Also that figure is over 9 years isn’t it and the average value at the time of earning would be like $800K, less than 100K per year. Just the last few of years would it more than, but averaged over the whole 9 then its more like $1 per bitcoin mined.

Is it really a big problem?

Definitely a good idea to spread ones balance across multiple coinAccounts. Especially considering what you said.

I would expect that only the front end programs would deal with the decimal point positioning. The back end could just work in 1 nano safecoin and never worry about scaling the number or such things.


Just for interest this is how the store cost changes as the section becomes full (more full nodes means higher store cost)

It uses the StoreCost formula from the rfc
SC = 1/G + F/N
ie 1/(N-F) + F/N
where N = 150


Not sure if 50% of full nodes will occur, but

Each section will aim to maintain a minimum ratio of 50% good nodes - ones which aren’t full. As vaults are added, removed, or flagged full, if that ratio of good nodes drops or remains below 50%, vaults will ask routing to add a new node to the section.

Than StoreCost 0,5 mean, that value of each SafeCoin is really low or would you pay for 2 PUT $0.2 ? Which is bad both farmers as well.

For now, we will use an algorithm which would eventually deplete all farmable coin, but which is simple to implement while we gather further data from testnets.

This propose reward algorithm does not motivate to provide more bandwidth which might result to bandwidth bottleneck if majority would have DL_10/1_UL ratio connection.


I also support this. Much better than splitting into two and using and funky arithmetic.

Edit: all finance systems I have worked on either use integers (pennies/cents multiples) or fixed decimals. The risk of bad representation/maths just isn’t worth it.


I’m not sure the visa comparison is fair, as that isnper transaction. The 5% fee is only part of the farming reward and would be way less than a 2% transaction fee. Aside: I assume safecoin transactions themselves will still be free?


Thanks @neo for answering me and taking the time to write up those examples, and to everyone digging into this.

It’s exciting getting to talk about Safecoin implementation again :slight_smile: