Blog

  1. Interacting with Simple Contracts on Ethereum

    The truffle project helps one get started in writing contracts, but after the bootstrap and deploying a contract to the testnet, I realized there was less support on how to interact with the contract. Alchemy has a good example in their docs, but I wanted to use the web3.js library maintained by ChainSafe.

    The key parts were:

    1. Getting the compiled json abi from trufflesuite and creating a web3.eth.Contract instance
    2. Creating an account with web3.eth.accounts.privateKeyToAccount
    3. Creating a transaction with the function call encoded by encodeABI
    4. and finally signing the transaction before sending it.
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    
    import Web3 from "web3";
    
    const yourApiKey = "..."
    const web3 = new Web3("https://eth-sepolia.g.alchemy.com/v2/" + yourApiKey);
    
    const privateKey = 'yourPrivateKey'
    const senderAccount = web3.eth.accounts.privateKeyToAccount(privateKey);
    
    const contractAddress = "0xd76E31314D760b51493278C72c22d280C6ba6C4b" # a deployed contract on Sepolia
    
    import SimpleStorage from './build/ethereum-contracts/SimpleStorage.json' assert { type: 'json' }
    const contract = new web3.eth.Contract(SimpleStorage.abi, contractAddress)
    const paymeTransaction = contract.methods.payme();
    
    const transactionObject = {
      from: senderAccount.address,
      to: contractAddress,
      data: paymeTransaction.encodeABI(),
      value: Web3.utils.toWei('0.001', 'ether'),
      gas: 200000,
      maxPriorityFeePerGas: 100000,
      maxFeePerGas: 200000
    };
    
    senderAccount.signTransaction(transactionObject)
      .then((signedTx) => {
        return web3.eth.sendSignedTransaction(signedTx.rawTransaction);
      })
      .then((receipt) => {
        console.log('Transaction successful:', receipt);
      })
      .catch((error) => {
        console.error('Transaction failed:', error);
      });
    

    In the browser environment, somehow the privateKey would be part of a default list of accounts, and the higher level transaction.call() can be used, but I’m unfamiliar with that flow currently.

    Read More

  2. Timezones in Postgres

    There are two representations for timestamp in postgres, timestamp, and timestamptz. Both store dates in the db as UTC, and the only difference between the two is that timestamptz uses to timezone to format the data for display. But I think this obscures what I would say is slightly unintuitive behavior when working with timestamps in postgres.

    Converting between timestamp and timestamptz

    Consider the following query:

    1
    2
    3
    4
    5
    6
    
    postgres=# select 
    pg_typeof(timestamp '2022-01-01' at time zone 'Pacific/Honolulu'), 
    pg_typeof(timestamptz '2022-01-01' at time zone 'Pacific/Honolulu');
            pg_typeof         |          pg_typeof
    --------------------------+-----------------------------
     timestamp with time zone | timestamp without time zone
    

    I think it makes sense that a timestamp at time zone becomes a timestamptz, but not so much that a timestamptz at time zone would be converted back to a timestamp! This has implications for methods like date or date part, because these operate on the ‘display’ value.

    Read More

  3. Some notes on matplotlib

    Matplotlib has two modes, ‘implicit’, and ‘object oriented’. Most code I know seems to use the ‘implicit’ method, which is to say, they use

    1
    
    import matplotlib.pyplot as plt
    

    Now, plt.figure is nice, but an implicit Axes object is created, and its kind of hard to get that object back. You might want Axes, so you could get the range in data coordinates, of the plot. So instead of using figure, use subplots:

    Read More

  4. A little bit about gamma

    Gamma is a kind of compression algorithm. It exploits the fact that our perception of brightness, as with many other sensory stimuli, follow the power law. Our eyes are much better at detecting the difference between 2 values that are darker, as opposed to two values that are brighter. From an evolutionary standpoint, this makes sense: it is much more advantageous to be able to see in the dark, than to accurately tell between two really bright shades.

    Read More

  5. Concurrency vs Parallelism in Ruby Apps

    A thing that came up some weeks ago which confused me, is whether languages like Python and Ruby are multithreaded. This my attempt to explain to myself how it works in Ruby, and I hope it helps you too. Firstly, we need to distinguish concurrency and parallelism, which are conflated with multithreading, but are not the same. Concurrency can be thought of as interleaving, so if two jobs are switched back and forth very quickly, there is a sense that both are being done ‘at the same time’, but they are merely being done concurrently. For example, you may be eating food, and drinking beer. Take a bite, then sip, then bite, then sip, so you are concurrently drinking beer and eating food. But you are not literally drinking beer and eating food at the same time, that would require you to have both the cup to your lips and fork to your lips at the same time(in parallel), which is not possible. To do so you’d need two mouths.

    Read More

  6. Tyranny of Virtualization

    Last Christmas I finally upgraded my 7 year old Macbook. I backed all my pictures, code, and dot files. But I left one very major thing out — I forgot to copy over my private keys. These were tied to all my AWS deploy keys deployed with Terraform over the past couple of years. This means I couldn’t get into my server to renew my SSL certs, (which for some awful reason that I couldn’t debug), did not update automatically. So I locked myself out of my own fortess, great. But I realized in retrospect that my whole set up to host this blog had been perhaps too close to the metal. I was interested in learning, and so led myself down that direction, but now I have no intention of doing so.

    Read More

  7. Hoisting JS

    I’m going through Joel Martin’s amazing teaching tool, mal, which teaches you how to write your own Lisp from scratch. I wanted to get a little better at Javascript, and so chose to use it as my language of implementation.

    I’m really glad I’m writing Javascript in the realm of ES6, but there was a bit of hoisting that definitely took me by surprise.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    
    function EVAL(ast, env) {
      ...
      switch (ast[0]) {
        case "def!":
          [__, first, second] = ast
          let value = EVAL(second, env)
          ...
          return value
        case "let*":
          [__, first, second] = ast
          ...
          return EVAL(second, newEnv)
        ...
    
    ...
    

    It turns out that even with the array destructuring, the variable is hoisted into the global context. I only detected this issue with a def that was nested in a let. In those situations, the variable ‘second’ would be overidden in the nested call, so that it would actually change when it returned to the caller.

    Read More