IN THIS ISSUE:
-- The magic of SMART CONTRACTS...
-- Scriptable clauses
-- Stashed funds
-- Hooks
-- RUN->CLAUSE->NOW!
-- Callbacks
-- Simple example: "Two-Way Trade"
-- Usage Credits
(for server operators to earn transaction fees)
-- #opentransactions on irc.freenode.net
-- New permissions switches (added to config file!)
-- OT Test Servers Are Popping Up...
-- #! /usr/local/bin/ot --script
Heya... it's me again: your old buddy FellowTraveler! Slaving away for your
financial freedom, as usual, while you surf the net like you have all
the time in the world.
Personally, I've been losing sleep. I was up ALL LAST NIGHT, working on
my latest release of OPEN TRANSACTIONS...
...VERSION 0.75 **** SMART CONTRACTS **** release!
Binary downloads:
https://github.com/FellowTraveler/Open-Transactions/downloadsSource code:
https://github.com/FellowTraveler/Open-TransactionsWiki, videos, radio interview:
https://github.com/FellowTraveler/Open-Transactions/wiki----------------------------------------
BACKGROUND
The concept of smart contracts originated with Nick Szabo, and you can
read about the basic concepts from the man himself, right here:
http://www.erights.org/smart-contracts/index.htmlAnd here:
http://www.erights.org/elib/capability/ode/ode-capabilities.html#simple-money...Man I gotta tell you what, looking at this stuff, I'm really blown
away by what Szabo was able to accomplish on a conceptual and technical
level. The potential for this sort of technology is just mind-boggling!
----------------------------------------
I'm not using Szabo's system -- My goal with Smart Contracts on OT was
to build scripting directly into OT's existing Ricardian-style
contracts, AND to fit scripting into OT's existing system of signed
receipts and destruction of account history, AND to fit it all into the
existing system of recurring transactions on OT! (I succeeded.)
So... IN A NUTSHELL?
Imagine that an ingrate is dissatisfied with the financial instruments that
OT already offers, such as cheques, markets, cash, etc.
He wants more: to design his OWN financial instrument, such as an ESCROW
agreement... with his OWN logic...
===> On OT, Smart Contracts have SCRIPTABLE CLAUSES, so YOU can design
the logic for how your financial instrument will operate! Then parties
can sign onto the agreement and activate it to be processed
automatically according to its terms.
===> This is FAR beyond the client-side scripting of my previous
announcement (where client side scripts programatically access the OT
client API.) These smart contracts run on the server side!
===> OT is fast becoming a real PLATFORM
----------------------------------------
Let's get down to BRASS TACKS...
--- Once the parties sign and activate the smart contract, it takes on a
life of its own, processing regularly according to its internal logic,
until it expires or is deactivated.
--- While active, the smart contract is able to perform various
functions, such as verifying account balances, sleeping until a timer
has triggered, moving funds from one party's account to another, etc.
(Of course, the smart contract is only able to manipulate its own valid
parties and their accounts.)
--- The smart contract is even able to stash funds INSIDE THE CONTRACT
ITSELF, for safekeeping over time (for performing escrow, for example, a
smart contract could store the funds internally for 30 days, and then
pass them to one party or another.)
----------------------------------------
...And that's not all!
HOOK CLAUSES!
--- 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 the
"OnProcess()" hook! (And set a 1-day sleep between processing.)
--- You can also define CUSTOM 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 drop
into the relevant parties' inboxes, exactly the same as already happens
with market trades and payment plans.
RUN->CLAUSE->NOW!
--- Let's say a party needs to DIRECTLY trigger one of the clauses on
the contract. For example, perhaps an escrow user wishes to activate 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 these sorts of things, limited only by your
imagination, and my code. These sorts of actions are, of course, subject
to the logic in the contract. (Perhaps the contract disallows Alice from
executing certain clauses. YOU decide.)
----------------------------------------
...But wait, there's more!
CALLBACK CLAUSES!
--- 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.
(This smart contract deactivates nearly instantly after activating --
its job is already done
------------
var alice_pays = "140"
var bob_pays = "100"
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)
{
if (bStAli)
{
var b01 = unstash_funds(alice_first_acct,"first_stash",alice_pays)
}
if (bStBob)
{
var b02 = unstash_funds(bob_second_acct,"second_stash",bob_pays)
}
}
else
{
var b11 = unstash_funds(bob_first_acct, "first_stash", alice_pays)
var b12 = unstash_funds(alice_second_acct,"second_stash", bob_pays)
// This is a variable in the smart contract. (Not declared inside
// this script, yet still accessible from within it.)
bSuccess = true
}
deactivate_contract()
----------------------------------------
(NOTE: the above is not the entire smart contract, but merely the
OnActivate() clause for that contract.)
You might ask: Why all the stashing? Why not just move the funds
directly, without stashing them in between?
Answer: actually, I tested it both ways, debugging move_funds() first,
followed by stash_funds()
Next I'm going to write a bigger smartcontract: "Escrow for an offline
shipment, with disputing and arbitration clauses."
I'll send you a camtasia video once I have it running
----------------------------------------
You didn't think we were done, did you?
EVEN MORE new features:
--- OT now supports USAGE CREDITS (a config option), which means server
operators can now earn transaction FEES, even anonymously! (Functions
have been added to the API for getting and setting these credits.)
--- A complete set of PERMISSIONS have been added to the OT Server,
allowing you to switch on-or-off individual messages and transaction
types.
You want to disallow everything but cheques? Or disallow the issuing of
new asset types? Flip the switch.
--- Permissions were also added for server lock-down, and, for example,
locking out transactions only (leaving messages active.) Etc.
See ~/.ot/server.cfg for a complete list of options.
----------------------------------------
The first Open-Transactions TEST SERVERS are starting to pop up!
https://bitcointalksearch.org/topic/open-transactions-server-assetbondcommoditycryptocoindeedsharestock-exch-53329 Others are being discussed at #opentransactions on irc.freenode.net
----------------------------------------
Oh and FYI, the OT project donation address is:
1NtTPVVjDsUfDWybS4BwvHpG2pdS9RnYyQ
(Bitcoin, of course.)
My favorite donation is actually "volunteer programmers" -- plenty of
work to be done! Chrome plugin, Firefox plugin, OSX Native app, QT App,
Windows Native app, iPad, iOS, Android, I2P integration, TAHOE-LAFS
integration, Magneto (and other shopping cart) plugin, POS system,
crypto cards... the list goes on and on.
// ******************************************************************
// THAT'S ALL FOR NOW!
//
// I leave you with an example of the new OT Client-side Scripting...
// The entire OT Client API is now accessible through these OT scripts..
//
// Below is a sample script, where Bob is signing on as a party
// to a smart contract (just prior to activation on a server):
#! /usr/local/bin/ot --script
// This temp variable is used for storing a "running copy".
var strSmartContract = ""
OT_API_Output(0, "\n\n\nThis script assumes you have already used:
create_two_way_trade.ot and sign_trade_as_alice.ot \n")
OT_API_Output(0, "To continue, paste or pipe the smart contract that was
created, followed by ^D \n")
strSmartContract = OT_CLI_ReadUntilEOF()
// This is where we go from creating a generic , re-usable template,
// to actually INSTANTIATING the contract for SPECIFIC USERS in a
// specific situation!
// BY THIS POINT, if we're going to ACTIVATE this up-until-now purely
// THEORETICAL smart contract, using ACTUAL Nyms and Accounts, then we
// need to check and see if they have enough transaction numbers to
// move forward!
//
// -----------------------------------------------
var numCountNymBob = OT_API_GetNym_TransactionNumCount(Server, HisNym)
var numCountNeededBob =
OT_API_SmartContract_CountNumsNeeded(strSmartContract, "agent_bob")
var bSuccess = false;
// -----------------------------------------------
if (numCountNymBob >= numCountNeededBob)
{
OT_API_Output(0, "Paste Bob's FIRST asset ACCOUNT ID (Bob will RECEIVE
to this account, from Alice). Default:
[w06QIURsSDV7sdWWvyPSxRaiv4T2MUQbJyWmIKxSmuL]: ")
var strBobFirstAcctID = OT_CLI_ReadLine()
if (strBobFirstAcctID.size() < 2)
{
strBobFirstAcctID =
"w06QIURsSDV7sdWWvyPSxRaiv4T2MUQbJyWmIKxSmuL".to_string(); // Bob's
default "first account" (for testing, from the test data.)
}
OT_API_Output(0, "Confirming Bob's first account...\n")
// --------------------------------------------
var strSmart9 = OT_API_SmartContract_ConfirmAccount(strSmartContract,
HisNym, "party_bob", "bob_first_acct", "agent_bob", strBobFirstAcctID)
strSmartContract = strSmart9
// -----------------------------------------------
if (strSmartContract.size() > 0)
{
var strBobSecondAcctID = HisAcct
if (HisAcct.size() <= 0)
{
OT_API_Output(0, "Paste Bob's SECOND asset ACCOUNT ID: ")
strBobSecondAcctID = OT_CLI_ReadLine()
}
OT_API_Output(0, "Confirming Bob's second account...\n")
strSmart9 = OT_API_SmartContract_ConfirmAccount(strSmartContract,
HisNym, "party_bob", "bob_second_acct", "agent_bob", strBobSecondAcctID)
strSmartContract = strSmart9
// --------------------------------------------------
if (strSmartContract.size() > 0)
{
OT_API_Output(0, "Confirming Bob as a PARTY to the smart
contract...\n")
var strSmart10 =
OT_API_SmartContract_ConfirmParty(strSmartContract, "party_bob", HisNym)
strSmartContract = strSmart10
// --------------------------------
if (strSmartContract.size() > 0)
{
bSuccess = true
}
else
{
OT_API_Output(0, "\n\n** Sorry -- Bob's ConfirmParty call
FAILED!\n\n")
}
}
else
{
OT_API_Output(0, "\n\n** Sorry -- Bob's second ConfirmAcct call
FAILED!\n\n")
}
}
else
{
OT_API_Output(0, "\n\n** Sorry -- Bob's first ConfirmAcct call
FAILED!\n\n")
}
}
// --------------------------------------------------
if (!bSuccess)
{
// *********************************************
// Take the transaction numbers BACK!
OT_API_Output(0, "SMART CONTRACT: Since this script failed, I'm
clawing BACK all the transaction numbers now (that way my data stays
good.)\n")
OT_API_HarvestAllNumbers(Server, HisNym, strSmartContract);
}
// SUCCESS!!!
else
{
OT_API_Output(0, "Final smart contract, ready for activation:\n\n")
print(strSmartContract)
}