In previous blog posts I talked about setting up your development environment for building your own ACA-py controller. I explained how you can run your own Hyperledger Indy nodes locally using VON-network.
My goal is to create three different applications: an application to issue credentials, an application to hold credentials, and an application to verify credentials.
In this blog post I’m going to talk about connecting ACA-py to one of the existing running ledgers.
There are several ledgers for you to connect to for both development and demo purposes. There are several options for configuring ACA-py to connect to a ledger and for registering a DID.
If you are creating an agent that wants to create schemas, credential definitions and issue credentials, you need to have a public DID registered in a ledger. For the Sovrin production ledger this means you need to request it and pay for actions on the ledger. Connecting to and writing to development ledgers is free, however you still need to register a DID. That’s what I’m going to explain in this blog post.
In order to write to a ledger, you require the genesis file. For the Sovrin ledgers you can find the genesis file in their github repo: github.com/sovrin-foundation/sovrin.
With the BCoverin ledgers you have two options. You can download the genesis file and load it with
--genesis-file, or you can give the direct url as
Create a DID for Sovrin BuilderNet using ACA-py and register it on BuilderNet with SelfServe
You can create a DID using ACA-py. When you start ACA-py in provision mode, it will create a DID and verkey for you based in the
--seed value that you provide.
Start ACA-py with:
--endpointThis is the public url your ACA-py instance is available on for other agents to connect to. This is NOT the admin endpoint for controlling ACA-py.
--genesis-fileAs with every blockchain, to join it you require the genesis-file.
--wallet-type indyFor now, you require an Indy wallet to connect to a Hyperledger Indy network.
--wallet-nameThis is the name of your wallet. In case you are not using a Postgres backend for your wallet, it is the name of the folder where your wallet information will be stored. For example
--wallet-keyThis is the key required to unlock your wallet. It is a value you can decide yourself, but you need to keep it secret.
--seedThis is the seed value that you can choose.
It will then ask you to accept the transaction author agreement:
Before you choose an option, head over to selfserve.sovrin.org to register the DID and verkey on BuilderNet. Once you have done that, choose option 1.
If you choose option 1 before registering your DID and verkey on SelfServe, you will be greeted with an error message:
Registering a DID on Sovrin BuilderNet using
To register a DID at the Builder and Staging ledgers, you can use selfserve.sovrin.org. At the bottom there is a link which describes how you can create a DID. However, the document is not super clear, so I’m going to describe what I did.
I installed the indy-cli on my Ubuntu 18.04 environment:
The document describes that you also need
libsovtoken, however that seems to not be available on Ubuntu 18.04, and it turned out not to be required. The document also describes how to set-up a payment address, but that is also not required.
Create a file called
cliconfig.json. The document tells you the content should be:
libsovtoken not being available, the
plugins line is going to result in an error:
Either ignore the error, or remove the
plugins line from the cliconfig.json.
Download the genesis file for the ledger you want to connect to from github.com/sovrin-foundation/sovrin. For Builder this is
Start indy-cli and configure the ledger you want to connect to:
Connect to BuilderNet, it will ask you if you want to view the license, select
y, and then accept it by choosing
Create a wallet and open it:
Generate a DID
You can also provide a seed value for your DID
Then go to selfserve.sovrin.org, select BuilderNet, enter the DID and verkey that you just generated, and leave the payment address empty and submit. At that moment, the DID will be registered in the ledger. You local wallet contains the keys that allow you to do things like register schema’s and credential definitions. With the did registered, you can run:
Then, you can configure that DID as the public did in your wallet using:
You should then also be able to register a schema:
Registering a DID on BCoverin Dev
A DID can only be registered via a DID that has the right permissions to write to the ledger. In the case of the BCoverin ledgers, there is a ledger browser that allows you to register a DID.
The BCoverin project has three environments. At each of these web pages there is an option for you to register a new DID on the ledger.
You can register your DID based on a seed that you can decide yourself. Store this seed value as this is what you need to start your aca-py.
ACA-py has a
provision argument. This is what they say about provisioning in the “Becoming a Hyperledger Aries Developer” course:
An agent is a stateful component that persists data in its wallet and to the ledger. When an agent starts up for the very first time, it has no persistent storage and so it must create a wallet and any ledger objects it will need to fulfill its role. When we’re developing an agent, we’ll do that over and over: start an agent, create its state, test it, stop it and delete it. However, when an agent is put into production, we only initialize its state once. We must be able to stop and restart it such that it finds its existing state, without having to recreate its wallet and all its contents from scratch.
Because of this requirement of a one time “start from scratch” and a many times “start with data,” ACA-Py provides two major modes of operation, provision and start. Provision is intended to be used one time per agent instance to establish a wallet and the required ledger objects. This mode may also be used later when something new needs to be added to the wallet and ledger, such as an issuer deciding to add a new type of credential they will be issuing. Start is used for normal operations and assumes that everything is in place in the wallet and ledger. If not, it should error and stop—an indicator that something is wrong.
The provision and start separation is done for security and ledger management reasons. Provisioning a new wallet often (depending on the technical environment) requires higher authority (e.g. root) database credentials. Likewise, creating objects on a ledger often requires the use of a DID with more access permissions. By separating out provisioning from normal operations, those higher authority credentials do not need to be available on an ongoing basis. As well, on a production ledger such as Sovrin, there is a cost to write to the ledger. You don’t want to be accidentally writing ledger objects as you scale up and down ACA-Py instances based on load. We’ve seen instances of that.
To me, it sounds like provisioning should be used to set up a local wallet, a schema and a credential definition. However, only setting up a local wallet seems to be part of the provision mode of ACA-py. This means that registering a schema and credential definition should be part of the provisioning step of your application. More on that in a later post.
If you have set up a wallet using aca-py or indy-cli, your wallet will be configured already and if you use the basic storage mode, you should be able to find your wallet in
~/.indy_client/wallet/<your-wallet-name>. In that case you can start ACA-py with the same
--wallet-key as you provided when you registered a DID.
If you have registered a DID using a BCoverin browser, you can use the
provision mode of ACA-py to create a wallet configured for the BuilderNet ledger with the seed value that the BCoverin browser gave you.
You can use provision mode like:
Running the same command twice will not cause any problems, as the provision tool will verify that you have the private keys for the public DID in your wallet and that nothing needs to be done.
When you run the provision command, it will ask you to accept an agreement.
Ledgers to connect
I have found 6 public Hyperledger Indy networks.
The Government of British Columbia has three:
And then there are the Sovrin ledgers:
- Sovrin Builder
- Sovrin Staging
- Sovrin Prod
Update 28-10-2020: I also found https://idunion.esatus.com/, but I have not been able to find how to register a DID on this network.
Which of these you want to use for development is up to you. However, if you want to create an agent that issues credentials, and you want to receive and store these credentials with an existing Android/iOS app, then you need to know which apps are compatible with which ledgers.
|Mobile client||BCoverin Dev||BCoverin Test||BCoverin Prod||Sovrin Builder||Sovrin Staging||Sovrin Production|
Finding your transaction
Once you have registered a DID, you can find the transaction that registers your DID. For BCoverin you can do that by going to the ledger browser of the respective ledger:
Go to “Domain”, select Type: “NYM”, and enter your DID in the Filter field.
For the Sovrin ledgers, you can go to indyscan.io. Select your network, select the Subledger “Domain”, select “NYM” and search for your DID.
After creating a public DID, you can start ACA-py with the same parameters that you used for provisioning. Use the same parameters for
Now that you have created a public DID and configured ACA-py to connect to a hosted ledger, it is time to create a controller that can issue credentials. More on that in the next blog post.