-
Notifications
You must be signed in to change notification settings - Fork 10
Permissions Tutorial
There are two kinds of contracts: resource contracts and non-resource contracts. The latter is the default; resource contracts are declared with the resource
keyword. For example:
resource contract Money {
int amount;
}
Or:
contract Student {
flavor Enrolled {
}
flavor Graduated {
}
transaction graduate () available in Enrolled {
->Graduated();
}
}
Our university only has room for one student. The registrar might be implemented like this:
contract Registrar {
Student.Enrolled s;
}
There may be other contracts that also reference the same student, however. Because the student might graduate, and the Registrar is responsible for changing the graduation status, all the other references to the Student cannot depend on whether the student is still enrolled:
contract StudentClub {
Student member;
}
The Registrar cannot give anyone else references to a student that guarantee the student is still enrolled because the registrar reserves the right to change the student. However, it can give out readonly
references that do not guarantee flavor:
contract Registrar {
Student.Enrolled s;
transaction getStudentReadonly() returns readonly Student // OK
{
return s;
}
transaction getStudent() returns Student.Enrolled // COMPILE ERROR
{
return s;
}
}
Another option is to not guarantee flavor. Here, the Registrar does not know what kind of Student it has. In that case, there may be many references to the same Student, each of which allows mutation.
contract Registrar {
Student s;
transaction getStudentReadonly() returns readonly Student // OK;
{
return s;
}
transaction getStudent() returns Student // OK
{
return s;
}
}
For resources, the situation is similar except that there is always exactly one reference that includes flavor. All other references must be readonly; those references can be used to get information about the contract instance but cannot be used to modify it.