Skip to content
LogoLogo

Using call results

A deferred call's result arrives after the transition that deferred it. then (result : T) { ... } runs a continuation with the decoded result, as a new phase that can write, emit, and defer again.

continuations.lithe
(* A deferred call can be followed by a continuation with `then`. The continuation
   runs after the call returns, receives its decoded result, and is a new phase of
   the transition: it may write storage, emit, and defer again. *)
 
interface Exchange is {
  function swap(amountIn : uint) : uint;
  function split(amount : uint) : (uint, uint);
}
 
error AlreadyFilled of uint;
 
event Filled of record {
  indexed id : uint;
  amountOut : uint;
}
 
type Order is record {
  status : uint8;
  amountOut : uint;
}
 
storage is record {
  exchange : Exchange;
  orders : map(uint, Order);
  left : uint;
  right : uint;
}
 
external function init(const exchange : Exchange) is {
  storage.exchange := exchange;
}
 
external nonreentrant function fill(const id : uint; const amountIn : uint)
  raises AlreadyFilled
is {
  assert(storage.orders[id].status = uint8(0), AlreadyFilled(id));
  (* The exchange sees this order as pending while it runs. *)
  storage.orders[id].status := uint8(1);
  defer storage.exchange.swap(amountIn)
    then (amountOut : uint) {
      storage.orders[id].status := uint8(2);
      storage.orders[id].amountOut := amountOut;
      emit Filled { id = id; amountOut = amountOut; };
    };
}
 
(* A tuple result destructures in the binding. *)
external nonreentrant function split(const amount : uint) is {
  defer storage.exchange.split(amount)
    then ((a, b) : (uint, uint)) {
      storage.left := storage.left + a;
      storage.right := storage.right + b;
    };
}
  • Parameters and const values are visible in the continuation. A var from the first phase is not.
  • If the swap reverts, the whole transaction reverts, including the first phase's writes. To handle the failure instead, see Recovering from failed calls.
  • See Continuations and the Order executor.