Skip to main content

SmartWeave Protocol

This document describes the core concepts behind the SmartWeave smart contracts protocol and is based on the original smartweave.js contract-guide.


SmartWeave is a data-centered protocol built on top of the Arweave chain that allows to implement smart contracts. The key difference between SmartWeave and other similar solutions is that the contracts can be evaluated on-demand and "lazily".

Most smart contracts treat data as a side-product that slows down processing. Data is digested, pruned, and pushed out to side chains. Nonetheless, the bloated global state is still the biggest challenge of modern blockchains - as it leads to extreme costs of data storage.

SmartWeave approach, on the other hand, has several advantages:

  1. It decouples the storage from the computation
  2. It allows for a flexible lazy-evaluation pattern
  3. It allows to directly process rich content.

Building SmartWeave on the Arweave allows saving time on the development of the basic infrastructure.

Protocol Specification

The SmartWeave protocol consists of few key concepts:

  1. Contract creation
  2. Contract interactions
  3. Lazy-evaluation of the contract state

Contract creation

In order to deploy a new contract on Arweave the SmartWeave client must:

  1. Create an Arweave transaction with contract source code
Transaction fieldValue
dataContract Source Code specification
tag['App-Version']the current version of the SDK, e.g. version from package.json
  1. Create an Arweave transaction with contract definition
Transaction fieldValue
data(*)Contract initial state - stringified json object - e.g. JSON.stringify(initialState)
tag['Init-State'](*)Contract initial state - as alternative for setting it in data field
tag['Init-State-TX'](*)Id of the transaction the holds the initial state
tag['App-Version']the current version of the SDK, e.g. version from package.json
tag['Contract-Src']id of the transaction created in previous step, eg: ovqOT6dVD7zYZYmIkq52gmSippk2MGs_TjXs3-D4BLU

(*) Either one of these options must be chosen for storing the initial state.

Contract source code specification

  1. A contract source code MAY be written in ES module format.
  2. A contract source MUST contain function (sync or async) named handle.
  3. A contract source MAY use IIFE bundling format.
  4. The handle function MUST accept exactly two arguments: state and action
  5. The state argument MUST be the current state of the contract.
  6. The action argument MUST contain caller field (i.e. Arweave wallet address) and input field. The input field MUST contain the function field and any additional data required to perform given operation.
  7. The maximum size of the JSON.stringified representation of the input field MUST NOT exceed 2048 bytes.
  8. The handle function MUST terminate by either:
    1. returning { state: newState } - this will cause the contract state to be updated
    2. returning { result: newResult }
    3. throwing ContractError

Contract Interactions

Contract interactions allow to modify the contract state. Each interaction MUST be deployed as a separate Arweave transaction:

Transaction fieldValue
tag['App-Version']the current version of the SDK, e.g. version from package.json
tag['Contract']Transaction id of the contract
tag['Input']JSON.stringified representation of the input

Lazy-evaluation of the contract state

In its current form, the SmartWeave protocol assumes that smart contract code is a javascript function, defined as:

contractFunction = (state, action) => state;

This function takes a state and an action as input arguments - and produces a new state as a result. In functional programming terms it acts as a fold function - the state of the contract is derived from:

  1. An initial state
  2. A contract function
  3. An ordered list of actions


In order to evaluate contract state, SmartWeave Protocol client:

  1. Loads all the contract's interaction transactions up to the requested block height.
  2. Sorts the interaction transactions. The order of the interactions is determined firstly by interaction transaction block height (i.e. when the transaction was mined in the chain) and secondly by sha256(transactionId + blockHash). The full ordering is [ block_height, sha256(transactionId + blockHash) ].
  3. Applies the sorted interactions onto the contract's handler function - evaluating contract's state up to the requested block height.