Transaction Permission Layer Protocol v1.0

By 0age


The Transaction Permission Layer protocol (TPL) is a method for assigning metadata (herein referred to as “attributes”) to Ethereum addresses. These attributes then form the basis for designing systems that enforce permissions when performing certain transactions. Security token transfers are one such transaction, where compliance with various laws and regulations will compel tokens to only permit a transfer once a set of conditions (e.g. identity verification, KYC/AML, or other attributes) have been met. There are also other families of transactions that will benefit from a permissions system, e.g. voting in digital collectives, participating in communities that depend on reputation or resistance to Sybil attacks, and maintaining curated lists or registries.

In our last post, we outlined a potential approach to compliant token offerings that utilizes the TPL protocol to limit the pool of participants until a sufficient level of decentralization has been reached. Other approaches to verifying attributes on participant addresses tend to fall into two broad categories:

Many of the general-purpose identity proposals allow for multiple claimants to issue identical claims on a given address and topic. This means that each token that relies on those claims would have to track and weigh the relative reputation of each entity issuing the relevant claims and metadata. Ideally, token implementors would be able to get back one trusted result without needing to know about its exact source.

On the other hand, platform solutions run the risk of discouraging cross-compatibility and flexibility by creating “walled gardens” constructed to serve a particular use-case (that is, unless they utilize a protocol like TPL under the hood as a bridge). Furthermore, many implementors may find that custom-built identity proposals may prove too complex or inefficient when translated to fit their particular needs.

The following proposed architecture is intended to address these challenges and enables projects to simplify the task of performing compliant token transfers or other permissioned transactions by providing a singular, trusted source for attribute metadata via a standardized interface. To do so, it implements an easy-to-use, effective, and flexible transaction permission layer — the TPL protocol.

Technical overview

At the core of TPL is the jurisdiction — a single smart contract that links attributes to addresses. It implements the ERC-1616 Attribute Registry standard interface, where attributes are registered to addresses as a uint256 => uint256 key-value pair, defined as follows:

The four external functions that make up the Attribute Registry interface.

Permissioned tokens and other contracts can then use this interface to identify and confirm attributes recognized by a jurisdiction without needing to take on the additional technical overhead of managing attribute assignment and revocation themselves. (The implementor can then optionally enter into an agreement with a jurisdiction that places the burden of validating and revoking attributes onto the jurisdiction.) By way of example, a simple ERC20 token implementing a shared whitelist only needs to check the result of one call into the registry.

Example of a simple whitelisted transfer function that inherits from an existing ERC20 implementation.

In addition to the AttributeRegistry interface, jurisdictions also implement additional interfaces for setting and removing attributes, monitoring for relevant events, and getting more detailed information on attributes and their verifiers when needed.

There are four basic categories of actors or entities, explained in detail below, that interact with the jurisdiction: an owner, the validators, the pool of participants, and the implementors, such as permissioned tokens.

A broad overview of the categories of entity that interact with a jurisdiction.

Jurisdiction Owner

The creator of a jurisdiction may designate an initial controlling entity of their choosing, including a governance collective (DAO, multi-sig, etc) or a regular, externally-owned account. The controller is primarily responsible for defining attribute types that are recognized by the jurisdiction and for designating validators that can assign attributes of those types to addresses.

The owner may set and declare a variety of optional properties on those attribute types, including a human-readable description of the attribute, restrictions on whether participants can set or remove the attribute (useful for creating blacklists), requirements to pay fees or lock up funds in order to set the attribute (more on that later), and other properties.

Jurisdictions are also fully composable and cross-compatible with one another. To accomplish this, attribute types designate secondary sources, including other jurisdictions or any contract that implements an Attribute Registry interface, that will be queried whenever an attribute has not yet been set locally for a given address. This gives jurisdictions the ability to delegate authority to other jurisdictions on a targeted basis.

As a result, implementors do not have to call into multiple jurisdictions to get different attributes. Instead, they can petition their jurisdiction to add attribute types with the desired secondary sources, or even create their own jurisdiction that references all the sources they need.


The owner of the jurisdiction does not assign attributes directly. Instead, they designate validators, specializing in particular areas, to perform this task. Specific validators are then approved by the owner to issue any number of specific attribute types.

The four external functions that make up the Attribute Registry interface.

Multiple validators can be approved to issue a given attribute type, but only a single attribute of a given type may be assigned to a specific address at a time (though addresses may contain any number of attributes of varying types), ensuring a canonical source of truth of the attribute’s state.

If a validator is removed by the owner, it cannot issue any more attributes and all the attributes it has issued become invalid. If it is reinstated, issued attributes become valid again. The same principle applies to attribute types and to attribute approvals. This highlights a particular design feature that differentiates the TPL protocol: attributes have a high bar to clear in order to remain valid, reinforcing the reliability of claims made by a jurisdiction.

Issuing Attributes

Validators have three ways of issuing attributes to participants. They can:

  • sign an off-chain attribute approval that the participant can relay to the network themselves using addAttribute,
  • sign an off-chain attribute approval that designates a third-party address, or operator, that can then relay the attribute to the network on behalf of the address being assigned an attribute using addAttributeFor , and
  • call into the jurisdiction and set the attribute directly on behalf of the participant using issueAttribute.

In order to issue attributes of a given type, validators must first be approved to issue them by the jurisdiction owner. If the attribute type requires fees or locked funds (called the stake), the validator must either provide the funds themselves or require that the participant or operator do so. They may then specify their own optional requirements on an attribute-by-attribute basis, including the attribute’s assigned value, a validator fee to be paid upon assignment, and any additional required stake.

A collection of addresses, values, and staked amounts for a particular validator & attribute type.

NOTE: Additional features of the TPL protocol outlined below, such as stake, fees, and operator access, are totally optional to use, and can be ignored in a nearly-transparent fashion by a jurisdiction if so desired.

Stake & transaction rebates

If a validator needs to revoke an attribute they have issued, and if that attribute has any funds staked, the validator will receive a transaction rebate from that stake, with the remainder being refunded to the entity that locked up the staked funds. The jurisdiction owner may also revoke any particular attribute and receive a transaction rebate if applicable.

The refund amount is calculated by multiplying a fixed gas amount (based on a lower bound on transaction gas usage after rebates, currently set to 37,700) by the gas price of the transaction, and is paid out to the externally-owned account that submits the transaction.

Furthermore, a validator may invalidate a signed attribute approval prior to its usage by providing a hash derived from the approval as well as the signature associated with that hash. This option will not pay out a transaction rebate, as the participant has not yet submitted a transaction and locked up funds. However, it should only be required in highly targeted circumstances, as any attribute approval invalidation at scale can be achieved by simply modifying the validator’s signing key.

Signed attribute approvals

While validators can always assign and revoke attributes directly, signing approvals off-chain and letting the participant (or an operator, designated by the validator) submit the transaction has a number of beneficial properties:

  • Validators do not have to pay the transaction fee themselves, and can even require that the attribute assigner include any required stake or fees right in the submitting transaction.
  • Participants (or operators) may decide when they want to add the attribute, enhancing privacy and saving on fees when attributes are not ultimately required.
  • Validators can easily modify the properties of the assigned attributes to reflect changing conditions, or even cater them to the participant in question.

Validators have an associated signing key that can be changed, which will invalidate any unused attribute approvals but leave existing attributes intact. To sign an attribute approval, a validator may call the following with appropriate arguments:

An example function for off-chain signing of attribute approvals (ES6 / web3.js v1.0)


The TPL protocol is built with simplicity and efficiency in mind for ERC20, ERC721, ERC777, and ERC1400 tokens — for users and development teams alike. Tokens and other smart contracts that wish to interface with the jurisdiction should do the following:

  • first, in the token constructor, initialization function, or other setter function, define the external registry interface & contract address of the jurisdiction as well as the attribute IDs of the attributes they’re interested in;
  • next, in the transfer and transferFrom functions, check for the required attributes or attribute values as applicable before transferring the tokens. Approved operators (for example, tokens exchanged via 0x) do not necessarily need to have attributes assigned to them in order to operate transfers. That being said, tokens may still want to allow for “trap-door” attribute checks for proxies or other pass-through contracts.

Participants who are interested in transacting in projects that use TPL will need to go through the appropriate checks with an approved validator, which can be located via the jurisdiction’s methods or through more traditional channels. They or their designated operator then submit a signed attribute approval from the validator that sets the required attribute. Alternately, the validator may assign the attribute on their behalf.


All of our work on TPL is totally open-source; to dig in to the technical details, run tests, analyze contract efficiency and gas usage metrics, and test-drive the contracts, check out the TPL project repository on Github. Opening new issues and submitting pull requests is of course always welcome.

Get Involved

We encourage you to join the discussion on our Telegram Discussion Board, and to get in touch if you are interested in collaborating as an implementor, a validator, or a member of the governance collective in our pilot jurisdiction.

Thanks to Connor Spelliscy, Demi Brener, Santiago Palladino, Alejo Salles, Leo Arias, Nicolas Venturo, AJ Ostrow, Max Mersch, Louis Guthmann, Peter Kieltyka, and Sina Habibian for feedback and conversations which contributed to this post.