updated following review

This commit is contained in:
jamescarlyle
2016-09-06 17:56:01 +01:00
parent ee65d4490b
commit cdb2c3efa6
16 changed files with 489 additions and 123 deletions

View File

@ -114,6 +114,7 @@
<li class="toctree-l2"><a class="reference internal" href="#how-to-test-your-contract">How to test your contract</a></li>
<li class="toctree-l2"><a class="reference internal" href="#adding-a-generation-api-to-your-contract">Adding a generation API to your contract</a></li>
<li class="toctree-l2"><a class="reference internal" href="#non-asset-oriented-based-smart-contracts">Non-asset-oriented based smart contracts</a></li>
<li class="toctree-l2"><a class="reference internal" href="#encumbrances">Encumbrances</a></li>
<li class="toctree-l2"><a class="reference internal" href="#clauses">Clauses</a></li>
</ul>
</li>
@ -924,6 +925,58 @@ The logic that implements measurement of the threshold, different signing combin
be implemented once in a separate contract, with the controlling data being held in the named state.</p>
<p>Future versions of the prototype will explore these concepts in more depth.</p>
</div>
<div class="section" id="encumbrances">
<h2>Encumbrances<a class="headerlink" href="#encumbrances" title="Permalink to this headline"></a></h2>
<p>All contract states may be <em>encumbered</em> by up to one other state, which we call an <strong>encumbrance</strong>.</p>
<p>The encumbrance state, if present, forces additional controls over the encumbered state, since the encumbrance state contract
will also be verified during the execution of the transaction. For example, a contract state could be encumbered
with a time-lock contract state; the state is then only processable in a transaction that verifies that the time
specified in the encumbrance time-lock has passed.</p>
<p>The encumbered state refers to its encumbrance by index, and the referred encumbrance state
is an output state in a particular position on the same transaction that created the encumbered state. Note that an
encumbered state that is being consumed must have its encumbrance consumed in the same transaction, otherwise the
transaction is not valid.</p>
<p>The encumbrance reference is optional in the <code class="docutils literal"><span class="pre">ContractState</span></code> interface:</p>
<div class="codeset container">
<div class="highlight-kotlin"><div class="highlight"><pre><span></span><span class="k">val</span> <span class="py">encumbrance</span><span class="p">:</span> <span class="n">Int</span><span class="p">?</span> <span class="k">get</span><span class="p">()</span> <span class="p">=</span> <span class="k">null</span>
</pre></div>
</div>
<div class="highlight-java"><div class="highlight"><pre><span></span><span class="nd">@Nullable</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">Integer</span> <span class="nf">getEncumbrance</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">null</span><span class="o">;</span>
<span class="o">}</span>
</pre></div>
</div>
</div>
<p>The time-lock contract mentioned above can be implemented very simply:</p>
<div class="codeset container">
<div class="highlight-kotlin"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">TestTimeLock</span> <span class="p">:</span> <span class="n">Contract</span> <span class="p">{</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="p">{</span>
<span class="k">val</span> <span class="py">timestamp</span><span class="p">:</span> <span class="n">Timestamp</span><span class="p">?</span> <span class="p">=</span> <span class="n">tx</span><span class="p">.</span><span class="n">timestamp</span>
<span class="p">...</span>
<span class="n">requireThat</span> <span class="p">{</span>
<span class="s">&quot;the time specified in the time-lock has passed&quot;</span> <span class="k">by</span>
<span class="p">(</span><span class="n">time</span> <span class="p">&gt;=</span> <span class="n">tx</span><span class="p">.</span><span class="n">inputs</span><span class="p">.</span><span class="n">filterIsInstance</span><span class="p">&lt;</span><span class="n">TestTimeLock</span><span class="p">.</span><span class="n">State</span><span class="p">&gt;().</span><span class="n">single</span><span class="p">().</span><span class="n">validFrom</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">...</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<p>We can then set up an encumbered state:</p>
<div class="codeset container">
<div class="highlight-kotlin"><div class="highlight"><pre><span></span>val encumberedState = Cash.State(amount = 1000.DOLLARS `issued by` defaultIssuer, owner = DUMMY_PUBKEY_1, encumbrance = 1)
val fourPmTimelock = TestTimeLock.State(Instant.parse(&quot;2015-04-17T16:00:00.00Z&quot;))
</pre></div>
</div>
</div>
<p>When we construct a transaction that generates the encumbered state, we must place the encumbrance in the corresponding output
position of that transaction. And when we subsequently consume that encumbered state, the same encumbrance state must be
available somewhere within the input set of states.</p>
</div>
<div class="section" id="clauses">
<h2>Clauses<a class="headerlink" href="#clauses" title="Permalink to this headline"></a></h2>
<p>Instead of structuring contracts as a single entity, they can be broken down into reusable chunks known as clauses.