
Functions must be annotated as `stateful` in order to - Update the contract state (using `put`) - Call `Chain.spend` or other primitive functions that cost tokens - Call an Oracle or AENS function that requires a signature - Make a remote call with a non-zero value - Construct a lambda calling a stateful function It does not need to be stateful to - Read the contract state - Call another contract with value=0, even when the remote function is stateful
19 lines
649 B
Plaintext
19 lines
649 B
Plaintext
contract BitcoinAuth =
|
|
record state = { nonce : int, owner : bytes(64) }
|
|
|
|
function init(owner' : bytes(64)) = { nonce = 1, owner = owner' }
|
|
|
|
stateful function authorize(n : int, s : signature) : bool =
|
|
require(n >= state.nonce, "Nonce too low")
|
|
require(n =< state.nonce, "Nonce too high")
|
|
put(state{ nonce = n + 1 })
|
|
switch(Auth.tx_hash)
|
|
None => abort("Not in Auth context")
|
|
Some(tx_hash) => Crypto.ecverify_secp256k1(to_sign(tx_hash, n), state.owner, s)
|
|
|
|
function to_sign(h : hash, n : int) : hash =
|
|
Crypto.blake2b((h, n))
|
|
|
|
private function require(b : bool, err : string) =
|
|
if(!b) abort(err)
|