Prechádzať zdrojové kódy

book: Format smart_contracts.md

parazyd 3 rokov pred
rodič
commit
853acdcf2c
1 zmenil súbory, kde vykonal 79 pridanie a 54 odobranie
  1. 79 54
      doc/src/architecture/smart_contracts.md

+ 79 - 54
doc/src/architecture/smart_contracts.md

@@ -4,8 +4,8 @@
 
 Every full node is a **verifier**.
 
-**Prover** is the person executing the smart contract function on their secret witness data.
-They are also verifiers in our model.
+**Prover** is the person executing the smart contract function on
+their secret witness data. They are also verifiers in our model.
 
 Lets take a pseudocode smart contract:
 
@@ -28,13 +28,15 @@ contract Dao {
 
 ## Important Invariants
 
-1. The state of a contract (the contract member values) is globally readable but
-   *only* writable by that contract's functions.
-2. Transactions are atomic. If a subsequent contract function call fails then the earlier
-   ones are also invalid. The entire tx will be rolled back.
-3. `foo_contract::bar_func::validate::state_transition()` is able to access the entire
-   transaction to perform validation on its structure. It might need to enforce requirements
-   on the calldata of other function calls within the same tx. See `DAO::exec()`.
+1. The state of a contract (the contract member values) is globally
+   readable but *only* writable by that contract's functions.
+2. Transactions are atomic. If a subsequent contract function call
+   fails then the earlier ones are also invalid. The entire tx will be
+   rolled back.
+3. `foo_contract::bar_func::validate::state_transition()` is able to
+   access the entire transaction to perform validation on its structure.
+   It might need to enforce requirements on the calldata of other
+   function calls within the same tx. See `DAO::exec()`.
 
 ## Global Smart Contract State
 
@@ -76,17 +78,21 @@ mod dao_contract {
 }
 ```
 
-There is a pipeline where the prover runs `MintCall::make()` to create the `MintParams` object that
-is then broadcast to the verifiers through the p2p network.
+There is a pipeline where the prover runs `MintCall::make()` to create
+the `MintParams` object that is then broadcast to the verifiers through
+the p2p network.
 
-The `CallData` usually is the public values exported from a ZK proof. Essentially it is the data
-used by the verifier to check the function call for `DAO::mint()`.
+The `CallData` usually is the public values exported from a ZK proof.
+Essentially it is the data used by the verifier to check the function
+call for `DAO::mint()`.
 
 ## Atomic Transactions
 
-Transactions represent several function call invocations that are atomic. If any function call fails,
-the entire tx is rejected. Additionally some smart contracts might impose additional conditions
-on the transaction's structure or other function calls (such as their call data).
+Transactions represent several function call invocations
+that are atomic. If any function call fails, the entire tx is
+rejected. Additionally some smart contracts might impose additional
+conditions on the transaction's structure or other function calls
+(such as their call data).
 
 ```rust
 {{#include ../../../src/tx/mod.rs:transaction}}
@@ -101,17 +107,24 @@ Function calls represent mutations of the current active state to a new state.
 The `contract_id` corresponds to the top level module for the contract which
 includes the global `State`.
 
-The `func_id` of a function call corresponds to predefined objects in the submodules:
+The `func_id` of a function call corresponds to predefined objects
+in the submodules:
+
 * `Builder` creates the anonymized `CallData`. Ran by the prover.
-* `CallData` is the parameters used by the anonymized function call invocation.
+* `CallData` is the parameters used by the anonymized function call
+  invocation.
   Verifiers have this.
-* `state_transition()` that runs the function call on the current state using the `CallData`.
-* `apply()` commits the update to the current state taking it to the next state.
+* `state_transition()` that runs the function call on the current state
+  using the `CallData`.
+* `apply()` commits the update to the current state taking it to the
+  next state.
 
-An example of a `contract_id` could represent `DAO` or `Money`. Examples of `func_id` could
-represent `DAO::mint()` or `Money::transfer()`.
+An example of a `contract_id` could represent `DAO` or `Money`.
+Examples of `func_id` could represent `DAO::mint()` or
+`Money::transfer()`.
 
-Each function call invocation is ran using its own `state_transition()` function.
+Each function call invocation is ran using its own
+`state_transition()` function.
 
 ```rust
 mod dao_contract {
@@ -141,16 +154,20 @@ mod dao_contract {
 }
 ```
 
-The `state_transition()` has access to the entire atomic transaction to enforce correctness. For example
-chaining of function calls is used by the `DAO::exec()` smart contract function to execute moving money out
+The `state_transition()` has access to the entire atomic transaction to
+enforce correctness. For example chaining of function calls is used by
+the `DAO::exec()` smart contract function to execute moving money out
 of the treasury using `Money::transfer()` within the same transaction.
 
-Additionally `StateRegistry` gives smart contracts access to the global states of all smart contracts on the network,
-which is needed for some contracts.
+Additionally `StateRegistry` gives smart contracts access to the
+global states of all smart contracts on the network, which is needed
+for some contracts.
 
-Note that during this step, the state is *not* modified. Modification happens after the `state_transition()` is run
-for all function call invocations within the transaction. Assuming they all pass successfully, the updates are then
-applied at the end. This ensures atomicity property of transactions.
+Note that during this step, the state is *not* modified. Modification
+happens after the `state_transition()` is run for all function
+call invocations within the transaction. Assuming they all pass
+successfully, the updates are then applied at the end. This ensures
+atomicity property of transactions.
 
 ```rust
 mod dao_contract {
@@ -171,11 +188,15 @@ mod dao_contract {
 The transaction verification pipeline roughly looks like this:
 
 1. Loop through all function call invocations within the transaction:
-    1. Lookup their respective `state_transition()` function based off their `contract_id` and `func_id`.
-       The `contract_id` and `func_id` corresponds to the contract and specific function, such as `DAO::mint()`.
-    2. Call the `state_transition()` function and store the update. Halt if this function fails.
+    1. Lookup their respective `state_transition()` function based off
+       their `contract_id` and `func_id`. The `contract_id` and
+       `func_id` corresponds to the contract and specific function,
+       such as `DAO::mint()`.
+    2. Call the `state_transition()` function and store the update.
+       Halt if this function fails.
 2. Loop through all updates
-    1. Lookup specific `apply()` function based off the `contract_id` and `func_id`.
+    1. Lookup specific `apply()` function based off the `contract_id`
+       and `func_id`.
     2. Call `apply(update)` to finalize the change.
 
 ## ZK Proofs and Signatures
@@ -192,33 +213,37 @@ And corresponding function calls.
 {{#include ../../../src/sdk/src/tx.rs:contractcall}}
 ```
 
-As we can see the ZK proofs and signatures are separate from the actuall `call_data` interpreted
-by `state_transition()`. They are both automatically verified by the VM.
+As we can see the ZK proofs and signatures are separate from the
+actuall `call_data` interpreted by `state_transition()`. They are
+both automatically verified by the VM.
 
-However for verification to work, the ZK proofs also need corresponding public values, and
-the signatures need the public keys. We do this in the `CallDataBase` trait by exporting these
-methods:
+However for verification to work, the ZK proofs also need corresponding
+public values, and the signatures need the public keys. We do this
+in the `CallDataBase` trait by exporting these methods:
 
-```rust
-{{#include ../../../bin/dao/daod/src/util.rs:calldatabase_trait}}
+```
+TODO
 ```
 
-These methods export the required values needed for the ZK proofs and signature verification
-from the actual call data itself.
+These methods export the required values needed for the ZK proofs
+and signature verification from the actual call data itself.
 
-For signature verification, the data we are verifying is simply the entire transactions minus
-the actual signatures. That's why the signatures are a separate top level field in the
-transaction.
+For signature verification, the data we are verifying is simply
+the entire transactions minus the actual signatures. That's why the
+signatures are a separate top level field in the transaction.
 
 ## Parallelisation Techniques
 
-Since verification is done through `state_transition()` which returns an update that is then committed
-to the state using `apply()`, we can verify all transactions in a block in parallel.
+Since verification is done through `state_transition()` which returns
+an update that is then committed to the state using `apply()`, we
+can verify all transactions in a block in parallel.
 
-To enable calling another transaction within the same block (such as flashloans), we can add a special
-depends field within the tx that makes a tx wait on another tx before being allowed to verify.
-This causes a small deanonymization to occur but brings a massive scalability benefit
-to the entire system.
+To enable calling another transaction within the same block (such
+as flashloans), we can add a special depends field within the tx
+that makes a tx wait on another tx before being allowed to verify.
+This causes a small deanonymization to occur but brings a massive
+scalability benefit to the entire system.
 
-ZK proof verification should be done automatically by the system. Any proof that fails marks the entire
-tx as invalid, and the tx is discarded. This should also be parallelized.
+ZK proof verification should be done automatically by the system. Any
+proof that fails marks the entire tx as invalid, and the tx is
+discarded. This should also be parallelized.