Community Token Proposal :IF:

Congrats on being one of the Top 12 for Impossible Futures!

I have some ideas that I’ve thought about for a while. There are ways to significantly reduce the amount of ETH needed for transactions.

I’m not sure how familiar you are with Gnosis / xDAI, and I’m not sure if the Autonomi team chose Arbitrum One over Gnosis for any particular reasons. From what I can tell, if Autonomi were run on that network, transaction fees would be around 30x cheaper. Would involve replicating two smart contracts (AutonomiNetworkToken.sol and PaymentVaultNoProxyV2.sol) and setting up a bridge.

This is fairly low-hanging fruit and can probably be done without consuming a lot of time.

However, I think the future can be bright with a longer-term (but time consuming to develop) solution: creating a EVM compatible blockchain for Autonomi that has even lower transaction fees (transaction fees that basically can be paid with ANT, or at least the blockchain’s native currency can be pegged to ANT). I’m imagining >100x cheaper transaction fees. The blockchain would be archived on its own Autonomi nodes. An architecture I have in mind involves Pears building blocks, an ever-growing tree of proofs from a zkEVM, and sharding/scaling to keep its chainstate from growing too big (forming a tree/hierarchy of interopererating chains). It could have a locally running client/server with a fairly light disk/memory footprint (and a localhost RPC URL available for Autonomi).

Advantage of both solutions: No significant upstream code changes for Autonomi are necessary. It’s “just another EVM network”: Autonomi can be configured to connect to via a RPC URL and a few parameters (e.g. token contract address, payment contract address).

Disadvantage of both solutions: Using a different blockchain basically forks the network. Autonomi nodes that are configured for Arbitrum One will not associate with nodes that have another blockchain (and vice versa). Files that were uploaded using one blockchain won’t be available for the other. Unless of course, Autonomi were to officially embrace the blockchain change and release a feature to support migrating nodes and their existing stored data to the next blockchain.

On the topic of payments being implemented within Autonomi (rather than a separate layer like I suggested in my previous post)…

If the goal is to reduce transaction fees that are paid for storage (i.e. via Arbitrum One), Autonomi’s current implementation of data types and payments make this a task that I think isn’t yet feasible.

I may be assuming too much about there being a goal of data payments being handled by a community token. Then again, if transaction fees are not a concern that the community token is intended to solve for, I’m unsure of what benefit there would be verses using ERC-20 (or other EVM-compatible tokens/contracts).

Receipts should one day be implemented by the Autonomi team (the documentation briefly refers to it, saying “Work in progress…”), which I think should unlock possibilities. However, I don’t know how soon that day will come.

For now, documentation indicates that GraphEntry is immutable. So I think to write a GraphEntry requires an Arbitrum (or other RPC-blockchain) transaction every time. And of course, Autonomi’s existing code for node payments would have to be modified so that nodes would recognize that they are getting paid using the new scheme (so they allow data to be hosted). Since the project has been embraced with Impossible Futures, maybe pull requests for code changes to Autonomi’s implementation would be prioritized, collaborated with and merged/released in a timely fashion.

I’m also hesitant about how adequate GraphEntry traversal performance will be, as the length of GraphEntry chains continues to increase over time (after all, double-spending needs to be checked for and prevented, etc). I try to think along the lines of “would the solution I’m thinking about be able to handle millions/billions of users everyday?” and at least for now, I’m not seeing it happening soon with today’s Autonomi implementations.

Then again, maybe (hopefully) I’m wrong - this may have been considered already. In any case, I definitely would like a way for Autonomi clients to not pay so much more for Arbitrum transaction fees compared to ANT paid to node operators (my understanding is the value is currently on the order of a million-to-one and has been since TGE).

3 Likes

This was one of the main points of maidsafe. Its sad that after waiting 10+ years this was never actually being worked on.

It has been worked on and the dev team has the goal to make it happen, from what I understand.

5 Likes

Thank you!

Actually, I was not thinking about Gnosis chain, rather the Safe{Wallet} app, which was developed by Gnosis earlier under a name of Gnosis Safe.

Thanks for your effort of researching Gnosis/xDAI and the bridge, but most probably I won’t dig into that, because this project’s goal is rather oposite – to explore ways of escaping EVM-dependence, rather than developing new dependencies or spending time to switch. It would be nice to have 100x smaller fees, but the main problem is the complication of whole process, which would not disappear with new EVM network. And your comment about fork is also :100: % right, we want to avoid that.

@maidsafe were working on a solution utlilizing DAG nodes:

And my idea is Forward validation together with Backward validation. Lots of work, but I think it is realistic, because it would mostly be done collectively. With a Native Token the checks would be even simpler, because only parents of a transaction would need to be checked, because instead of client, nodes were performing checks, so it was guaranteed, that all transactions were valid, otherwise they would not be added to the storage.

As we all do! But the million-to-one is also an effect of emissions, that incentivize node operators beyond simple payment for storage. If not emissions, there were much fewer nodes/operators, and price for storage would most probably significantly rise.

5 Likes

As you mentioned in the linked token.md, vicious users can sabotage forward validation by adding wrongful error markers. I’ll call this a “marker attack”. In my opinion, “it would mostly be done collectively” is an idea that may not be feasible (for today’s Autonomi).

I was working on a token vulnerability analysis (including detailed step-by-step validation tasks) based on my understanding of Autonomi’s data structures and how I think a community token might be most securely implemented. The analysis assumes that we can’t trust error markers due to malicious users, and so it basically disregards forward validation and focuses on a modified form of “backward validation” (thorough, all the way to genesis for every ancestor GraphEntry).

In the course of analysis of backward validation, it occurred to me that Autonomi doesn’t seem to provide a way to determine the order in which GraphEntry children are created. And if the order can’t be determined, I think there could be what I’ll call a “Joker money fire attack”: a malicious user makes several valid transactions into the economy, waits for a long while, then eventually publishes a transaction that overspends their balance. Doing this could cause every descending transaction to become tainted (basically, “burning” tokens of everyone who has received a transaction descended from Joker’s overspent GraphEntry).

Do you have more thoughts about meaningfully doing validation and preventing/mitigating attacks? (i.e. marker attack, Joker money fire attack)

4 Likes

Well… Rn with a couple thousand usd investment you could run a significant majority for a few days and have your nodes just accept and store a tx sending 1 billion ant from nowhere to your wallet…

Just validating the parent might be okayish for small txs when you’re running your client - but there definitely must be a strategy to deal with error cases…

2 Likes

Because there is only one.

That descendant can have multiple inputs and outputs but once the GraphEntry is written all outputs are specified and you need to spend from the outputs if you want to spend again…

… Which means that there needs to be a ‘default output’ in case the spender didn’t know of a input to an earlier graphEntry that wasn’t considered/mentioned in its input/output calculation. You could injest this ‘forgotten’ input with a later tx along the default path (as long as there is a default output to each graphEntry/TX…)

1 Like

I have doubts about what you say, and think that the money fire attack is possible based on what’s currently proposed.

However, based on several notes I’ve made & AI chats, I believe I’ve figured out a way to securely implement a community token, with each transaction utilizing three data types: Register, Chunk, and GraphEntry. Register can prevent a Joker money fire attack because it provides a way to ensure a consistent history of the sequence that transactions were made by Joker - the transactions that occurred later can be definitively identified, preventing overspending (and avoiding invalidation of transactions that were valid at the time they were made).

3 Likes

Wow, you seem to be the first person to seriously dig into this, thank you :slight_smile: Some of the concerns you raise, are also bothering me. I’m still not 100% sure, but I don’t see things in such hopeless way.

Yes, this is if you want to be 100% sure about your transaction. You would not always want to go all the way to Genesis, because you could keep a record of already checked txs (or get them from a trusted source) and stop validation when you encounter one. That’s another idea.

I’m also thinking about why someone would create false markers in the first place? A ransom comes to my mind: “give me $1000 or I’ll mark your transaction/spend invalid”. But how would she know my transaction address? And marking the transaction only burns the outputs, so it does not hurt me, but the person(s) I payed to… unless there is a rest output to myself. But which one would it be of the outputs? How would attacker know if it’s even worth the hassle of requiring ransom? How would she contact me? It gets complicated…

And even if we can’t trust the marker, we still have backward validation. If you trust the person you’re dealing with, there’s no problem. If not – probably when doing $1bn transaction, it’s ok if you say “give me one week, I have to check your outputs”. Or there could emerge some trusted entities, that would check transactions for money, and keep indexes of valid transactions, just like I wrote above,

The sabotage could come from some mighty player, who has power and willingness to disrupt entire network, they could just mark all transactions up from the Genesis. But again, they can break things in many different ways – spin up millions of nodes (it’s not impossible, as we have seen recently with emissions) to do a sybil attack, upload petabytes of data to inflate storage price, flood the network with Scratchpad edits to DOS other nodes…

I don’t quite understand the concept. Why would the order need to be determined? If you publish a spend (transaction), outputs are already set-up for public keys of person you are paying to, and only they have private/secret keys to spend the outputs. Sometimes you also include an output(s) to your own key(s) (a “rest”), but all outputs have values determined, and you cannot overspend (publish a spend at the address of rest output with output values that sum higher, than input), or it will be an invalid entry. And it does make only the new spend tainted, so nobody would accept this as a payment.

The concerns about back- ad forward- validation disappear though, if we do modify node software to perform checks, and then on each transaction we just need to check parents, and the rest relies on network’s security based on closed group consensus etc.

Are you speaking about sybil attack? This could disrupt the network in many ways – overwrite Scratchpads with garbage, accept uploads but not save them, respond with garbage to download requests… Nobody would trust the compromised network anymore, so probably would not want to make payments with Native Token as well. Thus, the attack is not feasible, because it leaves the attacker with loads of useless tokens if I think right.

BTW what’s “Rn”?

1 Like

only if people know and he would just create his initial mint and maybe split into 1000x smaller (valid) TXs from there

rn == right now

1 Like

Network size is tracked 24h by many people, so I think a 100% rise in nodes count would be noticed.

1 Like

and interpreted right?

and even if it was … for a local majority you don’t need a 100% increase … and the attacker wouldn’t need to care where precisely in the address space the mint would reside … so even at a larger network this attack would still be possible …

It would be great to know the details. I can’t get it from this short description…

2 Likes

Here’s a step by step use case:

  1. Joker legitimately acquires 100 ACT (Autonomi Community Token), e.g. from an exchange. His unspent 100 ACT is at one GraphEntry (let’s call it “J”).
  2. Joker spends 20 ACT buying a coffee from Alice. In other words, he creates a child GraphEntry for Alice’s received funds (let’s call this child “C1”)
  3. Joker spends 20 ACT on junk food from Bob - he creates a child GraphEntry for Bob’s received funds (let’s call this child “C2”)
  4. Joker spends with a few other merchants (20 ACT each) - let’s call those child GraphEntry records “C3”, “C4”, and “C5”.

At this point, GraphEntry J has five child GraphEntry records (transactions totaling 100 ACT). Joker patiently bides his time while the ACT that he spent into the economy circulates amongst lots of people.

If we don’t have a way to determine the order in which the children were created, that means we don’t know if, for example, C5 occurred before C1. Which isn’t a problem until Joker decides it’s time to torch the money by creating a child GraphEntry record C6 that spends 20 more ACT. Since at this time Joker has spent 120 ACT despite him only ever receiving 100 ACT, all children GraphEntry records are tainted. And their children’s children, and even their great great great grandchildren, etc. Because we haven’t implemented a way to definitively conclude that C6 is the overspend (and C1, C3, C2, C4, and C5 were valid at the time they were made).

1 Like

Maybe I’ve misunderstood the structure of the proposed ACT graph. e.g. if each 20 ACT transaction creates two outputs. But I think that’s still vulnerable without definitive ordering.

  1. Joker has 100 ACT at GraphEntry J.
  2. Joker buys a coffee from Alice for 20 ACT, creating two children of J (UTXOs) that he signs: C1 is 20 ACT for Alice and C2 is 80 ACT for Joker.
  3. Joker buys Bob’s junk food for 20 ACT, causing two children of C2 that he signs: C3 is 20 ACT for Bob, and C4 is 60 ACT for Joker.
  4. And so on three more times […]

At this point, Joker has spent 20 ACT with each merchant, for a total of 100 ACT. We’ll call the rest of the descendents C5, C6, C7, C8, C9, C10.

Joker patiently bides his time and eventually decides it’s time to torch the money. He does so by creating another child of J (let’s call it C11). Similar to how he paid Alice, he signs a transaction GraphEntry for 20 ACT to Mallory. At this point, GraphEntry J has three direct children: C1 (20 ACT), C2 (80 ACT), and C11 (20 ACT). This totals 120 ACT, which is invalid (because J only was given 100 ACT to spend).

Unless there is a mechanism in place to definitively identify whether C11 or C1 occurred first, all descendant GraphEntry transactions of J become tainted (great great grandchildren, etc).

1 Like

Ok, now I get your point. The problem is, it’s based on wrong assumption, that Graph Entries are mutable. Perhaps due to entire basic process poorly documented (note to myself).

This means the exchange creates GE (can we call it J?) with output of 100 EACT (there will be no such token as ACT, it’s just a system like ERC20, so let’s call it “Example ACT”) to one of Joker’s public keys (and perhaps a second one, the “rest” output to some exchange’s own key). Having a corresponding secret/private key allows Joker to spent this output by creating a child GE.

That would actually mean publishing a GE/spend/transaction J1 with input being J’s address and 2 outputs: 20 EACT to a public key provided by Alice (Alice can later publish C1 with this output as an input if she wants to pay someone later) and 80 EACT to one of Joker’s own private keys.

This means repeating whole process, until J5 has only one output – 20 EACT paid to the last merchant, because there’s no rest.

So, we actually have an order here, through the rest outputs.

2 Likes

He could create C11 with an input of J, and 20 EACT output to Mallory’s key, but Mallory (or nodes from close consensus group, if it’d be implemented) would verify this and see, that J has no corresponding output (becaue J is immutable and already set in stone), so the money is fictional, and she would not give Joker his junk food! :slight_smile:

1 Like

Autonomi’s documentation for GraphEntry shows example code in which a GraphEntry (graph_entry) is created and stored on Autonomi and retrieved from the network. After that, a child (graph_entry2) is instantiated and with its parent set to graph_entry. I guess that confused me.

So in my earlier examples, I guess I was missing that, e.g. C11 indicates that J is their parent, but at the same time, J does not indicate that C11 is their child. I assumed that later-created child nodes were traverseable from the parent. From the Autonomi documentation, I knew that “GraphEntry” is immutable, but I assumed that links to GraphEntry children were not considered to be in scope of the immutability.

In Alice & Bob’s world, “Mallory” is typically a name for a malicious person, not a merchant. :wink:

3 Likes

(Poll)

I’m wondering what’s the best option for non-bridged (non-ERC20; take note that I imagine Native Token as ArbOne ANT bridged to Autonomi, so this also excludes NT) tokens:

  • Have a deterministic token_id (a hash/xorname of symbol + name + decimals?), that would disallow creation of multiple identical tokens, but enable people to squat token ids. There could be a list of tokens (token_ids, names) to be “pre-squatted” before the release on a mainnet as a part of this project if necessary.
  • Make a token_id different for each new token, regardless of token parameters, so that multiple tokens with same parameters, but different token_ids could exist? Like many ANTs or ETHs?
0 voters
2 Likes