Просмотр исходного кода

book: Add more info about payments.

parazyd 3 лет назад
Родитель
Сommit
77a124f0fc
1 измененных файлов с 59 добавлено и 0 удалено
  1. 59 0
      doc/src/architecture/tx_lifetime.md

+ 59 - 0
doc/src/architecture/tx_lifetime.md

@@ -194,3 +194,62 @@ pub struct Note {
 In the blockchain state, every minted coin must be added into a Merkle
 In the blockchain state, every minted coin must be added into a Merkle
 tree of all existing coins. Once added, the new tree root is used to
 tree of all existing coins. Once added, the new tree root is used to
 prove existence of this coin when it's being spent.
 prove existence of this coin when it's being spent.
+
+Let's imagine a scenario where Alice has 100 ALICE tokens and wants to
+send them to Bob. Alice would create an `Input` object using the info
+she has of her coin. She has to derive a `nullifier` given her secret
+key and the serial number of the coin, hash the coin bulla so she can
+create a merkle path proof, and derive the value and token commitments
+using the blinds.
+
+```rust
+let nullifier = poseidon_hash([alice_secret_key, serial]);
+let signature_public = alice_secret_key * Generator;
+let coin = poseidon_hash([signature_public, value, token_id, blind]);
+let merkle_root = calculate_merkle_root(coin);
+let value_commit = pedersen_commitment(value, value_blind);
+let token_commit = pedersen_commitment(token_id, token_blind);
+```
+
+The values above, except `coin` become the public inputs for the `Burn`
+ZK proof. If everything is correct, this allows Alice to spend her coin.
+In DarkFi, the changes have to be atomic, so any payment transaction
+that is burning some coins, has to mint new coins at the same time, and
+no value must be lost, nor can the token ID change. We enforce this by
+using Pedersen commitments.
+
+Now that Alice has a valid `Burn` proof and can spend her coin, she can
+mint a new coin for Bob.
+
+```rust
+let blind = pallas::Base::random();
+let value_blind = ValueBlind::random();
+let token_blind = ValueBlind::random();
+let coin = poseidon_hash([bob_public, value, token_id, blind]);
+let value_commit = pedersen_commitment(value, value_blind);
+let token_commit = pedersen_commitment(token, token_blind);
+```
+
+`coin`, `value_commit`, and `token_commit` become the public inputs
+for the `Mint` ZK proof. If this proof is valid, it creates a new coin
+for Bob with the given parameters. Additionally, Alice would put the
+values and blinds in a `Note` which is encrypted with Bob's public key
+so only Bob is able to decrypt it. This `Note` has the necessary info
+for him to further spend the coin he received.
+
+At this point Alice should have 1 input and 1 output. The input is the
+coin she burned, and the output is the coin she minted for Bob. Along
+with this, she has two ZK proofs that prove creation of the input and
+output. Now she can build a transaction object, and then use her secret
+key she derived in the `Burn` proof to sign the transaction and publish
+it to the blockchain.
+
+The blockchain will execute the smart contract with the given payload
+and verify that the Pedersen commitments match, that the nullifier has
+not been published before, and also that the merkle authentication path
+is valid and therefore the coin existed in a previous state. Outside of
+the VM, the validator will also verify the signature(s) and the ZK
+proofs. If this is valid, then Alice's coin is now burned and cannot be
+used anymore. And since Alice also created an output for Bob, this new
+coin is now added to the Merkle tree and is able to be spent by him.
+Effectively this means that Alice has sent her tokens to Bob.