Contracts are Chat Logs

Here is, in the author’s opinion, the simplest smart contract we can write in Solidity that has any use as an agreement or contract.

contract MinimalContract {
  says(String something) public { return; };
}

Which can work. For example…

A: contract.says("I wish to buy sunscreen from $20.");
B: contract.says("I have some and can ship. Contract me +9121007811.");
A: contract.says("B has shipped to California and I have paid.");
B: contract.says("A has paid");
A: contract.says("We are done.");
B: contract.says("Yes. We are done.");

It is literally a chat log. And chat logs are contracts, or can be if we want them to be, because any agreement committing a person (natural or legal) is a contract. The global oil trade famously ran on Yahoo Chat for many years. And for an example closer to crypto, take a look at /r/TokenMarket.

In practice, this only really holds up if :-

  • A and B can prove off-chain that the keys they used to sign these calls belong to them.

  • Everyone involved is willing (and able) to read the chat exchange. Including a judge if things go wrong.

Note that each call is stored in the blockchain’s accepted transactions log even if it is never assign to a field in the contract. Since in this case the contract does not need access to its own history, there is no reason for store it there.

So the minimal legal contract on the blockchain is a single address at which multiple parties send natural language messages. A chat log.

Obviously this is hugely inefficient. Everyone has to read everything (and interpret it the same). Most contracts are not written from scratch, and generally have certain actions that are expected (at least if everyone co-operates). There is no great advantage to using MinimalContract over sending digitally signed emails.

Let’s consider someone selling their sunscreen at auction. We could do this with MinimalContract, because we can do anything with MinimalContract.

A: contract.says("I wish to auction 1 x 200ml bottle of sunscreen. Shipping to Paris only. Bids open at €20.");
B: contract.says("I bid €2.");
C: contract.says("I bid €21.");
A: contract.says("Auction closed. Ignoring B. C has won at €21.");
C: contract.says("A has shipped to Paris and I have paid.");
B: contract.says("Ok, I lost");
A: contract.says("We are done.");
C: contract.says("Yes. We are done.");

This is binding, but it is also obviously inefficient. B and C have to keyword search the entire blockchain for auction and sunscreen. Then read the description for the terms, and the log to see if the auction has finished. Let’s see if we can improve.

contract MinimalAuction is MinimalContract {

  MinimalAuction(String offering) public { return; }

  done() public { return; }
}

This is slightly better. Bidders can see which contracts are auction contracts. The description of the auction is separate. And if both the creator and all the bidders have called done(), we can assume the auction is closed. Note that we still do not need the contract to store anything itself.

This done mechanism doesn’t seem quite done though :-) Let’s break it out and develop it a little more.

contract Doneable() {

  mapping(address => boolean) private isParty;
  uint8 private activeParties;

  isDone() public view returns boolean {
    return 0 == activeParties;
  }

  done() public {
    if(isParty[partyAddress]){
      activeParties -= 1;
      isParty[partyAddress] = false;
    }
  }

  addParty(address partyAddress) protected {
    if(!isParty[partyAddress]){
      activeParties += 1;
      isParty[partyAddress] = true;
    }
  }

}

This is the point where we have exceeded what can be strictly defined within a system driven by passing around messages. Because we now share how to compute what a party is in relation to this particular contract.

Another smart contract might implement isDone() with an entirely different logic. And within a smart contract system that contract would just work. If we followed a conventional message passing model we’d need to reprogram some computers at this point.

(That we’re created a function named addParty(…) is something a court, or arbitrator, might take as evidence of intent, but within our code it only relates to the output of the done() call.)

If our auction contract is to benefit from this functionality, it will need to implement addParty(…). So we could write…

contract MinimalAuction is MinimalContract, Doneable {

  MinimalAuction(String offering) public { return; }

  says(String something) public override {
    addParty(msg.origin);
    parent.says(something);
  }

}

And we can continue like this until we have eBay.

My main point is that every area of commerce starts as a conversation, whether this is an exchange of letters, Yahoo Chat, or phone call. We develop conventions, codify them, then automate them. We put in rails. Smart Contracts as the crypto-world defines them are very poor human contracts, they’re excellent and flexible rails. Our isDone() is a rail. So would bid(…) and startAuction(…) if we wrote them.

A court will try to read smart contract code, or rather find independent experts to, but smart contracts, or dumb scripts which is more accurate, are like vending machines. Sure if I tilt the machine, I’m a thief, but if two chocolate bars come out instead of one… A promotional give-away maybe? How am I to know? :-) This is probably undesirable for a pharmaceuticals supply agreement!

Rails what our society normally runs on. I don’t sign anything when I walk up to a vending machine. The terms on my credit card are fixed into Visa’s (oversimplification, I know) servers. I can’t waive my chargeback rights even if I didn’t want them. Sometimes those rails don’t align with out intentions. No-one can pay directly into a house purchase; they pay an agent and hope they’re honest. And that the email really was from them.

When Lehmans struggled, it was not able to take money from its creditor’s accounts simply because it was due. So when it ran into problems several of its counter-parties decided to delay their payments. Partly in fear they might in turn not be able to collect other payments from Lehmans. Maybe because they thought renegotiating with the receivers might save them money. Whatever legal rights Lehmans might have had to collect, those rights were not wired into the interbank payment system. (It does seem likely now that Lehmans was solvent, but wasn’t even aware of this itself.)

Conversation -> Permanent Record -> Standardised Contracts -> Rails

In the paper world, we’ve gone from hand written letters of instruction to commercial agents, to 4 by 2 inch trade slips with four blank spaces dropped into boxes for a clerk. That trade slip might be backed by shelves of commercial rules, but in its time and place it is three scribbles and a signature with a pen.

Within a society this has the added benefit that parties can refer to an external body of fair rules, rather than trying to specify every outcome. They can simply refer to an industry code, ex. the ISDA Master Agreement, which governs the global financial derivatives market. The author doubts more than a few percent of participants have read it in its entirety, and yet it works. Globally, most derivatives are now moving to so-called Central Clearing Counter-parties, or to platforms like SwapsWire. We start by compressing conversations to save effort communicating, and end by compressing the actual execution of an agreement to improve reliability by removing the need and risk of the contracting parties acting at all.

So the points I’d like to make are two :-

  1. Whatever code happens to be intended as a binding contract is never going to be a useful unless it carries with it the whole body of law and business practice. I think that will mean sub-classing a chat log. And may more things the author is not qualified to write about, e.x. UKLaw or isProperyTitle(…). I will take a long time for this eco-system to build up, but it will. (See Mattereum for a first draft.)

  2. Every year 12,000 Americans "die" because Social Security numbers do not have a check digit! We already have a serious societal problem with human realities not lining up with the code in our machines. Let’s not make things any worse :)