2016-07-12 16:52:52 +00:00
<!DOCTYPE html>
<!-- [if IE 8]><html class="no - js lt - ie9" lang="en" > <![endif] -->
<!-- [if gt IE 8]><! --> < html class = "no-js" lang = "en" > <!-- <![endif] -->
< head >
< meta charset = "utf-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > Writing a contract using clauses — R3 Corda latest documentation< / title >
< link rel = "stylesheet" href = "_static/css/custom.css" type = "text/css" / >
< link rel = "top" title = "R3 Corda latest documentation" href = "index.html" / >
< link rel = "next" title = "Writing a contract test" href = "tutorial-test-dsl.html" / >
< link rel = "prev" title = "Writing a contract" href = "tutorial-contract.html" / >
< script src = "_static/js/modernizr.min.js" > < / script >
< / head >
< body class = "wy-body-for-nav" role = "document" >
< div class = "wy-grid-for-nav" >
< nav data-toggle = "wy-nav-shift" class = "wy-nav-side" >
< div class = "wy-side-scroll" >
< div class = "wy-side-nav-search" >
< a href = "index.html" class = "icon icon-home" > R3 Corda
< / a >
< div class = "version" >
latest
< / div >
< div role = "search" >
< form id = "rtd-search-form" class = "wy-form" action = "search.html" method = "get" >
< input type = "text" name = "q" placeholder = "Search docs" / >
< input type = "hidden" name = "check_keywords" value = "yes" / >
< input type = "hidden" name = "area" value = "default" / >
< / form >
< / div >
< br >
< a href = "api/index.html" > API reference< / a >
< / div >
< div class = "wy-menu wy-menu-vertical" data-spy = "affix" role = "navigation" aria-label = "main navigation" >
< p class = "caption" > < span class = "caption-text" > Overview< / span > < / p >
< ul >
< li class = "toctree-l1" > < a class = "reference internal" href = "inthebox.html" > What’ s included?< / a > < / li >
< li class = "toctree-l1" > < a class = "reference internal" href = "getting-set-up.html" > Getting set up< / a > < / li >
< li class = "toctree-l1" > < a class = "reference internal" href = "data-model.html" > Data model< / a > < / li >
< li class = "toctree-l1" > < a class = "reference internal" href = "transaction-data-types.html" > Data types< / a > < / li >
< li class = "toctree-l1" > < a class = "reference internal" href = "consensus.html" > Consensus model< / a > < / li >
< li class = "toctree-l1" > < a class = "reference internal" href = "messaging.html" > Networking and messaging< / a > < / li >
2016-08-30 11:05:32 +00:00
< li class = "toctree-l1" > < a class = "reference internal" href = "creating-a-cordapp.html" > Creating a Cordapp< / a > < / li >
2016-07-12 16:52:52 +00:00
< li class = "toctree-l1" > < a class = "reference internal" href = "running-the-demos.html" > Running the demos< / a > < / li >
< li class = "toctree-l1" > < a class = "reference internal" href = "node-administration.html" > Node administration< / a > < / li >
2016-08-09 10:21:07 +00:00
< / ul >
< p class = "caption" > < span class = "caption-text" > Contracts< / span > < / p >
< ul >
2016-08-30 11:05:32 +00:00
< li class = "toctree-l1" > < a class = "reference internal" href = "contract-catalogue.html" > Contract catalogue< / a > < / li >
2016-08-09 10:21:07 +00:00
< li class = "toctree-l1" > < a class = "reference internal" href = "contract-irs.html" > Interest Rate Swaps< / a > < / li >
2016-07-12 16:52:52 +00:00
< / ul >
< p class = "caption" > < span class = "caption-text" > Tutorials< / span > < / p >
< ul class = "current" >
< li class = "toctree-l1" > < a class = "reference internal" href = "where-to-start.html" > Where to start< / a > < / li >
< li class = "toctree-l1" > < a class = "reference internal" href = "tutorial-contract.html" > Writing a contract< / a > < / li >
< li class = "toctree-l1 current" > < a class = "current reference internal" href = "#" > Writing a contract using clauses< / a > < ul >
< li class = "toctree-l2" > < a class = "reference internal" href = "#commercial-paper-class" > Commercial paper class< / a > < / li >
< li class = "toctree-l2" > < a class = "reference internal" href = "#clauses" > Clauses< / a > < / li >
< li class = "toctree-l2" > < a class = "reference internal" href = "#group-clause" > Group Clause< / a > < / li >
< li class = "toctree-l2" > < a class = "reference internal" href = "#summary" > Summary< / a > < / li >
2016-08-30 11:05:32 +00:00
< li class = "toctree-l2" > < a class = "reference internal" href = "#debugging" > Debugging< / a > < / li >
2016-07-12 16:52:52 +00:00
< / ul >
< / li >
< li class = "toctree-l1" > < a class = "reference internal" href = "tutorial-test-dsl.html" > Writing a contract test< / a > < / li >
< li class = "toctree-l1" > < a class = "reference internal" href = "protocol-state-machines.html" > Protocol state machines< / a > < / li >
< li class = "toctree-l1" > < a class = "reference internal" href = "oracles.html" > Writing oracle services< / a > < / li >
< li class = "toctree-l1" > < a class = "reference internal" href = "event-scheduling.html" > Event scheduling< / a > < / li >
< / ul >
< p class = "caption" > < span class = "caption-text" > Appendix< / span > < / p >
< ul >
< li class = "toctree-l1" > < a class = "reference internal" href = "release-process.html" > Release process< / a > < / li >
< li class = "toctree-l1" > < a class = "reference internal" href = "release-process.html#steps-to-cut-a-release" > Steps to cut a release< / a > < / li >
< li class = "toctree-l1" > < a class = "reference internal" href = "release-notes.html" > Release notes< / a > < / li >
< li class = "toctree-l1" > < a class = "reference internal" href = "visualiser.html" > Using the visualiser< / a > < / li >
< li class = "toctree-l1" > < a class = "reference internal" href = "codestyle.html" > Code style guide< / a > < / li >
< li class = "toctree-l1" > < a class = "reference internal" href = "building-the-docs.html" > Building the documentation< / a > < / li >
< / ul >
< / div >
< / div >
< / nav >
< section data-toggle = "wy-nav-shift" class = "wy-nav-content-wrap" >
< nav class = "wy-nav-top" role = "navigation" aria-label = "top navigation" >
< i data-toggle = "wy-nav-top" class = "fa fa-bars" > < / i >
< a href = "index.html" > R3 Corda< / a >
< / nav >
< div class = "wy-nav-content" >
< div class = "rst-content" >
< div role = "navigation" aria-label = "breadcrumbs navigation" >
< ul class = "wy-breadcrumbs" >
< li > < a href = "index.html" > Docs< / a > » < / li >
< li > Writing a contract using clauses< / li >
< li class = "wy-breadcrumbs-aside" >
< a href = "_sources/tutorial-contract-clauses.txt" rel = "nofollow" > View page source< / a >
< / li >
< / ul >
< hr / >
< / div >
< div role = "main" class = "document" itemscope = "itemscope" itemtype = "http://schema.org/Article" >
< div itemprop = "articleBody" >
< script type = "text/javascript" src = "_static/jquery.js" > < / script >
< script type = "text/javascript" src = "_static/codesets.js" > < / script > < div class = "section" id = "writing-a-contract-using-clauses" >
< h1 > Writing a contract using clauses< a class = "headerlink" href = "#writing-a-contract-using-clauses" title = "Permalink to this headline" > ¶< / a > < / h1 >
< p > This tutorial will take you through restructuring the commercial paper contract to use clauses. You should have
already completed “ < a class = "reference internal" href = "tutorial-contract.html" > < span class = "doc" > Writing a contract< / span > < / a > ” .< / p >
2016-08-30 11:05:32 +00:00
< p > Clauses are essentially micro-contracts which contain independent verification logic, and can be logically composed
together to form a contract. Clauses are designed to enable re-use of common logic, for example issuing state objects
is generally the same for all fungible contracts, so a common issuance clause can be inherited for each contract’ s
issue clause. This cuts down on scope for error, and improves consistency of behaviour. By splitting verification logic
into smaller chunks, they can also be readily tested in isolation.< / p >
< p > Clauses can be composed of subclauses, for example the < code class = "docutils literal" > < span class = "pre" > AllClause< / span > < / code > or < code class = "docutils literal" > < span class = "pre" > AnyClause< / span > < / code > clauses take list of clauses
that they delegate to. Clauses can also change the scope of states and commands being verified, for example grouping
together fungible state objects and running a clause against each distinct group.< / p >
< p > The commercial paper contract has a < code class = "docutils literal" > < span class = "pre" > Group< / span > < / code > outermost clause, which contains the < code class = "docutils literal" > < span class = "pre" > Issue< / span > < / code > , < code class = "docutils literal" > < span class = "pre" > Move< / span > < / code > and < code class = "docutils literal" > < span class = "pre" > Redeem< / span > < / code >
clauses. The result is a contract that looks something like this:< / p >
2016-07-12 16:52:52 +00:00
< blockquote >
< div > < ol class = "arabic" >
< li > < dl class = "first docutils" >
< dt > Group input and output states together, and then apply the following clauses on each group:< / dt >
< dd > < ol class = "first last loweralpha simple" >
2016-08-23 12:29:46 +00:00
< li > If an < code class = "docutils literal" > < span class = "pre" > Issue< / span > < / code > command is present, run appropriate tests and end processing this group.< / li >
< li > If a < code class = "docutils literal" > < span class = "pre" > Move< / span > < / code > command is present, run appropriate tests and end processing this group.< / li >
< li > If a < code class = "docutils literal" > < span class = "pre" > Redeem< / span > < / code > command is present, run appropriate tests and end processing this group.< / li >
2016-07-12 16:52:52 +00:00
< / ol >
< / dd >
< / dl >
< / li >
< / ol >
< / div > < / blockquote >
< div class = "section" id = "commercial-paper-class" >
< h2 > Commercial paper class< a class = "headerlink" href = "#commercial-paper-class" title = "Permalink to this headline" > ¶< / a > < / h2 >
2016-08-30 11:05:32 +00:00
< p > To use the clause verification logic, the contract needs to call the < code class = "docutils literal" > < span class = "pre" > verifyClause< / span > < / code > function, passing in the
transaction, a clause to verify, and a collection of commands the clauses are expected to handle all of. This list of
commands is important because < code class = "docutils literal" > < span class = "pre" > verifyClause< / span > < / code > checks that none of the commands are left unprocessed at the end, and
raises an error if they are. The top level clause would normally be a composite clause (such as < code class = "docutils literal" > < span class = "pre" > AnyComposition< / span > < / code > ,
< code class = "docutils literal" > < span class = "pre" > AllComposition< / span > < / code > , etc.) which contains further clauses. The following examples are trimmed to the modified class
definition and added elements, for brevity:< / p >
2016-07-12 16:52:52 +00:00
< div class = "codeset container" >
2016-08-23 12:29:46 +00:00
< div class = "highlight-kotlin" > < div class = "highlight" > < pre > < span > < / span > < span class = "k" > class< / span > < span class = "nc" > CommercialPaper< / span > < span class = "p" > :< / span > < span class = "n" > Contract< / span > < span class = "p" > {< / span >
< span class = "k" > override< / span > < span class = "k" > val< / span > < span class = "py" > legalContractReference< / span > < span class = "p" > :< / span > < span class = "n" > SecureHash< / span > < span class = "p" > =< / span > < span class = "n" > SecureHash< / span > < span class = "p" > .< / span > < span class = "n" > sha256< / span > < span class = "p" > (< / span > < span class = "s" > " https://en.wikipedia.org/wiki/Commercial_paper" < / span > < span class = "p" > )< / span >
2016-07-12 16:52:52 +00:00
2016-08-30 11:05:32 +00:00
< span class = "k" > override< / span > < span class = "k" > fun< / span > < span class = "nf" > verify< / span > < span class = "p" > (< / span > < span class = "n" > tx< / span > < span class = "p" > :< / span > < span class = "n" > TransactionForContract< / span > < span class = "p" > )< / span > < span class = "p" > =< / span > < span class = "n" > verifyClause< / span > < span class = "p" > (< / span > < span class = "n" > tx< / span > < span class = "p" > ,< / span > < span class = "n" > Clauses< / span > < span class = "p" > .< / span > < span class = "n" > Group< / span > < span class = "p" > (),< / span > < span class = "n" > tx< / span > < span class = "p" > .< / span > < span class = "n" > commands< / span > < span class = "p" > .< / span > < span class = "n" > select< / span > < span class = "p" > < < / span > < span class = "n" > Commands< / span > < span class = "p" > > ())< / span >
2016-07-12 16:52:52 +00:00
< / pre > < / div >
< / div >
< div class = "highlight-java" > < div class = "highlight" > < pre > < span > < / span > < span class = "kd" > public< / span > < span class = "kd" > class< / span > < span class = "nc" > CommercialPaper< / span > < span class = "kd" > implements< / span > < span class = "n" > Contract< / span > < span class = "o" > {< / span >
< span class = "nd" > @Override< / span >
< span class = "kd" > public< / span > < span class = "n" > SecureHash< / span > < span class = "nf" > getLegalContractReference< / span > < span class = "o" > ()< / span > < span class = "o" > {< / span >
< span class = "k" > return< / span > < span class = "n" > SecureHash< / span > < span class = "o" > .< / span > < span class = "na" > Companion< / span > < span class = "o" > .< / span > < span class = "na" > sha256< / span > < span class = "o" > (< / span > < span class = "s" > " https://en.wikipedia.org/wiki/Commercial_paper" < / span > < span class = "o" > );< / span >
< span class = "o" > }< / span >
2016-08-23 12:29:46 +00:00
< span class = "nd" > @Override< / span >
< span class = "kd" > public< / span > < span class = "kt" > void< / span > < span class = "nf" > verify< / span > < span class = "o" > (< / span > < span class = "nd" > @NotNull< / span > < span class = "n" > TransactionForContract< / span > < span class = "n" > tx< / span > < span class = "o" > )< / span > < span class = "kd" > throws< / span > < span class = "n" > IllegalArgumentException< / span > < span class = "o" > {< / span >
2016-08-30 11:05:32 +00:00
< span class = "n" > ClauseVerifier< / span > < span class = "o" > .< / span > < span class = "na" > verifyClause< / span > < span class = "o" > (< / span > < span class = "n" > tx< / span > < span class = "o" > ,< / span > < span class = "k" > new< / span > < span class = "n" > Clauses< / span > < span class = "o" > .< / span > < span class = "na" > Group< / span > < span class = "o" > (),< / span > < span class = "n" > extractCommands< / span > < span class = "o" > (< / span > < span class = "n" > tx< / span > < span class = "o" > ));< / span >
2016-08-23 12:29:46 +00:00
< span class = "o" > }< / span >
2016-07-12 16:52:52 +00:00
< / pre > < / div >
< / div >
< / div >
< / div >
< div class = "section" id = "clauses" >
< h2 > Clauses< a class = "headerlink" href = "#clauses" title = "Permalink to this headline" > ¶< / a > < / h2 >
< p > We’ ll tackle the inner clauses that contain the bulk of the verification logic, first, and the clause which handles
2016-08-30 11:05:32 +00:00
grouping of input/output states later. The clauses must implement the < code class = "docutils literal" > < span class = "pre" > Clause< / span > < / code > interface, which defines
the < code class = "docutils literal" > < span class = "pre" > verify< / span > < / code > function, and the < code class = "docutils literal" > < span class = "pre" > requiredCommands< / span > < / code > property used to determine the conditions under which a clause
is triggered. Normally clauses would extend < code class = "docutils literal" > < span class = "pre" > ConcreteClause< / span > < / code > which provides defaults suitable for a clause which
verifies transactions, rather than delegating to other clauses.< / p >
< p > The < code class = "docutils literal" > < span class = "pre" > verify< / span > < / code > function defined in the < code class = "docutils literal" > < span class = "pre" > Clause< / span > < / code > interface is similar to the conventional < code class = "docutils literal" > < span class = "pre" > Contract< / span > < / code > verification
function, although it adds new parameters and returns the set of commands which it has processed. Normally this returned
set is identical to the < code class = "docutils literal" > < span class = "pre" > requiredCommands< / span > < / code > used to trigger the clause, however in some cases the clause may process
further optional commands which it needs to report that it has handled.< / p >
< p > The < code class = "docutils literal" > < span class = "pre" > Move< / span > < / code > clause for the commercial paper contract is relatively simple, so we will start there:< / p >
2016-07-12 16:52:52 +00:00
< div class = "codeset container" >
2016-08-30 11:05:32 +00:00
< div class = "highlight-kotlin" > < div class = "highlight" > < pre > < span > < / span > < span class = "k" > class< / span > < span class = "nc" > Move< / span > < span class = "p" > :< / span > < span class = "n" > ConcreteClause< / span > < span class = "p" > < < / span > < span class = "n" > State< / span > < span class = "p" > ,< / span > < span class = "n" > Commands< / span > < span class = "p" > ,< / span > < span class = "n" > Issued< / span > < span class = "p" > < < / span > < span class = "n" > Terms< / span > < span class = "p" > > > ()< / span > < span class = "p" > {< / span >
2016-07-12 16:52:52 +00:00
< span class = "k" > override< / span > < span class = "k" > val< / span > < span class = "py" > requiredCommands< / span > < span class = "p" > :< / span > < span class = "n" > Set< / span > < span class = "p" > < < / span > < span class = "n" > Class< / span > < span class = "p" > < < / span > < span class = "k" > out< / span > < span class = "n" > CommandData< / span > < span class = "p" > > > < / span >
< span class = "k" > get< / span > < span class = "p" > ()< / span > < span class = "p" > =< / span > < span class = "n" > setOf< / span > < span class = "p" > (< / span > < span class = "n" > Commands< / span > < span class = "p" > .< / span > < span class = "n" > Move< / span > < span class = "o" > ::< / span > < span class = "k" > class< / span > < span class = "p" > .< / span > < span class = "n" > java< / span > < span class = "p" > )< / span >
< span class = "k" > override< / span > < span class = "k" > fun< / span > < span class = "nf" > verify< / span > < span class = "p" > (< / span > < span class = "n" > tx< / span > < span class = "p" > :< / span > < span class = "n" > TransactionForContract< / span > < span class = "p" > ,< / span >
< span class = "n" > inputs< / span > < span class = "p" > :< / span > < span class = "n" > List< / span > < span class = "p" > < < / span > < span class = "n" > State< / span > < span class = "p" > > ,< / span >
< span class = "n" > outputs< / span > < span class = "p" > :< / span > < span class = "n" > List< / span > < span class = "p" > < < / span > < span class = "n" > State< / span > < span class = "p" > > ,< / span >
2016-08-30 11:05:32 +00:00
< span class = "n" > commands< / span > < span class = "p" > :< / span > < span class = "n" > List< / span > < span class = "p" > < < / span > < span class = "n" > AuthenticatedObject< / span > < span class = "p" > < < / span > < span class = "n" > Commands< / span > < span class = "p" > > > ,< / span >
< span class = "n" > groupingKey< / span > < span class = "p" > :< / span > < span class = "n" > Issued< / span > < span class = "p" > < < / span > < span class = "n" > Terms< / span > < span class = "p" > > ?):< / span > < span class = "n" > Set< / span > < span class = "p" > < < / span > < span class = "n" > Commands< / span > < span class = "p" > > < / span > < span class = "p" > {< / span >
2016-07-12 16:52:52 +00:00
< span class = "k" > val< / span > < span class = "py" > command< / span > < span class = "p" > =< / span > < span class = "n" > commands< / span > < span class = "p" > .< / span > < span class = "n" > requireSingleCommand< / span > < span class = "p" > < < / span > < span class = "n" > Commands< / span > < span class = "p" > .< / span > < span class = "n" > Move< / span > < span class = "p" > > ()< / span >
< span class = "k" > val< / span > < span class = "py" > input< / span > < span class = "p" > =< / span > < span class = "n" > inputs< / span > < span class = "p" > .< / span > < span class = "n" > single< / span > < span class = "p" > ()< / span >
< span class = "n" > requireThat< / span > < span class = "p" > {< / span >
< span class = "s" > " the transaction is signed by the owner of the CP" < / span > < span class = "k" > by< / span > < span class = "p" > (< / span > < span class = "n" > input< / span > < span class = "p" > .< / span > < span class = "n" > owner< / span > < span class = "k" > in< / span > < span class = "n" > command< / span > < span class = "p" > .< / span > < span class = "n" > signers< / span > < span class = "p" > )< / span >
< span class = "s" > " the state is propagated" < / span > < span class = "k" > by< / span > < span class = "p" > (< / span > < span class = "n" > outputs< / span > < span class = "p" > .< / span > < span class = "n" > size< / span > < span class = "p" > ==< / span > < span class = "m" > 1< / span > < span class = "p" > )< / span >
< span class = "c1" > // Don' t need to check anything else, as if outputs.size == 1 then the output is equal to< / span >
< span class = "c1" > // the input ignoring the owner field due to the grouping.< / span >
< span class = "p" > }< / span >
< span class = "k" > return< / span > < span class = "n" > setOf< / span > < span class = "p" > (< / span > < span class = "n" > command< / span > < span class = "p" > .< / span > < span class = "n" > value< / span > < span class = "p" > )< / span >
< span class = "p" > }< / span >
< span class = "p" > }< / span >
< / pre > < / div >
< / div >
2016-08-30 11:05:32 +00:00
< div class = "highlight-java" > < div class = "highlight" > < pre > < span > < / span > < span class = "kd" > class< / span > < span class = "nc" > Move< / span > < span class = "kd" > extends< / span > < span class = "n" > ConcreteClause< / span > < span class = "o" > < < / span > < span class = "n" > State< / span > < span class = "o" > ,< / span > < span class = "n" > Commands< / span > < span class = "o" > ,< / span > < span class = "n" > State< / span > < span class = "o" > > < / span > < span class = "o" > {< / span >
< span class = "nd" > @NotNull< / span >
2016-07-12 16:52:52 +00:00
< span class = "nd" > @Override< / span >
< span class = "kd" > public< / span > < span class = "n" > Set< / span > < span class = "o" > < < / span > < span class = "n" > Class< / span > < span class = "o" > < ?< / span > < span class = "kd" > extends< / span > < span class = "n" > CommandData< / span > < span class = "o" > > > < / span > < span class = "nf" > getRequiredCommands< / span > < span class = "o" > ()< / span > < span class = "o" > {< / span >
< span class = "k" > return< / span > < span class = "n" > Collections< / span > < span class = "o" > .< / span > < span class = "na" > singleton< / span > < span class = "o" > (< / span > < span class = "n" > Commands< / span > < span class = "o" > .< / span > < span class = "na" > Move< / span > < span class = "o" > .< / span > < span class = "na" > class< / span > < span class = "o" > );< / span >
< span class = "o" > }< / span >
2016-08-30 11:05:32 +00:00
< span class = "nd" > @NotNull< / span >
2016-07-12 16:52:52 +00:00
< span class = "nd" > @Override< / span >
2016-08-30 11:05:32 +00:00
< span class = "kd" > public< / span > < span class = "n" > Set< / span > < span class = "o" > < < / span > < span class = "n" > Commands< / span > < span class = "o" > > < / span > < span class = "nf" > verify< / span > < span class = "o" > (< / span > < span class = "nd" > @NotNull< / span > < span class = "n" > TransactionForContract< / span > < span class = "n" > tx< / span > < span class = "o" > ,< / span >
2016-07-12 16:52:52 +00:00
< span class = "nd" > @NotNull< / span > < span class = "n" > List< / span > < span class = "o" > < ?< / span > < span class = "kd" > extends< / span > < span class = "n" > State< / span > < span class = "o" > > < / span > < span class = "n" > inputs< / span > < span class = "o" > ,< / span >
< span class = "nd" > @NotNull< / span > < span class = "n" > List< / span > < span class = "o" > < ?< / span > < span class = "kd" > extends< / span > < span class = "n" > State< / span > < span class = "o" > > < / span > < span class = "n" > outputs< / span > < span class = "o" > ,< / span >
2016-08-30 11:05:32 +00:00
< span class = "nd" > @NotNull< / span > < span class = "n" > List< / span > < span class = "o" > < ?< / span > < span class = "kd" > extends< / span > < span class = "n" > AuthenticatedObject< / span > < span class = "o" > < ?< / span > < span class = "kd" > extends< / span > < span class = "n" > Commands< / span > < span class = "o" > > > < / span > < span class = "n" > commands< / span > < span class = "o" > ,< / span >
< span class = "nd" > @NotNull< / span > < span class = "n" > State< / span > < span class = "n" > groupingKey< / span > < span class = "o" > )< / span > < span class = "o" > {< / span >
< span class = "n" > AuthenticatedObject< / span > < span class = "o" > < < / span > < span class = "n" > Commands< / span > < span class = "o" > .< / span > < span class = "na" > Move< / span > < span class = "o" > > < / span > < span class = "n" > cmd< / span > < span class = "o" > =< / span > < span class = "n" > requireSingleCommand< / span > < span class = "o" > (< / span > < span class = "n" > tx< / span > < span class = "o" > .< / span > < span class = "na" > getCommands< / span > < span class = "o" > (),< / span > < span class = "n" > Commands< / span > < span class = "o" > .< / span > < span class = "na" > Move< / span > < span class = "o" > .< / span > < span class = "na" > class< / span > < span class = "o" > );< / span >
2016-07-12 16:52:52 +00:00
< span class = "c1" > // There should be only a single input due to aggregation above< / span >
< span class = "n" > State< / span > < span class = "n" > input< / span > < span class = "o" > =< / span > < span class = "n" > single< / span > < span class = "o" > (< / span > < span class = "n" > inputs< / span > < span class = "o" > );< / span >
2016-08-30 11:05:32 +00:00
< span class = "k" > if< / span > < span class = "o" > (!< / span > < span class = "n" > cmd< / span > < span class = "o" > .< / span > < span class = "na" > getSigners< / span > < span class = "o" > ().< / span > < span class = "na" > contains< / span > < span class = "o" > (< / span > < span class = "n" > input< / span > < span class = "o" > .< / span > < span class = "na" > getOwner< / span > < span class = "o" > ()))< / span >
< span class = "k" > throw< / span > < span class = "k" > new< / span > < span class = "n" > IllegalStateException< / span > < span class = "o" > (< / span > < span class = "s" > " Failed requirement: the transaction is signed by the owner of the CP" < / span > < span class = "o" > );< / span >
< span class = "c1" > // Check the output CP state is the same as the input state, ignoring the owner field.< / span >
< span class = "k" > if< / span > < span class = "o" > (< / span > < span class = "n" > outputs< / span > < span class = "o" > .< / span > < span class = "na" > size< / span > < span class = "o" > ()< / span > < span class = "o" > !=< / span > < span class = "mi" > 1< / span > < span class = "o" > )< / span > < span class = "o" > {< / span >
< span class = "k" > throw< / span > < span class = "k" > new< / span > < span class = "n" > IllegalStateException< / span > < span class = "o" > (< / span > < span class = "s" > " the state is propagated" < / span > < span class = "o" > );< / span >
< span class = "o" > }< / span >
2016-07-12 16:52:52 +00:00
< span class = "c1" > // Don' t need to check anything else, as if outputs.size == 1 then the output is equal to< / span >
< span class = "c1" > // the input ignoring the owner field due to the grouping.< / span >
< span class = "k" > return< / span > < span class = "n" > Collections< / span > < span class = "o" > .< / span > < span class = "na" > singleton< / span > < span class = "o" > (< / span > < span class = "n" > cmd< / span > < span class = "o" > .< / span > < span class = "na" > getValue< / span > < span class = "o" > ());< / span >
< span class = "o" > }< / span >
< span class = "o" > }< / span >
< / pre > < / div >
< / div >
< / div >
< / div >
< div class = "section" id = "group-clause" >
< h2 > Group Clause< a class = "headerlink" href = "#group-clause" title = "Permalink to this headline" > ¶< / a > < / h2 >
< p > We need to wrap the move clause (as well as the issue and redeem clauses - see the relevant contract code for their
2016-08-30 11:05:32 +00:00
full specifications) in an outer clause that understands how to group contract states and objects. For this we extend
the standard < code class = "docutils literal" > < span class = "pre" > GroupClauseVerifier< / span > < / code > and specify how to group input/output states, as well as the top-level to run on
each group. As with the top level clause on a contract, this is normally a composite clause that delegates to subclauses.< / p >
2016-07-12 16:52:52 +00:00
< div class = "codeset container" >
2016-08-30 11:05:32 +00:00
< div class = "highlight-kotlin" > < div class = "highlight" > < pre > < span > < / span > < span class = "k" > class< / span > < span class = "nc" > Group< / span > < span class = "p" > :< / span > < span class = "n" > GroupClauseVerifier< / span > < span class = "p" > < < / span > < span class = "n" > State< / span > < span class = "p" > ,< / span > < span class = "n" > Commands< / span > < span class = "p" > ,< / span > < span class = "n" > Issued< / span > < span class = "p" > < < / span > < span class = "n" > Terms< / span > < span class = "p" > > > (< / span >
< span class = "n" > AnyComposition< / span > < span class = "p" > (< / span >
< span class = "n" > Redeem< / span > < span class = "p" > (),< / span >
< span class = "n" > Move< / span > < span class = "p" > (),< / span >
< span class = "n" > Issue< / span > < span class = "p" > ()))< / span > < span class = "p" > {< / span >
< span class = "k" > override< / span > < span class = "k" > fun< / span > < span class = "nf" > groupStates< / span > < span class = "p" > (< / span > < span class = "n" > tx< / span > < span class = "p" > :< / span > < span class = "n" > TransactionForContract< / span > < span class = "p" > ):< / span > < span class = "n" > List< / span > < span class = "p" > < < / span > < span class = "n" > TransactionForContract< / span > < span class = "p" > .< / span > < span class = "n" > InOutGroup< / span > < span class = "p" > < < / span > < span class = "n" > State< / span > < span class = "p" > ,< / span > < span class = "n" > Issued< / span > < span class = "p" > < < / span > < span class = "n" > Terms< / span > < span class = "p" > > > > < / span >
2016-07-12 16:52:52 +00:00
< span class = "p" > =< / span > < span class = "n" > tx< / span > < span class = "p" > .< / span > < span class = "n" > groupStates< / span > < span class = "p" > < < / span > < span class = "n" > State< / span > < span class = "p" > ,< / span > < span class = "n" > Issued< / span > < span class = "p" > < < / span > < span class = "n" > Terms< / span > < span class = "p" > > > < / span > < span class = "p" > {< / span > < span class = "n" > it< / span > < span class = "p" > .< / span > < span class = "n" > token< / span > < span class = "p" > }< / span >
< span class = "p" > }< / span >
< / pre > < / div >
< / div >
2016-08-30 11:05:32 +00:00
< div class = "highlight-java" > < div class = "highlight" > < pre > < span > < / span > < span class = "kd" > class< / span > < span class = "nc" > Group< / span > < span class = "kd" > extends< / span > < span class = "n" > GroupClauseVerifier< / span > < span class = "o" > < < / span > < span class = "n" > State< / span > < span class = "o" > ,< / span > < span class = "n" > Commands< / span > < span class = "o" > ,< / span > < span class = "n" > State< / span > < span class = "o" > > < / span > < span class = "o" > {< / span >
< span class = "kd" > public< / span > < span class = "nf" > Group< / span > < span class = "o" > ()< / span > < span class = "o" > {< / span >
< span class = "kd" > super< / span > < span class = "o" > (< / span > < span class = "k" > new< / span > < span class = "n" > AnyComposition< / span > < span class = "o" > < > (< / span >
< span class = "k" > new< / span > < span class = "n" > Clauses< / span > < span class = "o" > .< / span > < span class = "na" > Redeem< / span > < span class = "o" > (),< / span >
< span class = "k" > new< / span > < span class = "n" > Clauses< / span > < span class = "o" > .< / span > < span class = "na" > Move< / span > < span class = "o" > (),< / span >
< span class = "k" > new< / span > < span class = "n" > Clauses< / span > < span class = "o" > .< / span > < span class = "na" > Issue< / span > < span class = "o" > ()< / span >
< span class = "o" > ));< / span >
2016-07-12 16:52:52 +00:00
< span class = "o" > }< / span >
2016-08-30 11:05:32 +00:00
< span class = "nd" > @NotNull< / span >
2016-07-12 16:52:52 +00:00
< span class = "nd" > @Override< / span >
2016-08-30 11:05:32 +00:00
< span class = "kd" > public< / span > < span class = "n" > List< / span > < span class = "o" > < < / span > < span class = "n" > InOutGroup< / span > < span class = "o" > < < / span > < span class = "n" > State< / span > < span class = "o" > ,< / span > < span class = "n" > State< / span > < span class = "o" > > > < / span > < span class = "nf" > groupStates< / span > < span class = "o" > (< / span > < span class = "nd" > @NotNull< / span > < span class = "n" > TransactionForContract< / span > < span class = "n" > tx< / span > < span class = "o" > )< / span > < span class = "o" > {< / span >
2016-07-12 16:52:52 +00:00
< span class = "k" > return< / span > < span class = "n" > tx< / span > < span class = "o" > .< / span > < span class = "na" > groupStates< / span > < span class = "o" > (< / span > < span class = "n" > State< / span > < span class = "o" > .< / span > < span class = "na" > class< / span > < span class = "o" > ,< / span > < span class = "n" > State< / span > < span class = "o" > ::< / span > < span class = "n" > withoutOwner< / span > < span class = "o" > );< / span >
< span class = "o" > }< / span >
< span class = "o" > }< / span >
< / pre > < / div >
< / div >
< / div >
2016-08-30 11:05:32 +00:00
< p > For the < code class = "docutils literal" > < span class = "pre" > CommercialPaper< / span > < / code > contract, this is the top level clause for the contract, and is passed directly into
< code class = "docutils literal" > < span class = "pre" > verifyClause< / span > < / code > (see the example code at the top of this tutorial).< / p >
2016-07-12 16:52:52 +00:00
< / div >
< div class = "section" id = "summary" >
< h2 > Summary< a class = "headerlink" href = "#summary" title = "Permalink to this headline" > ¶< / a > < / h2 >
< p > In summary the top level contract < code class = "docutils literal" > < span class = "pre" > CommercialPaper< / span > < / code > specifies a single grouping clause of type
< code class = "docutils literal" > < span class = "pre" > CommercialPaper.Clauses.Group< / span > < / code > which in turn specifies < code class = "docutils literal" > < span class = "pre" > GroupClause< / span > < / code > implementations for each type of command
(< code class = "docutils literal" > < span class = "pre" > Redeem< / span > < / code > , < code class = "docutils literal" > < span class = "pre" > Move< / span > < / code > and < code class = "docutils literal" > < span class = "pre" > Issue< / span > < / code > ). This reflects the flow of verification: In order to verify a < code class = "docutils literal" > < span class = "pre" > CommercialPaper< / span > < / code >
we first group states, check which commands are specified, and run command-specific verification logic accordingly.< / p >
< / div >
2016-08-30 11:05:32 +00:00
< div class = "section" id = "debugging" >
< h2 > Debugging< a class = "headerlink" href = "#debugging" title = "Permalink to this headline" > ¶< / a > < / h2 >
< p > Debugging clauses which have been composed together can be complicated due to the difficulty in knowing which clauses
have been matched, whether specific clauses failed to match or passed verification, etc. There is “ trace” level
logging code in the clause verifier which evaluates which clauses will be matched and logs them, before actually
performing the validation. To enable this, ensure trace level logging is enabled on the < code class = "docutils literal" > < span class = "pre" > Clause< / span > < / code > interface.< / p >
< / div >
2016-07-12 16:52:52 +00:00
< / div >
< / div >
< / div >
< footer >
< div class = "rst-footer-buttons" role = "navigation" aria-label = "footer navigation" >
< a href = "tutorial-test-dsl.html" class = "btn btn-neutral float-right" title = "Writing a contract test" accesskey = "n" > Next < span class = "fa fa-arrow-circle-right" > < / span > < / a >
< a href = "tutorial-contract.html" class = "btn btn-neutral" title = "Writing a contract" accesskey = "p" > < span class = "fa fa-arrow-circle-left" > < / span > Previous< / a >
< / div >
< hr / >
< div role = "contentinfo" >
< p >
© Copyright 2016, Distributed Ledger Group, LLC.
< / p >
< / div >
Built with < a href = "http://sphinx-doc.org/" > Sphinx< / a > using a < a href = "https://github.com/snide/sphinx_rtd_theme" > theme< / a > provided by < a href = "https://readthedocs.org" > Read the Docs< / a > .
< / footer >
< / div >
< / div >
< / section >
< / div >
< script type = "text/javascript" >
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'./',
VERSION:'latest',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true
};
< / script >
< script type = "text/javascript" src = "_static/jquery.js" > < / script >
< script type = "text/javascript" src = "_static/underscore.js" > < / script >
< script type = "text/javascript" src = "_static/doctools.js" > < / script >
< script type = "text/javascript" src = "_static/js/theme.js" > < / script >
< script type = "text/javascript" >
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
});
< / script >
< / body >
< / html >