sophia/test/contracts/oracles.aes
Ulf Norell 5aed8b3ef5 Check stateful annotations
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
2019-05-13 13:39:17 +02:00

113 lines
4.0 KiB
Plaintext

contract Oracles =
type fee = int
type ttl = Chain.ttl
type query_t = string
type answer_t = int
type oracle_id = oracle(query_t, answer_t)
type query_id = oracle_query(query_t, answer_t)
stateful function registerOracle(acct : address,
qfee : fee,
ttl : ttl) : oracle_id =
Oracle.register(acct, qfee, ttl)
stateful function registerIntIntOracle(acct : address,
qfee : fee,
ttl : ttl) : oracle(int, int) =
Oracle.register(acct, qfee, ttl)
stateful function registerStringStringOracle(acct : address,
qfee : fee,
ttl : ttl) : oracle(string, string) =
Oracle.register(acct, qfee, ttl)
stateful function signedRegisterOracle(acct : address,
sign : signature,
qfee : fee,
ttl : ttl) : oracle_id =
Oracle.register(acct, qfee, ttl, signature = sign)
function queryFee(o : oracle_id) : fee =
Oracle.query_fee(o)
stateful function createQuery(o : oracle_id,
q : query_t,
qfee : fee,
qttl : ttl,
rttl : ttl) : query_id =
require(qfee =< Call.value, "insufficient value for qfee")
Oracle.query(o, q, qfee, qttl, rttl)
// Do not use in production!
stateful function unsafeCreateQuery(o : oracle_id,
q : query_t,
qfee : fee,
qttl : ttl,
rttl : ttl) : query_id =
Oracle.query(o, q, qfee, qttl, rttl)
// Do not use in production!
stateful function unsafeCreateQueryThenErr(o : oracle_id,
q : query_t,
qfee : fee,
qttl : ttl,
rttl : ttl) : query_id =
let res = Oracle.query(o, q, qfee, qttl, rttl)
require(qfee >= 100000000000000000, "causing a late error")
res
stateful function extendOracle(o : oracle_id,
ttl : ttl) : () =
Oracle.extend(o, ttl)
stateful function signedExtendOracle(o : oracle_id,
sign : signature, // Signed oracle address
ttl : ttl) : () =
Oracle.extend(o, signature = sign, ttl)
stateful function respond(o : oracle_id,
q : query_id,
r : answer_t) : () =
Oracle.respond(o, q, r)
stateful function signedRespond(o : oracle_id,
q : query_id,
sign : signature,
r : answer_t) : () =
Oracle.respond(o, q, signature = sign, r)
function getQuestion(o : oracle_id,
q : query_id) : query_t =
Oracle.get_question(o, q)
function hasAnswer(o : oracle_id,
q : query_id) =
switch(Oracle.get_answer(o, q))
None => false
Some(_) => true
function getAnswer(o : oracle_id,
q : query_id) : option(answer_t) =
Oracle.get_answer(o, q)
datatype complexQuestion = Why(int) | How(string)
datatype complexAnswer = NoAnswer | Answer(complexQuestion, string, int)
stateful function complexOracle(question) =
let o = Oracle.register(Contract.address, 0, FixedTTL(1000)) : oracle(complexQuestion, complexAnswer)
let q = Oracle.query(o, question, 0, RelativeTTL(100), RelativeTTL(100))
Oracle.respond(o, q, Answer(question, "magic", 1337))
Oracle.get_answer(o, q)
stateful function signedComplexOracle(question, sig) =
let o = Oracle.register(signature = sig, Contract.address, 0, FixedTTL(1000)) : oracle(complexQuestion, complexAnswer)
let q = Oracle.query(o, question, 0, RelativeTTL(100), RelativeTTL(100))
Oracle.respond(o, q, Answer(question, "magic", 1337), signature = sig)
Oracle.get_answer(o, q)
private function require(b : bool, err : string) =
if(!b) abort(err)