Very Secure

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. []

Notes on how to speed up the trb resync process after data corruption

July 14th, 2020

I was syncing my local trb node and I saw this error in my debug.log file:


My most recent .dat file had been corrupted, from a cause unknown but most likely from my computer powering off during a write operation. I took some notes on how to avoid having to redownload all my hard earned blocks. The commands I've pasted below are specific to my case, but you can use them as an example.

I) Get asciilifeform's blkcut tool.

II) Remove your most recent blk000n.dat file, since it should be the file that is corrupted. Then cut up the remaining blk000*.dat files and organize the individual block files into a directory. How you do that second step is up to you. I moved all the blocks to ~/.bitcoin/cutblocks.

rm ~/.bitcoin/blk0003.dat # corrupted file.
cutblock ~/.bitcoin/blk0001.dat
cutblock ~/.bitcoin/blk0002.dat

mkdir ~/.bitcoin/cutblocks

for i in {0..9}
mv blk0001.dat.$i* ~/.bitcoin/cutblocks; mv blk0002.dat.$i* ~/.bitcoin/cutblocks;

III) Remove your old .dat files. I put them in a backup folder.

mkdir ~/bitcoin-data-backup
mv ~/.bitcoin/*.dat ~/bitcoin-data-backup

IV) Start bitcoind with the -caneat flag.

LC_ALL=C nohup ./bitcoind -caneat -myip= -addnode= -addnode= -verifyallll 2>&1 &

V) Now we need to run a script to eatblock on all our blocks. First find out how many blocks each old blkdata file had.

cutblock -c ~/bitcoin-data-backup/blk0001.dat

Then we load those blocks with a script to iterate through the eatblock commands. Run the following command replacing 188528 with the number you received from cutblock -c minus one1. If you have more than 1-3 blk000*.dat files, you'll want to create a more sophisticated script.

for i in {0..188528}; do echo "eating block $i"; ~/v/trb054/bitcoin/build/bitcoind eatblock ~/.bitcoin/cutblocks/blk0001.dat.$i.blk; done
  1. The first blk is blk0001.dat.0.blk []

Representing Data - Notes on Big And Little Endian Encodings

July 13th, 2020

While working on my block explorer I realized that my grasp on what it means for a system to be big or little endian was weak at best. I took the time to think about what exactly was the difference between the two. In the process I cleared up confusions in my overall understanding of encodings.


At a lower level, data structures in computer programs are all kept as series of bits. The state of these bits are stored on a piece of hardware such as a flash drive, an ssd drive, a mechanical hard drive, a stick of RAM, a CD, a cache, etc. Each bit has some physical location within its storage device. We can abstract this observation and give each location of a bit state a unique numerical address. Ostensibly numerically adjacent addresses map to physically adjacent bits, but this need not be the case.

We are often curious to know the state of the bits on our physical devices. Our goal becomes to bring an invisible state of the world into our field of consciousness. To do this we need our machine to read the bits on its storage device and construct light on our monitor that form characters we can perceive with our eyes. The characters we choose to represent the raw data are usually the same ones we use when we write numbers in hexadecimal: 0123456789ABCDEF. Since there are 16 characters in our symbol system, each character can represent an ordered list of 4 bits. To get a better understanding, we can work through an example.

Here is a mapping of addresses to bit states, with the address written in base 10 and bit state written as a 1 for on and a 0 for off.

0  -> 1
1  -> 0
2  -> 1
3  -> 0
4  -> 1
5  -> 1
6  -> 1
7  -> 0
8  -> 1
9  -> 1
10 -> 0
11 -> 1
12 -> 1
13 -> 1
14 -> 0
15 -> 1

Writing out the 1's and 0's with the lowest address on the left, the above becomes:


If we want to represent the data above with the hexadecimal characters we do the following. We write out a hexadecimal string such that if we were to convert each hexadecimal character into its 4 digit binary equivilant we would have the bit state of each address, with the leftmost bit being the lowest address (0) and the rightmost bit being the highest address (15)

1010 | 1110 | 1101 | 1101 |
  A  |   E  |   D  |   D  |

It's important to understand that so far we are not using the hexadecimal characters nor their 4-digit binary equivilant to represent numbers. These characters are only being used to represent the state of the data as it is stored in some storage device.

However, we do often use the state of chunks of memory to represent numbers. Coming up for a standard for how bit states map to numbers allows one to do arithmetic operations. We could, in theory, come up with any arbitrary mapping. For example, one could make the 5th position in memory represent the most significant bit of a number, then the 0th the 2nd most significant bit, the 9th the 3rd, etc. This would admittedly be a stupid and confusing scheme for representing numbers. In practice there are two prevailing conventions - big endian and little endian.

In a big endian1 system, the bit state at the lowest address represents the most sigificant bit in a binary number and the state in the highest address represents the least significant bit. The physical state of the machine above in a big endian context represents the following number: (I've written the same number 3 times in different bases)

1010111011011101 (base 2)
AEDD (base 16)
44,765 (base 10)

In little endian, the least significant byte is placed at the lowest memory address. However, within that byte, the bit with the lowest address is the most significant.

0  -> 1 (9th  most significant bit)
1  -> 0 (10th most significant bit)
2  -> 1 (11th most significant bit)
3  -> 0 (12th most significant bit)
4  -> 1 (13th most significant bit)
5  -> 1 (14th most significant bit)
6  -> 1 (15th most significant bit)
7  -> 0 (16th most significant bit)
8  -> 1 (1st  most significant bit)
9  -> 1 (2nd  most significant bit)
10 -> 0 (3rd  most significant bit)
11 -> 1 (4th  most significant bit)
12 -> 1 (5th  most significant bit)
13 -> 1 (6th  most significant bit)
14 -> 0 (7th  most significant bit)
15 -> 1 (8th  most significant bit) 

When in the context of little endian, the same above state now represents a different number, again written 3 times in different bases:

1101110110101110 (base 2)
DDAE (base 16)
56,750 (base 10)

If you tell a computer "store 56,750 starting at address 0 for me", the state of the bits at the addresses in memory on a big/little endian machine will differ. But if you give the more specfic instruction "write byte 9F at address 0", then the resulting state will be the same on the two machines.


As jfw points out, some fields in trb have the endianness of their internal and external representations swapped. So when you extract the hex characters that represent the "state of the machine" that is storing the block data, you need to (sometimes) reverse the order of the bytes so that the resulting hexadecimal string represents the correct numerical value for the field you're observing.

Creating/finding an exhausitive list of which fields in trb are represented in little endian and which are represented in big endian is on the todo list.

  1. Also known as Network Byte Order, since it is the standard way to organize bits to send accross networks. []

A Bitcoin Block Explorer - The Why & The How

July 9th, 2020

I've embarked on a mission to create a bitcoin block explorer. My motivation is the network is sorely missing a public block explorer that has a public vpatch'd source. Afaik the only public block explorer made by someone in the web of trust was ben_vulpes's mimisbrunnr, which has been dead for years.

Current heathen block explorers1 have the wrong ethos. They do not publish their source prominently, they have no guarantee that they won't break their api, they support all sorts of various scam coins, they support non-standard bitcoin transactions, they likely run off prb, etc. etc. They are operated by amorphous identities, rather than by an individual in the web of trust.

So a better block explorer is a low-hanging fruit. But it's worth questioning whether making a block explorer that serves data over http is worth creating in the first place. Bitcoin operators should treat their locally verified blockchain as the source of truth instead of the output of some site.2 The thing is... trb operators cannot view what's inside their blockchain because the design for its storage is atrocious.3 If trb stored its data in a sane manner to begin with, a public block explorer wouldn't be necessary. Trb operators would just query their local blockchain.

Since we are stuck with the trb abomination, what's needed is a second program that monitors the growing tumor blockchain and packages the information into a second, sane database. This program, which provides a reasonable way to actually understand wtf's inside all those blk****.dat files, is likely desired by ~all trb node operators.4 So while I do plan to provide an http service, the goal is first and foremost to make a block explorer that one can run locally on top of trb.

Much of the hard work for this job has already been completed by jfw. He released gbw-node, a piece of software for the online portion of his wallet that provides a way to track the balances of provided addresses. His program scans the trb blockchain, inserts relevant information in a sanely structured sqlite3 database, and then provides a way to query that db.

A few tweaks and additions are needed to make his gbw-node provide a way to access all the information that a block explorer is generally expected to provide. For example, the db needs a new table for blocks. Also, instead of tracking specific addresses, the gbw-node needs to track all addresses.5

The next task on my plate is figuring out the full list of necessary changes and creating an estimation of how much storage space trb + the mirror'd db will require. Meanwhile I need find a home to host my block explorer and begin syncing a trb node in that home asap.

  1. Here are some: []

  2. Perhaps a proper http block explorer signs its responses to queries when requested. []
  3. And trb is something that the world is stuck with. Fork the source and eventually you'll fork the chain. And who has the authority to say that their new chain, one that is not the accepted longest chain in og trb, is to be called "Bitcoin" proper? Bitcoin defends itself economically, you know. []
  4. So long as that node operator is using trb to manage their own bitcoins, rather than just to place a node in the world to increase the robustness of the network / number of copies of the blockchain. []
  5. Arguably this is a feature a wallet user with extra storage space / cpu cycles to spare would want anyways. []

Spanish Study Log 13, July 8th 2020

July 9th, 2020

I. Leer El Entenado Por José Saer (30 minutos)


I. Vocabulario

disimular - ocultar con astucia o habilidad lo que se siente o se padece.
la intemperie - ambiente atmosférico
el alcance - distancia que alcanza la acción o la influencia de una cosa
negrura - cualidad de negro
chisporroteantes - sizzling
acribillada de un volcán - ??
entrever - ver una cosa de manera confusa o imprecisa
la incandescencia - estado de un cuerpo incandescente
incandescente - [cuerpo] que adquiere un color rojo o blanco por haber sido sometido a altas temperaturas, especialmente el carbón y los metales.
la orfandad - condición de huérfano (alguien sin padres)
el cáñamo humedecido - the moistened hemp
amontonamiento de mercaderías - stacking of merchandise
capitanes - captains
me acunó - it cradled me
mandadero - persona que hace mandados o recados
changador - porter (some ship job in South America)
un acoplamiento gratuito - a free hookup
me bastaban - They were enough for me
torpeza - cualidad de torpe
torpe - [persona, animal] que se mueve con lentitud y dificultad sin dominar del todo los movimientos.
la incomodidad - the discomfort
grumete - muchacho que en un barco ayuda a la tripulación en sus tareas para aprender el oficio de marinero.
el poniente - the West

8:40PM Empieza
9:08PM Fin

How To Test gbw-node By Viewing The First Ever Transaction Containing a p2pkh Address

July 8th, 2020

After setting up gbw-node and getting a local trb running, I wanted to do a basic test to make sure that my instance of jfw's wallet software was able to show a balance for an address that had received some bitcoins. Dorion had done a similar exercise, except he scanned up to block 634,000 which took about 24 hours.

Being impatient, I attempted to track the address found in the first non-coinbase txn in history, found in block 170. But I discovered that gbw-node cannot track the receiving address in that transaction, since gbw-node only supports addresses that receive bitcoins via the p2pkh script. The first transaction in bitcoin's history was paid directly to the public key, not the public key's hash.

I believe the first address in the form of a p2pkh script can be found in block 728 in a transaction that sent the address 100 bitcoins.

The corresponding bitcoin address and txn-id are 12higDjoCCNXSA95xZMWUdPvXNmkAduhWv and 6f7cf9580f1c2dfb3c4d5d043cdbb128c640e3f20161245aa7372e9666168516, respectively.

So to quickly test basic functionality of gbw-node, run the following commands:

gbw-node watch firstp2pkh

gbw-node reset
gbw-node scan # Wait for block 728 to pass, then 
gbw-node unspent-outs

You should see:

12higDjoCCNXSA95xZMWUdPvXNmkAduhWv 100.00000000 6f7cf9580f1c2dfb3c4d5d043cdbb128c640e3f20161245aa7372e9666168516 0 #blk 728 tx 1

Building TRB on CentOS 6.9, Notes on a Few Gotchas

July 8th, 2020

Yesterday I built trb on my local computer running CentOS 6.9. I imagine I saved a bit of time from already having keccak V setup. The only dependency from the list on the bitcoin foundation's website I was missing was "bc."1

After grabbing the vpatches from the foundation's website I also pulled in two other vpatches written by jfw, one that provides an improved way to get/send rawtx's and another that fixes up the bitcoind build process in various ways. The commands to grab the patches and seals:


After a successful press, I ran into a couple of errors when trying to build the beast that is trb. The first one was some error related to my LD_LIBRARY_PATH variable. (UPDATE: As jfw pointed out in the comments, this error was received when I tried to do the build for the first time, without his system_compiler patch.)

You seem to have the current working directory in your
LD_LIBRARY_PATH environment variable. This doesn't work.
make[2]: *** [core-dependencies] Error 1
make[2]: Leaving directory `/home/whaack/v/trb054/bitcoin/build/buildroot-2015.05'
make[1]: *** [buildroot-2015.05] Error 2
make[1]: Leaving directory `/home/whaack/v/trb054/bitcoin/build'
make: *** [build] Error 2

I updated my environment by running:


in my terminal.

The next problem I ran into was building Boost. I caught the issue because I actually stared at the screen and watched all that compiler spew. Python errors flowed in front of my eyes, and I figured that the problem must be related to the fact that the native python on CentOS 6.9 is python 2.6.6 rather than python 2.7.x.

Getting my environment to use python 2.7.x instead of python 2.6.6 was a little bit tricky. Apparently you cannot update the native python without putting your OS in danger. So you need to install this program scl as well as python27 through yum and then use scl to start a temporary environment that has python pointed at python27. In this environment you build bitcoind.

scl enable python27 bash
cd ~/v/trb054/bitcoin/
make ONLINE=1
  1. I also had to downgrade my gpg from 2.X to 1.4.23, as well as tweak my path so that my gcc was 4.4.7. (Previously my gcc was pointed to some gcc 8.x used by a 2019 version of GNAT.) []

Spanish Study Log 11, July 6th 2020

July 8th, 2020

I. Read La Buena Suerte (30 mins)

II. Read Que Bien Suena (30 mins)

== Review

I. Vocab

búho - an owl
sutilmente - subtly
la revancha - the rematch
despistar - hacer perder la pista o el camino a alguien (mislead/sidetrack)
enfurecer - hacer que una persona o un animal se pongan furiosos
encajar - (1) to fit in (2) put up with
malévola - que tiene tendencia a hacer el mal
aullidos - voz quejumbrosa y prolongada que emiten el lobo, el perro, y otros cánidos
asió con firmeza - grasped firmly
la empuñadura - the grip
refunfuñando - emitir [una persona] sonidos no articulados o palabras murmuradas entre dientes en señal de enojo o desagrado
brotar - nacer o salir [una planta] de la tierra.
pringosa - sticky
la losa - the slab [of rock]

II. Que Bien Suena

When one word ends in a consonant and the next begins with a vowel, the words are linked and not separated with glottal stops [?]. The linked words ALSO respect the rule of preferred open vowels. SO:

un alma = []

los olmos = [lo.sol.mos]

remember to combine the consonants if a word ends with a consonant and the following word begins with the same one

el lago []
es Sara []

same thing happends when you end/start on the same vowel

este estudiante [es.tes.tu.djan.te]
río Orinoco []

you make the vowel above a little longer than normal vowels, but not 2x as long. You can note the increased duration with a :


va a hacer bien [ba.ser.bjen] / [ba:.ser.bjen]

double consonants are also reduced to one within words, example:

innecesario = []

dipthongs can be formed between words

casi olvidado = []
esta idea = []
siete u ocho [sje.te.wo.cho]
la unidad []

(Finished on pg 63)


9:14AM: Start reading.
9:36AM: Lookup vocab words
9:39AM: Begin Reading Que Bien Suena
10:12AM: Finish

Spanish Study Log 12, July 7th 2020

July 8th, 2020

I. Read La Buena Suerte (30mins)

II. Read Que Bien Suena (30mins)


I. Vocab

vaya paradoja - What a paradox
un cosquilleo en el tobillo - a tickle in the ankle
una brizna - a blade (of a tree, I believe)
rozar - to touch
los osados - the daring
cotidiano - que ocurre, se hace o se repite todos los dias.

II. Notes

La "g" dura en espanol puede escribir con solo "g" o "gu"

guedeja [ge.dé.xa]
guillermo [gi.jé]
juegue [xwé.ge]

If you are going to pronounce the u after a g you need an umlaut:

güero [gwé.ro]
güira [gwí.ra]
averigüé [é] (I found out)

Or if the gu is followed by something that is not e or i:

guantanamera [gwan-ta-na-mé-ra]
antiguo [an-tí-gwo]

gemir [xe.mír]
gitano []
Argentina [ar.xen.tí.na]

jornada [xor.ná.da]
jujuy [xu.xwí]

Page 69 has a list of notes on fonetic symbols for Spanish.

(Finished at page 70.)

I have a lot of exercise debt.


6:05PM Begin Reading
6:23PM Begin translating (finished book)
6:25PM Begin reading Que Bien Suena
6:54PM Finished.