-
- CPI inflated 8.5% from last march to this march (highest 1yr delta in over 40yrs).
- Uniswap added a venture arm.
- Starcoin (chinese) is another blockchain. They manage their own L1 and L2, with diff responsibilities for each. https://starcoin.org/downloads/Starcoin_en.pdf. Smart contracts are written in Move. List of examples: https://github.com/starcoinorg/starcoin-framework/tree/main/sources.
- 0L (from libra) also uses Move: https://github.com/OLSF/libra.
- Read some of Tesla’s 14A from the shareholder meeting on 2021-10-07. He owns 23.1% and has collateralized about half his shares. (that’s like $30b straight if 30% LTV on the current tsla market cap).
- MEVs are tougher on solana. Much faster, you don’t know when you’re going to be leader until right before.
- Deepdive on Prysm / private equity ABL dynamics.
- Move.
- Move’s name comes from Rust. Rust uses an “Affine” type system, which means that a resource is Moved (not Copied) which means that it must be used 0 or 1 time. Resources can only have one owner (one variable), and that ownership can be transferred. After moving, the previous owner can no longer be used (dangling pointers are automatically cleaned).
- There are two primary docs: Diem’s (https://diem.github.io/move/) and the Move Book (https://move-book.com/). I’m using the latter.
- Why an entirely new language? https://community.diem.com/t/introducing-the-move-programming-language/72/43. Blockchain requires a lang to be (1) deterministic (2) hermetic (3) metered. Sure, these aren’t mandatory built-ins for most languages, but they can be easily enforced. (1) is common. (2) disable network. (3) observability and control tools on cpu.
- Installed “Move IDE” vscode extension (only 682 downloads).
- No strings or floats. Ints u8/64/128. Cast with “as” or <>. Bool false/true. Address = wallet. Comment // and block /* */. Let, block scope {}. And const. fun. Every var must be used. To intentionally not use, “_” just like python. If, while, continue, break, abort. Assert.
- A vector is a collection of the same type. An array, but one type. The module is called Vector. It then provides functions like: empty (instantiate), push_back, pop_back, length, borrow_mut.
- For strings, it’s technically a vector<u8> using ascii conversion from ints to chars. Move allows you simplify this with bytestring literals: b”hello world!”
- If there’s no semicolon after the last expression in a block, that’s the return value for the block.
- An overall if statement can’t return a value, must end in semicolon. Same for while.
- Publish code with module. Call module code with scripts, or nested modules. Modules are published from an address, and called from that address. use <address>::<module>; then <module>::<function>
- Functions. snake_case names. Modules define many functions. Scripts define just one function, main(). Default is private. “public” to expose it. “native” functions are actually defined by the Move VM.
- Move requires types for function arguments/returns and all variables.
- Struct is used for custom types. It’s a dictionary = hashmap = key/val with field:type. You can have a struct (object) nest within a field of a parent struct to compose them.
- Access properties of instances with dot. “<struct>.<field>”
- You can destructure like js with {}. Can also define getter/setter functions in a module.
- An example move contract for a coin swap: https://github.com/diem/move/blob/main/language/documentation/examples/experimental/coin-swap/sources/CoinSwap.move. 100 lines.
- Types have 4 abilities: copy, drop, store, key.
- Primitives (int, vector, address, bool) have copy/drop/store (no key).
- You can specify for your custom types. “struct <name> has store, copy, drop {…}”
- For example: compiler will complain if a function has a hanging variable without the “drop” ability, because GC won’t be able to kill it.
- Each variable only has one owner/scope. And the only scope is functions in Move (no classes). So if you pass a var to a function as an argument, that function now owns it. The original scope does NOT have access to the var anymore.
- The two keywords are “move” and “copy”.
- By default, when you pass an arg to a func, there’s an implicit “move” before the arg.
- You can put “copy” instead so the original scope still owns the var. This obviously doubles the memory footprint for this var.
- Or, you can just “reference” it with “&” before the variable type. It’s not copied, but the new function doesn’t take ownership. The original func still owns that var. Under the hood the VM just creates a link to that section in mem, obv.
- If the other function wants a writable reference instead of just reading the value, pass with &mut type.
- “Borrow checking” is a compiler concept. It will statically verify if you’ve violated anything by moving a borrowed value.
- If you’re passed a reference, you can dereference with *. This creates a copy of the var.
- You can use a reference of an object but then copy a property for your own purposes. “*&<var>.<inner>”
- And remember, primitives are always copied. References are not created.
- Just like typescript, it has the generic type “T” which will accept whatever it’s passed. You may restrict abilities for generic types as well. You may have a list of types in a generic.
- All Diem currencies are defined with the generic Diem::T type.
- “Signer” is a native type. It only has one ability: drop. It can’t copy or key or store. It holds the address of the transaction sender. The canonical name for a variable of type Signer is “account”.
- “Resource” is a struct that has only the Key and Store abilities. Not drop or copy. It used to be a separate type, before abilities became a formal thing.
- Canonically you name the main resource in a module “Collection”.
- You can only put a resource under your account (you can have multiple). And you can’t have MULTIPLE resources of the same type under the same account. Eg you can only have 1 sol balance, not 3 sol balances.
- Native functions: move_to(), exists(), borrow_global(), borrow_global_mut(), acquires, move_from()