DS-Auth is the most fundamental building block of the Dappsys framework. It introduces the concept of contract ownership with two types that work together:
DSAuthority. All the contracts in your system that require some level of authorization to access at least one of their functions should inherit from the
DSAuth type. This is because this type introduces a public
owner member of type
address, a public
authority member of type
DSAuthority, and a function modifier called
Any function that is decorated with the
auth modifier will perform an authorization check before granting access to the function. It will perform these checks in order and grant access if any are true:
msg.senderis the contract itself. This will be the case if a contract makes an external call to one of its own functions (e.g.
msg.senderis the contract’s
- If the contract’s
truewhen making this call:
authority.canCall(msg.sender, this, msg.sig)
The authority will return
msg.sender is authorized to call the function identified by
This is an extremely powerful design pattern because it creates a separation of concerns between authorization and application business logic. The authority could have any number of complex rules that the application contract doesn’t need to worry about. For example the authority could be:
address 0x123abc canCall function mint on 0xdef456
- A timelocked whitelist:
address 0x123abc canCall function mint on 0xdef456 two days after proposing the action to the authority
address 0x123abc is a member of group 1 which canCall function mint on 0xdef456
- A voter veto system:
address 0x123abc canCall function mint on 0xdef456 two days after proposing the action to the authority unless 50% of these token holders veto the action
From the application contract’s point of view, it’s just asking if
canCall the function it is trying to call. It doesn’t need to worry about all these different schemes that the authority contract might be using. Because the authority member is updateable, this means that more complex authorization/governance logic can be introduced to the system later. Conversely, access can be removed once the system is finished and ready to “lockout” privileged administrators.
Updateability is one of the key benefits offered by DS-Auth. Consider a system where backend-contract A is calling an
auth-controlled function on another backend-contract B, both owned by authority-contract X. Replacing B with backend-contract C would proceed as follows:
- Create contract C and set its authority to X
- Store data in X that allows contract A to call
auth-controlled functions on C
- Change the pointer in A to point at C instead of B
- Store data in X that disallows anyone from calling B
This ensures that your production system is always consistent and can easily be rolled back to previous configurations.
TL;DR: If you use just one package from the Dappsys framework, make it DS-Auth. Your system will remain manageable as it grows in size, each individual component will become much easier to understand, and it will integrate seamlessly with the numerous tools that DappHub is building to work with DS-Auth controlled systems.
Your contract should inherit from the
DSAuth type if you want it to have functions that can only be called by specifically authorized addresses.
The constructor function sets
msg.sender to be the initial
owner of the contract. It does not need to be explicitly called because it doesn’t take any parameters.
Returns the contract’s public
address public owner
This function sets the
owner member that automatically has access to all the contract’s functions. It is itself
function setOwner(address owner_) auth note
This function modifier is the main entrypoint into the logic of
DSAuth. Decorate your functions with this modifier when you want to control what addresses can call them. It calls
isAuthorized(msg.sender, msg.sig) and asserts that the return value is
true, otherwise it throws an exception.