An account has many different forms and can be used in different ways. When users create an account an attacker could try to frontrun the transaction. The attacker would mutate the guard associated with the account, hoping the user won't notice or worse tokens are already on it's way to this newly created account. We can prevent such attacks by providing a way to pin an account to it's guard. If the attackes decides to mutate the guard now, the account associated will result in a different account and therefore will fail the transaction. An account that has their guard pinned in their name is called a principal account.
To better understand principals in pact, you need to understand guards. Every guard serves as a way to limit access. It defines what conditions have to be met before granting access. So what type of guards exists and what do they do?
The most used guards and closest to other blockchains way of guarding access are keysets. A keyset holds a collection of 1 or more public keys and defines how many of those keys need to sign in order for the guard to pass; the predicate of a keyset
Keysets holding single keys with the keys-all
predicate result in
a k:account
. Any other type of keyset combination will result in
a w:account
.
In some cases you'd want to customize the guard to allow for example one two keysets to sign, i.e. in one keyset the board of directors are registered, while in the other keyset the union stakeholders are registered. This type of guard can be very flexible and powerful. It however does not allow access to a database during evaluation of the guard. A user guard is in essence a pure function that will be evaluated on runtime to guard an account.
Such accounts result in a u:account
.
Since user guards are required to be pure, they don't have the ability to take database state into account. To gain this dynamic property one could retrieve such data while bringing a capability into scope. This way you can define a guard that requires a capability to be brought into scope. This can be achieved using a user guard, but a capability guard is more convienient and a more explicit way to achieve the same.
Accounts guarded by a capability result in a c:account
.
Every type of guard can be represented in a unique way. For every type of guard you have a different protocol name. Here is a short overview of the protocols:
k
for single key keysetsw
for multiple keys keysetsc
for capability guardsu
for user guards
There are more principals, but I'll leave it at these as these are the most likely guards you'll use for creating an account.
You can see some examples below.