How to make sure a Smart Contract is also a Contract
Published January 13th, 2016 edit replace rm!
As I discussed in my previous article From Contract to Smart Contract a Smart Contract is not necessarily a contract in it self.
If the Smart Contract is designed to be run 100% autonomously you don’t necessarily need what a normal legal contract offers you. But very few things live entirely on the block chain for now.
What is a contract?
I am not lawyer myself so take what I write with a grain of salt.
Contracts are a really old way of doing business. It is essentially an agreement for 2 or more parties to do something in exchange for something.
The basic requirements for contracts are:
- 2 or more parties
- The contract is offered by one party
- The contract is accepted willingly by all remaining parties
- Each party has to do something and receives something in exchange
Traditionally acceptance is indicated by the ritual of a signature or a handshake. This is only a ritual and is not necessarily required. But some level of acceptance should be made and ideally recorded.
Why contracts?
Contracts were created by business for business. They ensure that commerce happens smoothly.
The basic idea is that all parties understand clearly what they need to do as part of a business transaction.
There is also an implied threat in any contract that I can go to a higher authority - judge, arbitrator, PayPal or what have you to force the other party to do their part of the contract if they don’t fulfill their part.
The brilliant thing about Smart Contracts is that they are theoretically self enforcing. There is no need for the higher authority. However this only works if every part of the contract functions on the blockchain.
Origins of contracts
It is a common misconception that contracts were created by governments. But that is not true. The traditional was created over thousands of years by commerce as an early kind of Open Source project. See Lex Mercatoria for more. Only recently have governments started to create rules governing contracts such as UCC in the US.
The basic rules for contracts are mostly based on traditional contract law and are valid in most parts of the world.
When do our Smart Contracts need to be real contracts
It is very easy to create an electronic currency or token using Ethereum smart contracts. It is more difficult to determine what the ownership of such a token means.
A currency exchange could issue a token for each currency supported. Without some sort of legal contract for what that token and some way of enforcing it out of the blockchain you open yourself up to rogue exchanges like we saw with MtGox.
If there is a real contract behind it at least there is some way of enforcing it through the courts.
Example of a better Escrow Smart Contract with acceptance
So my last example of an Escrow Smart Contract had some deficiencies. Most important right now is the lack of managing acceptance.
I will fix that in this new improved version:
contract EscrowContract {
address buyer;
address seller;
address agent;
// Each party has an entry here with the timestamp of their acceptance
uint[3] acceptances;
bool active;
function EscrowContract(address _agent, address _seller) {
// In this simple example, the person sending money is the buyer and
// sets up the initial contract
buyer = msg.sender;
agent = _agent;
seller = _seller;
active = false;
acceptances[0] = now; // As part of the creation of the contract the buyer accepts
}
// This only allows function if contract is active
modifier onlywhenactive { if (!active) throw; _ }
// This only allows agent to perform function
modifier onlyagent { if (msg.sender != agent) throw; _ }
// This only allows parties of the contract to perform function
modifier onlyparties {
if ((msg.sender != buyer) && (msg.sender != seller) && (msg.sender != agent))
throw; _
}
// Any party to the contract can accept the contract
function accept() onlyparties returns(bool) {
uint party_index;
// First find the index in the acceptances array
if (msg.sender == seller)
party_index = 1;
else if (msg.sender == agent)
party_index = 2;
if (acceptances[party_index] > 0)
throw;
else
acceptances[party_index] = now;
if (acceptances[0]>0 && acceptances[1]>0 && acceptances[2]>0)
active = true;
return active;
}
function release() onlywhenactive onlyagent {
suicide(seller); // Send all funds to seller
}
function cancel() onlyparties {
// Any party can cancel the contract before it is active
if (!active || (msg.sender == agent))
suicide(buyer); // Cancel escrow and return all funds to buyer
else
throw;
}
}
Source code for Better Escrow Smart Contract Updated with feedback from Sitaram Chamarty.
Don’t worry if you’re not a programmer, but if you are it should be fairly straightforward to understand.
I have added the concept of the contract being active as well as maintain the timestamps that each party accepts it.
Now the current flow of the successful execution of the contract is:
- Buyer creates Contract (Offer) with payment
- Seller accepts offer
- Agent accepts offer
- Now all parties have accepted Contract and it is active
- Buyer informs the Agent off the blockchain that he has received merchandise
- Agent releases funds to Seller
Anyone can cancel the contract before it becomes active and funds are released back to buyer.
Once the contract is active the only party able to release or cancel funds is the agent.
One important thing to remember about Ethereum is that each of these parties including the agent can be another smart contract.
What is missing?
We still have not defined the terms of the contract that determines what the Escrow is for. This still has to be done out of blockchain in an app or in email.
We also don’t have anyway of identifying each party. That is a more complex issue, that I will try to get to in future articles in this series.
I will cover a great way of integrating a human readable contract with a Smart Contract in the next article. Please subscribe, so you don’t miss the next one.