Very Secure

Receiving/Sending Bitcoins To/From An Offline Wallet, A Basic Explanation

March 4th, 2021

There is a common confusion amongst bitcoin newcomers regarding how an offline wallet is able to receive bitcoins and then later send those same bitcoins to another address. The core of the misunderstanding is revealed in the commonly asked question:

How can an offline computer receive bitcoins? Doesn't the offline computer need to download a piece of information that represents the bitcoin?

The answer to the latter question is no, the offline computer does not need to download anything to receive bitcoins. However, to be able to spend the bitcoins, the offline computer needs to be transferred a piece of information called an Unspent Transaction Outputs (UTXO) from a computer connected to the bitcoin network.

The reason that the offline wallet does not need to download anything to receive a bitcoin is because to own a bitcoin means to have the potential ability to extend a chain of transactions. To understand this let's walk through an example.

Bitcoins first appear in the blockchain as a single transaction paid out to a miner.1 When the miner mines a block, a piece of data gets added to the blockchain that looks something like:

50 BTC -> 1A7Ae2RczM1T2ZqgLQhLRzx5RdcJWvHDot (TX ID: 4039)2

Now let's say the miner decides to send his bitcoins to someone else's address. In the next block, He will add data to the blockchain that looks like

Use the output from TX ID 4039 to send 50 BTC from 1A7Ae2RczM1T2ZqgLQhLRzx5RdcJWvHDot -> 1C26k7Z7JMmhKf1zZyZUEFEvcQCEPqRPvx + (Signature from 1A7Ae2RczM1T2ZqgLQhLRzx5RdcJWvHDot)3 (TX ID: 5019)

Now let's say you are friends with the owner of address 1C26k7Z7JMmhKf1zZyZUEFEvcQCEPqRPvx and you want him to send you some bitcoins. So with your offline wallet you generate a public / private key pair - your bitcoin address is 1NKrRM2M5TmdVJRHwAeWXAZyAGHJ7U1dEV. Then the owner of address 1C26.. can then send you the bitcoins by appending a transaction to the blockchain that looks like the previous one:

Use the output from TX ID 5019 to send 50 BTC from 1C26k7Z7JMmhKf1zZyZUEFEvcQCEPqRPvx -> 1NKrRM2M5TmdVJRHwAeWXAZyAGHJ7U1dEV + (Signature from 1C26k7Z7JMmhKf1zZyZUEFEvcQCEPqRPvx) (TX ID: 8492)

Once this transaction is in the blockchain, you have effectively "received" the bitcoins. The offline computer itself does not (yet) need to have the transaction data, once the transaction is in the blockchain the bitcoin network has acknowledged that the owner of the 50 BTC is the person with the private key corresponding to (your) bitcoin address 1NKrRM2M5TmdVJRHwAeWXAZyAGHJ7U1dEV.

This being said, at the moment you want to spend the bitcoins that you have in address 1NKrRM2M5TmdVJRHwAeWXAZyAGHJ7U1dEV, your offline computer will need the data in the above transaction with ID 8492. This is because the offline computer creates the transaction signature. To generate that signature, the offline computer needs to have the information of the transaction it is creating. That information includes the source of the bitcoins to be spent, i.e. the UTXO from TX with ID 8492.

To conclude let's go over how someone may use an offline wallet to receive and then send bitcoins. First, the bitcoin user creates his public/private key on the offline computer. He then monitors the blockchain using an online computer to see that he has received funds. Finally, when he wants to spend the funds, he downloads the necessary information from the blockchain (i.e. the relevant UTXO's), puts the UTXO information on his offline computer, uses the UTXO information to create a signed transaction,4 and transfers that signed transaction to an online computer that broadcasts the transaction to the network.

For some more technical details regarding bitcoin transactions check out jfw's series "bitcoin transactions and their signing".

  1. This transaction is commonly called a coinbase transaction. A company called "Coinbase" took this term and used it as their name. []
  2. This "transaction id" is actually a hash of the data in the transaction, not just a number. I chose to represent the tx hash as a number for sake of explanation. []
  3. This signature is a piece of data that is a mathematical proof showing that the person who generated the address 1A7Ae2RczM1T2ZqgLQhLRzx5RdcJWvHDot authorizes the transaction. []
  4. Alternatively he creates the transaction on the online computer, and the only task of the offline computer is to sign the transaction. In this scenario the offline computer doesn't need to have (direct) access to the UTXO. []

The Fake Covid Consensus

January 19th, 2021

If one looks around Costa Rica without speaking to anyone they will get the impression that everyone believes in and supports the covid mask-wearing hysteria. Lots of people here walk around with masks on. Store owners have signs on their windows stating that masks are required for entry, plz keep a social distance, put some alcohol goo on your hands, etc, etc. Recently a local restaurant I frequent put this ridiculous police tape around chairs preventing clients from accessing their bar.

Given the apparent universality of the idea that one should be wearing a mask indoors, it is easy to get into the habit of showing you agree with this craziness. Many people who don't buy into the lamestream narrative still put on a mask whenever they walk into a store. Often when you ask these people if they believe in the mask mandates they will say ~ "no, I am just wearing the mask to avoid trouble" (i.e. conversation/confrontation.) But because the mask is on their face, they inadvertently signal a belief in the importance of the covid mandates. I myself sometimes forget that I'm wearing a mask after I've left a store. And until I remember to take it off, I am signaling that one should wear a mask when walking outside on the street!

The CR government is enforcing businesses to put these 'mask required' signs on their windows. The restaurant with the police tape around the bar put that there, not from the owner's own wish, but because some police officer threatened to shut down the business after the officer had a temper tantrum from seeing some guys sitting at the bar drinking together. So really the various restrictions and mask-required signs do not represent the will of the actual business owners, the owners only put them there to appease the bureaucratic clipboard lady and her police henchmen. Thus, as a client, I default to ignoring the signs and I walk into stores without a mask. I always do this for mom and pop shops, and I try to say something along the lines of "I don't mind if you don't wear a mask" so the clerks working there don't feel obligated to "protect" me.

If you are against the mask nonsense then you must be mask-free. If a private business owner wants you to wear a mask, they must tell you explicitly, posted signs mean nothing since those signs are government-mandated. Don't signal your support for something you don't believe in.

Scheduled Defibrillation For The Jalopy That is TRB

January 5th, 2021

A couple of months ago I was unable to start my car. So I used a trick a mechanic taught me - I opened the hood and banged on the starter with a hammer. I then turned the key in the ignition, but the car still wouldn't start. I tried again, this time banging on the starter harder. And voila, it worked. I had to do this routine of banging on the starter with a hammer1 every time i wanted to use my car. But eventually something got bumped into the right position, I guess, because I no longer have to do this absurd routine to start my car.

It seems that the same type of bang-it-till-it-works approach is required to get trb running. I have restarted my node countless times in order to get it unstuck during the sync process. So I'm posting an example shell script that kills and then restarts trb's bitcoind.2 With the current state of trb, a script like this running on a crontask every 24 hours seems ~required to get sync'd in a timely fashion.3

pid=`top -n 1 -b | grep "bitcoind" | awk '{print $1}';`
echo "killing bitcoind with pid $pid";
kill $pid;
echo "sleeping 60s";
sleep 60;
echo "force killing bitcoind"
kill -9 $pid;
sleep 60;
echo "sleeping another 30s";
# Change IPs and home path accordingly.
LC_ALL=C /your/raw/path/to/bitcoind -daemon -logtimestamps -myip= -connect= -connect= -connect= -verifyall &

The script works as follows. First it snags the pid of the process by piping the results from top into grep. If bitcoind is not running then the $pid variable is going to be empty and the following kill commands will fail. Otherwise, as per asciilifeform's advice, the script first does a normal kill to the bitcoind process. This should shutdown bitcoind "gracefully" so that there is no interrupted write to the db, or what have you. However, normal kill's often fail to stop bitcoind, so the script follows up with a kill -9. Finally, the script starts trb.

A potential improvement to this script would be to add some code that handles a corrupted db.

  1. the starter starter! []
  2. You have to change the last line that starts trb to meet the requirements of your specific environment. []
  3. aka less than three months. []

Breathing While Surfing

December 27th, 2020

Hold downs in surfing are much shorter than they feel. When the waves are < 10 feet, the max amount of time you're going to be tumbling underwater is ~10 seconds. The body can easily go without oxygen for 3, maybe 4, minutes. Knowing this helps me relax when I go through the washing machine. After I fall on a wave I try to always place my arms so that they protect my head1 and I relax the rest of my body as I wait for the turbulence to stop. It's not worth wasting my energy thrashing around before the wave's energy has dissipated.

Since hold downs are quite short, you can control your breath so that at no point during a surf session do you stop breathing. Instead, you just time your breaths so that you are exhaling when you go under the water. This requires a little bit of on-land yoga training, you need to be able to do inhalations and exhalations that last 15 seconds. To do this I breathe through the nose. while focusing on controlled contraction and relaxation of the diaphragm. Then, while surfing, I try to finish a deep breath before duck-diving or taking off on a wave. I can watch the horizon and adjust the speed of my breath to get the timing right. Concentrating on the breath keeps the mind and body focused and calm.


Here are some shots from a recent session in Marbella:


  1. I bet 85%+ of surfing deaths are from being banged on the head by one's own board. Someone died at Playa Negra three days ago in this manner. I heard he was knocked unconscious from the impact and then drowned. []


December 13th, 2020

A person with little to no flexibility training can (usually) stand on their left leg while supporting their right leg on a table such that the two legs form a 90-degree angle. The same person can mirror that action by standing on their right leg and lifting their left leg to a 90-degree angle. So if someone has the range of motion to move each leg individually 90 degrees, then...

Why can't they do a split?

Is it because there is some physical connection between the two legs? Are there muscles, tendons, or ligaments that tie the two legs together so when they simultaneously stretch out their range of motion is limited? No. The reason one can't do a split is neurological, when they attempt to move a muscle or group of muscles past what their nervous system believes to be their maximum range, their muscles start contracting to prevent the stretch. Stretching further requires removing unnecessary muscle contractions, not increasing the length of tissue.1

This is the premise of Pavel Tsatsouline's book, Relax Into Stretch. Mr. Tsatsouline gives a list of different techniques and stretches to "trick" the nervous system into allowing your body to realize its full range of motion. I cannot verify Tsatsouline's claims myself, as I have not yet attempted his methods. But guitar has taught me that learning to relax muscle groups can lead to an incredible increase in performance.

  1. I have seen other sources argue that it is indeed possible to increase the length of tissue, by adding length to muscle fibers via adding "sarcomeres" - the contractile unit of the fiber. The field of sports "science" seems to be wrapped in pseudoscience. I certainly don't know whether Tsatsouline's theory is correct. []

BJJ Training Log 1 - December 11, 2020

December 13th, 2020

In my third class of BJJ1 in CR we did a series of stretches, went over a new technique, and rolled.

I. Stretching

During the warmup Jarrid led a series of stretches, many of which I was unfamiliar with. We did a sequence that involved the wrist. These involved getting into a push-up position and lifting the palm off the ground while keeping the 4 fingers (not the thumb) on the ground. Then we got into a push-up position where the hand was bent so that the fingers pointed towards the toes and the back of the hand was lying on the mat. More advanced students were able to do a pushup from this position.

Injury prevention is paramount in BJJ, improving flexibility is thus a necessity. I have always been stiff - can't bend over with straight legs and touch my toes. Stretching can be worked on outside of the gym, so looks like I'll have to add some yoga to my life.2 From preliminary interwebs searching and advice from my sensei, I have learned that static stretching post-workout, where one tries to extend the range of the stretch upon exhalation, seems to be one of the more effective ways to increase long term range. There is no need (or perhaps even ability) to increase the length of any tissue, stretching is about turning off the nervous system's automatic contraction response when muscles reach their maximum range of motion.

II. Technique

The combat technique we went over is a little involved and has many components, it's not worth it for me to write down the whole sequence. Rather, it's best to note a fundamental that I learned from studying the complicated technique.

While drilling the technique, I was struggling to put pressure on my opponent as I was laying on top of them. Another student, Nacho, taught me an important lesson - when your knees are on the mat while lying on someone the force you are applying to your opponent from your own weight is dramatically reduced. The proper position when on top of someone is to sprawl your legs out wide and rest on your toes and lean forward so that the weight distribution is maximally placed on the opponent.

III. Rolling

I rolled with more energy as I had at least some small idea of what I should be doing during my battles. I found it useful to tie one of my opponent's legs with my two legs, although I am dubious as to how effective this is in general since it's a 2 for 1 trade.

I also came the closest I've ever been to submitting an opponent. I had back control and attempted my first headlock choke. My technique on the choke was poor. I was squeezing my opponent for almost a full minute, but I could not get him to submit. The correct technique (taught to me by Jarrid) is to place the hand of the arm that is wrapped around the opponent's neck on the other arm's bicep, and then place the hand of the non-choking arm on the back of the opponents head. A mnemonic for remembering the technique is to make the "fuck-you" gesture where you slap the hand on a bicep and flex the bicep.3

  1. Brazilian Jiu Jitsu []
  2. There is so much mysticism in yoga that I am allergic to the idea of starting, but I'll put away my preconceptions and try to find out what sub-discipline can help my bendability. I've found what appears to be a good book on the subj - Relax Into Stretching []
  3. I wonder whether this gesture originates from showing an enemy that you know how to choke them. []

Jiu Jitsu

December 10th, 2020

This week I decided to give Jiu Jitsu a shot.

I have tried the martial art once before. About two years ago I messaged an old friend, Tom, asking to catch up. He responded by inviting me to train with him in his gym.

Tom and I use to wrestle as kids. His dad was in the military and into boxing, and was always pushing Tom to develop his fighting skills. I remember Tom would usually get the best of me, and I distinctly remember being punched in the face as he was demoing new boxing gloves.

Given our rivalry and fighting history it was fitting to meet up in a gym. Didn't know what to expect, but I knew Jiu Jitsu was a martial art that has proven itself useful in the UFC.1 Jiu Jitsu is a grappling sport, like wrestling, where no punches or kicks are allowed. The fight goes until time runs out or one contestant is able to force the other one to submission. One usually gets a submission from his opponent by putting him in a choke hold or by putting him in a compromising position where a large joint2 can be broken by applying force with leverage.

What makes Jiu Jitsu interesting is that you can practice sparring with near full commitment while maintaining a lowered risk of injury compared to other martial arts. You can be choked several times in a session, maybe even pass out, and still be able to train the next day. Imagine sparring hard in boxing, where one punch can send you to the hospital and cause permanent brain damage.

In my first session with Tom I discovered that it is thus common in Jiu Jitsu to roll3 several times with various opponents at the end of a class. Awesome. What a rush to fight against Tom and various strangers all the way to "the death." I was smoked in all my rolls, but I left the gym feeling alive.

I've signed up for one month of Jiu Jitsu classes at a local gym. I plan on training three days a week. I have no illusions that Jiu Jitsu will one day save me in some street fight. But perhaps training in Jiu Jitsu will help me build up discipline and lead me to a healthier lifestyle. In any case, despite the disgusting smell of sweat and the physical pain experienced during a roll, it feels great to fight.

  1. The UFC has exposed other martial arts - such as karate - as being ~useless in anything resembling a real fight. []
  2. Attempting to break small joints such as those in the fingers is banned. []
  3. Rolling is the Jiu Jitsu term for sparring. []

The Galileo Complex

December 2nd, 2020

While reading about the psychology of "climate change denial" I came across the idea of a Galileo Complex - a feeling of superiority that comes from holding contrarian beliefs. When one has a Galileo Complex, they necessarily believe that which goes against the Cathedral's Official Truths, just as Galileo did in his time. Share one of those contrarian beliefs at a dinner party, and the Galileo Complex will be fed as one's "statements of logic" are met with "persecution" via others' "emotion-based arguments."

The man with the Galileo Complex walks through the streets with a smug grin, feeling himself above others because he knows truths - USD inflation is more than 2% per annum, bitcoin is sound money, evidence for impending-doom via man-made global warming is poppycock/cherry-picked for political purposes, the risk of death has not changed because of the covid pandemic, taxation is theft, democracy is rule by the mob, updating software does not mean improving software, etc. etc.

I'm guilty of this Galileo Complex myself.1 Even if the stances I hold are true,2 this Galileo shit does not serve me. It only exists to feed the ego lacking of gratification from meaningful accomplishment. In the end what matters is what one has done, not the beliefs they held.

  1. And boy was I more guilty before Diana Coman helped "draw myself out before my eyes" via her younghands project. []
  2. Which in all cases is debatable, I mean if other people are duped all the time then why should I think that I am not being duped as well? []

Drone Tours

October 13th, 2020

My blog has been in a coma, but it shall not die until I do. Why not break the silence with a (maybe not so) far-fetched business idea? A blog is a journal for thoughts, after all.

So the other day my friend mentioned how he simply could not get his mind off of thinking of projects related to drones.1 He reminded me that, while consumer drones are usually controlled by NFC means, drones can be controlled from across the globe.2 This got me thinking that there may be room in this world for a company to provide... drone tours!

The Drone Tour Company would go to various iconic and picturesque sites and setup "drone stations." These stations would consist of a place for the drones to charge and an internet-connected tower that could communicate with drones in a given radius. The Drone Tour Company would provide software for customers that allows them to control a drone located at any one of the various stations. Customers would pay a fee (and a deposit, lest the company lose all its money due to crashed drones) to take a drone for a spin for some allotted amount of time.

Imagine giving yourself a tour through fjords and canyons, over pyramids and volcanoes, and in the sea3 through kelp beds and coral reef - all in a couple of hours from your own home.

  1. The newer models of those little flyin' buggers are pretty nifty. Like bitcoin, drones fall under the category of actually interesting technology (as opposed to any and all "smart" phone apps) that our generation is the first to experience. []
  2. Although long distance droning means having to deal with some 100-300ms lag both when receiving the video feed and giving piloting commands []
  3. There are aquatic drones too! []

Block Explorer Progress - What's Done, What's Next

July 18th, 2020

Block Explorer Progress - What's Done, What's Next

I) What's Done

I've taken jfw's gbw-node and repurposed it to serve as a block explorer. The functions I'm left with after my changes are view-block,1 view-txn-by-hash/view-txn-by-pos,2 view-ancestors/view-descendents,3 view-address4, balance,5 utxos,6 and push.7

Per jfw's suggestion, I merged the input table into the output table in the sql schema. I renamed the output table as output_input. Thinking of the output of one txn and the corresponding input in the txn that spends that output as being a single structure has helped me form a clearer picture of how chains of bitcoin transactions are connected.

Here is a snapshot of the current sql schema with the new "output_input" table.

--- Gales Bitcoin Wallet: node (online component) schema
--- J. Welsh, December 2019
--- Dialect: SQLite (3.7.0 for WAL)                                                                                                                                                                                                          

PRAGMA journal_mode=WAL;

       block_id  INTEGER PRIMARY KEY,
       height    Integer NOT NULL,
       size      INTEGER NOT NULL,
       version   INTEGER NOT NULL,
       prev_hash BLOB NOT NULL,
       hash      BLOB NOT NULL,
       root      BLOB NOT NULL,
       timestamp INTEGER NOT NULL,
       target    INTEGER NOT NULL, -- Should we include this?
       nonce     INTEGER NOT NULL
CREATE UNIQUE INDEX i_block_hash on block(hash);
CREATE UNIQUE INDEX i_block_height on block(height);

        tx_id    INTEGER PRIMARY KEY,
        hash     BLOB    NOT NULL,
        block_id INTEGER NOT NULL REFERENCES block,
        pos      INTEGER NOT NULL, --pos in block
        comment  TEXT,
        size     INTEGER NOT NULL,
        fee      INTEGER
CREATE INDEX i_tx_hash ON tx(hash);
CREATE UNIQUE INDEX i_tx_block_id_pos ON tx(block_id, pos);

-- Every input begins its life as an output.
CREATE TABLE output_input (
        output_input_id INTEGER PRIMARY KEY,
        creating_tx_id  INTEGER NOT NULL REFERENCES tx,
        out_pos         INTEGER NOT NULL,
        address_id      INTEGER NOT NULL REFERENCES address, -- aka script pub key
        value           INTEGER NOT NULL,
        spending_tx_id  INTEGER REFERENCES tx, -- If null, it hasn't been spent.
        in_pos          INTEGER, -- position in input vector in spending txn
        scriptsig       BLOB,
        flags           TEXT
CREATE UNIQUE INDEX i_output_txid_out_pos ON output_input(creating_tx_id, out_pos);
CREATE INDEX        i_output_addrid ON output_input(address_id);
CREATE INDEX i_input_txid_n  ON output_input(spending_tx_id);

CREATE TABLE address (
        address_id INTEGER PRIMARY KEY,
        address    BLOB NOT NULL

CREATE UNIQUE INDEX i_address_address ON address(address);

        scan_height INTEGER NOT NULL DEFAULT(-1)


II. What's Next

A) Refactor commands so that they can be used by both the command line and web interface.

I've decided to use flask to run the web server portion of the block explorer. From reading the logs, this python package appears to be a handy utility whose use is a mortal sin. So I don't want to make flask's installation a requirement for running the block explorer locally.

I plan to do the following. I'm going to design the block explorer so that I can run a public web interface using flask. The source of everything will be public, so anyone will be able to install the block explorer along with flask and use the explorer locally via the web interface. Alternatively, they will be able to install the explorer without flask, but in this case they will only be able to use the block explorer via a command line interface similar to the one gbw-node currently employs.

In order to allow for the two uses of the explorer, I need to split all the command functions into two parts - one that returns structured data8 and the other that prints the structure data. The command line interface and web interface will stringify the data appropriately.9

B) Write a view-raw-hex of block command.

As an exercise in understanding and in order to check the integrity of the explorer's stored data, I want to make sure that I can take the tables in the gbw-node sql database and reconstruct a bit-perfect block.10 In order to provide this feature I need to store some data considered extraneous by the original gbw-node wallet, such as the input field for a coinbase as well as a transaction's sequence number, version, and locktime.

C) Get domain names and configure servers.

I now have one box currently syncing trb on asciilifeform's rack.11 But setting up at least one other mirror in a different geographical location seems prudent.

D) Continous trb scanning.

Currently gbw-node has no way to handle reorgs. It pulls data from the bitcoin rpc up until the 'block height - CONFIRMATION'th12 block. This is done via the command "scan", which halts when it reaches the most recent block. To keep the explorer's data up to date, the block explorer must always be scanning. I can either modify the scan command to run on an infinite loop, sleeping for ~10 mins when it hits the max block height, or I can just continually rescan via a crontask.

E) Provide a way to show information about transactions in the mempool / recent blocks.

The main use cases I have for a block explorer are obtaining utxo data for spending bitcoins, pushing raw bitcoin transactions to the network, and confirming that recently pushed transactions were received by the network. The block explorer in its current state has no way to store transactions in the mempool. The schema requires a transaction to have an associated block id and block position. So currently the block explorer is not useful for showing recent blocks, nor for showing recent unconfirmed transactions.

I plan to create a separate table, mempool_transaction, that displays information about transactions in the mempool. The scan function will delete mempool transactions whenever it finds the transaction successfully placed in a deep block.13 I also will want to figure out how to store recent blocks that may be reorg'd. I think that I'll handle this in a similar manner to mempool_transaction, with some volatile table named recent_blocks. The corresponding row from this table will be deleted when the block has confirmed its place in the explorer's "main chain."

  1. Show's the information from a block's blockheader. []
  2. Both of these functions display the same information for a transaction. But one lets you search for the transaction by providing the block height and the position of the transaction. The other lets you search for a transaction by its hash. []
  3. These two functions return the txn hashes for every single txn in a transaction's ancestor tree, all the way up to the original coinbases, and the descendents of a transaction, all the way down to the current UTXOs, respectively. []
  4. Displays all transactions where the given address either creates or consumes a UTXO. []
  5. Displays the bitcoin-denominated balance of an address []
  6. Displays all the unspent transaction outputs for an address. []
  7. Sends a raw hex txn to the network. []
  8. I think I'll use python's class system, and then create and return immutable objects. []
  9. \n's for command line <b>'s + links for the web interface, etc. []
  10. It also seems prettty basic to me that a block explorer should be able to return a hexadecimal representation of a block, yet afaik none of the heathen ones provide this simple feature. []
  11. It seems like half of the network resides on asciilifeform's shelf... []
  12. Defaulting to 6 confirmations []
  13. I have not yet concluded what I should do with dust transactions that start to fill up the mempool. []