squid-contracts.md 8.79 KB
Newer Older
Bernd Paysan's avatar
Bernd Paysan committed
1 2 3 4 5 6 7 8 9
[up](squid.md) [back](squid-fed.md) [next](squid-literature.md)

# Dumb Contracts

To keep things simple, I chose to not have smart contracts; rather the
opposite: dumb contracts.  The main reason is that people don't understand
complicated contracts in legalese, and much less so in Forth or JavaScript.
For most financial transactions, you don't need a smart contract, anyways.
The basics of a contract is that you offer something and want something else
Bernd Paysan's avatar
Bernd Paysan committed
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
in exchange.  We assume for simplicity that all things offered or asked for
are recorded in the same BlockChain.

## Assets and Obligations

To allow arbitrary real world goods to be represented by a token on the
BlockChain, we allow people to create those as future assets.  When the future
expires, the creator has an obliation to deliver that asset to the current
owner; it will be removed from the BlockChain afterwards.  Verification of
actual delivery of that asset may be up to some notary or other arbiter,
usually complaint-based (i.e. the arbiter is only there to resolve conflicts;
conflicts should be public and lower the score of an asset creator).  Future
assets have the same form as credits, they create two tokens, an asset and an
obligation.  Both can be traded, and when the obligation is fulfilled, asset
and obligation meet each other again, and are annihilated.

Legal tenders inserted into the BlockChain are handled that way, too: A bank
issues a pair of assets and obligations, the obligation stays at the bank, the
asset is sold for that legal tender to the purchaser (the legal tender is
transmitted by normal bank transfer).  The purchaser can trade that legal
tender with others, and if you want to leave the BlockChain, you sell it (for
normal bank transfer) to one of those banks that have obligations in that
currency; they are now free to annihilate those obligations, as they have
fulfilled them.

Mortgages and loans with interest rates are too complicated for a dumb
contract, which is a good thing.

38 39 40 41
## State of an Asset Account

An asset account contains the following state:

Bernd Paysan's avatar
Bernd Paysan committed
42 43 44
* A hash of the contract that last changed the state
* A table of assets and their values (how many)
* A timestamped signature of all that in canonical form
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

An asset account is addressed by its pubkey.  Contracts are addressed by their

A wallet has a securely created random number as seed to create a sequence of
secret keys and their corresponding pubkeys.

The merkle tree to calculate the hashes of a block starts with the signatures
only; the R and S values of the ed25519 signature are xored to compress one
signature to a 256 bit value (enough for the security guarantee of the

A chain also contains metadata (e.g. asset types, permission rules,
granularities of assets), metadata is stored in a DVCS repository, and the
current revision's hash represents that metadata.  Updates can only be checked
in by consensus, i.e. if a new version is available, signers who accept the
new version of the metadata first try to sign and check in the new version,
and if that doesn't reach a consensus, try again with the old version.

Bernd Paysan's avatar
Bernd Paysan committed
## What's a Dumb Contract?
Bernd Paysan's avatar
Bernd Paysan committed
65 66

A dumb contract represents the state transition of the active data in the
Bernd Paysan's avatar
Bernd Paysan committed
67 68
BlockChain to fulfill that contract.  A contract is valid if it preserves all
the transacted goods (allows creation and annihilation of assets+obligations,
69 70
all other values have to be preserved).  Obligations are just another name for
an asset with a negative value.
Bernd Paysan's avatar
Bernd Paysan committed
71 72 73 74 75 76

Contracts are stored as shortened forms of the state transitions, only those
values that change are recorded in a form that is by design valid, and only
needs checking of the sources.  The new states need a valid signature of the
respective owner.  To execute a contract, all sources are fetched, the
transitions (assets moved from one account to the other) are performed, and
the signatures (destinations) of the new states are checked.
Bernd Paysan's avatar
Bernd Paysan committed
78 79

Contracts can be offered in open form, where parts of the transaction are left
80 81 82 83
open to be filled in, e.g. source or destination addresses.  If the open form
contains a destination, and the relevant information to update it is completed
by then, it can be appended by further informations without needing a
signature of the contract again.
Bernd Paysan's avatar
Bernd Paysan committed

85 86 87
To formalize a contract, Sources are written as S (timestamp), destinations as
D (new timestamp + signature), obligations as O, assets as A, delta amounts as
+ or - (give or take), and numbers to select the correct source if unclear
88 89 90
(the last source is always the active one).  B is a shortcut for balancing an
asset, and can be used instead of the last value on that asset type.  Also,
previously used assets can be selected by number.
Bernd Paysan's avatar
Bernd Paysan committed
91 92 93 94

All sources specify the date of the source state, so that a contract can be
performed only once — the destination date must be later than the source date.

Bernd Paysan's avatar
Bernd Paysan committed
* Claimed money cheque (anybody who has the transaction can claim the money;
  requires trust to the ledger node that accepts the cheque): SA-DSA+D
Bernd Paysan's avatar
Bernd Paysan committed
97 98 99 100 101
* Money transfer (only the designated recipient can claim the money): SA-SA+D1D
* Creation of asset and obligation: SA+OBD
* Two party purchase: SA¹+A²-S¹B²B1D2D
* Two party purchase delivery: SA-SOB1D2D (annihilates the asset)
* Bid/Ask in an exchange: SA¹+A²-D, finalized by SA¹+A²-DS¹B²BD. Note that
102 103 104 105 106 107
  bids/asks in an exchange can be more complicated when they are only partly
  fulfilled; the splitting requires action by the bidder; and also note that
  this kind of bid requires, like the cheque, trust in the ledger node; but
  less than: The ledger node can only buy for the same price, not steal the
  Better finalize the contract with the other side.
Bernd Paysan's avatar
Bernd Paysan committed
* Auction offer: SA¹-, auction bid: SA¹-S¹BA²-D, auction conclusion:
  SA¹-S¹BA²-D1²BD. Auction offers are signed with an end-of-auction
110 111 112 113
  beginning to indicate the timeout, and the offering party can select the
  best match, allowing other algorithms as maximum price, too, or other
  timeout algorithms than the fixed deadline; e.g. 15 minutes after last bid
  or so.
Bernd Paysan's avatar
Bernd Paysan committed
114 115 116 117 118 119 120 121 122 123 124 125 126

The evaluation of a dumb contract is rather easy: All sources and destinations
must balance (i.e. the sums of all sources with their respective units must be
equal to the sums of all sinks with their units) and all destinations must
have a signature for their state.  The contract must have signatures of all
destinations inside, but the signature is allowed to cover only part of the
contract.  As and Os can be created in pairs or annihilated in pairs,
permission who is allowed to create depend on the type of asset and obligation
(everybody is allowed to annihilate).

Sources are seen as selector (a source is a pk+timestamp), assets select the
asset value in the source, values operate on that asset.  Destinations are
signatures and refer to the corresponding source by number of occurance — the
127 128 129 130
sources are never reordered.  Sources are written as pk+timestamp, but hashed
in as their signature, so you can only verify the destination signature if you
actually have checked for the source state in the corresponding ledger.

131 132 133 134 135 136 137 138 139
## Mixer

Note that there can be an arbitrary amount of participants in one contract, so
it is possible to merge contracts with the consent of all participants.  If
you want to anonymize your account, you need to distribute the value into
difficult to track coins (e.g. powers of two), and to do so without being
tracked, many other people have to do the same thing, and do it in the same
big merged contract.

140 141
## Size of a transaction

Bernd Paysan's avatar
Bernd Paysan committed
* Opcodes are one byte (there aren't that many); literals are bytewise encoded
143 144
  and strings have a length preceeding the raw data — see
Bernd Paysan's avatar
Bernd Paysan committed
145 146
* Sources are 8+32=40 bytes strings
* Assets are an integer (index into the set of assets), an optional describing
  string (not needed for a currency)
Bernd Paysan's avatar
Bernd Paysan committed
* Values are 64 bit integers.  For a legal tender, the scale is in cents, for
149 150 151
  deflationary coins the scale can be considerably larger.  Sums are always
  kept in 128 bits, so for really large transactions, you can use double
  values (two 64 bit integers).
Bernd Paysan's avatar
Bernd Paysan committed
* Destinations are signatures with timestamp and expiration, i.e. 80 bytes
153 154 155 156

A minimal transaction is somewhat less than 300 bytes, and that's already
non-emtpy to non-empty account.
Bernd Paysan's avatar
Bernd Paysan committed

158 159 160 161 162 163
## Descriptive Assets

Monetary assets are just units of a currency; interchangeable, summable, and
it is irrelevant who's obligation will be used to fulfill the contract.

Real world assets may need a description.  The description however reveals a
164 165 166 167 168
lot about the transaction, and therefore must be encrypted.  Real-world assets
have two-party transfers (you can't split real world assets), so a DHE between
the sender and receiver vault key is sufficient.  The DHE is mixed with an IV
generated from the contract so far, and the description string has a 128 bit
HMAC to check that the decryption was likely correct.

Bernd Paysan's avatar
Bernd Paysan committed
[up](squid.md) [back](squid-fed.md) [next](squid-literature.md)