DID.tyron: Decentralized Identifier smart contract

A tyronzil Decentralized Identifier gets instantiated from the DID.tyron smart-contract code that is stored on-chain in the INIT.tyron smart contract. For that, the user MUST give their Zilliqa address as the contract owner. Once the DID smart contract gets deployed, its code is immutable (the code can never get modified under the same contract's address). However, the DID contract has mutable fields declared in its code, and there are predetermined ways, called transitions, that can modify those fields in specific manners.

Find the DID.tyron smart contract code on GitHub.

Immutable fields

Immutable fields are set at deployment and can not get modified. The DID smart contract gets deployed with the following immutable fields:

  1. initContractOwner: The Zilliqa address of the user who is the owner of the contract | [ByStr20 type]
  2. initTyron: The Zilliqa address of the INIT.tyron smart contract | [ByStr20 type]

Mutable fields

Mutable fields can get modified but only if there is a specific code in the contract that allows it. They MUST get initialized with a value at deployment.

  1. contract_owner: The Zilliqa address of the user that can get updated by the UpdateOwner transition | [ByStr20 type]
  2. decentralized_identifier: The user's DID generated according to the DID Scheme - [String type].
  3. init_tyron: The address of the INIT.tyron contract's latest implementation | [ByStr20 type]
  4. resource_records: The Decentralized Identifier's DNS resource records | @key: domain | @value: avatar | [Map String String type]
  5. did_agents: The user's SSI agents | @key: avatar.agent | @value: agent's address | [Map String ByStr20 type]
  6. latest_agent: The Zilliqa address of the current agent | [ByStr20 type]
  7. did_status: The DID Status can be Undefined, Initialized, Created, Updated, Recovered or Deactivated | [DidStatus ADT type]
  8. verification_methods: The Tyron verification methods are the public keys used by the DID smart contract | @key: key purpose | @value: public key of type "SchnorrSecP256k1VerificationKey2019" | [Map String ByStr33 type]
  9. services: The DID service endpoints | @key: ID | @value: service type & URI | [Map String Pair String String type]
  10. tyron_hash: The SHA256 hash of the DID. It is necessary to sign this hash to perform certain operations, such as deactivation of the DID | [ByStr type]
  11. did_update_key & did_recovery_key: The public DID Keys to enable future operations are stored in the DID contract to execute the IsRightSignature procedure - [ByStr type]
  12. created: The block number when the DID Create tyronzil transaction occurred | [BNum type]
  13. ledger_time: The block number when the last tyronzil transaction occurred | [BNum type]
  14. transaction_number: A monotonically increasing number representing the amount of tyronzil transactions that have taken place | [Uint128 type]

    The following fields get determined by calling the init transition which sends a message to the INIT.tyron contract that, in return, call the InitCallBack transition:

  15. operation_cost: The cost of each tyronzil transaction type, e.g. ".did" for DID operations | [Map String Uint128 type]

  16. foundation_address: The address of the Tyron Pungtas Foundation | [ByStr20 type]
  17. agent_comission: The agent's comission as a % of the operation_cost | @key: avatar.agent | @value: comission | [Map String Uint 128 type]
  18. latest_comission: It corresponds to the commission of the current agent | [Uint128 type]

The xWallet fields

  1. xWallet: The SSI Token implementations | @key: token address | @value: token name | [Map ByStr20 String type]
  2. xBalances: The SSI Token balances | @key: token name | @value: balance | [Map String Uint128 type]
  3. xProxies: The SSI Token proxies | @key: token name | @value: proxy address | [Map String ByStr20 type]
  4. donation: The Donation Scheme | @key: campaign name | @value: campaign's starting blok number | [Map String BNum]

    Pung.me is the first DID dapp that the user can use to make donations


Procedures can change the state of the contract (mutable fields), but they are not part of the public API which means that they can only get invoked from within the contract itself.

  1. DidScheme: It generates the user's decentralized_identifier & tyron_hash. This procedure is the only way to generate the Decentralized Identifier, and it can only get executed by the DidCreate transition.
  2. ThrowError: The procedure to throw an error.
  3. IsRightCaller: Validates that the call comes from an SSI Trinity entity. This procedure matches against the SsiTrinity ADT that can be: user (to validate that the call comes from the user/ contract owner address), agent (to verify the agent in the Payment procedure) or tyron (to validate that the call comes from the INIT.tyron contract.
  4. IsRightStatus: Verifies that the DID Status is correct for the given operation.
  5. Donation: Checks that the donation campaign code is within the limitation period of 1-week.
  6. Payment: Executes the payment to the agents and foundation.
  7. IsRightSignature: Verifies the Schnorr signature that comes with the signed data corresponds with the public DID Keys stored in the contract.
  8. UpdateDocument: Updates the verification methods and services map fields.
  9. IsValidKey: Verifies that the new DID Key is unique and not utilized more than once.
  10. Timestamp: Generates a timestamp that sets the ledger_time & transaction_number.

The xWallet procedure

  1. XWallet: Verifies the validity, checks & updates the balance of the SSI Tokens


Transitions are the public API and get invoked by sending messages to the contract.

  1. UpdateOwner: Updates the Zilliqa address of the user aka contract owner.
  2. UpdateInit: Updates the INIT.tyron contract to the address of its latest implementation - only the user can execute this transition.
  3. Init: Sets the agent's info into the user's DID smart contract & sends a message to the INIT.tyron contract that, in return, calls the InitCallBack transition. It also sets the did_status to Initialized.
  4. InitCallBack: The INIT.tyron contract calls this transition to set the operation_cost, foundation_address & address and commission of the given agent.
  5. SetSsiDomain: Sets a domain name for the Decentralized Identifier.
  6. SetDomainCallBack: The INIT.tyron contract calls this transition to set a user's domain name.
  7. DidCreate: Executes a DID Create tyronzil transaction.
  8. DidRecover: Executes a DID Recover tyronzil transaction.
  9. DidUpdate: Executes a DID Update tyronzil transaction.
  10. DidDeactivate: Executes a DID Deactivate tyronzil transaction.

The xWallet transitions

  1. SsiToken: To set/update a SSI Token.
  2. SsiTokenCallBack: The INIT.tyron contract calls this transition to update an SSI Token to its latest implementation (token name, proxy address and token implementation address).
  3. ZilIn: Adds native funds (ZIL) to the xWallet.
  4. ZilOut: Sends ZIL from the xWallet to any recipient that implements the input tag (e.g. "ZilIn", "").
  5. RecipientAcceptTransfer: The ZRC-2 acceptance transition - MUST be defined or transfers to this xWallet will fail otherwise.
  6. XTransfer: Transfers ZRC-2 SSI Tokens.
  7. TransferSuccessCallBack: the ZRC-2 callback transition - MUST be defined or transfers from this xWallet will fail otherwise.
  8. Donate: To initialize a donation campaign code.
  9. DonateCallBack: The INIT.tyron contract calls this transition to save the donation campaign code into the DID smart contract.F