Docs: Regen HTML

This commit is contained in:
Mike Hearn 2015-11-27 16:23:32 +01:00
parent e9c60c2722
commit 57118d46a8
3 changed files with 200 additions and 3 deletions

View File

@ -620,8 +620,113 @@ the exact message).
Adding a crafting API to your contract
--------------------------------------
TODO: Write this after the CP contract has had a crafting API actually added.
Contract classes **must** provide a verify function, but they may optionally also provide helper functions to simplify
their usage. A simple class of functions most contracts provide are *crafting functions*, which either generate or
modify a transaction to perform certain actions (an action is normally mappable 1:1 to a command, but doesn't have to
be so).
Crafting may involve complex logic. For example, the cash contract has a ``craftSpend`` method that is given a set of
cash states and chooses a way to combine them together to satisfy the amount of money that is being sent. In the
immutable-state model that we are using ledger entries (states) can only be created and deleted, but never modified.
Therefore to send $1200 when we have only $900 and $500 requires combining both states together, and then creating
two new output states of $1200 and $200 back to ourselves. This latter state is called the *change* and is a concept
that should be familiar to anyone who has worked with Bitcoin.
As another example, we can imagine code that implements a netting algorithm may craft complex transactions that must
be signed by many people. Whilst such code might be too big for a single utility method (it'd probably be sized more
like a module), the basic concept is the same: preparation of a transaction using complex logic.
For our commercial paper contract however, the things that can be done with it are quite simple. Let's start with
a method to wrap up the issuance process:
.. container:: codeset
.. sourcecode:: kotlin
fun craftIssue(issuance: InstitutionReference, faceValue: Amount, maturityDate: Instant): PartialTransaction {
val state = State(issuance, issuance.institution.owningKey, faceValue, maturityDate)
return PartialTransaction(state, WireCommand(Commands.Issue, issuance.institution.owningKey))
}
We take a reference that points to the issuing institution (i.e. the caller) and which can contain any internal
bookkeeping/reference numbers that we may require. Then the face value of the paper, and the maturity date. It
returns a ``PartialTransaction``. A ``PartialTransaction`` is one of the few mutable classes the platform provides.
It allows you to add inputs, outputs and commands to it and is designed to be passed around, potentially between
multiple contracts.
.. note:: Crafting methods should ideally be written to compose with each other, that is, they should take a
``PartialTransaction`` as an argument instead of returning one, unless you are sure it doesn't make sense to
combine this type of transaction with others. In this case, issuing CP at the same time as doing other things
would just introduce complexity that isn't likely to be worth it, so we return a fresh object each time.
The function we define creates a ``CommercialPaper.State`` object that mostly just uses the arguments we were given,
but it fills out the owner field of the state to be the same public key as the issuing institution. If the caller wants
to issue CP onto the ledger that's immediately owned by someone else, they'll have to create the state themselves.
The returned partial transaction has a ``WireCommand`` object as a parameter. This is just a container for any object
that implements the ``Command`` interface, along with a key that is expected to sign this transaction. In this case,
issuance requires that the issuing institution sign, so we put the key of the institution there.
The ``PartialTransaction`` constructor we used above takes a variable argument list for convenience. You can pass in
any ``ContractStateRef`` (input), ``ContractState`` (output) or ``Command`` objects and it'll build up the transaction
for you.
What about moving the paper, i.e. reassigning ownership to someone else?
.. container:: codeset
.. sourcecode:: kotlin
fun craftMove(tx: PartialTransaction, paper: StateAndRef<State>, newOwner: PublicKey) {
tx.addInputState(paper.ref)
tx.addOutputState(paper.state.copy(owner = newOwner))
tx.addArg(WireCommand(Commands.Move, paper.state.owner))
}
Here, the method takes a pre-existing ``PartialTransaction`` and adds to it. This is correct because typically
you will want to combine a sale of CP atomically with the movement of some other asset, such as cash. So both
craft methods should operate on the same transaction. You can see an example of this being done in the unit tests
for the commercial paper contract.
The paper is given to us as a ``StateAndRef<CommercialPaper.State>`` object. This is exactly what it sounds like:
a small object that has a (copy of) a state object, and also the (txhash, index) that indicates the location of this
state on the ledger.
Finally, we can do redemption.
.. container:: codeset
.. sourcecode:: kotlin
@Throws(InsufficientBalanceException::class)
fun craftRedeem(tx: PartialTransaction, paper: StateAndRef<State>, wallet: List<StateAndRef<Cash.State>>) {
// Add the cash movement using the states in our wallet.
Cash().craftSpend(tx, paper.state.faceValue, paper.state.owner, wallet)
tx.addInputState(paper.ref)
tx.addArg(WireCommand(CommercialPaper.Commands.Redeem, paper.state.owner))
}
Here we can see an example of composing contracts together. When an owner wishes to redeem the commercial paper, the
issuer (i.e. the caller) must gather cash from its wallet and send the face value to the owner of the paper.
The *wallet* is a concept that may be familiar from Bitcoin and Ethereum. It is simply a set of cash states that are
owned by the caller. Here, we use the wallet to update the partial transaction we are handed with a movement of cash
from the issuer of the commercial paper to the current owner. If we don't have enough quantity of cash in our wallet,
an exception is thrown. And then we add the paper itself as an input, but, not an output (as we wish to delete it
from the ledger permanently). Finally, we add a Redeem command that should be signed by the owner of the commercial
paper.
A ``PartialTransaction`` is not by itself ready to be used anywhere, so first, we must convert it to something that
is recognised by the network. The most important next step is for the participating entities to sign it using the
``signWith()`` method. This takes a keypair, serialises the transaction, signs the serialised form and then stores the
signature inside the ``PartialTransaction``. Once all parties have signed, you can call ``PartialTransaction.toSignedTransaction()``
to get a ``SignedWireTransaction`` object. This is an immutable form of the transaction that's ready for *timestamping*.
.. note:: Timestamping and passing around of partial transactions for group signing is not yet fully implemented.
This tutorial will be updated once it is.
You can see how transactions flow through the different stages of construction by examining the commercial paper
unit tests.
Non-asset-oriented based smart contracts
----------------------------------------

File diff suppressed because one or more lines are too long

View File

@ -694,7 +694,99 @@ the exact message).</p>
</div>
<div class="section" id="adding-a-crafting-api-to-your-contract">
<h2>Adding a crafting API to your contract<a class="headerlink" href="#adding-a-crafting-api-to-your-contract" title="Permalink to this headline"></a></h2>
<p>TODO: Write this after the CP contract has had a crafting API actually added.</p>
<p>Contract classes <strong>must</strong> provide a verify function, but they may optionally also provide helper functions to simplify
their usage. A simple class of functions most contracts provide are <em>crafting functions</em>, which either generate or
modify a transaction to perform certain actions (an action is normally mappable 1:1 to a command, but doesn&#8217;t have to
be so).</p>
<p>Crafting may involve complex logic. For example, the cash contract has a <code class="docutils literal"><span class="pre">craftSpend</span></code> method that is given a set of
cash states and chooses a way to combine them together to satisfy the amount of money that is being sent. In the
immutable-state model that we are using ledger entries (states) can only be created and deleted, but never modified.
Therefore to send $1200 when we have only $900 and $500 requires combining both states together, and then creating
two new output states of $1200 and $200 back to ourselves. This latter state is called the <em>change</em> and is a concept
that should be familiar to anyone who has worked with Bitcoin.</p>
<p>As another example, we can imagine code that implements a netting algorithm may craft complex transactions that must
be signed by many people. Whilst such code might be too big for a single utility method (it&#8217;d probably be sized more
like a module), the basic concept is the same: preparation of a transaction using complex logic.</p>
<p>For our commercial paper contract however, the things that can be done with it are quite simple. Let&#8217;s start with
a method to wrap up the issuance process:</p>
<div class="codeset container">
<div class="highlight-kotlin"><div class="highlight"><pre><span class="k">fun</span> <span class="nf">craftIssue</span><span class="p">(</span><span class="n">issuance</span><span class="p">:</span> <span class="n">InstitutionReference</span><span class="p">,</span> <span class="n">faceValue</span><span class="p">:</span> <span class="n">Amount</span><span class="p">,</span> <span class="n">maturityDate</span><span class="p">:</span> <span class="n">Instant</span><span class="p">):</span> <span class="n">PartialTransaction</span> <span class="p">{</span>
<span class="k">val</span> <span class="py">state</span> <span class="p">=</span> <span class="n">State</span><span class="p">(</span><span class="n">issuance</span><span class="p">,</span> <span class="n">issuance</span><span class="p">.</span><span class="n">institution</span><span class="p">.</span><span class="n">owningKey</span><span class="p">,</span> <span class="n">faceValue</span><span class="p">,</span> <span class="n">maturityDate</span><span class="p">)</span>
<span class="k">return</span> <span class="n">PartialTransaction</span><span class="p">(</span><span class="n">state</span><span class="p">,</span> <span class="n">WireCommand</span><span class="p">(</span><span class="n">Commands</span><span class="p">.</span><span class="n">Issue</span><span class="p">,</span> <span class="n">issuance</span><span class="p">.</span><span class="n">institution</span><span class="p">.</span><span class="n">owningKey</span><span class="p">))</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<p>We take a reference that points to the issuing institution (i.e. the caller) and which can contain any internal
bookkeeping/reference numbers that we may require. Then the face value of the paper, and the maturity date. It
returns a <code class="docutils literal"><span class="pre">PartialTransaction</span></code>. A <code class="docutils literal"><span class="pre">PartialTransaction</span></code> is one of the few mutable classes the platform provides.
It allows you to add inputs, outputs and commands to it and is designed to be passed around, potentially between
multiple contracts.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Crafting methods should ideally be written to compose with each other, that is, they should take a
<code class="docutils literal"><span class="pre">PartialTransaction</span></code> as an argument instead of returning one, unless you are sure it doesn&#8217;t make sense to
combine this type of transaction with others. In this case, issuing CP at the same time as doing other things
would just introduce complexity that isn&#8217;t likely to be worth it, so we return a fresh object each time.</p>
</div>
<p>The function we define creates a <code class="docutils literal"><span class="pre">CommercialPaper.State</span></code> object that mostly just uses the arguments we were given,
but it fills out the owner field of the state to be the same public key as the issuing institution. If the caller wants
to issue CP onto the ledger that&#8217;s immediately owned by someone else, they&#8217;ll have to create the state themselves.</p>
<p>The returned partial transaction has a <code class="docutils literal"><span class="pre">WireCommand</span></code> object as a parameter. This is just a container for any object
that implements the <code class="docutils literal"><span class="pre">Command</span></code> interface, along with a key that is expected to sign this transaction. In this case,
issuance requires that the issuing institution sign, so we put the key of the institution there.</p>
<p>The <code class="docutils literal"><span class="pre">PartialTransaction</span></code> constructor we used above takes a variable argument list for convenience. You can pass in
any <code class="docutils literal"><span class="pre">ContractStateRef</span></code> (input), <code class="docutils literal"><span class="pre">ContractState</span></code> (output) or <code class="docutils literal"><span class="pre">Command</span></code> objects and it&#8217;ll build up the transaction
for you.</p>
<p>What about moving the paper, i.e. reassigning ownership to someone else?</p>
<div class="codeset container">
<div class="highlight-kotlin"><div class="highlight"><pre><span class="k">fun</span> <span class="nf">craftMove</span><span class="p">(</span><span class="n">tx</span><span class="p">:</span> <span class="n">PartialTransaction</span><span class="p">,</span> <span class="n">paper</span><span class="p">:</span> <span class="n">StateAndRef</span><span class="p">&lt;</span><span class="n">State</span><span class="p">&gt;,</span> <span class="n">newOwner</span><span class="p">:</span> <span class="n">PublicKey</span><span class="p">)</span> <span class="p">{</span>
<span class="n">tx</span><span class="p">.</span><span class="n">addInputState</span><span class="p">(</span><span class="n">paper</span><span class="p">.</span><span class="n">ref</span><span class="p">)</span>
<span class="n">tx</span><span class="p">.</span><span class="n">addOutputState</span><span class="p">(</span><span class="n">paper</span><span class="p">.</span><span class="n">state</span><span class="p">.</span><span class="n">copy</span><span class="p">(</span><span class="n">owner</span> <span class="p">=</span> <span class="n">newOwner</span><span class="p">))</span>
<span class="n">tx</span><span class="p">.</span><span class="n">addArg</span><span class="p">(</span><span class="n">WireCommand</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="n">paper</span><span class="p">.</span><span class="n">state</span><span class="p">.</span><span class="n">owner</span><span class="p">))</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<p>Here, the method takes a pre-existing <code class="docutils literal"><span class="pre">PartialTransaction</span></code> and adds to it. This is correct because typically
you will want to combine a sale of CP atomically with the movement of some other asset, such as cash. So both
craft methods should operate on the same transaction. You can see an example of this being done in the unit tests
for the commercial paper contract.</p>
<p>The paper is given to us as a <code class="docutils literal"><span class="pre">StateAndRef&lt;CommercialPaper.State&gt;</span></code> object. This is exactly what it sounds like:
a small object that has a (copy of) a state object, and also the (txhash, index) that indicates the location of this
state on the ledger.</p>
<p>Finally, we can do redemption.</p>
<div class="codeset container">
<div class="highlight-kotlin"><div class="highlight"><pre><span class="n">@Throws</span><span class="p">(</span><span class="n">InsufficientBalanceException</span><span class="o">::</span><span class="k">class</span><span class="p">)</span>
<span class="k">fun</span> <span class="nf">craftRedeem</span><span class="p">(</span><span class="n">tx</span><span class="p">:</span> <span class="n">PartialTransaction</span><span class="p">,</span> <span class="n">paper</span><span class="p">:</span> <span class="n">StateAndRef</span><span class="p">&lt;</span><span class="n">State</span><span class="p">&gt;,</span> <span class="n">wallet</span><span class="p">:</span> <span class="n">List</span><span class="p">&lt;</span><span class="n">StateAndRef</span><span class="p">&lt;</span><span class="n">Cash</span><span class="p">.</span><span class="n">State</span><span class="p">&gt;&gt;)</span> <span class="p">{</span>
<span class="c1">// Add the cash movement using the states in our wallet.</span>
<span class="n">Cash</span><span class="p">().</span><span class="n">craftSpend</span><span class="p">(</span><span class="n">tx</span><span class="p">,</span> <span class="n">paper</span><span class="p">.</span><span class="n">state</span><span class="p">.</span><span class="n">faceValue</span><span class="p">,</span> <span class="n">paper</span><span class="p">.</span><span class="n">state</span><span class="p">.</span><span class="n">owner</span><span class="p">,</span> <span class="n">wallet</span><span class="p">)</span>
<span class="n">tx</span><span class="p">.</span><span class="n">addInputState</span><span class="p">(</span><span class="n">paper</span><span class="p">.</span><span class="n">ref</span><span class="p">)</span>
<span class="n">tx</span><span class="p">.</span><span class="n">addArg</span><span class="p">(</span><span class="n">WireCommand</span><span class="p">(</span><span class="n">CommercialPaper</span><span class="p">.</span><span class="n">Commands</span><span class="p">.</span><span class="n">Redeem</span><span class="p">,</span> <span class="n">paper</span><span class="p">.</span><span class="n">state</span><span class="p">.</span><span class="n">owner</span><span class="p">))</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<p>Here we can see an example of composing contracts together. When an owner wishes to redeem the commercial paper, the
issuer (i.e. the caller) must gather cash from its wallet and send the face value to the owner of the paper.</p>
<p>The <em>wallet</em> is a concept that may be familiar from Bitcoin and Ethereum. It is simply a set of cash states that are
owned by the caller. Here, we use the wallet to update the partial transaction we are handed with a movement of cash
from the issuer of the commercial paper to the current owner. If we don&#8217;t have enough quantity of cash in our wallet,
an exception is thrown. And then we add the paper itself as an input, but, not an output (as we wish to delete it
from the ledger permanently). Finally, we add a Redeem command that should be signed by the owner of the commercial
paper.</p>
<p>A <code class="docutils literal"><span class="pre">PartialTransaction</span></code> is not by itself ready to be used anywhere, so first, we must convert it to something that
is recognised by the network. The most important next step is for the participating entities to sign it using the
<code class="docutils literal"><span class="pre">signWith()</span></code> method. This takes a keypair, serialises the transaction, signs the serialised form and then stores the
signature inside the <code class="docutils literal"><span class="pre">PartialTransaction</span></code>. Once all parties have signed, you can call <code class="docutils literal"><span class="pre">PartialTransaction.toSignedTransaction()</span></code>
to get a <code class="docutils literal"><span class="pre">SignedWireTransaction</span></code> object. This is an immutable form of the transaction that&#8217;s ready for <em>timestamping</em>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Timestamping and passing around of partial transactions for group signing is not yet fully implemented.
This tutorial will be updated once it is.</p>
</div>
<p>You can see how transactions flow through the different stages of construction by examining the commercial paper
unit tests.</p>
</div>
<div class="section" id="non-asset-oriented-based-smart-contracts">
<h2>Non-asset-oriented based smart contracts<a class="headerlink" href="#non-asset-oriented-based-smart-contracts" title="Permalink to this headline"></a></h2>