  Decentralized applications (dApps) consist of smart contracts that run on
blockchains and clients that model collaborating parties. dApps are used to
model financial and legal business functionality. Today, contracts and clients
are written as separate programs -- in different programming languages --
communicating via send and receive operations. This makes distributed program
flow awkward to express and reason about, increasing the potential for
mismatches in the client-contract interface, which can be exploited by
malicious clients, potentially leading to huge financial losses. In this paper,
we present Prisma, a language for tierless decentralized applications, where
the contract and its clients are defined in one unit and pairs of send and
receive actions that "belong together" are encapsulated into a single
direct-style operation, which is executed differently by sending and receiving
parties. This enables expressing distributed program flow via standard control
flow and renders mismatching communication impossible. We prove formally that
our compiler preserves program behavior in presence of an attacker controlling
the client code. We systematically compare Prisma with mainstream and advanced
programming models for dApps and provide empirical evidence for its
expressiveness and performance.
