contract 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)