Initial Design

AEIOU is a “digital bearer certificate” system, though I wasn’t aware of that term or of other DBC systems I first started working on the project.  The DBC concept is pretty simple.  For each certificate there is an entry in a database on a server consisting of a unique ID, a password (sometimes the ID is the password), and some information pertaining to who issued the certificate and what they promise to give the bearer in exchange for it.  The issuer exports all of this from the database as a block of text, which is the certificate itself.  When the certificate is given to someone, that person sends it back to the server, which verifies the password.  If the password in the certificate matches the one in the corresponding database entry, the server changes the password and sends the new bearer a new certificate with the new password.  This is done every time the certificate changes hands, so that only the current bearer knows the current password.

This setup is analogous to the use of real-world IOUs (“I owe unto” or “I owe you”).  Someone issuing an IOU writes down what they owe to another person on a slip of paper, signs it, and gives it to that person.  The IOU can then be traded as representative money among those who trust that the issuer will make good on their debt.  When dealing with electronic IOUs, however, it is impossible to distinguish a valid IOU from an illegitimate copy, hence the necessity to “phone home” to the server for every transaction.  Fortunately, doing so over the internet is quick and inexpensive, and there’s no need for the bearer to disclose their identity.

I wrote AEIOU in PHP, and used MySQL for the database, simply because they’re both available on pretty much every web host.  In hindsight, other considerations should probably have taken priority, but I’ll talk about that later.  The easiest way to understand the design is probably to start by looking at the database tables.  In version 0.1, these were quite simple, and matched pretty closely what I described above.  From install.php, the issuers table:

mysql_query('
	create table issuers
		   ( id int not null auto_increment
		   , username varchar(20) not null
		   , password_hash char(40) not null
		   , password_salt char(4) not null
		   , id_cookie varchar(30)
		   , contact_info text
		   , primary key (id)
		   , unique username (username)
		   )
') or die(mysql_error());

The issuers table stores:

  • id: a numeric ID for each issuer
  • username: the name that is displayed on the issuer’s IOUs and that they use to log in with
  • password_hash and password_salt: an md5 hash of the password with a 4-byte salt
  • id_cookie: a cookie for identifying page requests from logged-in issuers
  • contact_info: a block of contact info text that is editable by the issuer and displayed on their profile page

The IOU entries on the server are referred to as “IOU tickets”, and are stored in the tickets table:

mysql_query('
	create table tickets
		   ( id int not null auto_increment
		   , issuer_id int not null
		   , commodity varchar(255) not null
		   , quantity decimal(9, 2)
		   , units varchar(255)
		   , iou_text text
		   , allow_split boolean not null default false
		   , split_minimum decimal(9,2) not null default 0.01
		   , split_precision decimal(9,2) not null default 0.01
		   , status enum("active"
		   		,"retired"
				,"split"
				,"merged") not null default "active"
		   , secret_hash char(40)
		   , secret_salt char(4)
		   , primary key (id)
		   , foreign key (issuer_id) references issuers (id)
		   )
') or die(mysql_error());

The allow_split, split_minimum, split_precision, and status fields were unused in this version.  That leaves the following:

  • id: a numeric ID for each IOU
  • issuer_id: the issuer ID of whoever created the IOU
  • commodity: what commodity the debt is denominated in (gold, labor, beans, etc.)
  • quantity: the quantity of that commodity
  • units: what units the quantity is measured in (ounces, hours, cans, etc.)
  • iou_text: a block of text that states explicitly what the issuer owes
  • secret_hash and secret_salt: salted hash of the password (“secret key”) used to transfer the IOU

That’s it for the database.  The actual bearer certificates are called “IOU ticket stubs”, and are generated by the code in stub.php.  Here’s a snippet:

	$stub = '-----BEGIN AEIOU TICKET STUB-----'."\n";
	$stub .= $tdata['quantity'].' ';
	$stub .= $tdata['units'].' of ';
	$stub .= $tdata['commodity']."\n";
	$stub .= 'Issued by ';
	$stub .= $issuer_data['username'].' at ';
	$stub .= $surl."\n";
	$stub .= 'URL: http://';
	$stub .= $surl.'/ticket.php?tid=';
	$stub .= $tdata['id']."\n";
	$stub .= 'Secret Key: ';
	$stub .= $new_key."\n";
	$stub .= '-----END AEIOU TICKET STUB-----'."\n";

The ticket stub would look something like this:

-----BEGIN AEIOU TICKET STUB-----
10.00 hours of labor
Issued by chris_acheson at chrisacheson.net
URL: http://chrisacheson.net/ticket.php?tid=345098
Secret Key: XZg75rz0gdYF7h7qNpqX
-----END AEIOU TICKET STUB-----

Upon going to the URL listed on the ticket stub, you’d be presented with a page with information about that particular IOU ticket, as well as form inputs allowing you to verify or change the secret key.  The page would display the full statement of what the issuer owes, such as:

I will perform a number of hours of simple labor equal to the face value of this ticket within one week of it being presented to me by the ticket-bearer. Alternatively, I will guarantee the labor of another person, who will work in my stead.

That’s pretty much the extent of the noteworthy features of version 0.1.  In the next post, I’ll cover the highlights of the changes between 0.1 and the current version, 0.6.

Leave a Reply