<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Hongchao&apos;s Notes</title>
    <description>sensing the abstract nonsense</description>
    <link>hongchao.me</link>
    <atom:link href="hongchao.me/feed.xml" rel="self" type="application/rss+xml" />
    
      <item>
        <title>Visualize ALPHred VM Execution</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://medium.com/@alephium/meet-alphred-a-virtual-machine-like-no-others-85ce86540025&quot;&gt;ALPHred&lt;/a&gt; is a stack-based virtual machine designed for &lt;a href=&quot;https://www.alephium.org/&quot;&gt;Alephium&lt;/a&gt;, used to execute smart contracts on the Alephium blockchain. The need for a specialized VM arises from Alephium’s unique stateful UTXO (&lt;a href=&quot;https://medium.com/@alephium/an-introduction-to-the-stateful-utxo-model-8de3b0f76749&quot;&gt;sUTXO&lt;/a&gt;) model, which supports the &lt;a href=&quot;https://ethereum.org/en/&quot;&gt;Ethereum&lt;/a&gt; style account model for handling contracts state, as well as the &lt;a href=&quot;https://bitcoin.org/&quot;&gt;Bitcoin&lt;/a&gt; style immutable UTXO model for secure assets management.&lt;/p&gt;

&lt;p&gt;ALPHred also introduced many innovative features to enhance the security and efficiency of smart contracts execution. One example is &lt;a href=&quot;https://docs.alephium.org/dapps/concepts/asset-permission-system/&quot;&gt;Asset Permission System&lt;/a&gt;, which explicitly stipulates the flow of assets at the VM level, giving confidence to developers and users that all asset transfers within the smart contract happen as intended. Together with the UTXOs model, it offers a simpler and more secure user experience by eliminating the token approval risks in systems such as &lt;a href=&quot;https://ethereum.org/en/developers/docs/evm/&quot;&gt;EVM&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this article, let’s dive into ALPHred’s internals with the help of &lt;a href=&quot;https://alephium-decoder.softfork.se&quot;&gt;Alephium Decoder&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;general-architecture&quot;&gt;General Architecture&lt;/h2&gt;

&lt;p&gt;The ALPHred VM utilizes a stack-based architecture, with a decicated frame stack managing function calls. A new frame is pushed onto the stack when a function is invoked, and removed once the function returns. Each frame contains local variables, an operation stack (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opStack&lt;/code&gt;) and a series of instructions. It also has access to the immutable and mutable fields of the contract, asset balances, block and transaction information, etc. During execution, ALPHred VM processes a sequence of instructions for the function on top of the frame stack, relying on its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opStack&lt;/code&gt; to store intermediate values and operants. These instructions cover a wide range of operations, such as loading and storing local variables and contract fields, approving and transferring assets, initiating local or external function calls, etc. ALPHred VM finishes execution when the last frame is successfully popped out of the stack.&lt;/p&gt;

&lt;p&gt;This design enables efficient smart contract execution while maintaining clear separation between different function contexts and contract states.&lt;/p&gt;

&lt;p&gt;The following image visualizes the general architecture of ALPHred VM when replaying a &lt;a href=&quot;https://explorer.alephium.org/transactions/c61a3f9a597398ebc79d5aca341d274a72d1a8c89516671f7e8f6a53cef4a82c&quot;&gt;transaction&lt;/a&gt; on &lt;a href=&quot;https://alephium-decoder.softfork.se&quot;&gt;Alephium Decoder&lt;/a&gt;. On the left hand side, we can see the next VM instructions to be executed for the top frame. On the right hand side, we can see the active frames in the frame stack. &lt;a href=&quot;https://docs.alephium.org/dapps/concepts/programming-model/#txscript&quot;&gt;TxScript&lt;/a&gt; frame is always at the bottom of the stack since it is the entry point of a Alephium transaction that interacts with the smart contracts. For other frames, it displays the address of the contract where the function belongs to and its method index. It also shows the local variables, asset balances and contract fields that are accessible to the frame if they exist.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/vm-architecture.png&quot; alt=&quot;Architecture&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As we replay the instructions step by step, we can observe the changes for the frame stack and the contract state, as well as the gas consumption for each instruction.&lt;/p&gt;

&lt;h2 id=&quot;key-vm-instructions&quot;&gt;Key VM Instructions&lt;/h2&gt;

&lt;p&gt;The ALPHred VM utilizes a set of carefully designed instructions to efficiently manage its operations. Let’s explore some of the key instructions that form the backbone of its functionality.&lt;/p&gt;

&lt;h3 id=&quot;load-and-store-variables&quot;&gt;Load and Store Variables&lt;/h3&gt;

&lt;p&gt;ALPHred VM provides instructions to load and store variables from the frame’s local variables as well as the contract’s state (fields).&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadLocal&lt;/code&gt;: Loads a local variable onto the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opStack&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StoreLocal&lt;/code&gt;: Stores the top value from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opStack&lt;/code&gt; into a local variable.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadImmField&lt;/code&gt;: Loads an immutable field from the contract onto the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opStack&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadMutField&lt;/code&gt;: Loads a mutable field from the contract onto the operation stack.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StoreMutField&lt;/code&gt;: Stores the top value from the operation stack into a mutable field of the contract.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These instructions allow the VM to efficiently access and modify both local variables within a function’s scope and the contract’s state. The distinction between immutable and mutable fields is crucial:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Immutable fields (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadImmField&lt;/code&gt;) are set when the contract is deployed and cannot be changed afterwards. They are used for constant values that should remain the same throughout the contract’s lifetime.&lt;/li&gt;
  &lt;li&gt;Mutable fields (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadMutField&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StoreMutField&lt;/code&gt;) represent the changeable state of the contract. These can be modified during contract execution, allowing for dynamic state management.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This separation provides a clear distinction between constant and variable contract properties, enhancing both security and efficiency. Immutable fields can be optimized by the VM, while mutable fields allow for flexible state updates as required by the contract’s logic.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/vm-variables.png&quot; alt=&quot;VM Variables&quot; style=&quot;width: 500px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As shown in the image above, the top &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadMutField&lt;/code&gt; instructions will load the first mutable fields onto the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opStack&lt;/code&gt;. We can also see the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadLocal&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StoreLocal&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadImmField&lt;/code&gt; instructions as well.&lt;/p&gt;

&lt;h3 id=&quot;function-calls&quot;&gt;Function Calls&lt;/h3&gt;

&lt;p&gt;ALPHred VM provides two key instructions for function calls: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;callExternal&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;callLocal&lt;/code&gt;. These instructions allow for efficient execution of both inter-contract and intra-contract function calls.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;callExternal&lt;/code&gt;: This instruction is used to call functions in other contracts. It enables cross-contract interactions, which are essential for building complex decentralized applications. When executing a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;callExternal&lt;/code&gt; instruction, the VM creates a new frame for the called function and pushes it onto the frame stack. This new frame includes its own set of local variables and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opStack&lt;/code&gt;, ensuring proper isolation of execution contexts between different contracts.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;callLocal&lt;/code&gt;: This instruction is used to call functions within the same contract. When a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;callLocal&lt;/code&gt; instruction is executed, a new frame is created for the called function and pushed onto the frame stack, but it retains access to the same contract state (immutable and mutable fields) as the calling function.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/images/vm-function-call.png&quot; alt=&quot;Function Call&quot; style=&quot;width: 500px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In the image above, we can see an example of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;callExternal&lt;/code&gt; instruction. The VM is about to call a function from another contract: the top of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opStack&lt;/code&gt; is the contract id, the method index is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;7&lt;/code&gt; as encoded in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;callExternal&lt;/code&gt; instruction. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;U256 2&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;U256 0&lt;/code&gt; represents the number of return values and arguments for this function, which are used by ALPHred VM to perform basic compatibility checks. When the called function returns, the VM will pop out the new frame, push its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt; return values onto the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opStack&lt;/code&gt; of the current frame and continue execution.&lt;/p&gt;

&lt;h3 id=&quot;asset-management&quot;&gt;Asset Management&lt;/h3&gt;

&lt;p&gt;ALPHred VM provides instructions to approve and transfer assets.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;approveToken&lt;/code&gt;: Approve a certain amount of token to an address.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;approveALPH&lt;/code&gt;: Approve a certain amount of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ALPH&lt;/code&gt; to an address.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transferToken&lt;/code&gt;: Transfer certain amount of token to an address’s transaction output.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transferALPH&lt;/code&gt;: Transfer certain amount of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ALPH&lt;/code&gt; to an address’s transaction output.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/images/vm-asset-management.png&quot; alt=&quot;Asset Management&quot; style=&quot;width: 500px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In the image above, we can see an example of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ApproveToken&lt;/code&gt; instruction. The VM is about to approve &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;U256 1&lt;/code&gt; amount of token &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fed6cb5a26e2bcbf0be83f0bf472b45d91a4f68c4e995a12255f4591e75c1000&lt;/code&gt; to address &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;12aH6to1JQxDFsvJ89jtFCnKEcub5ew8x2EABGEDMTYyK&lt;/code&gt; (see &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opStack&lt;/code&gt;). After that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;available&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;approved&lt;/code&gt; asset balance for this address will be updated.&lt;/p&gt;

&lt;p&gt;When calling a function, it can only use the assets approved for it. As we can imagine, if we have a tree of method calls, the approved fund will cascade from the root of the tree all the way to the leaves. This is how ALPHred VM supports the &lt;a href=&quot;https://docs.alephium.org/dapps/concepts/asset-permission-system/&quot;&gt;Asset Permission System&lt;/a&gt;, which makes the flow of funds across method calls explicit and enforces constraints on each method, specifying which tokens can be spent and in what amounts.&lt;/p&gt;

&lt;h3 id=&quot;contract-creation&quot;&gt;Contract Creation&lt;/h3&gt;

&lt;p&gt;ALPHred VM provides a set of instructions for creating contracts and &lt;a href=&quot;https://docs.alephium.org/ralph/contracts/#subcontract&quot;&gt;subcontracts&lt;/a&gt; (more on its benefits &lt;a href=&quot;https://x.com/hongchao/status/1751189481921605788&quot;&gt;here&lt;/a&gt;). These instructions are also how tokens are issued on Alephium.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Create Contract
    &lt;ul&gt;
      &lt;li&gt;Base instruction: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;createContract&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;Token variants: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;createContractWithToken&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;createContractAndTransferToken&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;Copy creation versions: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;copyCreateContract&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;copyCreateContractWithToken&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;copyCreateContractAndTransferToken&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Create Subcontract
    &lt;ul&gt;
      &lt;li&gt;Base instruction: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;createSubContract&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;Token variants: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;createSubContractWithToken&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;createSubContractAndTransferToken&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;Copy creation versions: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;copyCreateSubContract&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;copyCreateSubContractWithToken&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;copyCreateSubContractAndTransferToken&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each base instruction has variants for issuing token (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WithToken&lt;/code&gt;) and transferring those tokens to a recipient (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AndTransferToken&lt;/code&gt;). The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;copy&lt;/code&gt; versions allow for creating new contracts based on the code of an existing contract.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/vm-contract-creation.png&quot; alt=&quot;Contract Creation&quot; style=&quot;width: 500px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In the image above, ALPHred VM is about to create a new subcontract using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;copyCreateSubContract&lt;/code&gt; instruction. On the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opStack&lt;/code&gt; it has its parent contract id, the subcontract path, as well as the the template contract id where it can copy code from. After execution, it will push the new subcontract’s id onto the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opStack&lt;/code&gt;. You can read more about &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;copyCreateSubContract&lt;/code&gt; instruction &lt;a href=&quot;https://docs.alephium.org/ralph/built-in-functions/#copycreatesubcontract&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;other-instructions&quot;&gt;Other Instructions&lt;/h3&gt;

&lt;p&gt;ALPHred VM includes a variety of other instructions that are essential for smart contract execution and blockchain operations. Here are some of the common instructions, it is not meant to be an exhaustive list.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Control Flow
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Jump&lt;/code&gt;: Unconditional jump to a specified instruction.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IfTrue&lt;/code&gt;: Conditional jump if the top of the stack is true.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IfFalse&lt;/code&gt;: Conditional jump if the top of the stack is false.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Stack Operations
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pop&lt;/code&gt;: Remove the top element from the stack.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dup&lt;/code&gt;: Duplicate the top element of the stack.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Swap&lt;/code&gt;: Swap the top two elements of the stack.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Arithmetic and Logic
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;I256Add/U256Add&lt;/code&gt;: Add two numbers.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;I256Sub/U256Sub&lt;/code&gt;: Subtract two numbers.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;I256Mul/U256Mul&lt;/code&gt;: Multiply two numbers.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;I256Div/U256Div&lt;/code&gt;: Divide two numbers.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;I256Mod/U256Mod&lt;/code&gt;: Compute the modulus of two numbers.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BoolNot&lt;/code&gt;: Logical NOT operation.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BoolAnd&lt;/code&gt;: Bitwise AND operation.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BoolOr&lt;/code&gt;: Bitwise OR operation.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;U256Xor&lt;/code&gt;: Bitwise XOR operation.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Cryptographic Operations
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Blake2b&lt;/code&gt;: Compute the Blake2b hash of the input.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Keccak256&lt;/code&gt;: Compute the Keccak256 hash of the input.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Sha256&lt;/code&gt;: Compute the Sha256 hash of the input.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VerifySecP256K1&lt;/code&gt;: Verify a secp256k1 signature.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VerifyED25519&lt;/code&gt;: Verify an ED25519 signature.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EthEcRecover&lt;/code&gt;: Recover an address from an ECDSA signature&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Blockchain Interaction
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TxId&lt;/code&gt;: Get the current transaction ID.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BlockTimeStamp&lt;/code&gt;: Get the timestamp of the current block.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BlockTarget&lt;/code&gt;: Get the target of the current block.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Contract Interaction
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DestroySelf&lt;/code&gt;: Destroy the current contract and transfer its balance.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These instructions, along with the instructions highlighted earlier, form the comprehensive instruction set of the ALPHred VM. They enable developers to create complex, secure, and efficient smart contracts on the Alephium blockchain.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;The ALPHred VM is a key component of the Alephium blockchain, offering a robust and secure environment for smart contract execution. Its comprehensive instruction set enables sophisticated operations, efficient asset management, and flexible contract creation. These features, combined with built-in security measures and blockchain-specific operations, make ALPHred VM a solid foundation for developers building on Alephium.&lt;/p&gt;
</description>
        <pubDate>Sat, 07 Sep 2024 00:00:00 +0000</pubDate>
        <link>hongchao.me/visualize-alph-vm-execution/</link>
        <guid isPermaLink="true">hongchao.me/visualize-alph-vm-execution/</guid>
      </item>
    
      <item>
        <title>An Imperfect Perfection</title>
        <description>&lt;p&gt;In a world that often chases perfection – whether in our work, our
relationships, or the objects we possess – there lies a certain
beauty in imperfection. This paradoxical notion is something I’ve come
to appreciate deeply through my relationship with a particular
timepiece: the Mark 1 version of the Explorer 1 (Reference
214270). While some may see its flaws as detracting from its value, I
have found that these imperfections are precisely what make this watch
not just special, but a true embodiment of “imperfect perfection.”&lt;/p&gt;

&lt;h3 id=&quot;a-classic-with-quirks&quot;&gt;A Classic with Quirks&lt;/h3&gt;

&lt;p&gt;Explorer 1 is renowned as one of the quintessential tool
watches, designed with adventurers in mind. With its minimalist design
and rugged build, epitomizes the spirit of exploration and
resilience.&lt;/p&gt;

&lt;p&gt;However, the Explorer 1 214270 Mark 1 is not without its
controversies. Two features, in particular, have sparked debate among
watch aficionados: the short hands and the unlumed 3, 6, and 9
numerals. Critics argue that the minute hand should extend further to
meet the minute markers, enhancing readability and aesthetic
harmony. Meanwhile, the absence of lume on the key numerals is seen as
a significant drawback, especially for a watch with a legacy rooted in
extreme conditions where readability in low light is important.&lt;/p&gt;

&lt;p&gt;For some, these elements are flaws that mar an otherwise perfect
watch. But for me, they are the very features that give the Explorer 1
Mark 1 its character and uniqueness.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/rolex-explorer-1.jpg&quot; alt=&quot;Rolex Explorer 1&quot; style=&quot;width: 420px;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;a-reflection-of-lifes-imperfections&quot;&gt;A Reflection of Life’s Imperfections&lt;/h3&gt;

&lt;p&gt;Life itself is far from perfect. It is filled with moments of regret,
decisions we might wish to change, and paths we could have taken
differently. Yet, it is these very imperfections that make life rich
and meaningful. This watch, with its minor “flaws”, serves as a daily
reminder of this truth.&lt;/p&gt;

&lt;p&gt;There is a certain beauty in things that are not entirely perfect or
complete. This watch’s imperfections make it more approachable, more
human. It is not a sterile object of mechanical precision but a watch
with a soul, reflecting the idea that a complete life is not about
achieving flawless perfection but about appreciating the beauty in
what is, including the rough edges and the unfinished chapters.&lt;/p&gt;

&lt;p&gt;The imperfections of this watch are also analogous to the regrets we
all carry in life. However, just as these watch “flaws” do not
diminish its overall value, our regrets do not detract from the
richness of our experiences. They are integral to our personal
narratives, adding depth and complexity. My appreciation to this
watch, despite – or perhaps because of – its controversies, mirrors
the acceptance of life’s imperfections as essential to a complete and
fulfilling existence.&lt;/p&gt;

&lt;h3 id=&quot;attachment-loyalty-and-identity&quot;&gt;Attachment, Loyalty and Identity&lt;/h3&gt;

&lt;p&gt;The emotional attachment toward an object such as a watch is not
unique; it reflects a broader human tendency to form deep connections
with entities, whether they are objects, sports teams, or
even nations. This phenomenon is deeply rooted in the psychology of
attachment, loyalty, and identity.&lt;/p&gt;

&lt;p&gt;Fans of sports teams often remain loyal even when their team performs
poorly. This loyalty is not purely rational; it is emotional, tied to
a sense of identity and belonging. Similarly, nationalism often
involves a strong emotional bond with one’s country, even in the face
of its imperfections. People justify and rationalize their attachment
to their nation, often overlooking or downplaying its flaws. In both
cases, the attachment is about more than the object or entity itself;
it’s about what it represents – identity, history, and a sense of
belonging.&lt;/p&gt;

&lt;p&gt;On a more extreme level, there is a psychological phenomenon known as
&lt;a href=&quot;https://en.wikipedia.org/wiki/Stockholm_syndrome&quot;&gt;Stockholm
Syndrome&lt;/a&gt;, where
hostages develop a bond with their captors, often rationalizing their
captors’ actions as a way to cope with the trauma. While the context
is vastly different, the underlying mechanism – justifying flaws to
maintain a sense of connection – is similar. In the case of my watch,
am I over-justifying its flaws, clinging to its imperfections as a way
to deepen my emotional attachment to it? Perhaps. In any case, it
highlights how the human mind can create strong bonds with even
imperfect entities, often finding meaning in the very flaws that
others might see as detracting from value.&lt;/p&gt;

&lt;h3 id=&quot;the-perfectly-imperfect-companion&quot;&gt;The Perfectly Imperfect Companion&lt;/h3&gt;

&lt;p&gt;The Explorer 1 214270 Mark 1 is, to some, a watch with
flaws. But to me, it is a symbol of life’s imperfect perfection. It is
a reminder that true beauty lies not in the absence of flaws but in
the presence of character, authenticity, and meaning. This watch is
more than just a timepiece; it is a reflection of my life philosophy:
a belief that imperfection is not something to be corrected but
something to be embraced.&lt;/p&gt;

&lt;p&gt;In a world that often demands flawless perfection, it stands as a
testament to the value of imperfection. It teaches that completeness
comes not from eliminating flaws but from appreciating them as part of
our unique journey. Just as this watch remains one of my most
cherished possessions despite its controversies, so too does life
become richer and more meaningful when we accept and embrace its
inherent imperfections.&lt;/p&gt;

&lt;p&gt;And perhaps, I am indeed over-justifying its flaws. But in doing so, I
find a deeper connection, not just to the watch itself but to the
larger human experience of loving and cherishing what is imperfectly
perfect.&lt;/p&gt;
</description>
        <pubDate>Sat, 24 Aug 2024 00:00:00 +0000</pubDate>
        <link>hongchao.me/imperfect-perfection/</link>
        <guid isPermaLink="true">hongchao.me/imperfect-perfection/</guid>
      </item>
    
      <item>
        <title>Web3 and Advertising</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Marc_Andreessen&quot;&gt;Marc Andreessen&lt;/a&gt;
famously attributes the proliferation of internet advertising today to
browser’s lack of built-in payment support from the beginning. He
calls it the &lt;strong&gt;original sin of the internet&lt;/strong&gt;. The downstream from
advertising, he argues, is everything people are anxious and worked up
about today: privacy, user data collection, misalignment of the
incentives, etc. The assumption is that if crypto were around in the
early internet, it would be much easier to incorporate financial
transactions into the browser and the landscape of the internet
economy could look vastly different compared to what we’ve seen today.&lt;/p&gt;

&lt;p&gt;In general, advertisement has a negative connotation in the Web3
community. It represents a “legacy” business model from the web2 era
that web3 is set out to disrupt. Sovereign individuals in the next
stage of the internet evolution are supposed to not only take back the
control of money but personal data as well. With the help of
blockchain technologies, new waves of web3 applications will finally
be able to deliver on products that align incentives, respect privacy,
promote economic fairness with superior user experience. Isn’t that
great?&lt;/p&gt;

&lt;p&gt;The reality is that a class of existing web3 projects struggle to find
sustainable business models. Many projects (especially some of the
X2Earn ones) rely on Ponzi tokenomics where earnings of the
participants come from the funds collected from the new
investors. When no new speculative capital flows into the system, the
party stops and the project goes into a death spiral. Web3 projects,
like any projects, need &lt;strong&gt;external sources of revenue&lt;/strong&gt; to maintain a
sustainable token economy.&lt;/p&gt;

&lt;p&gt;Advertising should be appreciated more despite many of its real
issues. Some of the internet’s most important “common goods” are
funded directly or indirectly by advertising: search engines, social
networks, browsers, public town halls (e.g. twitter), etc. One thing
in common about these services is that their usage is typically
non-transactional: “pay per use” model introduces friction and
negatively impacts their user experience. Subscription model fixes
some of the issues, but as Vitalik &lt;a href=&quot;https://twitter.com/VitalikButerin/status/992068638982238208&quot;&gt;pointed
out&lt;/a&gt;,
advertising is in some cases a superior model: it massively improves
accessibility to a large portion of the population who are unable or
unwilling to pay by providing free (in money terms) products . It
accomplishes near-perfect price discrimination where the price of
users’ attention is usually proportional to their income. Without
advertising or similar mechanisms, it is unclear if the Web3 version
of the “common goods” such as social network could reach a similar
level of mass adoption as its Web2 predecessors.&lt;/p&gt;

&lt;p&gt;Advertising played a crucial role in Web2 also because people’s
attention is one of the rare mechanisms that naturally bridges the
online/offline world. Another example of such bridges is Bitcoin’s
&lt;a href=&quot;https://en.wikipedia.org/wiki/Proof_of_work&quot;&gt;PoW&lt;/a&gt; algorithm: an
onchain hash that meets the difficulty target mathematically
demonstrates the burning of a certain amount of energy offchain. This
allows Bitcoin to programmatically control participants’ behavior and
establish a vibrant ecosystem (both on and off chain) around
it. Similarly, leveraging people’s attention allows a class of online
services such as search engines and social networks to trigger both
online and offline economic activities in a relatively easy and
scalable way, which is crucial for generating revenues. That is why I
believe even without its original sin, advertising would still have been
one of the most important business models on the internet. It existed
in the age of newspapers and it will continue to exist in the era of
Web3.&lt;/p&gt;

&lt;p&gt;How advertising would play out in Web3 is a question worth
exploring. The airdropped tokens and NFTs are certainly a form of
advertising since it demands attention and incentives certain
measurable behaviors. Crypto wallets and
&lt;a href=&quot;https://www.w3.org/TR/did-core/&quot;&gt;DID&lt;/a&gt; has the potential to expand ads
from pure impressions to rich and interoperable objects. Self custody
of identity and personal data in combination with well designed
tokenomic systems and crypto primitives such as &lt;a href=&quot;https://en.wikipedia.org/wiki/Zero-knowledge_proof&quot;&gt;zero knowledge
proofs&lt;/a&gt; might
offer new ideas as to how advertising could be done in a fairer and
more private way. The design and tradeoff space is massive, hopefully
a better form of advertising can come out of the Web3 movement that
addresses most of the current issues while preserving its enormous
benefits.&lt;/p&gt;

&lt;p&gt;Advertising in Web3 also has the potential to make a new positive
impact to the world. For example, the financial component of Web3 is a
great tool to incentivize human behavior that in accumulation has long
term benefits with short term sacrifices. That includes health,
environmental protection, fundamental research, etc. With the right
tokenomics design, Web3 projects can incentivize such behaviors and
build a community around it while leveraging Web3 version of the
advertising as the mechanism to keep the tokenomics sustainable. A
coherent community with a common goal might also be a valuable target
for like-minded merchants. Advertising helped us fund many “common
goods” in the past, it could continue to help us fund new types of
“common goods” in the future with new tools and technologies.&lt;/p&gt;

&lt;p&gt;In summary, advertising should not be disdained by the Web3 community,
it is just a tool that can be improved and leveraged to the benefit of
Web3!&lt;/p&gt;
</description>
        <pubDate>Sun, 05 Feb 2023 00:00:00 +0000</pubDate>
        <link>hongchao.me/web3-and-ads/</link>
        <guid isPermaLink="true">hongchao.me/web3-and-ads/</guid>
      </item>
    
      <item>
        <title>Deep Dive into Ethereum Logs</title>
        <description>&lt;p&gt;Logs in Ethereum are very useful since they are the underlying
mechanism for events, which is the recommended way for smart contracts
to communicate with the outside world. They also provide a
significantly cheaper way to store data on-chain.
&lt;br /&gt;
&lt;br /&gt;
&lt;img src=&quot;/images/logs.png&quot; alt=&quot;logs&quot; style=&quot;width: 360px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As an example, the following code snippet from the
&lt;a href=&quot;https://github.com/Uniswap/v2-core/blob/4dd59067c76dea4a0e8e4bfdda41877a6b16dedc/contracts/UniswapV2ERC20.sol#L60&quot;&gt;UniswapV2ERC20.sol&lt;/a&gt;
contract emits a
&lt;a href=&quot;https://github.com/Uniswap/v2-core/blob/4dd59067c76dea4a0e8e4bfdda41877a6b16dedc/contracts/UniswapV2ERC20.sol#L22&quot;&gt;Transfer&lt;/a&gt;
event whenever a
&lt;a href=&quot;https://github.com/Uniswap/v2-core/blob/4dd59067c76dea4a0e8e4bfdda41877a6b16dedc/contracts/UniswapV2ERC20.sol#L68&quot;&gt;transfer&lt;/a&gt;
of tokens takes place.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Transfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_transfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;balanceOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;balanceOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;balanceOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;balanceOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;emit&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Transfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;For a more detailed description of the Ethereum logs, including the
concept of indexes/topics, data and cost, etc, highly recommend Luit
Hollander’s excellent blog post &lt;a href=&quot;https://medium.com/mycrypto/understanding-event-logs-on-the-ethereum-blockchain-f4ae7ba50378&quot;&gt;Understanding event logs on the
Ethereum
blockchain&lt;/a&gt;. This
blog post will instead focus on how logs are actually implemented in Ethereum,
specifically in &lt;a href=&quot;https://geth.ethereum.org/&quot;&gt;Geth&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When an event is emitted from a smart contract, one of the &lt;a href=&quot;https://github.com/ethereum/go-ethereum/blob/b1e72f7ea998ad662166bcf23705ca59cf81e925/core/vm/opcodes.go#L198&quot;&gt;LOG
opcodes&lt;/a&gt;
will be generated by the smart contract compiler. Events can have
maximum 4 topics/indexes, which is why there are 5 LOG opcodes (LOG0,
LOG1, …, LOG4) defined. The
&lt;a href=&quot;https://github.com/Uniswap/v2-core/blob/4dd59067c76dea4a0e8e4bfdda41877a6b16dedc/contracts/UniswapV2ERC20.sol#L22&quot;&gt;Transfer&lt;/a&gt;
event in the above example has three indexes/topics in total: two
explicit indexes &lt;strong&gt;from&lt;/strong&gt; and &lt;strong&gt;to&lt;/strong&gt;, and one implicit index which is
the hash of the event signature (see Luit’s
&lt;a href=&quot;https://medium.com/mycrypto/understanding-event-logs-on-the-ethereum-blockchain-f4ae7ba50378&quot;&gt;post&lt;/a&gt;),
in this case &lt;strong&gt;Transfer(address, address, uint)&lt;/strong&gt;. As the result, the
generated opscode is
&lt;a href=&quot;https://github.com/ethereum/go-ethereum/blob/b1e72f7ea998ad662166bcf23705ca59cf81e925/core/vm/opcodes.go#L202&quot;&gt;LOG3&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;LOG opcode is then interpreted by the &lt;a href=&quot;https://github.com/ethereum/go-ethereum/blob/master/core/vm/instructions.go#L844&quot;&gt;makeLog(size
int)&lt;/a&gt;
function, which basically reads the indexes as well as a blob of
arbitrary data from the stack, uses them to construct a
&lt;a href=&quot;https://github.com/ethereum/go-ethereum/blob/master/core/types/log.go#L31&quot;&gt;log&lt;/a&gt;
object and then adds it to
&lt;a href=&quot;https://github.com/ethereum/go-ethereum/blob/master/core/state/statedb.go#L64&quot;&gt;StateDB&lt;/a&gt;. &lt;strong&gt;StateDB&lt;/strong&gt;
is an EVM data structure that stores anything within the merkle trie, and
is the general query interface to retrieve contracts and
accounts. It’s used to store data during transaction execution,
including logs.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-go&quot; data-lang=&quot;go&quot;&gt;&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;makeLog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;executionFunc&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;interpreter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EVMInterpreter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ScopeContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;([]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;// ... skip ...&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;topics&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bytes32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c&quot;&gt;// ... skip ...&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;interpreter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;evm&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StateDB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddLog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;types&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Contract&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;Topics&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;topics&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;c&quot;&gt;// This is a non-consensus field, but assigned here because&lt;/span&gt;
			&lt;span class=&quot;c&quot;&gt;// core/state doesn&apos;t know the current block number.&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;BlockNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;interpreter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;evm&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BlockNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Uint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;// ... skip ...&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;When a transaction is executed using the
&lt;a href=&quot;https://github.com/ethereum/go-ethereum/blob/master/core/state_processor.go#L95&quot;&gt;applyTransaction&lt;/a&gt;
function, the generated &lt;a href=&quot;http://man.hubwiz.com/docset/Ethereum.docset/Contents/Resources/Documents/eth_getTransactionReceipt.html&quot;&gt;transaction
receipt&lt;/a&gt;
contains logs that are retreived from &lt;strong&gt;StateDB&lt;/strong&gt; together with a
bloom filter that statistically keeps track of all the topics of the
log as well as the address of the contract that emits the logs. The
reason to use a &lt;a href=&quot;https://en.wikipedia.org/wiki/Bloom_filter&quot;&gt;bloom
filter&lt;/a&gt; here is to strike
a balance between query efficiency and storage space. If a user wants
to search for logs with a set of topics, these topics can be run
against the bloom filter to probabilistically determine if any log
match the search criteria exist in this transaction receipt. False
positives are removed by checking with the search criteria again.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-go&quot; data-lang=&quot;go&quot;&gt;&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;applyTransaction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;types&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ChainConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bc&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ChainContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;author&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;common&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GasPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;statedb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StateDB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;blockNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;big&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;blockHash&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;common&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;types&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Transaction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;usedGas&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evm&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EVM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;types&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Receipt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// ... skip ...&lt;/span&gt;

	&lt;span class=&quot;c&quot;&gt;// Set the receipt logs and create the bloom filter.&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;receipt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Logs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;statedb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetLogs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;blockHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;receipt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bloom&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;types&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CreateBloom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;types&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Receipts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;receipt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;receipt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BlockHash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;blockHash&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;receipt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BlockNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;blockNumber&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;// ... skip ...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;When a block is created in the
&lt;a href=&quot;https://github.com/ethereum/go-ethereum/blob/master/core/types/block.go#L198&quot;&gt;NewBlock&lt;/a&gt;
function, it creates a bloom filter in the block header which
essentially combines the bloom filters of all the transaction receipts
included in this block. This allows quick check of whether any logs
with matching criteria exists in this block.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-go&quot; data-lang=&quot;go&quot;&gt;&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NewBlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;txs&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Transaction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uncles&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;receipts&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Receipt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hasher&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TrieHasher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Block&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// ... skip ...&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;receipts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReceiptHash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EmptyRootHash&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReceiptHash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DeriveSha&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Receipts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;receipts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hasher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bloom&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CreateBloom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;receipts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;// ... skip ...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;When a block is persisted using
&lt;a href=&quot;https://github.com/ethereum/go-ethereum/blob/master/core/blockchain.go#L1175&quot;&gt;writeBlockWithState&lt;/a&gt;
function, it persists all transaction receipts with logs per
block. The
&lt;a href=&quot;https://github.com/ethereum/go-ethereum/blob/master/core/rawdb/schema.go#L88&quot;&gt;format&lt;/a&gt;
of the key value pair is &lt;strong&gt;blockReceiptsPrefix + num (uint64 big endian) + hash -&amp;gt; block receipts&lt;/strong&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-go&quot; data-lang=&quot;go&quot;&gt;&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BlockChain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;writeBlockWithState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;block&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;types&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;receipts&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;types&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Receipt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logs&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;types&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StateDB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// ... skip ...&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;rawdb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WriteBlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;blockBatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;rawdb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WriteReceipts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;blockBatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NumberU64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;receipts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;rawdb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WritePreimages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;blockBatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Preimages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;// ... skip ...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;There are a few ways to consume the emmited events. After a
transaction is mined into the blockchain,
&lt;a href=&quot;https://eth.wiki/json-rpc/API#eth_gettransactionreceipt&quot;&gt;eth_getTransactionReceipt&lt;/a&gt;
can be called with the transaction hash to get the &lt;a href=&quot;https://eth.wiki/json-rpc/API#eth_getfilterchanges&quot;&gt;transaction
receipt&lt;/a&gt;, which
contains a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;logs&lt;/code&gt; field that carries an array of log objects that this
transaction generated. DApp frontends can also leverage the
combination of the
&lt;a href=&quot;https://eth.wiki/json-rpc/API#eth_newfilter&quot;&gt;eth_newFilter&lt;/a&gt; and
&lt;a href=&quot;https://eth.wiki/json-rpc/API#eth_getfilterchanges&quot;&gt;eth_getFilterChanges&lt;/a&gt;
method to poll the new events of interest. Web3.js abstracts this away
by providing the
&lt;a href=&quot;https://web3js.readthedocs.io/en/v1.2.11/web3-eth-subscribe.html#subscribe-logs&quot;&gt;subscribe(“log”)&lt;/a&gt;
method to help real time consumption of the incoming logs using the
subscription model.&lt;/p&gt;

&lt;p&gt;Let’s look at these JSON-RPCs in more details:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://eth.wiki/json-rpc/API#eth_gettransactionreceipt&quot;&gt;eth_getTransactionReceipt&lt;/a&gt;.
Return the transaction receipt for a transaction id. Since
transaction receipts are stored per block, this basically
&lt;a href=&quot;https://github.com/ethereum/go-ethereum/blob/master/internal/ethapi/api.go#L1615&quot;&gt;fetches all the receipts for the
block&lt;/a&gt;
that this transaction belongs to and only return the requested
one. As mentioned before, logs are part of the transaction receipt.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://eth.wiki/json-rpc/API#eth_newfilter&quot;&gt;eth_newFilter&lt;/a&gt; &amp;amp;
&lt;a href=&quot;https://eth.wiki/json-rpc/API#eth_getfilterchanges&quot;&gt;eth_getFilterChanges&lt;/a&gt;.
Return logs that match the search criteria such as the block range,
contract address as well as topics. This leverages the bloom filter
both in the block header as well as in the transaction receipt to
determine which logs should be returned. False positives are
filtered again using the search criteria. The filter logic can be found
&lt;a href=&quot;https://github.com/ethereum/go-ethereum/blob/master/eth/filters/filter.go#L119&quot;&gt;here&lt;/a&gt;. There
are also some &lt;a href=&quot;https://github.com/ethereum/go-ethereum/blob/master/eth/filters/filter.go#L153&quot;&gt;index
optimization&lt;/a&gt;
so that it doesnt have to iterate through each blocks in the block
range while searching for the matching logs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hope this blog post has shed some light on how logging is implemented
Ethereum. The overall design feels pretty elegant and efficient. One
tradeoff here is how much data should be indexed on-chain v.s
off-chain. Ethereum decided to have max 4 topics per log, perhaps a
good balance between searchability and storage, but one can make an
legitimate argument that indexes should be pushed more to the
application layer since data is more understood there and it is easier
to make changes afterwards.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Reference:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://ethereum.org/ig/developers/tutorials/logging-events-smart-contracts/&quot;&gt;Logging data from smart contracts with events&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://medium.com/mycrypto/understanding-event-logs-on-the-ethereum-blockchain-f4ae7ba50378&quot;&gt;Understanding event logs on the Ethereum blockchain&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://ethereum.stackexchange.com/questions/3418/how-does-ethereum-make-use-of-bloom-filters/3426&quot;&gt;How does Ethereum make use of bloom filters?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://consensys.net/blog/developers/guide-to-events-and-logs-in-ethereum-smart-contracts&quot;&gt;A guide to events and logs in ethereum smart contracts&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://medium.com/remix-ide/the-anatomy-of-a-transaction-receipt-d935aacc9fcd&quot;&gt;The Anatomy of a Transaction Receipt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 22 Jan 2022 00:00:00 +0000</pubDate>
        <link>hongchao.me/eth-event-logs/</link>
        <guid isPermaLink="true">hongchao.me/eth-event-logs/</guid>
      </item>
    
      <item>
        <title>Alephium Stack on GKE</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://github.com/alephium/alephium&quot;&gt;Alephium&lt;/a&gt; is the first
operational sharded blockchain that brings scalability, ETH-inspired
smart contracts and dApps capabilities to Bitcoin’s proven core
technologies while ensuring better performance and improved energy
efficiency. Alephium is one of those rare gems in the crypto
space that has solid innovations, high code quality and great mindset
for decentralization.&lt;/p&gt;

&lt;p&gt;The project comes with a docker
&lt;a href=&quot;https://github.com/alephium/alephium/tree/master/docker&quot;&gt;setup&lt;/a&gt; that
helps to run the entire stack, including the &lt;a href=&quot;https://github.com/alephium/alephium&quot;&gt;full
node&lt;/a&gt;, block explorer
(&lt;a href=&quot;https://github.com/alephium/explorer/&quot;&gt;frontend&lt;/a&gt; &amp;amp;
&lt;a href=&quot;https://github.com/alephium/explorer-backend&quot;&gt;backend&lt;/a&gt;), &lt;a href=&quot;https://github.com/alephium/gpu-miner&quot;&gt;GPU
miner&lt;/a&gt;, as well as monitoring
(prometheus &amp;amp; grafana). This is especially convenient if you want to
experiment with the entire stack on your local machine. For more
details, please consult the
&lt;a href=&quot;https://github.com/alephium/alephium/blob/master/docker/README.md&quot;&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It might also be a good idea to run the Alephium full stack on K8S
cluster. Here are some of the potential benefits:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Expose Alephium stack to the public&lt;/li&gt;
  &lt;li&gt;Mine with the &lt;a href=&quot;https://cloud.google.com/kubernetes-engine/docs/how-to/gpus&quot;&gt;rented GPUs&lt;/a&gt; in the cloud&lt;/li&gt;
  &lt;li&gt;Develop against remote Alephium stack locally&lt;/li&gt;
  &lt;li&gt;Run applications that depends on Alephium full node in production&lt;/li&gt;
  &lt;li&gt;Scale different components of the Alephium stack depending on your
use case&lt;/li&gt;
  &lt;li&gt;Leverage managed service such as &lt;a href=&quot;https://www.google.com/search?client=firefox-b-d&amp;amp;q=cloud+postgres+gcp&quot;&gt;CloudSQL for
Postgres&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Ease of operation if you are already familiar with K8S&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have setup the Alephium stack on GKE, mined some ALPHs and and
exposed the following sites:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://alephium.softfork.se&quot;&gt;Alephium Explorer&lt;/a&gt; (&lt;span class=&quot;image-label&quot;&gt;alephium.softfork.se&lt;/span&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://grafana.softfork.se/d/S3eJTo3Mk/alephium-overview?orgId=1&amp;amp;refresh=10s&quot;&gt;Alephium Monitoring&lt;/a&gt; (&lt;span class=&quot;image-label&quot;&gt;grafana.softfork.se&lt;/span&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://alephium.softfork.se/docs&quot;&gt;Alephium API Documenation&lt;/a&gt; (&lt;span class=&quot;image-label&quot;&gt;alephium.softfork.se/docs&lt;/span&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s comforting to be able to monitor the status of your full node wherever
you are:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/alephium-grafana.png&quot; alt=&quot;Alephium Overview&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It is also pretty easy to develop against the remote Alephium locally,
e.g.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Port forward alephium from Kubernetes cluster&lt;/span&gt;
➜ kubectl port-forward svc/alephium 12973
Forwarding from 127.0.0.1:12973 -&amp;gt; 12973
Forwarding from &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;::1]:12973 -&amp;gt; 12973

&lt;span class=&quot;c&quot;&gt;# Curl locally&lt;/span&gt;
➜ curl localhost:12973/infos/self-clique
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cliqueId&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;03764042ab3c875481e5eed6d7a59027a7232582c189e1c266f57b62591ae0d8e0&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;networkId&quot;&lt;/span&gt;:1,&lt;span class=&quot;s2&quot;&gt;&quot;numZerosAtLeastInHash&quot;&lt;/span&gt;:18,&lt;span class=&quot;s2&quot;&gt;&quot;nodes&quot;&lt;/span&gt;:[&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;address&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;127.0.0.1&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;restPort&quot;&lt;/span&gt;:12973,&lt;span class=&quot;s2&quot;&gt;&quot;wsPort&quot;&lt;/span&gt;:11973,&lt;span class=&quot;s2&quot;&gt;&quot;minerApiPort&quot;&lt;/span&gt;:10973&lt;span class=&quot;o&quot;&gt;}]&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;selfReady&quot;&lt;/span&gt;:true,&lt;span class=&quot;s2&quot;&gt;&quot;synced&quot;&lt;/span&gt;:true,&lt;span class=&quot;s2&quot;&gt;&quot;groupNumPerBroker&quot;&lt;/span&gt;:4,&lt;span class=&quot;s2&quot;&gt;&quot;groups&quot;&lt;/span&gt;:4&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The code for setting everything up is open sourced in the
&lt;a href=&quot;https://github.com/h0ngcha0/alephium-stack&quot;&gt;alephium-stack&lt;/a&gt;
repo. Checkout the
&lt;a href=&quot;https://github.com/h0ngcha0/alephium-stack/blob/master/README.md&quot;&gt;README.md&lt;/a&gt;
for more details. Happy Hacking! :fire::fire::fire:&lt;/p&gt;

</description>
        <pubDate>Sun, 09 Jan 2022 00:00:00 +0000</pubDate>
        <link>hongchao.me/alephium-stack/</link>
        <guid isPermaLink="true">hongchao.me/alephium-stack/</guid>
      </item>
    
      <item>
        <title>Part of &quot;The Game&quot;</title>
        <description>&lt;p&gt;Complains&lt;/p&gt;
</description>
        <pubDate>Sat, 25 Dec 2021 00:00:00 +0000</pubDate>
        <link>hongchao.me/this-is-part-of-the-game/</link>
        <guid isPermaLink="true">hongchao.me/this-is-part-of-the-game/</guid>
      </item>
    
      <item>
        <title>Some Challenges of Freedom of Speech</title>
        <description>&lt;p&gt;If there exists a superintelligence system that posesses all the
knowledge and truth of the world and is able to always process it with
the most “optimal” algorithm, no matter what circumstances are,
perhaps planned economy would become a better mechanism for resource
allocation and growth generation than market economy. In fact, if such
a superintelligence system happens to have the capacity and intention
to advance human society as a whole, maybe the most sensible thing for
us to do is to follow its lead.&lt;/p&gt;

&lt;p&gt;Fortunately and unfortunately, this superintelligence doesn’t exist,
at least not yet. History seems to have shown repeatedly that no
matter how capable and well intended an individual or a group of
individuals are, it is difficult for mere mortals to be the guardians
of information for everybody without suffocating the society. On top
of that, such power almost always leads to Orwellian like state: Power
corrupts; absolute power corrupts absolutely. Many have fought and
continue to fight for the right of freedom of speech as a response to
that.&lt;/p&gt;

&lt;p&gt;From the societal perspective, freedom of speech as a mechanism as
done a remarkable job so far to continuously generate ideas based on
new circumstances so that humanity can be equipped with more knowledge
and societies can evolve from one consensus to the next. It encourages
the contribution from individuals with different skillsets and
perspectives; It provides a market place where ideas can be
challenged, debated and tested; It also protects the “unorthodox”
ideas from being suppressed by the powerful status quo consensus. At a
higher level, it is a dynamic, decentralized, bottom up approach to
achieve collective goals, analogous to biological evolution or market
economy in their respective domains.&lt;/p&gt;

&lt;p&gt;However, information has some interesting properties. One of them is
that the cost of verification is asymmetrically higher than the cost
of generation. This might not be very obvious before the age of Web
2.0, when both information generation and distribution were still
controlled by mainstream medias. In that era, the flow of information
within society was still relatively simple due to its largely
hierachical nature. The media outlets basically took on the
responsibility to verify and filter their contents for their
audiences. However, in the past 15 years or so, new technologies such
as social media platforms have essentially democratized the ability to
generate and distribute information. Putting aside the benefits this
must have created for a moment, with the explosion of user generated
content and the flow of information that is orders of magnitude more
complex, the overall cost of information verification at the societal
level must have skyrocketed. This puts companies such as Facebook in
an extremely tough spot. With billions of users from different
countries, the sheer amount of information that needs to be moderated
as well its complexity is astonishing.&lt;/p&gt;

&lt;p&gt;This begs the question: should they play the role of truth arbiter? If
they should, can they theoretically and practically keep up with the
continued explosion of information when it has such an inherent
asymmetric property? If they shouldn’t, what is the effect of forcing
this responsibility to the individuals when most people neither have
the time nor expertise to sufficiently identify misinformation? When
freedom of speech is enhanced so much by technology, it seems logical
that more moderation (i.e. censorship) needs to happen somewhere in the
information flow to keep the verification cost in check and prevent
the overall quality of the information from decaying. Who should do
that? To which extent should they do that?  Is this against the very
spirit of freedom of speech?&lt;/p&gt;

&lt;p&gt;Another property of information is that it thrives in big networks and
therefore creates network effect. If there are many diversified,
competing platforms that people can easily migrate, these platforms
could compete on the ways that the information is moderated and
probably wouldn’t cause significant issues at the societal level. The
problem is that due to the network effect, we end up with a handful
very large and powerful ones that are not diversified enough when
it comes to information moderation, which poses systematic threat to
the freedom of speech. These companies are also dorminated by similiar
business models: harvest user data, create &lt;a href=&quot;https://en.wikipedia.org/wiki/Echo_chamber_(media)&quot;&gt;echo
chambers&lt;/a&gt; to
increase the stickiness of the platform and make money by selling ads
to the users. Freedom of speech includes the freedom to hear. These
profit oriented algorithms implicitly impose constrains to the flow of
information and have profound impact to the quality of the information
we consume. “Garbage in, Garbage out”. The implication of this to the
quality of the democracy over the long run remains to be seen.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/echo-chamber.png&quot; alt=&quot;Echo Chamber&quot; style=&quot;width: 42%;&quot; /&gt;&lt;br /&gt;
&lt;span class=&quot;image-label&quot;&gt;Media Echo Chamber, &lt;a href=&quot;https://en.wikipedia.org/wiki/Echo_chamber_(media)&quot;&gt;Wikipedia&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Even though the quality of information is crucial to the quality of
democracy and there is a risk that the ads model is fundamentally
incompatible with societies’ larger goals. It seems that the industry
still struggles to find a good replacement for it. Ads model has an
ingenious property that is often underappreciated: it is &lt;a href=&quot;https://en.wikipedia.org/wiki/Incentive_compatibility&quot;&gt;incentive
compatible&lt;/a&gt; for
most of the participants within the system. Majority of the users
always prefer convenience and immediate economic benefits. A “free”
product paid by your attention instead of money is still winning the
usability battle at least with the current state of the technology.&lt;/p&gt;

&lt;p&gt;Another threat to freedom of speech is the extent to which its
alternative models can succeed, even temporarily. Human societies have
gone through times where there were explosions of scientific and
technological breakthroughs. However, other parts of the human history
is filled with incremental improvements or even staganations. Freedom
of speech as an idea generation and selection mechanism is much more
valuable in periods of breakthoughs. Arguments can be made that
science has been staganating in the past 40 years and we are just
reaping the benefits from the research done by the generations before
that. It is unclear if this is temporary and how long this would
last. Under this assumption, societies emphasizing more on freedom of
speech might not get enough benefits for its cost, whereas countries
that actively censor information might be able to reach social
consensus much more effectively without incuring an unbearable cost of
losing the battle of innovation. Of course, this dynamic could change
under different circumstances, perhaps this is one of the hidden forces
that can influence the rise and falls of the civilizations that focus
more on individualism vs collectivism.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;How many
&lt;a href=&quot;https://en.wikipedia.org/wiki/Hundred_Flowers_Campaign&quot;&gt;flowers&lt;/a&gt;
should be let bloom?&lt;/p&gt;
</description>
        <pubDate>Tue, 24 Aug 2021 00:00:00 +0000</pubDate>
        <link>hongchao.me/freedom-of-speech/</link>
        <guid isPermaLink="true">hongchao.me/freedom-of-speech/</guid>
      </item>
    
      <item>
        <title>Constraints and Liberties</title>
        <description>&lt;p&gt;In &lt;a href=&quot;https://en.wikipedia.org/wiki/The_Shawshank_Redemption&quot;&gt;The Shawshank
Redemption&lt;/a&gt;,
&lt;a href=&quot;https://shawshank.fandom.com/wiki/Brooks_Hatlen&quot;&gt;Brooks Hatlen&lt;/a&gt; was
released from the prison after being locked up for 50 years. He
finally regained his liberty and yet his inability to adjust to the
outside world gives him constant fear and desperation. He commited
suicide. The freedom from the constraints of the prison killed
him. Similiarly, after &lt;a href=&quot;https://en.wikipedia.org/wiki/Booker_T._Washington&quot;&gt;Booker
T. Washington&lt;/a&gt; was
emancipated as a slave, his initial rejoicing was soon overwhelmed by
the sense of deep gloom due to the realization that without money,
education, skills and property, life is not significantly different
after liberation.&lt;/p&gt;

&lt;p&gt;Instead of drowning in desperation, Booker spent his life promoting
education, hard work and material prosperity among the
blacks. Ultimately, without a fairer access to education, health care,
security and other social rights, liberty would be an empty slogan for
a large portion of the population. However, enforcing those social
rights requires the redistribution of wealth and resources, therefore
inevitably infringing the liberty of other portion of the
population. The balance of this tension is one of the most important
topics in the debate between liberals and conservatives in
contemporary politics.&lt;/p&gt;

&lt;p&gt;An important question to answer when discussing constraints
and liberties is &lt;strong&gt;who are we optimizing for&lt;/strong&gt;. The goal of most of the
societies is to promote long term freedom and happiness of the
entire population. &lt;a href=&quot;https://en.wikipedia.org/wiki/Isaiah_Berlin&quot;&gt;Isaiah
Berlin&lt;/a&gt; articulated in
his essay &lt;a href=&quot;https://en.wikipedia.org/wiki/Two_Concepts_of_Liberty&quot;&gt;Two Concepts of
Liberty&lt;/a&gt; about
the idea of &lt;a href=&quot;https://en.wikipedia.org/wiki/Negative_liberty&quot;&gt;negative
&lt;/a&gt; and &lt;a href=&quot;https://en.wikipedia.org/wiki/Positive_liberty&quot;&gt;positive
&lt;/a&gt; liberty. With only
negative liberty, which focuses primarily on the freedom from
interference by other people, the collective liberty and happiness can
neither be maximized nor fairly distributed. As a balancing force,
positive liberty emphathizes the importance of population’s collective
capacity to act upon their free will, which can be achieved by
applying certain constraints to the society. In that sense, negative
liberty alone constrains the society from reaching its full potential,
whereas proper constraints at the right level librate society at
large.&lt;/p&gt;

&lt;p&gt;Constraints and liberties seem to have similiar dynamics at smaller
scale as well. For example, without the constraints of the rules, the
game of &lt;a href=&quot;https://en.wikipedia.org/wiki/Go_(game)&quot;&gt;Go&lt;/a&gt; will not be able
to librate the mind-blowing creativities from the players. The limited
form of expression offered by the likes of Tiktok, Twitter and WeChat
seems to have unleashed the creative energy from their users and therefore
created more sticky networks. Often times, less is more, constraint is
liberty. This probably has to do with our &lt;strong&gt;limited mental capacity&lt;/strong&gt;
as human beings. Constraints abstract things away, sometimes at the
expense of choice, but as a tradeoff we get to focus our precious
cognitive effort somewhere else. This is not to say all constraints
are well designed. Countless games must have been invented throughout
history, the set of constraints Go offers stood the test of time.&lt;/p&gt;

&lt;p&gt;Another example is programming languges. C is a great language for
system programming with very little constraints, but at the same time
it is also a double edged sword that can cut both ways. People who
mastered the language (e.g. &lt;a href=&quot;https://en.wikipedia.org/wiki/Linus_Torvalds&quot;&gt;Linus
Torvalds&lt;/a&gt;) might feel
that &lt;a href=&quot;https://www.youtube.com/watch?v=CYvJPra7Ebk&quot;&gt;nothing is better than
C&lt;/a&gt;. However, for many
programmers, having to worry about the countless traps and pitfalls of
C severely limits their capabilities to create. Many languages try to
fix this by enforcing different constraints. One example is functional
programming, where mutation of variables are strongly discouraged or even
disallowed. As it turns out, programmers’ creativity are liberated by
these types of constraints because now their cognative energy can be spent
more on solving the actual problems. In general, when we
are trying out different ways of working, we are applying different
constraints and see which one yields the best result. Liberty in the
context of work usually constrains our ability to perform.&lt;/p&gt;

&lt;p&gt;Constraint and liberty are also &lt;strong&gt;multifaceted&lt;/strong&gt;. Even at the
individual level, one freedom might come at the cost of another. The
constraint of being monitored by the surveillance camera might give
you the freedom to walk around safely at 2am anywhere in the city. The
unregulated freedom of speech in the age of information explosion
could significantly constrain your freedom to understand the truth due
to the asymmetric cost to prove false information. Financial freedom
at certain age might require very displined life style and prudent
management of wealth at earlier age. The liberty to smoke many packs
of cigerettes a day could deprive of any other freedom you might have
the chance to enjoy prematurely.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Constraints Liberate, Liberties Constrain.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Positive_liberty&quot;&gt;Wikipedia article on Positive Liberty&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Booker_T._Washington&quot;&gt;Wikipedia article on Booker T Washinton&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Two_Concepts_of_Liberty&quot;&gt;Two Concepts of Liberty&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=GqmsQeSzMdw&quot;&gt;Constraints Liberate, Liberties Constrain&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 03 Jul 2021 00:00:00 +0000</pubDate>
        <link>hongchao.me/liberty-and-constraint/</link>
        <guid isPermaLink="true">hongchao.me/liberty-and-constraint/</guid>
      </item>
    
      <item>
        <title>Project K2</title>
        <description>&lt;p&gt;The purpose of the project is cryptographically (sha256) committed to:
&lt;span style=&quot;background: blue; color: yellow; font-size: 90%; font-weight: bold; word-wrap: break-word&quot;&gt;f3b0ce65c0e350236ac89bb59acfdb7c90cdddad90366918aaa1b67f57ad00d1&lt;/span&gt;&lt;/p&gt;

&lt;h3 id=&quot;places-to-be-visited&quot;&gt;Places to be Visited&lt;/h3&gt;

&lt;h4 id=&quot;--stockholm-sweden&quot;&gt;[-] Stockholm (Sweden)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/gamla-stan.jpg&quot; alt=&quot;gamla stan&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Gamla stan &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/gamla-stan.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;x-nanjing-china&quot;&gt;[X] Nanjing (China)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/taicheng.jpg&quot; alt=&quot;Tai cheng&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Tai cheng &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/taicheng.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;--ireland&quot;&gt;[-] Ireland&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/dublin.jpg&quot; alt=&quot;Dublin&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Dublin &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/dublin.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;--california-usa&quot;&gt;[-] California (USA)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/gold-gate-bridge.jpg&quot; alt=&quot;Golden gate bridge&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Golden gate bridge &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/gold-gate-bridge.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;--japan&quot;&gt;[-] Japan&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/tokyo.jpg&quot; alt=&quot;Tokyo&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Tokyo &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/tokyo.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;--koh-samui-thailand&quot;&gt;[-] Koh Samui (Thailand)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/koh-samui-islands.jpg&quot; alt=&quot;Koh Samui&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Koh Samui &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/koh-samui-islands.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;--verona-italy&quot;&gt;[-] Verona (Italy)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/verona_arena.jpg&quot; alt=&quot;Arena di Verona&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Arena di Verona &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/verona_arena.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;--amsterdam-holland&quot;&gt;[-] Amsterdam (Holland)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/amsterdam.jpg&quot; alt=&quot;Amsterdam&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Amsterdam &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/amsterdam.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;--iceland&quot;&gt;[-] Iceland&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/blue-lagoon.jpg&quot; alt=&quot;Blue lagoon&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Blue lagoon &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/blue-lagoon.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;x-hangzhou-china&quot;&gt;[X] Hangzhou (China)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/hangzhou.jpg&quot; alt=&quot;West lake&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;West lake &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/hangzhou.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;x-sanya-china&quot;&gt;[X] Sanya (China)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/sanya.jpg&quot; alt=&quot;Sanya&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Sanya &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/sanya.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;x-zhuhai-china&quot;&gt;[X] Zhuhai (China)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/zhugangao.jpg&quot; alt=&quot;Zhu gang ao bridge&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Zhu gang ao bridge &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/zhugangao.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;x-lianyungang-china&quot;&gt;[X] Lianyungang (China)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/lyg.jpg&quot; alt=&quot;Lianyungang&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Lianyungang &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/lyg.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;--sydney-australia&quot;&gt;[-] Sydney (Australia)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/sydney.jpg&quot; alt=&quot;Sydney&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Sydney opera house &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/sydney.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;--vienna-austria&quot;&gt;[-] Vienna (Austria)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/musikverein.jpg&quot; alt=&quot;Vienna&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Vienna Musikverein &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/musikverein.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;--paris-france&quot;&gt;[-] Paris (France)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/paris.jpg&quot; alt=&quot;Paris&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Paris &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/paris.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;--athens-greece&quot;&gt;[-] Athens (Greece)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/athens.jpg&quot; alt=&quot;Athens&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Acropolis &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/athens.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;--istanbul-turkey&quot;&gt;[-] Istanbul (Turkey)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/istanbul.jpg&quot; alt=&quot;Istanbul&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Hagia Sofia &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/istanbul.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;--egypt&quot;&gt;[-] Egypt&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/egypt.jpg&quot; alt=&quot;Istanbul&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Pyramid &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/egypt.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;--south-africa&quot;&gt;[-] South Africa&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/south-africa-safari.jpg&quot; alt=&quot;Istanbul&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Safari in SA &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/south-africa-safari.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;--jerusalem-israel&quot;&gt;[-] Jerusalem (Israel)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/western-wall.jpg&quot; alt=&quot;Istanbul&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Western wall &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/western-wall.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;--dunhuang-china&quot;&gt;[-] Dunhuang (China)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/dunhuang.jpg&quot; alt=&quot;Istanbul&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Dunhuang &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/dunhuang.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h4 id=&quot;--hoh-xil---kekexili-china&quot;&gt;[-] Hoh Xil - Kekexili (China)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/images/k2/kekexili.jpg&quot; alt=&quot;Istanbul&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Kekexili &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;image-label&quot; href=&quot;/images/k2/kekexili.jpg&quot;&gt;original image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 21 Feb 2021 00:00:00 +0000</pubDate>
        <link>hongchao.me/project-k2/</link>
        <guid isPermaLink="true">hongchao.me/project-k2/</guid>
      </item>
    
      <item>
        <title>Emacs is the 2D Command-line Interface</title>
        <description>&lt;p&gt;One of the most popular arguments against Emacs is that it is “a great
operating system, lacking only a decent editor”. The promotion of the
idea of “Living in Emacs” by some of the hardcore Emacs users only
make this argument more compelling. At the first glance, using a
single program for “everything” does seem to contradict the &lt;a href=&quot;https://en.wikipedia.org/wiki/Unix_philosophy&quot;&gt;Unix
philosophy&lt;/a&gt;, which
favors single-purposed programs that compose really well instead of
monolithic systems that try to solve many complex problems at the same
time. In this article, I’d like to argue that Emacs largely follows
the Unix philosophy in its problem domain: &lt;em&gt;working with text&lt;/em&gt;, and
can be seen as a two dimentional version of the &lt;a href=&quot;https://en.wikipedia.org/wiki/Command-line_interface&quot;&gt;command-line
interface&lt;/a&gt;
(CLI).&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;This is the Unix philosophy: Write programs that do one thing and do
it well. Write programs to work together. Write programs to handle
text streams, because that is a universal interface.&lt;/p&gt;

  &lt;p&gt;McIlroy, head of the Bell Labs Computing Sciences Research Center&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Many CLI tools stood the test of time. Programs like &lt;em&gt;find&lt;/em&gt;, &lt;em&gt;grep&lt;/em&gt;,
&lt;em&gt;awk&lt;/em&gt;, etc have been indispensable for IT professionals for
decades. They are effective, sometimes more so than their GUI
counterparts, because command line interpreters such as
&lt;a href=&quot;https://en.wikipedia.org/wiki/Bourne_shell&quot;&gt;Bash&lt;/a&gt; provides an
environment where they can be composed together to accomplish tasks
that the original designer of the individual program have never
thought about. For example, through the composition of &lt;em&gt;kubectl&lt;/em&gt;,
&lt;em&gt;grep&lt;/em&gt;, &lt;em&gt;awk&lt;/em&gt; and &lt;em&gt;base64&lt;/em&gt;, the following command displays the content
of the &lt;em&gt;tls.crt&lt;/em&gt; certificate in a Kubernetes secret called
&lt;em&gt;nioctib-tech-it-tls&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/compose-cli.png&quot; alt=&quot;compose cli&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The following two things are quintessential to the composibility and
extensibility of the CLI programs:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Text streams as the univeral interface&lt;/li&gt;
  &lt;li&gt;Command line interpreter as a programming environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are definitely disadvantages to use text streams as the
universal interface between programs due to its lack of structure. But
the timelessness of many of the programs following this pattern and
the prosperity that it brings to the CLI ecosystem proved its
effectiveness as a design choice. Text can be read by both human and
programs. It can be manipulated, printed, stored, trasferred, version
controlled with the tools of your choice. For programs that do not
inheritantly require structured data, using text streams as interface
provides the most flexibility and composibility.&lt;/p&gt;

&lt;p&gt;However, the flip side is that for programs that do require structured
data, such as browsers, image viewers, music players, etc. Their text
based versions usually become the toys of the hobbyists with
neglectable impact.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/lynx-browser.png&quot; alt=&quot;lynx browser&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Lynx: a text based browser with tiny user base&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Another important contributor to the success of many of the CLI
programs is the fact that they live in a programmable environment. In
Bash, programs can be written from scratch or glued together using
Bash script. This makes the CLI environment infinitely extensible. By
enabling smaller programs that “do one thing and do it well” work
together to accomplish more complex tasks, it becomes an environment
that boosts synergy, productivity and creativity.&lt;/p&gt;

&lt;p&gt;The word “line” in the CLI (Command-line interface) environment
indicates its one dimentional nature. For programs that potentially
need to interact with (two-dimentional) text files, Emacs offers an
environment with similiar characteristics that makes CLI enviornment
successful: A universal text interface and a programming environment
which enables infinite extensibility.&lt;/p&gt;

&lt;p&gt;Self described as “an extensible, customizable, free/libre text
editor”, &lt;a href=&quot;https://en.wikipedia.org/wiki/GNU_Emacs&quot;&gt;GNU Emacs&lt;/a&gt;’s
infinite extensibility is enabled by a Turing-complete language called
&lt;a href=&quot;https://en.wikipedia.org/wiki/Emacs_Lisp&quot;&gt;Elisp&lt;/a&gt;, which also is used
to write most of Emacs itself. This is similiar to how for example
Bash achieves its extensibility through Bash script. Just like most of
the programs that thrives under the Bash environment are inheritantly
text focused, most of the popular Emacs programs are text focused as
well, such as &lt;a href=&quot;https://magit.vc/&quot;&gt;Magit&lt;/a&gt; and
&lt;a href=&quot;https://orgmode.org/&quot;&gt;Org-mode&lt;/a&gt;. They also tend to integrate very
well with other Emacs programs, creating synergy similiar to that of
the CLI programs. For example, you can look at the commit history of a
Git repository using Magit, jump directly to the diff of a commit, and
then jump straight to the source code in the diff. In the following
example, the source code is written in Scala, you can then edit the
code with Emacs’s exellent Scala support thanks to
&lt;a href=&quot;https://github.com/emacs-lsp/lsp-mode&quot;&gt;lsp-mode&lt;/a&gt; and
&lt;a href=&quot;https://github.com/emacs-lsp/lsp-metals&quot;&gt;lsp-metals&lt;/a&gt;, which are
programs in the Emacs ecosystem that Magit is not aware of at all.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/magit-code.png&quot; alt=&quot;magit&quot; /&gt;
&lt;span class=&quot;image-label&quot;&gt;Magit: jumping from commit to diff to source code&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;If Emacs is an environment for programs that focus on two dimensional
text, it is also more than capable of running programs that deal with
one dimensional text. In fact, many CLI tools such as &lt;em&gt;grep&lt;/em&gt;, &lt;em&gt;find&lt;/em&gt;
and many file system management utilities
(&lt;a href=&quot;https://en.wikipedia.org/wiki/Dired&quot;&gt;Dired&lt;/a&gt;) are implemented in
Elisp and thus integrated into the Emacs ecosystem as well. This is
one of the reasons that if your main workflow is text focused, “Living
in Emacs” is probably not a terrible idea due to the synergy many of
these Emacs programs produce.&lt;/p&gt;

&lt;p&gt;However, that doesn’t mean that &lt;em&gt;everything&lt;/em&gt; should be run in
Emacs. Emacs is probably not the best tool for browsing web
(&lt;a href=&quot;https://www.gnu.org/software/emacs/manual/html_mono/eww.html&quot;&gt;EWW&lt;/a&gt;)
or listening to music
(&lt;a href=&quot;https://en.wikipedia.org/wiki/EMMS_(media_player)&quot;&gt;EMMS&lt;/a&gt;), just like
CLI tools such as Lynx will never have significant impact because they
are fundamentally not text focused. The argument that Emacs is “a
great operating system, lacking only a decent editor” tries to paint
Emacs as a monolithic swiss army knife ambitious enough to run any
programs. In fact, Emacs is more like a two dimensional CLI
environment that embraces the same Unix philosophy: enable simple,
elegant programs interacting with each other using an univeral
interface.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Edit:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.reddit.com/r/emacs/comments/kk1voo/emacs_is_the_two_dimensional_commandline_interface/&quot;&gt;Reddit Discussion&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://news.ycombinator.com/item?id=26521186&quot;&gt;Hacker News Discussion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 25 Dec 2020 00:00:00 +0000</pubDate>
        <link>hongchao.me/cli-and-emacs/</link>
        <guid isPermaLink="true">hongchao.me/cli-and-emacs/</guid>
      </item>
    
  </channel>
</rss>