• Wednesday

    All Aptos notes today.

    1. Accounts and Transactions.
      • https://aptos.dev/tutorials/your-first-transaction/.
      • Wrote a typescript client that hit testnet (rest api) to perform various actions/transactions on accounts.
      • Remember, an account is a resource that can send transactions. Accounts have two things: code (Move modules) and data (Move resources).
      • An account holds its own public/private keypair. It also has an authentication key, which allows it to rotate the public/private keypair while still maintaining identity.
      • Nacl is a crypto lib for js.
      • Aptos REST API: https://fullnode.devnet.aptoslabs.com/spec.html#/.
        • Get info from the ledger, get or submit transactions, get account info and modules and resources, get events.
      • Instantiate account locally (just a private/public keypair). Then hit the faucet (/mint endpoint) so testnet “creates” your account on the actual blockchain. Then you can call anything on the rest client with your account.
      • Transaction. First generate a json with the request parameters (address, seqnum, gas limits, payload, etc). Payload is which function to call and with what arguments (eg 0x1::TestCoin::Transfer). Then sign it with the nacl library (tweetnacl) and add the “signature” field to the same json. Then submit (just a POST of that final json). Then observe state of transaction and block or continue or error handle or whatever.
      • To get balance, hit /accountResources then just loop over until you find the 0x1::TestCoin resource.
      • You can see the data directly, eg for one of my test accounts: https://fullnode.devnet.aptoslabs.com/accounts/2c0df74faebd29729a0bd9a26de988d7354cc9c1888d363dd324f8fed6a8a02f/resources
      • You can also use the aptos explorer: https://aptos-explorer.netlify.app/account/2c0df74faebd29729a0bd9a26de988d7354cc9c1888d363dd324f8fed6a8a02f
      • Generic explorer link: https://aptos-explorer.netlify.app/.
      • Remember this is all devnet, and very open. A full node could modify your payload before you sign it. The explorer shows auth keys (same as private key, but abstracted so you can rotate the privkey).
    2. Modules to blockchain.
    3. NFTs.
    4. Local testnet validator.
      • https://aptos.dev/tutorials/run-a-local-testnet/.
      • No hardhat or anchor to make this dead simple yet, but it’s in the works.
      • 2 ways: build from aptos source (allowing you to modify it) or using prepackaged docker containers (easier, and persists). If you’re going to change the aptos blockchain, do the former; else skip the build and just use the latter.
      • From source:
        • To start the node: CARGO_NET_GIT_FETCH_WITH_CLI=true cargo run -p aptos-node — –test
        • It writes a config file, so you can pick back up there (instead of genesis). It hosts the rest service obviously. Port 8080.
        • To start a faucet: cargo run –package aptos-faucet — –chain-id TESTING –mint-key-file-path “<root key path from node start command output>” –address 0.0.0.0 –port 8000 –server-url http://127.0.0.1:8080
        • Then you can interact with the faucet and node, just replace the URLs in the first_transaction example with your new localhost addresses.
      • From docker:
        • Download their two yamls then docker-compose up. You’ll have a node on 8080 and a faucet on 8000, just like the build from source.
    5. Local devnet fullnode.
      • https://aptos.dev/tutorials/run-a-fullnode.
      • Work from aptos-core source, as expected. Or docker. Download the genesis file (https://devnet.aptoslabs.com/genesis.blob) and waypoint file (https://devnet.aptoslabs.com/waypoint.txt) and yaml configs. Then run with cargo or docker-compose.
      • NoAvailablePeers when first starting. This is because devnet sets max connections per node, and all peers may be full during times of high volume. To bypass this, just define upstream seeds (peers) by their address directly in the config yaml (not the docker-compose yaml).
      • Grep the metrics endpoint to check the sync state, compare the number to that on https://status.devnet.aptos.dev/. Took about 10 minutes to sync devnet’s full blockchain (a little more than version 1M) onto my local data drive. Execed into container to check the size of /opt/aptos/data, it’s 7.8GB at this point in time.
      • To give your fullnode a static identity, you can use “aptos-operational-tool”. It’s available to build from source in aptos-core and run with cargo, or available in a docker image.
        • docker run -i aptoslab/tools:devnet sh -x (drops you into the container, then run the rest)
        • aptos-operational-tool generate-key –encoding hex –key-type x25519 –key-file ~/private-key.txt
        • aptos-operational-tool extract-peer-from-file –encoding hex –key-file ~/private-key.txt –output-file ~/peer-info.yaml
        • Then set the identity in your config and restart the node.
        • You can generate a new identity (public/private key) at anytime and restart your node.
      • You’ll need to update your node every week when devnet updates.
      • You need to statically expose your node too, if you want external connections. Same as bitcoin node. My router’s public ipv4 is 96.239.66.140, my desktop has a static ipv4 lease, and I set up port forwarding rules in the fios router for API and metrics ports etc. Then it hits my host, wsl forwards to the linux VM, then docker forwards to the fullnode running in a container. Ports needs to be exposed through the whole path (docker-compose.yaml and windows firewall). Then restart desktop.
      • There’s this site too with some good scripts and helpers: https://ohsnail.com/aptos-fullnode-docker-guide-eng/#-linux-setup
      • Aptos nodetester: https://node.aptos.zvalid.com/ 
      • Final node is up: http://96.239.66.140:8080/ and http://96.239.66.140:9101/metrics
      • Full API http://96.239.66.140:8080/spec.html.
      • Compare block count (version) to official status page: https://status.devnet.aptos.dev/.
      • When testnet goes live (incentivized, and prep for mainnet) on May 13th, I assume they’ll provide a new image/genesis/waypoint, as well as upstream seeds of their nodes to kickstart the test network.
      • Went through and did an upgrade too.
        • docker-compose down –volumes and then docker volume rm <dir>_db -f (just check with docker volume ls)
        • Then just update the genesis and waypoint and restart the node.
  • Tuesday

    • Listened to Odd Lots podcast, guests SBF and Matt Levine. “How to Make Money in Crypto.” Fewer gems than expected.
    • Plaid is used by venmo, betterment, chive, many popular payment apps. Connects your users’ bank accounts with your app. Doesn’t charge transaction fees or anything to the user. The platform (like venmo) pays plaid to use their service.
    • Sardine handles settlement to accounts. ACH to bank, crypto wallet transactions, etc. They offer fraud indemnification (they take liability). They manage KYC. They link to coinbase analytics. Overall pretty useful.
    • IJavascript is the kernel for jupyter notebooks in js.
    • Tons of Aptos notes, but I’ll collate all those and post at once later.
  • Thursday

    • Aquarium.
      • Installed Trident. Calcium 445ppm and Magnesium 1295ppm. All from tap -> rodi -> salt -> tank. This is good salt. Priming takes a while (~20min?) during which the trident beeps and lights the on-unit icon blue. Once finished, will stabilize orange.
      • Set up apex fusion login/dashboard on browser.
      • Input power rates (nyc ~20c/kwh) so apex reports my usage in watts over time and monthly bill projection.
      • Set up and tested feed cycles: A for fish (pump off 5min) and B for coral (pump off 10min). The skimmer follows in each case, delayed by 5 minutes. Instead of using the “Pump” control types (return or powerhead), I did advanced with “If FeedX 000 Then OFF” so I could put all 4 feed cycles A/B/C/D. The skimmer has 005 for all to allow the water level to stabilize in the sump before disabling the pump. You can’t schedule these; just click the button in the app right before feeding.
      • Fallback (in advanced settings) is for conditional failures.
      • Remember that the heater I have is self-closed-loop, so leave the Apex control type to “Always” rather than on/off based on apex temp probe.
      • Remember that the light I have is self-closed-loop, so leave the Apex control type to “Always” rather than on/off based on clock timer.
      • Received and set up protein skimmer. Sump is basically `100% full of equipment now.
      • Enabled logs for main devices (on apex fusion, so this is just a power setting).
    • Olympus.
      • Rebase rewards are minted every 8 hours (as long as there’s >1 DAI backing for each OHM).
      • Deposited gOHM in the tokemak reactor for 5% APY. Come back next wed for rollover to claim and then vote with the resultant TOKE.
      • gOHM increases in value by (sOHM quantity increase) whereas sOHM just increases in quantity (via the rebase rewards from treasury passive yield strategies as well as minting more to stabilize ohm value in relation to backing). I understand how PCV works for OHM (and thus gOHM) but I don’t understand how this works in an open market. How do you control gOHM value against sOHM index when it’s being traded by the world?
    • UST/LUNA/anchor article: https://wantfi.com/terra-luna-anchor-protocol-savings-account.html.
    • Celo is a mobile-first blockchain/ecosystem.
      • Has many components. It’s an L1, has many DEXs, bvridges, DeFi apps, custody solution, more.
      • They’re going to provide a (VERY strongly contending) mobile-mobile payment system.
      • Celo will run a light client on all (participating) mobile devices, but the primary validation/consensus will occur on desktops. All clients will be in contact on the same network.
      • You’ll be able to deploy mobile dapps that run directly alongside the L1 blockchain.
    • Looked through payment services, WaaS, custody apps, much more.
  • Wednesday

    • Final tank fill. Total ~12 buckets.
    • Had to tighten and teflon tape the join where the pump supply line meets the bottom of the overflow trapezoid. Was leaking on initial pump enable.
    • Calibrated, mounted, and enabled/configured the apex probes: temp, ph, salinity, ORP.
    • Enabled and configured the heater.
    • Hung the radion via 2 DOF (rotational) cables. Great height, great angle, clear of canopy and hinges, doesn’t affect overflow trapezoid splashguard, great color.
    • Measured nitrate NO3 (2ppm), nitrite NO2 (<0.05ppm), phosphate PO4 (<0.01ppm), and ammonia (NH3) (<0.1mg/L) with salifert manual kits. All in acceptable low range, with the standard process: tap water -> rodi -> salt -> tank. Will check again after fish/coral in the tank.
    • Also used a 5-in-1 strip. Nitrates and nitrites agreed with the former, negligible. Calcium content was enough (~500mg/L) just with tap -> rodi -> salt -> tank because of the traces in the salt. Carbonate hardness (ability to stabilize ph) was about 8-9 dKH, which is good. ph was ~8.2 (slightly alkaline/basic), which agrees with the apex probe at 8.1.
    • Mounted the emerald hologram alveopora, ragnorak goniopora, and fruit loops zoanthids (with epoxy) to the live rock. Alveopora on left mid, zoanthids front and center (most light), goniopora lower right (least light).
    • Some zoanthids have palytoxin. Check and wear protective gear.
    • Dipping coral = disinfecting for a few minutes in a solution before introducing to your reef. Kills many of the common diseases: worms, nudibranchs, algae, bugs, bacteria, etc.

  • Tuesday

    • Liquidation insurance can be offered by a protocol. JPEGd (NFT collateral platform) does 1%. You can tweak many options. Buy collateral back at an inflated price, deposit additional at a worse LTV, diversify…
    • UST is to LUNA as OHM is to (a gigantic treasury of diverse cryptocurrencies). That’s why I like olympus. It’s not a shock absorber that burns/mints to hold a stablecoin’s peg steady, it’s a backing that burns/mints the actual currency to maintain supply and PCV.
    • Bonds continued to have negative discount on olympus so I bypassed the bonding lockup by removing my ohm/eth liquidity on sushi, zapping the eth to gOHM, and staking the ohm to gohm.
    • SUI validates transactions individually (rather than lumped in a block) for efficiency and lower latency. https://docs.sui.io/learn/sui-compared#a-different-approach-to-state. Remember, it parallelizes everything as atomically as possible, down to individual transactions when it can determine they’re unrelated.
    • Aptos testnet.
      • https://medium.com/aptoslabs/aptos-incentivized-testnet-roadmap-209be695c77c
      • Phase 1: Validator registration may 13 and launches may 16. Limited to 100 validator nodes. They’ll provide the tooling via github, it’s called Genesis.
      • Phase 2: staking. They’ll test rewards, faucets, experiment with gas. Starts in June.
      • Phase 3: onchain governance and voting. Finalize state sync between validators. Starts July.
      • Phase 4: onboard many validators and add ddos protection. Start August.
    • Finished move tutorial, steps 4-8: https://github.com/diem/move/tree/main/language/documentation/tutorial.
      • assert!(<predicate>, <abort_code>);
      • You can define something like [addresses] NamedAddr = “0xCAFE” in Move.toml and then use it in the module like @NamedAddr.
      • Remember borrow_global() to read from global storage. And move_to(), exists(), borrow_global_mut(), acquires, move_from().
      • You don’t need to return something from a function, you can just modify a mutable ref.
      • Wrote some tests, designated with #[test].
      • Convert to generics, so BasicCoin has stuff like <phantom CoinType> for the Coin and Balance structs and then all functions (like deposit()) have <CoinType>. Then you can define something like MyCoin. Kinda like inheriting from ERC20 in solidity. Provides standards. Classes to inherit from. And overwrite, if desired.
      • Use the move prover to run Formal Verification checks (consistent checks on inputs and outputs). “move package prove” – make sure to specify the “aborts if” condition or “ensures” within the “spec”. Add “post” to compare a value after execution. The spec has access to all the input variables of the target function, by name.
        • You can add “pragma” for stuff like aborts_if_is_strict or aborts_if_is_partial.
        • You can even create a spec with generics that they become customized into other similar specs with overwrites for their different signatures.
    • Magnum6’ aptos blogs (https://mirror.xyz/magnum6.eth).
      • $200M, a16z.
      • Resources (structs) that have very clear ownership and deletion rules. That’s it.
      • Devnet resets every week.
      • Everything inside a struct inherits its abilities from the parent struct (unless redefined).
      • If you don’t explicitly put “move” or “copy” then it assumes “move” for resources (structs) and “copy” for scalars and primitives.
      • Remember address::module::resource
      • Coinbase and binance are already building on aptos devnet. https://aptoslabs.com/developers/.
      • Remember when you borrow_global() that each address can only have 0 or 1 of each resource. You can’t have 2 structs named the same thing under 1 account.
        • For my example ticketmaster app, each address can only own one Venue (unless you make it a vector). And each customer (address) can only own one ConcertTicket struct. Just make a wrapper struct (Wallet or something) with vector<ConcertTicket>.
      • And borrow acts as mutex. You can’t have two things borrow a resource at the same time and modify it.
      • _ to ignore a return variable. Technically it will ignore anything starting with _, so _foo will also be ignored.
      • Rust’s (effective) spread operator is [x].iter().chain(&[y]). Move does not have a spread operator.
      • AptosFramework. Very common dep. Contains modules like TestCoin (the native currency right now) for transferring and such. Here are the others: https://github.com/aptos-labs/aptos-core/tree/main/aptos-move/framework/aptos-framework/sources. The TestCoin module is <400 lines long.
      • Here is the stdlib (Signer, Vector, etc): https://github.com/aptos-labs/aptos-core/tree/main/aptos-move/framework/move-stdlib/sources.
      • Remember everything must be signed by the relevant parties. Obvious for a transfer, needs sender signature. What about recipient? This is implicit when they register that resource to their account. No followup signatures required to receive subsequent transfers.
    • Went through aptos dev docs (https://aptos.dev/).
      • Accounts have 16-byte addresses. They’re containers for modules (code) and resources (data).
      • Sequence number is the incremental transaction number for each account. Goes up by 1 for every transaction on that account. This is how you prevent replay attacks.
      • The native resources for an account (present at creation) are Authentication Key and Sequence Number (0).
      • Events are emitted for transactions (eg SentEvent and ReceivedEvent).
      • There’s a rest API to query accounts, transactions, events, etc. Eg: https://fullnode.devnet.aptoslabs.com/spec.html#/operations/get_events_by_event_handle
      • Two types of nodes: validator nodes and fullnodes. They both serve REST, run the mempool, forward transactions, run the aptos VM, has storage, and sync state. The difference is that ONLY validators participate in consensus.
      • Primary reasons to run your own node: perform transactions directly, query the REST api directly, listen for onchain events faster, MEV.
      • Gas works the same as eth. Atomic price for the atomic unit of computation, as well as max so that you can bound execution.
      • The aptos blockchain is a merkle tree. Aptos uses BFT for consensus.
      • A raw transaction will have the account address, private key, which move module is to be invoked and with which inputs (all bytecode), gas price, max gas, expiration time, sequence number, chain id.
      • First, aptos client (wallet or rest call or whatever) will send the raw transaction to a rest service on a fullnode or a validator. This will be forwarded among fullnodes until it reaches a validator. The validator will then perform initial checks (signature verification, doublespend, account balance, replay resistance, etc) on it within the node’s mempool. If they pass, it will forward to ALL other validator nodes’ mempools. Then a node will be elected as leader and that validator will pull the next transactions from its own mempool, create a block, and broadcast it to every other validator for verification. If consensus is reached, this block is accepted by all.

  • Monday

    • Uniswap widget for use in third-party apps, can swap anywhere: https://github.com/Uniswap/interface. (fake widgets a big security concern).
    • Beanstalk hack. Flash loan -> got majority governance tokens -> proposal to withdraw to address. Stole ~75M, donated a small amount to ukraine.
      • The DAO didn’t have any protection about lock times. How long you have to hold a governance token before it provides a vote, how long a proposal must be open before it’s voted on and accepted/rejected, etc. So the hacker proposed the change and approved/executed it within one block before anyone could see or vote No.
    • Aquarium.
      • Got multiple adapter kits. Finally pieced it together.
        • 13/16″ female tap. Adapter 13/16″ male to 55/64″ male. Adapter 55/64″ female to 55/64″ male. 55/64″ female hose.
        • All 27T.
        • Standard sink is 15/16″ or 55/64″. Mine is not.
        • Standard hose is 3/4″. Mine is not.
      • Started filling the tank. 5gal bucket, takes about 90min through the RODI. Couple small leaks. Minus rocks/sand, plus sump/overflow/plumbing. I expect ~12 buckets. Did 3 yesterday, 6 today.
    • Meta gets 47.5% fee of sales on content sold in its metaverse.
    • You can send someone a message onchain by minting an nft with an svg image of text then sending it to them.
    • Narwhal/Tusk.
      • From the libra/diem team, now mystem and aptos.
      • A DAG-based mempool. Very fast/efficient. Narwhal is the mempool protocol. Tusk is the liveness protocol.
      • Whitepaper: https://arxiv.org/pdf/2105.11827.pdf
    • Solana supports programs written in Move: https://docs.solana.com/proposals/embedding-move.
      • This is because both Solana and Move runtimes depend on accounts for all shared state, making parallelization much easier (that runtimes like EVM, for example).
      • Because of the typing system, many of the runtime checks that solana executes for ownership can be checked at buildtime (well, module deploy time) for Move!
    • CRDTs: https://medium.com/@istanbul_techie/a-look-at-conflict-free-replicated-data-types-crdt-221a5f629e7e.
      • Conflict-free Replication Data Types. Basically you can update a lot of objects in parallel without immediate consensus.
      • Used in distributed systems (obviously), and more recently in blockchain networks.
      • If all the merge operations are commutative (order doesn’t matter), then we can guarantee eventual convergence/consistency. This of course doesn’t apply to most blockchain cases, where transaction order is very important to avoid the doublespend problem.
    • Played with metamask mobile for a sec. The app ships with a browser which you can use to visit and favorite any dapp url. Then it connects to metamask mobile wallet as you’d expect. I tried to visit the same dapps from a non-metamask browser directly (brave) and it wouldn’t connect to metamask mobile.
    • Curve is a DEX for stablecoin pairs. Supports EURS/USDC.
    • Thorchain is an existing solution for cross-chain swaps.
      • DEX across eth, bnb, terra, native, and synth.
      • It does this by running its own network of nodes, “native”. Each of these basically runs a full node for the other blockchains.
      • They insure liquidity providers against impermanent loss.
      • It doesn’t offer crosschain by locking tokens in a smart contract and minting wrapped tokens on the new chain, like most others. It maintains its own thor network that it basically uses as a gigantic liquidity pool.

  • Saturday

    • Correction: my second device still hasn’t deposited the march BAT reward to Gemini.
    • The RODI stages are:
      1. Sediment prefilter.
      2. UDF carbon.
      3. Carbon prefilter.
      4. RO membrane.
      5. Deionization cartridge.
      6. Deionization cartridge.
      7. Deionization cartridge.
    • Placed the live sand and rock. Prepped the salt and test kits. Set up the whole RODI system but don’t have the proper sink-hose adapter. Most sinks are 15/16″ but my aerator threads are different, maybe 55/64″. Ordered a multi adapter kit for tomorrow.
    • Bought protein skimmer, a few corals, and some reef roids.
    • Did taxes.