The attribute module functions as a blockchain registry system that enables accounts to associate structured data with their addresses. This data takes the form of name-value pairs where the name must be registered through the Name Service, and each name can have multiple values of different types associated with it.
ConceptsStateOverviewAttribute KV-StoreKey Generation ProcessKey LayoutKey Components BreakdownAttribute RecordField DescriptionsAttribute TypesSupported Data TypesState Storage ArchitectureStorage ModelKey BenefitsStorage OperationsSummaryMessagesOverviewMessage Types1. MsgAddAttributeRequestMessage StructureValidation RulesSuccess Result2. MsgUpdateAttributeRequestMessage StructureValidation RulesSuccess Result3. MsgUpdateAttributeExpirationRequestMessage StructureValidation Rules4. MsgDeleteAttributeRequestMessage StructureValidation Rules5. MsgDeleteDistinctAttributeRequestMessage StructureValidation Rules6. MsgSetAccountDataRequestMessage StructureValidation RulesSummaryKey Security Features:EventsOverviewEvent CategoriesEvent Types1. Attribute Added2. Attribute UpdatedUpdate Tracking Features:3. Attribute Expiration Updated4. Attribute DeletedNote: This event covers general attribute deletion by name.5. Distinct Attribute DeletedDistinction from Regular Delete:6. Attribute ExpiredAutomatic Lifecycle Management:7. Account Data UpdatedSimple but Important:SummaryComplete Lifecycle TrackingRich Event DataBusiness ValueQueriesParamsOverviewModule ParametersMaxValueLength
Concepts
The purpose of the Attributes Module is to act as a registry that allows an Address to store
<Name, Value>
pairs. Every Name must be registered by the Name Service, and a Name have multiple Values associated with it. Values are required to have a type, and they can be set or retrieved by Name.This feature provides the blockchain with the capability to store and retrieve values by Name. It plays a major part in some of our components such as smart contract creation process. It allows an Address to create and store a named smart contract on the blockchain.
State
Overview
The attribute module inserts all attributes into a basic state store. This module provides a structured way to store and retrieve typed key-value pairs associated with blockchain accounts.
Attribute KV-Store
The attribute module takes in an attribute supplied by the user and generates a unique key for it. This key generation process combines multiple components to ensure uniqueness and efficient retrieval.
Key Generation Process
The key is generated by combining the following components:
- Attribute prefix - Module identifier
- Address - Account address the attribute belongs to
- Attribute name - The name of the attribute
- Hash value - Hashed value of the attribute content
This composite key can then be used to either:
- Store a marshaled attribute record
- Retrieve the value it points to in the store
Key Layout
The key structure follows a specific byte layout pattern:
plain text[0x02][address][attribute name][hashvalue]
Key Components Breakdown
Component | Description | Purpose |
0x02 | Module prefix byte | Identifies attribute module data |
address | Account address | Associates attribute with specific account |
attribute name | Name identifier | Specifies which attribute this is |
hashvalue | Hash of attribute value | Ensures uniqueness for duplicate names |
Attribute Record
The core data structure that represents an attribute in the state store.
go// Attribute holds a typed key/value structure for data associated with an account type Attribute struct { // The attribute name. Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // The attribute value. Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` // The attribute value type. AttributeType AttributeType `protobuf:"varint,3,opt,name=attribute_type,json=attributeType,proto3,enum=provenance.attribute.v1.AttributeType" json:"attribute_type,omitempty"` // The address the attribute is bound to Address string `protobuf:"bytes,4,opt,name=address,proto3" json:"address,omitempty"` }
Field Descriptions
Field | Type | Description |
Name | string | The human-readable name of the attribute |
Value | []byte | The actual data content stored as bytes |
AttributeType | AttributeType | Enum defining how to interpret the value |
Address | string | The blockchain address this attribute belongs to |
Attribute Types
The attribute module supports multiple data types to ensure type safety and proper data interpretation.
go// AttributeType defines the type of the data stored in the attribute value type AttributeType int32 const ( // ATTRIBUTE_TYPE_UNSPECIFIED defines an unknown/invalid type AttributeType_Unspecified AttributeType = 0 // ATTRIBUTE_TYPE_UUID defines an attribute value that contains a string value representation of a V4 uuid AttributeType_UUID AttributeType = 1 // ATTRIBUTE_TYPE_JSON defines an attribute value that contains a byte string containing json data AttributeType_JSON AttributeType = 2 // ATTRIBUTE_TYPE_STRING defines an attribute value that contains a generic string value AttributeType_String AttributeType = 3 // ATTRIBUTE_TYPE_URI defines an attribute value that contains a URI AttributeType_Uri AttributeType = 4 // ATTRIBUTE_TYPE_INT defines an attribute value that contains an integer (cast as int64) AttributeType_Int AttributeType = 5 // ATTRIBUTE_TYPE_FLOAT defines an attribute value that contains a float AttributeType_Float AttributeType = 6 // ATTRIBUTE_TYPE_PROTO defines an attribute value that contains a serialized proto value in bytes AttributeType_Proto AttributeType = 7 // ATTRIBUTE_TYPE_BYTES defines an attribute value that contains an untyped array of bytes AttributeType_Bytes AttributeType = 8 )
Supported Data Types
Type ID | Type Name | Description | Use Cases |
0 | Unspecified | Unknown/invalid type | Error handling |
1 | UUID | V4 UUID string representation | Unique identifiers |
2 | JSON | JSON data as byte string | Structured data |
3 | String | Generic string value | Text data |
4 | URI | Uniform Resource Identifier | Links and references |
5 | Int | Integer (cast as int64) | Numeric data |
6 | Float | Floating point number | Decimal values |
7 | Proto | Serialized protobuf bytes | Binary protocol data |
8 | Bytes | Untyped byte array | Raw binary data |
State Storage Architecture
Storage Model
plain textState Store โโโ Attribute Records (by composite key) โ โโโ [0x02][address1][name1][hash1] โ Attribute{...} โ โโโ [0x02][address1][name2][hash2] โ Attribute{...} โ โโโ [0x02][address2][name1][hash3] โ Attribute{...} โโโ Index Structures (for efficient queries)
Key Benefits
- Efficient Lookup: Composite keys enable fast retrieval
- Type Safety: Strongly typed attribute values
- Flexible Data: Support for 8 different data types
- Multiple Values: Same name can have different values per account
- Performance: Hash-based key generation for uniqueness
Storage Operations
Operation | Description | Key Usage |
Create | Store new attribute record | Generate new composite key |
Read | Retrieve attribute by key | Use existing composite key |
Update | Modify existing attribute | Update record at existing key |
Delete | Remove attribute record | Remove entry by composite key |
Summary
The x/attribute module state management provides:
- Efficient Storage: Composite key structure for optimal performance
- Type Flexibility: 8 different attribute types for various data needs
- Account Binding: Attributes are securely tied to specific addresses
- Scalability: Hash-based keys prevent naming conflicts
- Fast Retrieval: Direct key-based lookups in the state store
This architecture enables the attribute module to serve as a robust registry for storing structured data associated with blockchain accounts while maintaining performance and type safety.
Messages
Overview
In this section we describe the processing of the attribute messages and the corresponding updates to the state. The attribute module provides several message types for managing attribute data associated with accounts.
Message Types
1. MsgAddAttributeRequest
An attribute record is created using the
MsgAddAttributeRequest
message.Message Structure
protobuf// MsgAddAttributeRequest defines an sdk.Msg type that is used to add a new attribute to an account. // Attributes may only be set in an account by the account that the attribute name resolves to. message MsgAddAttributeRequest { option (gogoproto.equal) = false; option (gogoproto.goproto_stringer) = false; option (gogoproto.stringer) = false; option (gogoproto.goproto_getters) = false; // The attribute name. string name = 1; // The attribute value. bytes value = 2; // The attribute value type. AttributeType attribute_type = 3; // The account to add the attribute to. string account = 4; // The address that the name must resolve to. string owner = 5; // Time that an attribute will expire. google.protobuf.Timestamp expiration_date = 6 [(gogoproto.stdtime) = true, (gogoproto.nullable) = true]; }
Validation Rules
This message is expected to fail if:
- Any components of the request do not pass basic integrity and format checks
- Attribute value exceeds the maximum length
- Unable to normalize the name
- The account does not exist
- The name does not resolve to the owner address
Success Result
If successful, an attribute record will be created for the account.
2. MsgUpdateAttributeRequest
The update attribute request method allows an existing attribute record to replace its value with a new one.
Message Structure
protobuf// MsgUpdateAttributeRequest defines an sdk.Msg type that is used to update an existing attribute to an account. // Attributes may only be set in an account by the account that the attribute name resolves to. message MsgUpdateAttributeRequest { option (gogoproto.equal) = false; option (gogoproto.goproto_stringer) = false; option (gogoproto.stringer) = false; option (gogoproto.goproto_getters) = false; // The attribute name. string name = 1; // The original attribute value. bytes original_value = 2; // The update attribute value. bytes update_value = 3; // The original attribute value type. AttributeType original_attribute_type = 4; // The update attribute value type. AttributeType update_attribute_type = 5; // The account to add the attribute to. string account = 6; // The address that the name must resolve to. string owner = 7; }
Validation Rules
This message is expected to fail if:
- Any components of the request do not pass basic integrity and format checks
- Updated attribute value exceeds the maximum length
- Unable to normalize the original or updated attribute name
- Updated name and the original name don't match
- The owner account does not exist
- The updated name does not resolve to the owner address
- The original attribute does not exist
Success Result
If successful, the value of an attribute will be updated.
3. MsgUpdateAttributeExpirationRequest
The update attribute expiration request method updates the attribute's expiration date.
Message Structure
protobuf// MsgUpdateAttributeExpirationRequest defines an sdk.Msg type that is used to update an existing attribute's expiration // date message MsgUpdateAttributeExpirationRequest { option (gogoproto.equal) = true; option (gogoproto.stringer) = true; option (gogoproto.goproto_stringer) = false; // The attribute name. string name = 1; // The original attribute value. bytes value = 2; // Time that an attribute will expire. google.protobuf.Timestamp expiration_date = 3 [(gogoproto.stdtime) = true, (gogoproto.nullable) = true]; // The account to add the attribute to. string account = 4; // The address that the name must resolve to. string owner = 5; }
Validation Rules
This message is expected to fail if:
- Any components of the request do not pass basic integrity and format checks
- The owner account does not exist
- The name does not resolve to the owner address
- The attribute does not exist
- The expiration date is before current block height
4. MsgDeleteAttributeRequest
The delete attribute request method removes an existing account attribute.
Message Structure
protobuf// MsgDeleteAttributeRequest defines a message to delete an attribute from an account // Attributes may only be removed from an account by the account that the attribute name resolves to. message MsgDeleteAttributeRequest { option (gogoproto.equal) = false; option (gogoproto.goproto_stringer) = false; option (gogoproto.stringer) = false; option (gogoproto.goproto_getters) = false; // The attribute name. string name = 1; // The account to add the attribute to. string account = 2; // The address that the name must resolve to. string owner = 3; }
Validation Rules
This message is expected to fail if:
- Any components of the request do not pass basic integrity and format checks
- The owner account does not exist
- The name does not resolve to the owner address
- The attribute does not exist
5. MsgDeleteDistinctAttributeRequest
The delete distinct attribute request method removes an existing account attribute with a specific value.
Message Structure
protobuf// MsgDeleteDistinctAttributeRequest defines a message to delete an attribute with matching name, value, and type from // an account. Attributes may only be removed from an account by the account that the attribute name resolves to. message MsgDeleteDistinctAttributeRequest { option (gogoproto.equal) = false; option (gogoproto.goproto_stringer) = false; option (gogoproto.stringer) = false; option (gogoproto.goproto_getters) = false; // The attribute name. string name = 1; // The attribute value. bytes value = 2; // The account to add the attribute to. string account = 3; // The address that the name must resolve to. string owner = 4; }
Validation Rules
This message is expected to fail if:
- Any components of the request do not pass basic integrity and format checks
- The owner account does not exist
- The name does not resolve to the owner address
- The attribute does not exist
6. MsgSetAccountDataRequest
The set account data request method associates some data (a string) with an account.
Message Structure
protobuf// MsgSetAccountDataRequest defines a message to set an account's accountdata attribute. message MsgSetAccountDataRequest { option (cosmos.msg.v1.signer) = "account"; string value = 1; string account = 2; }
Validation Rules
This message is expected to fail if:
- The value is too long (as defined in attribute module params)
- The message is not signed by the provided account
Summary
The attribute module provides 6 message types for comprehensive attribute management:
Message Type | Purpose | Key Features |
MsgAddAttributeRequest | Create new attribute | Supports expiration dates |
MsgUpdateAttributeRequest | Update existing attribute | Can change value and type |
MsgUpdateAttributeExpirationRequest | Update expiration only | Modify expiration dates |
MsgDeleteAttributeRequest | Delete attribute by name | Removes all matching attributes |
MsgDeleteDistinctAttributeRequest | Delete specific attribute | Removes exact value match |
MsgSetAccountDataRequest | Set account data | Simple string data association |
Key Security Features:
- All operations require name resolution to owner address
- Account existence validation
- Integrity and format checking
- Maximum length enforcement
- Proper signing requirements
Events
Overview
The attribute module emits comprehensive events to track all attribute lifecycle operations. These events provide detailed information about attribute changes, enabling applications to monitor and react to attribute modifications in real-time.
Event Categories
The attribute module emits 7 distinct event types covering the complete attribute lifecycle:
Event Category | Events Count | Purpose |
Create | 1 | Track new attribute creation |
Update | 2 | Monitor attribute modifications |
Delete | 2 | Log attribute removal operations |
Lifecycle | 1 | Handle automatic expiration |
Account Data | 1 | Track account data changes |
Event Types
1. Attribute Added
Trigger: Fires when an attribute is successfully added to an account.
Proto Type:
provenance.attribute.v1.EventAttributeAdd
Attribute Key | Attribute Value | Description |
Name | {name string} | The name of the added attribute |
Value | {attribute value} | The value content of the attribute |
Type | {attribute value type} | The data type of the attribute |
Account | {account address} | The target account address |
Owner | {owner address} | The owner who added the attribute |
Expiration | {expiration date/time} | When the attribute expires (if set) |
2. Attribute Updated
Trigger: Fires when an existing attribute is successfully updated.
Proto Type:
provenance.attribute.v1.EventAttributeUpdate
Attribute Key | Attribute Value | Description |
Name | {name string} | The name of the updated attribute |
OriginalValue | {attribute value} | The previous attribute value |
OriginalType | {attribute value type} | The previous attribute type |
UpdateValue | {new attribute value} | The new attribute value |
UpdateType | {new attribute value type} | The new attribute type |
Account | {account address} | The target account address |
Owner | {owner address} | The owner who updated the attribute |
Update Tracking Features:
- Before/After Values: Complete audit trail of changes
- Type Changes: Tracks data type modifications
- Owner Validation: Ensures proper authorization
3. Attribute Expiration Updated
Trigger: Fires when an existing attribute's expiration date is successfully updated.
Proto Type:
provenance.attribute.v1.EventAttributeExpirationUpdate
Attribute Key | Attribute Value | Description |
Name | {name string} | The name of the attribute |
Value | {attribute value} | The current attribute value |
Account | {account address} | The target account address |
Owner | {owner address} | The owner who updated expiration |
OriginalExpiration | {old expiration date/time} | The previous expiration time |
UpdatedExpiration | {new expiration date/time} | The new expiration time |
4. Attribute Deleted
Trigger: Fires when an existing attribute is deleted from an account.
Proto Type:
provenance.attribute.v1.EventAttributeDelete
Attribute Key | Attribute Value | Description |
Name | {name string} | The name of the deleted attribute |
Account | {account address} | The target account address |
Owner | {owner address} | The owner who deleted the attribute |
Note: This event covers general attribute deletion by name.
5. Distinct Attribute Deleted
Trigger: Fires when an existing attribute is deleted with specific value matching.
Proto Type:
provenance.attribute.v1.EventAttributeDistinctDelete
Attribute Key | Attribute Value | Description |
Name | {name string} | The name of the deleted attribute |
Value | {attribute value} | The specific value that was deleted |
AttributeType | {attribute value type} | The type of the deleted attribute |
Owner | {owner address} | The owner who deleted the attribute |
Account | {account address} | The target account address |
Distinction from Regular Delete:
- Exact Match: Deletes only attributes with specific name + value + type
- Granular Control: Allows precise attribute removal
- Value Tracking: Records the exact value that was removed
6. Attribute Expired
Trigger: Fires when an attribute's expiration date/time has been reached and the attribute has been automatically deleted.
Proto Type:
provenance.attribute.v1.EventAttributeExpired
Attribute Key | Attribute Value | Description |
Name | {name string} | The name of the expired attribute |
Value | {attribute value} | The value of the expired attribute |
AttributeType | {attribute value type} | The type of the expired attribute |
Account | {account address} | The account that owned the attribute |
Owner | {owner address} | The original owner of the attribute |
Expiration | {expiration date/time} | The expiration timestamp |
Automatic Lifecycle Management:
- System Triggered: No manual intervention required
- Complete Audit: Full details of expired attribute
- Timestamp Verification: Exact expiration time recorded
7. Account Data Updated
Trigger: Fires when account data is updated for an account.
Attribute Key | Attribute Value | Description |
Account | {account address} | The account whose data was updated |
Simple but Important:
- Account-Level Changes: Tracks broader account data modifications
- Integration Point: Useful for account monitoring systems
Summary
The x/attribute module provides comprehensive event coverage for:
Complete Lifecycle Tracking
- Creation: Full details of new attributes
- Modification: Before/after change tracking
- Deletion: Multiple deletion patterns supported
- Expiration: Automatic lifecycle management
Rich Event Data
- Owner Information: Authentication and authorization details
- Value Tracking: Complete data change history
- Type Safety: Attribute type information included
- Timestamp Data: Expiration and modification times
Business Value
- Compliance: Complete audit trails for regulatory requirements
- Monitoring: Real-time attribute change detection
- Integration: Rich event data for external systems
- Debugging: Detailed operation tracking for troubleshooting
Queries
We are still updating our documentation, but for now, you can review supported queries at by looking at the query proto in our Github.
Params
Overview
The attribute module contains configurable parameters that control the behavior and constraints of attribute operations. These parameters ensure proper resource management and maintain system performance by setting operational limits.
Module Parameters
The x/attribute module currently contains the following parameters:
MaxValueLength
Controls the maximum allowed length for attribute values to prevent resource exhaustion.
Parameter | Type | Default Value | Description |
MaxValueLength | uint32 | 32 | Maximum number of bytes allowed for an attribute value |