-
Notifications
You must be signed in to change notification settings - Fork 84
Smart contracts
The concept of “smart contracts” originated with Nick Szabo: Nick Szabo's smart contracts Also: E-Rights Also: Money example in E language
That being said, OT has its own, entirely different implementation…
In the Open-Transactions universe, a “smart contract” has these properties:
- A smart contract can be activated, after which point it takes on a “life of its own”, in the sense that it will process regularly over time according to its own internal terms and logic, until it expires or is deactivated. In this sense, it is like any other recurring OT transaction such as market trades and payment plans.
- Smart contracts are most distinguished by the fact that they can have scriptable clauses. (Normally on OT, a typical contract only contains data tags, and human-readable clauses. Only the smart contracts “can come to life” with their own custom-scripted clauses.)
- Smart contracts can have multiple parties, each with their own agents and asset accounts.
- Only a select few functions are made available from within the script code of a smart contract, and all funds transfers go through this tightly-controlled interface, with notices and receipts sent to all relevant parties.
- The script code is unable to manipulate any assets excepting those explicitly declared beforehand on the smart contract, and verified as valid property of a legitimate party to the contract. And when funds are moved, it’s to a contract-specific name, not an account ID. For example, you wouldn’t transfer funds from account pckjsdf9872345kj34kjhsf, but rather, by that account’s name as declared in the contract, such as
alice_petty_cash
orbobs_acct
. (This means that it’s impossible to even reference any account other than those declared on the smart contract by name, since the functions provided can only operate based on those names.) - Not only can the smart contract move_funds() between these declared accounts, as its script logic dictates, but it can also stash_funds() directly inside the contract itself! For example, during an escrow, funds might be stashed inside the smart contract for 14 or 30 days, and then transferred to one party or another.
- Scripted clauses can also be configured to trigger on certain events. For example, do you need a script to fire right when the smart contract first activates? No problem! Just attach it to the
OnActivate()
hook. Do you have a script that needs to fire every single day for a month? No problem, just put your logic on theOnProcess()
hook! (And set a 1-day sleep between processing… and code your script to deactivate itself after 30 days.) You can even set multiple clauses to fire based on a single hook. For example, the main_bylaw might have a clause that’s set to trigger on the onActivate() hook… yet the secondary_bylaws might also have a clause that triggers on that same hook. Both clauses will execute on that hook, based on their order inside the smart contract itself. - You can also define variables in your smart contract, which persist through its entire lifetime. As the smart contract—including its internal state—continues to process over time, receipts will continue to drop into the relevant parties’ inboxes, showing the change in state, in those variables, over time (using exactly the same inboxes and receipts that OT uses already for transfers, for, market trades and payment plans… using exactly the same destruction of account history based core system, with signed receipts, finalReceipts, etc.)
- A signed copy of the original smart contract shows it as it was, when the parties first signed and activated it. Additionally, a server-signed, updated version of the contract comes with each receipt, showing the latest state. The server keeps all of these receipts in each relevant user’s inbox, as proof of the transactions and current state, until any given user signs off on the latest balance, which enables the server to then discard any old receipts out of his inbox. This is the exact same process as with all of the other financial instruments on OT.
- Once the contract expires (or is deactivated) then a finalReceipt is dropped into all relevant inboxes, after which no other receipts are possible for that smart contract. (As with the other recurring instruments, such as market offers and payment plans, users must close all receipts related to that contract, in order to close the finalReceipt. And no new receipts can come in for that transaction, once the finalReceipt has dropped.)
- Smart contract variables can be defined as “Constant” (value cannot change), “Persistent” (value can change, and will persist between script runs), and “Important” (value is persistent, AND any changes in the value will result in server notices being sent to the parties.)
- Let’s say a party needs to DIRECTLY trigger one of the clauses on the contract. (Instead of waiting around for it to trigger automatically based on some rule.) For example, perhaps an escrow user wishes to execute a clause in order to DISPUTE THE OUTCOME, or perhaps an arbitrator wishes to activate a clause in order to RENDER A JUDGMENT. OT’s smart contracts can do precisely these sorts of things, limited only by your imagination (and my pre-alpha code.) See the new API call:
OT_API_triggerClause
as well as the command-line option: opentxs trigger
These sorts of actions are, of course, subject to the logic in the contract itself. Perhaps the contract disallows Alice from executing certain clauses, or disallows Bob from moving more than 100 grams of gold. YOU decide. - Once voting groups are someday eventually added to OT, they will also be able to act as parties to agreements, and they will be able to take a vote in order to change their own bylaws! (Each smart contract already contains a list of bylaws, and each bylaw contains a list of scripted clauses and variables.) This will enable corporations. You can read about it more here: Future Direction
- You can also define CALLBACK SCRIPTS: These scripts fire automatically whenever OT needs an answer to some important question. Such as:
- “Is Alice allowed to cancel this agreement?” (Your script returns true or false.)
- “Is Bob allowed to trigger the DISPUTE clause?” (Your script returns true or false.)
As long as you provide the script, YOUR logic can be there 24 hours a day, making decisions for your best interests, while you’re off sipping cocktails and getting arrested at Occupy Protests.
A SIMPLE EXAMPLE - “Two-way trade”
Here’s a sample “OnActivate()” clause from my very first (test) smartcontract, which implements a two-way-trade (where Bob doesn’t get his clams unless Alice also gets her gold at the same time).
Notice the entire functionality, while bare-bones, is implemented in this single OnActivate() clause, with deactivate_contract() being called at the bottom.
// These are the amounts being paid by both parties.
// These amounts are for different currency types...
// ...Alice is trading 140 XYZs for Bob's 100 ABCs.
//
var alice_pays = "140"
var bob_pays = "100"
// Stash is a function that only works inside smart contracts. It takes
// the funds from the denoted account and stashes them INSIDE the smart
// contract (in the below example, into "first_stash" and "second_stash".)
//
// Only after BOTH stashes are successful, do we then unstash the funds
// to the OTHER user. i.e. Alice gets Bob's funds and Bob gets Alice's funds.
//
// NOTICE: You cannot use actual account IDs while inside a scripted clause.
// Instead, you can only refer to accounts by NAME (the name that was chosen
// for that account when the smart contract was written.) OT will resolve the
// name to the appropriate ID, based on the contents of the signed contract.
// This way, it would be useless to come up with some sneaky trick for slipping
// unexpected IDs into a running script's code or data, -- since it doesn't operate
// based on the IDs! (Of course, the normal client API operates based on IDs, but
// the smart contracts must operate from within their "sandbox" on the server.)
//
var bStAli = stash_funds(alice_first_acct, "first_stash", alice_pays)
var bStBob = stash_funds(bob_second_acct, "second_stash", bob_pays)
if (!bStAli || !bStBob) // FAILURE
{
// Somehow, one of the stashes failed (technically impossible,
// unless one or both of them didn't have the necessary funds...)
// Therefore, we give the parties their money back.
//
// IF Alice's stash was successful, then unstash back to her.
if (bStAli)
{
var b01 = unstash_funds(alice_first_acct,"first_stash",alice_pays)
}
if (bStBob) // IF Bob's stash was successful, then unstash back to him.
{
var b02 = unstash_funds(bob_second_acct,"second_stash",bob_pays)
}
}
else // Success stashing funds from both parties!
{
// Now let's unstash across, to the receiving parties...
var b11 = unstash_funds(bob_first_acct, "first_stash", alice_pays)
var b12 = unstash_funds(alice_second_acct,"second_stash", bob_pays)
// bSuccess is a variable in the smart contract itself. That is, it's declared in the XML
// of the contract, not inside this script proper--yet it's still accessible from in here.
bSuccess = true
}
// Our work is done, so let's shut down the contract.
// Receipts were already sent to the parties' inboxes when
// the money was moved. Now this deactivate will cause a finalReceipt
// to go to all the parties.
//
deactivate_contract()
Of course, that isn’t the entire smart contract, but just the onActivate() clause. Here’s what the entire smart contract might look like:
(Subject to change, of course. This is very new code.)
-----BEGIN SIGNED SMARTCONTRACT-----
Hash: SAMY
<smartContract
version="1.0"
serverID="tmHvLZxb13hW6OyH1oHKTmKd7fTMRsUfzqPE6KCwSjl"
activatorUserID=""
activatorAcctID=""
lastSenderUserID=""
lastSenderAcctID=""
lastRecipientUserID=""
lastRecipientAcctID=""
transactionNum="0"
creationDate="1323862266"
validFrom="1323862228"
validTo="0"
nextProcessDate="0" >
<scriptableContract>
<party name="party_alice"
ownerType="nym"
ownerID="T1Q3wZWgeTUoaUvn9m1lzIK5tn5wITlzxzrGNI8qtaV"
openingTransNo="37"
signedCopyProvided="true"
authorizingAgent="agent_alice"
numAgents="1"
numAccounts="2" >
<agent name="agent_alice"
doesAgentRepresentHimself="true"
isAgentAnIndividual="true"
nymID="T1Q3wZWgeTUoaUvn9m1lzIK5tn5wITlzxzrGNI8qtaV"
roleID=""
groupName="" />
<assetAccount name="alice_first_acct"
acctID="2K3LoD1UxsJLO0FAfng0fgqnxnXScO8rM2eO5tdDTOE"
assetTypeID="mNS1ODAXQoSXpWJfC5awE9zAXCm9aVfiE0WQGsIOw4B"
agentName="agent_alice"
closingTransNo="36" />
<assetAccount name="alice_second_acct"
acctID="A6CcGwNiTtEPQnv7HLUcmf0QFaCGy862pb1SJ3zVqIU"
assetTypeID="SjSYAUzN1RLjGre0kqDJynFos1MRYzrxOOenHY0Lpjd"
agentName="agent_alice"
closingTransNo="35" />
<mySignedCopy>
eJytVsuyokgQ3fsDszXcGt2CbzvmdgQiKj4ABZ+bGyWUUAoUVvEQvmM+eArw9rV7
bvREd7Qb4VRm1snMU1RW/vnrU/4bShNZqeryRJFGVX0prA1RVYy1IBrFcmUKqPOl
qgvLQ6XyN/UACUXshwSYYaUaQ0IR9l9q/GeuVqlSSBgij15qoTeNF8f7iW85u66a
Tnk8nRve3OqdjeWabs7ZTZO6czHRLy7zY7FQDEJMNrR0f8YE0wwfmAtoqEPfgs+G
7+APlmtoogBBP/zB+Bv+ZM/y8Wm+JfaVyHup5dmYBIIcGIEQsgxbzVa/22y2e2wp
Bi6yxgR773iz/4YbuPT34T3UCDYhpWUIrlb9mtfQJCgIwcmFb4XM0YAVNq36wGOG
xfMri2VCFgcnPiRGGrAFP/XegJy4wa9ayXFnQ2ODwSb2Bx7vZvK8E/qdRDbc7J6R
iSL3byHY5m4B9JFvG3mqCuPYyjOhyPahJeIgZVRjZEHrpXYGLs03BlHoYIIy5iTY
rF4vNZD/fSPmR16BU1aFx6tp4qgAmmWuhcMjq++dLQxp4b2GAYGUPUyRR6F7ZuIh
UW6BynXBl30LMWoRcL+tsUL8egEIduGj3zbBUaAUtGrVRsGUUhg++L8Rzqm+nhGh
jDbTSqHKUjLNeWuBR/zmTmcLlRsLZ9/mzvbNv/t73VT7ZNmEaie0RoYq5V557LyD
uaun6Lw6EvYrrO+D3ewsdkAiDTJhL3oDsD0jidutJlRWk/Ywd81LoHxQP9PF9Ltu
dv8vEQpN7Fs/ZiJ0RXOSKMgIJW3lx73pYmN6Z241BuIkZcIOTrw+a2Xbm7z5MRP9
oh+ETabw68VlQiB3vY1mqT/GlF+uDxm5qyr0pwduEVysX8qk88ikUZyDjw/HCZ9+
ejQ+0Dv3m3Ivt/otsZeuf0Tqv6FftvvH6v1jkvyge9zP+Xwswj+mrJ8QelfTKXVB
8uDkAeS/FgAtu7oFBOXf5vc+iy6I6NP7FOPr0ypw3RMwc4QrLhjfjhihl5rpAFTq
In6EfCuDHpn5pVDeFxF8V2BYKPmEcXkp5kZM7/kdS0OW4iMRs+DzprPymoSvJVr7
WoGz++B64aMkE5YOMCPV3l/SFRAbw7WldlfT7mwROShbiMJ0PLquumtrdE0W/Hhu
upO9AOUKlrddXjPhEPhnt6c18ZADu06Pc3SRWn3UPHXCJVu73Ui0CmRe1q04yzyp
PVOO3HwW1StEdzUqHAYm8JS2vr3eDo7SXMueRfdyHaKbqpvta7a1dkn/kMrHdCi3
juJtl9j75N5ZuLByOE5WzjlYS5ebrOuhODH7Ao4Vb97tDOqZ0Wg0LkZfmneMVYra
g8wemGNbCx1KtHAj7QdGhQ/Gis0ZaHAZp5G2uCY7uJbqm/u2GfSuXtZtL2dHUp8S
W9BT6yAiEiTjkyxp4whh7aCZleOtr5B01OgNnRvoZM0wOHhJiFVJaK+WTkeTYh7t
9u2hakM9Gc6cwwjU1b7c0r3lIp2H18qUh3yvqZ5GS7U+rs+UULnNZ8c232zJy+vw
fBtlVtzn6QvTZdm5vLMOU9ajrybB/utbcwtV50b/7fdD24WCi6ePpwtQHsQFE9JD
ZTRkc12tWsDfRpPGk10Z7XneY8jzxPg8Khbzo2Bs1lI5NG7LwfBLVWUf4arxPl3R
Kve516mI2POYor9UnTAMvjQaNgqd6PTZxF5jDF0XJ8wlhi4kjTzAp+cAjQRdUYVF
EIYRkba9OE41p5mQlZUe45AY/pQL5w3tgi1qKzJRHGl9H9rOAS1321nUbp2ycO91
vIrk2vz67nKX7hpFbdFZBI7JT6d+hnbrqDWI/RPPdQBFCn/H4nW+OZJshMlyQEBT
O5gdULG1hXZxfFc8LMYc6nnb7C7N7Fl0ObiSc2jIe+pOHCEcuTSqL+LrS1k8SRn9
tHT/Ap89zUk=
</mySignedCopy>
</party>
<party name="party_bob"
ownerType="nym"
ownerID="1mxwHcQvxSgqWqy2e28ZREeuVVfgs0kxE41FN10TnS3"
openingTransNo="67"
signedCopyProvided="true"
authorizingAgent="agent_bob"
numAgents="1"
numAccounts="2" >
<agent name="agent_bob"
doesAgentRepresentHimself="true"
isAgentAnIndividual="true"
nymID="1mxwHcQvxSgqWqy2e28ZREeuVVfgs0kxE41FN10TnS3"
roleID=""
groupName="" />
<assetAccount name="bob_first_acct"
acctID="w06QIURsSDV7sdWWvyPSxRaiv4T2MUQbJyWmIKxSmuL"
assetTypeID="mNS1ODAXQoSXpWJfC5awE9zAXCm9aVfiE0WQGsIOw4B"
agentName="agent_bob"
closingTransNo="66" />
<assetAccount name="bob_second_acct"
acctID="vuXpQt8h6CRGcz6G5zMOXqQeIRpsOq05VLuJ5IAFS5R"
assetTypeID="SjSYAUzN1RLjGre0kqDJynFos1MRYzrxOOenHY0Lpjd"
agentName="agent_bob"
closingTransNo="65" />
<mySignedCopy>
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
</mySignedCopy>
</party>
<bylaw name="main_bylaws"
numVariables="1"
numClauses="1"
numHooks="1"
numCallbacks="0"
language="chai" >
<variable name="bSuccess"
value="false"
type="bool"
access="persistent" />
<clause name="activate_clause">
eJx9kj1uwzAMhacuOgXjyQaC/BRdO6QH6JLuhizLCAHFDkQ6RdDkwL1FKclGXAeI
oIV61PceBanfl7P2oB0aW570hSCsd8i2b5tMBanqqruQpI1ISdvzzmE4JNZ0KJu+
rSlPsAY9camN4SVkqYhN2RImdsXI+eiqOSc4kzVdWw8YyIZyBI3ZCqWwgXwx5Lle
YZGQhfpREjqISStCGc8AovNmK659+zT///jT8EK5TQyi49zg9cFgPthsrPtUEX9T
1pFNg0Ti9jFyuPLkwWeRE+UxV2p7kmz64MJZr+HrgASydYCirpwFbIEPFuioPYPc
Zq8NryD/7Bhqa5z2tpYmwtoOEA4QMh5PEv1iWX4BOgeSwBJhYDa+O8I3SmMLyKtk
H1e172ObDMO+F+JNtNqKJZ4123IMkBfqDzdv81s=
</clause>
<hook name="cron_activate"
clause="activate_clause" />
</bylaw>
</scriptableContract>
<accountList type="stash" count="0" >
</accountList>
</smartContract>
-----BEGIN SMARTCONTRACT SIGNATURE-----
Version: Open Transactions 0.75
Comment: http://github.com/FellowTraveler/Open-Transactions/wiki
CoABiNsgHCRFOVBFgU80CqPUnMYpb+IMLmBWMroLSVEkHBuUojcIcAGXMBqKxy96
tjBD0GLb9TINu9ehVKGyyqcNKcxb5QlQQbKpkFiEELAB2mhtJsTQlsPZaa6e+KWg
0OhmgwbNVHohbKUwyJAgrPN8FHlguw2uW+dJ/3gX5huctLA=
-----END SMARTCONTRACT SIGNATURE-----
Many have asked about my choice of script interpreter. FYI, I’m currently using ChaiScript, which was chosen for being cross-platform, clean, easy-to-use, and integrates well with C++.
However, the design of OT is very modular, such that it is very easy to replace the script language. OT is coded to the abstract interface OTScript, and the actual Chai integration is done in a subclass called OTScriptChai. All you have to do, to replace the script language, is just make your own subclass of OTScript. To do that, copy the OTScriptChai class, and make your own version such as OTScriptLua or OTAngelScript or OTScriptE, or whatever floats your boat.
In fact, each Bylaw stores the name of its script language, so you could technically have 3 or 4 completely different script interpreters running against the same smart contract! (I do NOT recommend this.)
Bottom line: the point of OT is to be able to easily swap in/out different storage, different network transport, and yes, a different script interpreter. This way OT can best adjust to everyone’s needs, and focus more purely on its financial crypto aspects, abstracting all else away for others to worry about. The best choice for a reference implementation such as OT is something simple, clean and cross-platform (like chaiscript.)
Here are those links again:
Nick Szabo's smart contracts Also: E-Rights Also: Money example in E language