ERC-4519 Physical Asset-Linked NFT (Non-Fungible Tokens Tied to Physical Assets)

Final · NFTs & multi-token · created 2021-12-03

A standard interface for NFTs bound to physical assets such as Internet of Things (IoT) devices. It lets the asset sign with its own Ethereum address and mutually authenticate with its owner and user, so the link can be verified as genuine.

Why it is needed

EIP-721, the most widely used NFT standard, records only token ownership. It does not cover who actually uses the asset (the usage right), and it does not record the asset's own Ethereum address. So even if a smart asset such as an IoT device is represented as an NFT, there is no way to confirm that the token is really linked to that device, and a user who borrows the device cannot be managed separately from the owner. This standard solves the problem by storing the Ethereum addresses of the asset and the user in the NFT, letting the asset sign messages and transactions itself, and having the owner, the user, and the asset authenticate each other to create a secure communication channel. Even when the owner and user change, the asset's trustworthiness can still be tracked.

What to implement

In depth

Two address attributes and token states

The NFT can hold addressAsset, the asset's Ethereum address, and addressUser, the user's address. Both are optional attributes, but at least one must be used. If only addressUser is used, the token alternates between two states, notAssigned and userAssigned: it is notAssigned when created, transferred or unassigned, and becomes userAssigned when assigned to a valid user. If only addressAsset is used, it has two states, waitingForOwner and engagedWithOwner: it becomes waitingForOwner when created or transferred to a new owner, and becomes engagedWithOwner once mutual authentication between the asset and the owner is complete. If both are used, there are four states, waitingForOwner, engagedWithOwner, waitingForUser and engagedWithUser, which indicate whether the asset is connected to the owner and the user.

Elliptic curve based key agreement

To complete an ownership transfer, the new owner must perform mutual authentication with the asset. It is done off-chain with the asset and on-chain with the token. Using the elliptic curve secp256k1 and the base point P, the owner creates a secret key SK_O_A and a public key PK_O_A = SK_O_A * P, then computes the shared key K_O = PK_A * SK_O_A from the asset's public key PK_A. The asset computes K_A = SK_A * PK_O_A with its own secret key, and mathematically the two values are equal. The token stores the public data needed for the agreement in dataEngagement and the hashes of the shared keys in hashK_OA and hashK_UA, and the asset, owner and user must verify that they are using the correct shared secret key. Because a new session key is created for each authentication, the asset's trustworthiness can be traced even when the owner and user change.

Conditions for the owner authentication functions

startOwnerEngagement can be called only by the token owner, when addressAsset is defined and the token state is waitingForOwner. It does not change the state and only stores _dataEngagement and _hashK_OA in the token. ownerEngagement can be called only by the asset bound to the token, when the state is waitingForOwner and dataEngagement is not 0. It compares the hashK_OA stored in the token with the hashK_A sent by the asset, and if they match it changes the state to engagedWithOwner, sets dataEngagement to 0 and emits an OwnerEngaged event. The asset receives this event and switches its own operating mode to engagedWithOwner.

User assignment and user authentication

setUser can be called only by the token owner. If addressAsset is defined, the token state must be one of engagedWithOwner, waitingForUser and engagedWithUser, and the state after the call is waitingForUser. If addressAsset is absent, the state becomes userAssigned. In both cases addressUser is set to _addressUser. When the asset queries the chain and sees that its NFT is in the waitingForUser state, it switches its operating mode to waitingForUser and performs the same mutual authentication with the user that it did with the owner. startUserEngagement can be called only by the user, when addressAsset and addressUser are defined and the state is waitingForUser. userEngagement is called only by the asset, and if the hashes match it changes the state to engagedWithUser and emits a UserEngaged event. From then on the user can use the asset.

Timestamp and timeout

The token has a timestamp attribute, which records when the asset last confirmed its connection, and a timeout attribute, which is the maximum delay within which the asset must prove its connection again. This mechanism prevents a malicious owner or user from using the asset indefinitely. When the asset calls updateTimestamp, the contract must use block.timestamp. This value is in Unix seconds, so timeout must also be specified in seconds. Anyone can call checkTimeout to check whether the timeout has expired, and if it has, a TimeoutAlarm event is emitted. setTimeout can be called only by the owner, when the token state is engagedWithOwner, waitingForUser or engagedWithUser.

Query functions and EIP-721 compatibility

The standard provides read-only functions such as tokenFromBCA to find a token from an asset address, ownerOfFromBCA to find the owner, userOfFromBCA and userOf to find the user, and userBalanceOf and userBalanceOfAnOwner to count the tokens assigned to a user, so anyone can query the relationship between assets and tokens on chain. This standard extends EIP-721, the most widely used NFT standard, and is fully compatible with the optional extensions IERC721Metadata and IERC721Enumerable. The EIP-165 identifier of this interface is 0x8a68abe3. This proposal is a standard finalized in Final status.

Things to watch out for

Original ERC · ← ERCs