-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
69 additions
and
0 deletions.
There are no files selected for viewing
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
================= | ||
Stateful Contract | ||
================= | ||
|
||
Bitcoin/sCrypt contract uses Unspent Transaction Output (UTXO) model: a contract is inside a UTXO, dictating how the bitcoins in the UTXO can be spent. | ||
When a UTXO is spent (i.e., an sCrypt contract public function is called successfully), the contract is terminated. | ||
For a contract to keep state and able to be called multiple times while carrying the mutable state, these steps have to be followed. | ||
|
||
1. state decorator | ||
================== | ||
Declare any property that is part of the state with a decorator ``@state``. | ||
The state property can be used the same way as a regular property. | ||
|
||
.. code-block:: solidity | ||
contract Counter { | ||
@state | ||
int counter; | ||
constructor(int counter) { | ||
this.counter = counter; | ||
} | ||
} | ||
2. Propogate the state | ||
====================== | ||
A contract can keep state across chained transactions by storing it in the locking script. | ||
In the following example, a contract goes from ``state0`` to ``state1``, and then to ``state2``. | ||
Input in transaction 1 ``tx1`` is spending UTXO in ``tx0``, and ``tx2`` spending ``tx1``. | ||
|
||
.. image:: _static/images/state.png | ||
:width: 400px | ||
:alt: keep state | ||
:align: center | ||
|
||
When you are ready to pass the new state into the output[s] in the current spending transaction, | ||
simply call a built-in function ``this.getStateScript()`` to get the locking script containing the latest stateful properties. | ||
It is automatically generated for every stateful contract, i.e., a contract that has at least one property decorated with ``@state``. | ||
|
||
Finally, use :ref:`OP_PUSH_TX<pushtx-label>` to ensure the output[s] containing the state go into the current spending transaction. | ||
The following is an example contract that records the number of times ``mutate()`` have been called. | ||
|
||
.. code-block:: solidity | ||
contract Counter { | ||
@state | ||
int counter; | ||
constructor() { | ||
this.counter = 0; | ||
} | ||
public function mutate(SigHashPreimage txPreimage, int amount) { | ||
require(Tx.checkPreimage(txPreimage)); | ||
// mutate state | ||
this.counter++; | ||
// get the locking script containing the latest stateful properties | ||
bytes outputScript = this.getStateScript(); | ||
// construct an output from its locking script and satoshi amount | ||
bytes output = Util.buildOutput(outputScript, amount); | ||
// only 1 input here | ||
require(hash256(output) == Util.hashOutputs(txPreimage)); | ||
} | ||
} |