sophia/test/contracts/stateful.aes
Radosław Rowicki 1d9f59fec3
Contract factories and bytecode introspection (#305)
* Support for CREATE, CLONE and BYTECODE_HASH

* Add missing files

* Pushed the clone example through the typechecker

* CLONE compiles

* Fix dependent type in CLONE

* Bytecode hash fixes

* Refactor

* Refactor 2

* move some logic away

* Fixed some error messages. Type inference of child contract still does some random shit\n(mistakes arguments with result type)

* CREATE sometimes compiles and sometimes not

* Fix some scoping/constraint issues

* works, needs cleanup

* cleanup

* Fix some tests. Remove optimization of singleton tuples

* Fix default argument for clone

* Cleanup

* CHANGELOG

* Mention void type

* Address review, fix some dialyzer errors

* Please dialyzer

* Fix failing tests

* Write negative tests

* Docs

* TOC

* missing 'the'

* missing 'the'

* missing 'the'

* missing 'the'

* mention pre-fund

* format

* pre-fund clarification

* format

* Grammar in docs
2021-05-18 12:21:57 +02:00

55 lines
1.8 KiB
Plaintext

contract interface Remote =
stateful entrypoint remote_spend : (address, int) => unit
entrypoint remote_pure : int => int
contract Stateful =
function pure(x) = x + 1
stateful function local_spend(a) =
Chain.spend(a, 1000)
// Non-stateful functions cannot mention stateful functions
entrypoint fail1(a : address) = Chain.spend(a, 1000)
entrypoint fail2(a : address) = local_spend(a)
entrypoint fail3(a : address) =
let foo = Chain.spend
foo(a, 1000)
// Private functions must also be annotated
private function fail4(a) = Chain.spend(a, 1000)
// If annotated, stateful functions are allowed
stateful entrypoint ok1(a : address) = Chain.spend(a, 1000)
// And pure functions are always allowed
stateful entrypoint ok2(a : address) = pure(5)
stateful entrypoint ok3(a : address) =
let foo = pure
foo(5)
// No error here (fail4 is annotated as not stateful)
entrypoint ok4(a : address) = fail4(a)
// Lamdbas are checked at the construction site
function fail5() : address => unit = (a) => Chain.spend(a, 1000)
// .. so you can pass a stateful lambda to a non-stateful higher-order
// function:
function apply(f : 'a => 'b, x) = f(x)
stateful entrypoint ok5(a : address) =
apply((val) => Chain.spend(a, val), 1000)
// It doesn't matter if remote calls are stateful or not
entrypoint ok6(r : Remote) = r.remote_spend(Contract.address, 1000)
entrypoint ok7(r : Remote) = r.remote_pure(5)
// But you can't send any tokens if not stateful
entrypoint fail6(r : Remote) = r.remote_spend(value = 1000, Contract.address, 1000)
entrypoint fail7(r : Remote) = r.remote_pure(value = 1000, 5)
entrypoint fail8(r : Remote) =
let foo = r.remote_pure
foo(value = 1000, 5)
entrypoint ok8(r : Remote) = r.remote_spend(Contract.address, 1000, value = 0)