Community Token Proposal :IF:

So, now we can create tokens and display balances! Transactions coming soon™.

19 Likes

Weeks 5 & 6 summary

Hello. It’s a long time since last weekly update. Making the update in fact bi-weekly :slight_smile: Today I received more funding (thank you!), so it’s a good occasion to wrap up what’s been happening recently, expect also a few daily updates!

Most important news is that the project qualified for “backing” round of Impossible Futures program. We took place near the top depending on interpretation. Thank you all brave voters!

This allowed me to repay my first donor with USDC reward, ANTs waiting in line for their time :slight_smile: Thanks a lot for the support!

These weeks were also weeks of great community time, engaging discussions with @bytes on Forum about security and @ sbosshardt on GitHub about multichain ERC-20 operation, as well as a recent poll about allowing same names for tokens. Also, hope for comments on token_id and genesis spends.

Code-wise, most significant changes were on UI side, so we look like this now:

18 Likes

As I understand it, the network uses quantum-safe encryption for data storage, but ANT token does not. Not a dev, so pardon my ignorance, but I would assume that’s yet another motivating factor for getting to native asap. I’m sure you have considered that and would appreciate if you could clarify that for the rest of us non-techies. Thanks in advance.

2 Likes

ANT token is based on Arbitrum/Ethereum, which don’t seem to be quantum secure. Autonomi also uses BLS signatures mentioned in linked article, which are not considered quantum secure. Also, it uses AES-256 for node record storage, but self-encryption seems to use weaker AES-128 (although the Whitepaper states otherwise), which is considered not Q-S. As I understand it, node storage is secure, but network traffic not so much.

6 Likes

Here are my thoughts…

This statement about the bridged token seems to be a consequence of having a constrained model intended to work within the GraphEntry’s 32 bytes of content:

“first 6 bytes of SHA256 hash of minimal unsigned int (eg. 0x02AB34 for 174900) representation of Chain Id (eg. sha256(0xA4B1)[0..6] for Arbittrum One)”.

I think that token parameters (such as the Chain Id) ought to be easily read and understood. A hashing function produces irreversible random output.

Seems like it’d be better to have a chunk for bridged token metadata, like you have for Native ACT. The genesis GraphEntry would similarly use its 32 bytes to point to that chunk. Then you are no longer constrained to store limited metadata - you have up to 4 MB, which leaves room for the standard to grow as needed, and can easily store data in a format that’s more comfortable to read (e.g. json).

I’m not sure what a “Token ID” is intended to be. If it’s just something that needs to be unique and immutable, basically that’s the address the GraphEntry is stored at.

If we want to securely defend against a malicious genesis signer who down the road manages to cause a fork (two GraphEntry records at the same address), the Token ID can instead be a hash of the GraphEntry record and the address it’s stored at. But then that can’t be known at the time of creating the genesis chunk (since the chunk’s XOR address is the GraphEntry’s content). So with this more secure approach, the user “needs” two values (address and hash-id) instead of one (address).

2 Likes

We’ve seen some action here today.

Creation of token (wallet #1) and requesting payment (wallet #2):

Crating payment (wallet #1) and receiving it (wallet #2):

16 Likes

i’ve a couple of questions @loziniak

on github i read

Bridged (ERC20)
A token consists of multiple graphs, each of them created from a EVM burn transaction. Token info can be read from EVM blockchain, currently Arbitrum.

Token ID is a hash/derivation of EVM token address. TODO: or maybe first bridge user should create token info structure?

Genesis transaction GE:

content is a burn transaction ID on the blockchain
Single parents entry, pointing to the GE itself (or zero?), as a marker of Bridged genesis transaction.

how do you make sure that there is only one Genesis TX per blockchain burn ..?
imho the secret key of the genesis TX must be derived from the burn TX otherwise there could be multiple genesis TXs just pointing to the blockchain …


what is your precise data structur/model used in the DAG? Since you seem to be moving along fast and far this should be pretty precisely defined now ..?

  1. Spend recipient is the [not yet existing] next GraphEntry of the recipient wallet? So does my Wallet Address change all the time? Does the wallet iterate along the graphEntries or is there a pointer speeding stuff up involved?
  2. what do we do if a spend is not known when the next GraphEntry gets created and we therefore have a “missing input” ..?
  3. do people always need to tell us (in time) out of bound about the new spend to us ..? how can we know about new incoming TXs? One possibility would be to branch out an outgoing TX of amount 0 to n secret key controlled by the other party for it to be able to create to store TXs to a place we check periodically - either we’d know the secret key too and would then branch amounts back into our main wallet or the other party would actively push into our wallet (but then we’re back at the question how do we make sure we don’t “miss” incoming TXs …
8 Likes

And wouldn’t it be better if the Hash TX of the burn and the XOR address of the genesis were the same? Both are 32 bytes.

4 Likes

issue here is that the xor-address of a graphEntry is it’s public key that cannot be freely chosen only the private key. that’s why i suggested to only use the TX to point to the private key where every user can then calculate the public key (xor-address) from. so cannot be identical but can be unambiguously connected coming from the blockchain.

4 Likes

That’s was how I also imagined it. Great to have your opinion as a confirmation.

It’s not set in stone, as I started with normal token operation. Bridge will be dealt with later, as well as exchange. The design may change at these points, so I did not try to design it in every detail. In fact, it changed a little already, with current implementation of tokens. I’ll try to update docs where possible.

There is a wallet structure, that keeps track of unspent outputs of graph entries. On request, wallet returns (and creates if it does not exist) public key, that is associated with given token, so that spend can be created with output pointing at this key. All spends are collected to the same key, and on spending, a new GE is created at this key, with those outputs as its inputs, and with two outputs: one being a pk given (in request process) by next payee, and second - a rest spent back to a new key that is created in payer’s wallet for that token (old one is removed). A wallet is saved to a Scratchpad on every operation. But it can be kept somewhere else, like local storage, because it’s not referenced by any of token graph’s elements.

GraphEntry is created only with known spends. Only existing spends are the ones you “own” tokens from.

Basically, yes. There is no structure to warn about incoming spend. Probably a task for Friends layer, or perhaps something more persistent. I have to digest your idea, because I don’t quite get it yet…

4 Likes

I’ve made a test release (Linux only for now):

Wallet: Release ACT Wallet alpha v0.0.1 · safenetforum-community/community-token · GitHub
Lib: crates.io: Rust Package Registry
Docs: ant_act - Rust

11 Likes

Here’s what I propose for an exchange scheme in ACT. Let me know what you think, can be on GitHub if you prefer.

Autonomi Community Token Exchange

Exchange is be based on both sides publishing a spend transaction Graph Entries, that are connected by inputs/outputs. Each transaction has it’s own Token ID, and it will be a single exception in transaction validation process, when Token IDs can differ in parent/child relation.

Exchange process requires a separate means of announcing offers and finding buyers. This can be based on Autonomi, and such solution will be proposed later, but it’s not a part of the protocol.

Exchange Process

  1. Initial state. Alice has 40000 TT on GE3, Bob has 500 WBTC on GE4
TT: Native, genesis: GE0, [...]
WBTC: ERC20, [...]

GE0/Alice (ID: TT, in [], out [GE3: 40000])
GE1/Bob (ID: WBTC, in [TX1], out [GE4: 400])
GE2/Bob (ID: WBTC, in [TX2], out [GE4: 100])
(GE3/Alice)
(GE4/Bob)
  1. (out of band) Alice gives GE0 (proof), GE3 (exchange) and GE5 (target) PKs to Bob, Bob gives GE1 and GE2 (proofs) GE4 (exchange) and GE6 (target) PKs to Alice. They agree on the amounts, rate etc.
GE0/Alice (ID: TT, in [], out [GE3: 40000])
GE1/Bob (ID: WBTC, in [TX1], out [GE4: 400])
GE2/Bob (ID: WBTC, in [TX2], out [GE4: 100])
(GE3/Alice)
(GE4/Bob)
(GE5/Alice)
(GE6/Bob)
  1. Alice checks, that Bob has unspent agreed amount on GE4, and publishes exchange GE3 with inputs GE4 (want_from) and GE0 (source), outputs GE5 (200, want_to), 2000 to Bob’s GE6 and 38000 (rest) to own GE7.
    This means proposing 2000 TT to Bob in exchange for 200 WBTC. GE3 will be valid only if Bob publishes GE4 and GE3 will fulfill it.
GE0/Alice (ID: TT, in [], out [GE3: 40000])
GE1/Bob (ID: WBTC, in [TX1], out [GE4: 400])
GE2/Bob (ID: WBTC, in [TX2], out [GE4: 100])
GE3/Alice (ID: TT, in [GE4, GE0], out [GE5: 200, GE6: 2000, GE7: 38000])
(GE4/Bob)
(GE5/Alice)
(GE6/Bob)
(GE7/Alice)
(GE8/Bob)
  1. Bob checks, that Alice has unspent agreed amount on GE3, and publishes exchange GE4 with inputs GE3 (want_from) GE1 and GE2 (sources), outputs GE6 (2000, want_to), 200 to Alice’s GE5 and rest to own GE8.
    This means accepting 2000 TT from Alice in exchange for 200 WBTC.
GE0/Alice (ID: TT, in [], out [GE3: 40000])
GE1/Bob (ID: WBTC, in [TX1], out [GE4: 400])
GE2/Bob (ID: WBTC, in [TX2], out [GE4: 100])
GE3/Alice (ID: TT, in [GE4, GE0], out [GE5: 200, GE6: 2000, GE7: 38000])
GE4/Bob (ID: WBTC, in [GE3, GE1, GE2], out [GE6: 2000, GE5: 200, GE8: 300])
(GE5/Alice)
(GE6/Bob)
(GE7/Alice)
(GE8/Bob)
  1. Bob can spend his 2000 TT from GE6 and 300 WBTC from GE8, Alice can spend her 200 WBTC from GE5, and 38000 TT from GE7.

Validation

GE is an exchange if:

  • It has more than 1 input and more than 1 output.
  • First input GE have different token id, than rest of the input GEs.

Exchange GE1 is valid if:

  • Its first output GE2 fulfills it
  • It fulfills its first input GE2, which means:
    • It is GE2’s first input
    • One of its outputs is equal (amount and address) to GE2’s first output
  • Rest of the inputs have same token IDs, equal exchange GE’s token id
  • Their sum is equal sum of second and subsequent outputs
  • (rest of the rules are the same as in standard GE validation)

(edit) Exchange diagram:

8 Likes