Soroban Smart Contract for Decentralized Identifiers as standardized by W3C DIDs v1.0 specification.
Important
🤝 In line with our commitment to contribute to the Stellar community, we have developed this DID smart contract that serves as an interface. This contract can be utilized by anyone seeking to innovate with a solution that follows the W3C specification.
The DID contract enables you to manage a Decentralized Identifier within the Soroban & Stellar ecosystem. With this smart contract, you will be able to:
- Create a DID.
- Update the DID attributes.
- Retrieve the DID document.
- Set the contract admin.
- Upgrade the contract.
- Get the contract version.
Defines the type of verification method associated with a DID subject.
Tip
Allowed values: Ed25519VerificationKey2020
, X25519KeyAgreementKey2020
Expresses the relationship between the DID subject and a verification method.
Tip
Allowed values: Authentication
, AssertionMethod
, KeyAgreement
, CapabilityInvocation
, CapabilityDelegation
.
Represents a cryptographic key or method used for verification purposes.
This type is used as parameter to set the verification methods in the Initialize and Update DID functions.
Name | Type | Values |
---|---|---|
id |
String |
Arbitrary identifier (e.g., keys-1 ). |
type_ |
VerificationMethodType |
See VerificationMethodType. |
controller |
String |
If the DID URI is not provided, the DID URI from the contract is set as the controller. |
public_key_multibase |
String |
Public key encoded in Multibase format (Base58BTC). |
verification_relationships |
Vec<VerificationRelationship> |
List of VerificationRelationships. |
{
"id": "keys-1",
"type_": "Ed25519VerificationKey2020",
"controller": "",
"public_key_multibase": "z6MkgpAN9rsVPXJ6DrrvxcsGzKwjdkVdvjNtbQsRiLfsqmuQ",
"verification_relationships": ["Authentication", "AssertionMethod"]
}
Represents a cryptographic key or method used for verification purposes.
This type is used to represent a verification method in the DIDDocument type.
Name | Type | Values |
---|---|---|
id |
String |
DID URI appended with an arbitrary identifier. |
type_ |
VerificationMethodType |
See VerificationMethodType. |
controller |
String |
DID URI of the key controller. |
public_key_multibase |
String |
Public key encoded in Multibase format (Base58BTC). |
{
"id": "did:chaincerts:565s4nk6hch3jxlqjtn3e4il#keys-1",
"type_": "Ed25519VerificationKey2020",
"controller": "did:chaincerts:565s4nk6hch3jxlqjtn3e4il",
"public_key_multibase": "z6MkgpAN9rsVPXJ6DrrvxcsGzKwjdkVdvjNtbQsRiLfsqmuQ",
}
Defines the service type associated with a DID.
Tip
Allowed values: LinkedDomains
, DIDComm
, DIDCommMessaging
, CredentialRegistry
, OID4VCI
, OID4VP
.
Extends the functionality of DIDs by providing detailed information about specific services associated with a DID.
Name | Type | Values |
---|---|---|
id |
String |
Arbitrary identifier. |
type_ |
ServiceType |
See ServiceType. |
service_endpoint |
String |
The service endpoint URL. |
{
"id": "chaincerts",
"type_": "LinkedDomains",
"service_endpoint": "https://chaincerts.co"
}
Represents a W3C DID document, which is a set of data that describes the DID subject.
Name | Type | Values |
---|---|---|
id |
String |
DID URI generated on initialization. |
context |
Vec<String> |
List of URLs defining W3C DID spec version and verification method suites. |
verification_method |
Vec<VerificationMethod> |
List of VerificationMethods |
authentication |
Vec<String> |
List of verification method ids for authentication. |
assertion_method |
Vec<String> |
List of verification method ids for assertion. |
key_agreement |
Vec<String> |
List of verification method ids for key agreement. |
capability_invocation |
Vec<String> |
List of verification method ids for capability invocation. |
capability_delegation |
Vec<String> |
List of verification method ids for capability delegation. |
service |
Vec<Service> |
List of Services. |
{
"id": "did:chaincerts:vyfrxab6umfxddlzl62jktu7",
"context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/suites/ed25519-2020/v1",
"https://w3id.org/security/suites/x25519-2020/v1"
],
"verification_method": [
{
"controller": "did:chaincerts:vyfrxab6umfxddlzl62jktu7",
"id": "did:chaincerts:vyfrxab6umfxddlzl62jktu7#keys-1",
"public_key_multibase": "z6MkgpAN9rsVPXJ6DrrvxcsGzKwjdkVdvjNtbQsRiLfsqmuQ",
"type_": "Ed25519VerificationKey2020"
},
{
"controller": "did:chaincerts:vyfrxab6umfxddlzl62jktu7",
"id": "did:chaincerts:vyfrxab6umfxddlzl62jktu7#keys-2",
"public_key_multibase": "z6LSnL6WNE3cqZyWBqh9JTQ3DwWNNvXuNVD8oKZL8jdFyuWN",
"type_": "X25519KeyAgreementKey2020"
}
],
"authentication": [
"did:chaincerts:vyfrxab6umfxddlzl62jktu7#keys-1"
],
"assertion_method": [
"did:chaincerts:vyfrxab6umfxddlzl62jktu7#keys-1"
],
"key_agreement": [
"did:chaincerts:vyfrxab6umfxddlzl62jktu7#keys-2"
],
"capability_invocation": [],
"capability_delegation": [],
"service": [
{
"id": "did:chaincerts:vyfrxab6umfxddlzl62jktu7#chaincerts",
"service_endpoint": "https://chaincerts.co",
"type_": "LinkedDomains"
}
]
}
Initializes the DID Contract by generating the DID URI, setting the contract admin, and storing the DID attributes: Context
, VerificationMethods
, and Services
. The DID URI is generated by concatenating the DID method name with a random value encoded in Base32.
fn initialize(
e: Env,
admin: Address,
did_method: String,
context: Vec<String>,
verification_methods: Vec<VerificationMethodEntry>,
services: Vec<Service>
) -> DIDDocument;
Returns a DID document.
soroban contract invoke \
--id CONTRACT_ID \
--source SOURCE_ACCOUNT_SECRET_KEY \
--rpc-url https://soroban-testnet.stellar.org:443 \
--network-passphrase 'Test SDF Network ; September 2015' \
-- \
initialize \
--admin ADMIN_PUBLIC_KEY \
--did_method chaincerts \
--services '[{"id": "chaincerts", "type_": "LinkedDomains", "service_endpoint": "https://chaincerts.co"}]' \
--verification_methods '[{"id": "keys-1", "type_": "Ed25519VerificationKey2020", "controller": "", "public_key_multibase": "z6MkgpAN9rsVPXJ6DrrvxcsGzKwjdkVdvjNtbQsRiLfsqmuQ", "verification_relationships": ["Authentication", "AssertionMethod"]}, {"id": "keys-2", "type_": "X25519KeyAgreementKey2020", "controller": "", "public_key_multibase": "z6LSnL6WNE3cqZyWBqh9JTQ3DwWNNvXuNVD8oKZL8jdFyuWN", "verification_relationships": ["KeyAgreement"]}]' \
--context '["https://www.w3.org/ns/did/v1", "https://w3id.org/security/suites/ed25519-2020/v1", "https://w3id.org/security/suites/x25519-2020/v1"]'
# Output: DID DOCUMENT
{
"id": "did:chaincerts:vyfrxab6umfxddlzl62jktu7",
"context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/suites/ed25519-2020/v1",
"https://w3id.org/security/suites/x25519-2020/v1"
],
"verification_method": [
{
"controller": "did:chaincerts:vyfrxab6umfxddlzl62jktu7",
"id": "did:chaincerts:vyfrxab6umfxddlzl62jktu7#keys-1",
"public_key_multibase": "z6MkgpAN9rsVPXJ6DrrvxcsGzKwjdkVdvjNtbQsRiLfsqmuQ",
"type_": "Ed25519VerificationKey2020"
},
{
"controller": "did:chaincerts:vyfrxab6umfxddlzl62jktu7",
"id": "did:chaincerts:vyfrxab6umfxddlzl62jktu7#keys-2",
"public_key_multibase": "z6LSnL6WNE3cqZyWBqh9JTQ3DwWNNvXuNVD8oKZL8jdFyuWN",
"type_": "X25519KeyAgreementKey2020"
}
],
"authentication": [
"did:chaincerts:vyfrxab6umfxddlzl62jktu7#keys-1"
],
"assertion_method": [
"did:chaincerts:vyfrxab6umfxddlzl62jktu7#keys-1"
],
"key_agreement": [
"did:chaincerts:vyfrxab6umfxddlzl62jktu7#keys-2"
],
"capability_invocation": [],
"capability_delegation": [],
"service": [
{
"id": "did:chaincerts:vyfrxab6umfxddlzl62jktu7#chaincerts",
"service_endpoint": "https://chaincerts.co",
"type_": "LinkedDomains"
}
]
}
Provides the DID document.
fn get_did(e: Env) -> DIDDocument;
Returns a DID document.
soroban contract invoke \
--id CONTRACT_ID \
--source SOURCE_ACCOUNT_SECRET_KEY \
--rpc-url https://soroban-testnet.stellar.org:443 \
--network-passphrase 'Test SDF Network ; September 2015' \
-- \
get_did
# Output: DID DOCUMENT
{
"id": "did:chaincerts:vyfrxab6umfxddlzl62jktu7",
"context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/suites/ed25519-2020/v1",
"https://w3id.org/security/suites/x25519-2020/v1"
],
"verification_method": [
{
"controller": "did:chaincerts:vyfrxab6umfxddlzl62jktu7",
"id": "did:chaincerts:vyfrxab6umfxddlzl62jktu7#keys-1",
"public_key_multibase": "z6MkgpAN9rsVPXJ6DrrvxcsGzKwjdkVdvjNtbQsRiLfsqmuQ",
"type_": "Ed25519VerificationKey2020"
},
{
"controller": "did:chaincerts:vyfrxab6umfxddlzl62jktu7",
"id": "did:chaincerts:vyfrxab6umfxddlzl62jktu7#keys-2",
"public_key_multibase": "z6LSnL6WNE3cqZyWBqh9JTQ3DwWNNvXuNVD8oKZL8jdFyuWN",
"type_": "X25519KeyAgreementKey2020"
}
],
"authentication": [
"did:chaincerts:vyfrxab6umfxddlzl62jktu7#keys-1"
],
"assertion_method": [
"did:chaincerts:vyfrxab6umfxddlzl62jktu7#keys-1"
],
"key_agreement": [
"did:chaincerts:vyfrxab6umfxddlzl62jktu7#keys-2"
],
"capability_invocation": [],
"capability_delegation": [],
"service": [
{
"id": "did:chaincerts:vyfrxab6umfxddlzl62jktu7#chaincerts",
"service_endpoint": "https://chaincerts.co",
"type_": "LinkedDomains"
}
]
}
Updates the DID attributes in the storage for an initialized DID Contract. Only the admin account is authorized to invoke this function.
The updatable DID attributes include Context
, VerificationMethods
, and Services
.
You have the flexibility to update one or more attributes in the same invocation by providing the corresponding parameters. For attributes that are not intended to be updated, simply pass None
in the respective parameter.
Verification Methods and Context must not be empty; otherwise, a contract error will be thrown.
fn update_did(
e: Env,
context: Option<Vec<String>>,
verification_methods: Option<Vec<VerificationMethodEntry>>,
services: Option<Vec<Service>>
) -> DIDDocument;
Returns a DID document.
soroban contract invoke \
--id CONTRACT_ID \
--source SOURCE_ACCOUNT_SECRET_KEY \
--rpc-url https://soroban-testnet.stellar.org:443 \
--network-passphrase 'Test SDF Network ; September 2015' \
-- \
update_did \
--services '[{"id": "ChaincertsVault", "type_": "LinkedDomains", "service_endpoint": "https://vault.chaincerts.co"}]' \
--verification_methods '[{"id": "keys-1", "type_": "Ed25519VerificationKey2020", "controller": "", "public_key_multibase": "z6MkgpAN9rsVPXJ6DrrvxcsGzKwjdkVdvjNtbQsRiLfsqmuQ", "verification_relationships": ["Authentication", "AssertionMethod"]}]' \
--context '["https://www.w3.org/ns/did/v1", "https://w3id.org/security/suites/ed25519-2020/v1"]'
# Output: DID DOCUMENT
{
"id": "did:chaincerts:vyfrxab6umfxddlzl62jktu7",
"context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"verification_method": [
{
"controller": "did:chaincerts:vyfrxab6umfxddlzl62jktu7",
"id": "did:chaincerts:vyfrxab6umfxddlzl62jktu7#keys-1",
"public_key_multibase": "z6MkgpAN9rsVPXJ6DrrvxcsGzKwjdkVdvjNtbQsRiLfsqmuQ",
"type_": "Ed25519VerificationKey2020"
}
],
"authentication": [
"did:chaincerts:vyfrxab6umfxddlzl62jktu7#keys-1"
],
"assertion_method": [
"did:chaincerts:vyfrxab6umfxddlzl62jktu7#keys-1"
],
"key_agreement": [],
"capability_invocation": [],
"capability_delegation": [],
"service": [
{
"id": "did:chaincerts:vyfrxab6umfxddlzl62jktu7#ChaincertsVault",
"service_endpoint": "https://vault.chaincerts.co",
"type_": "LinkedDomains"
}
]
}
Replaces the current contract admin with a new one. Also, you have the flexibility to update the VerificationMethods
, if it is not intended to be updated, simply pass None
.
Verification Methods must not be empty; otherwise, a contract error will be thrown.
fn set_admin(e: Env, new_admin: Address, new_verification_methods: Option<Vec<VerificationMethodEntry>>);
soroban contract invoke \
--id CONTRACT_ID \
--source SOURCE_ACCOUNT_SECRET_KEY \
--rpc-url https://soroban-testnet.stellar.org:443 \
--network-passphrase 'Test SDF Network ; September 2015' \
-- \
set_admin \
--new_admin GCWZBFEKWUGQKYLCLI5ULI4DTXLEA7LPC5QVB55NZPC7FY2NGMLP4YMC \
--new_verification_methods '[{"id": "keys-1", "type_": "Ed25519VerificationKey2020", "controller": "", "public_key_multibase": "z6MkgpAN9rsVPXJ6DrrvxcsGzKwjdkVdvjNtbQsRiLfsqmuQ", "verification_relationships": ["Authentication", "AssertionMethod"]}]'
Replaces the current contract code with a new one.
fn upgrade(e: Env, new_wasm_hash: BytesN<32>);
soroban contract invoke \
--id CONTRACT_ID \
--source SOURCE_ACCOUNT_SECRET_KEY \
--rpc-url https://soroban-testnet.stellar.org:443 \
--network-passphrase 'Test SDF Network ; September 2015' \
-- \
upgrade \
--new_wasm_hash 4e3e2a3e6286149775c308c8420fd87c9e5f655549073506f72b917577ef1e33
Returns the contract version.
fn version(e: Env) -> String;
Returns the contract version as a string.
soroban contract invoke \
--id CONTRACT_ID \
--source SOURCE_ACCOUNT_SECRET_KEY \
--rpc-url https://soroban-testnet.stellar.org:443 \
--network-passphrase 'Test SDF Network ; September 2015' \
-- \
version
# Output: CONTRACT VERSION
"0.5.0"
Code | Error | Description |
---|---|---|
1 | AlreadyInitialized |
Contract already initialized |
2 | EmptyContext |
Context provided is an empty vector |
3 | EmptyVerificationMethods |
Verification Methods provided is an empty vector |
In order to develop and test the smart contract, you need to install Rust and Soroban CLI. The process is outlined in the Soroban setup documentation, which can be accessed at Soroban setup.
-
Clone the repository:
git clone git@github.com:kommitters/soroban-did-contract.git
-
Build the project and install dependencies:
cd soroban-did-contract soroban contract build
-
Run tests:
cargo test
-
Build the contract:
soroban contract build
This will generate a WASM file for the contract in the
target/wasm32-unknown-unknown/release/
directory. -
Deploy using Soroban CLI:
soroban contract deploy \ --source SOURCE_ACCOUNT_SECRET_KEY \ --rpc-url https://soroban-testnet.stellar.org:443 \ --network-passphrase 'Test SDF Network ; September 2015' \ --wasm target/wasm32-unknown-unknown/release/soroban_did_contract.wasm CONTRACT_ID
Features and bug fixes are listed in the CHANGELOG file.
We welcome everyone to contribute. Make sure you have read the CODE_OF_CONDUCT before.
For information on how to contribute, please refer to our CONTRIBUTING guide.
This software is licensed under the MIT © kommit.