Executing actions
Executing an action in the Powers protocol follows a request and callback logic between the Powers contract and Law contracts. Here's how it works:
Requesting an action
An account requests an action by calling the request
function in Powers.sol. It takes the following parameters:
lawId
: The ID of the law that will be calledlawCalldata
: The encoded function call data for the lawnonce
: A random nonce to ensure uniquenessuriAction
: A brief description or URI to an IPFS document
Execution Flow
Initial Request
User calls
request()
in Powers.solPowers checks if:
The law is active
The caller has the appropriate role to call this law
The action hasn't been requested before
The action hasn't been cancelled
If all checks pass, Powers creates an actionId by hashing
lawId
,lawCalldata
, andnonce
Powers stores the action details in its
_actions
mappingPowers calls
executeLaw()
on the target law contract
Law Execution
The law's
executeLaw()
function is called with:caller
: The original requestor's addresslawId
: The ID of the lawlawCalldata
: The original calldatanonce
: The original nonce
The law performs validation checks:
checksAtPropose()
: Validates proposal conditionschecksAtExecute()
: Validates execution conditions
The law calls its
handleRequest()
function which:Processes the request
Returns execution data including:
actionId
: The unique identifiertargets
: Array of contract addresses to callvalues
: Array of ETH values to sendcalldatas
: Array of encoded function callsstateChange
: Any state changes to apply
State Changes and Execution
If
stateChange
is returned, the law calls_changeState()
to apply state changesThe law calls
_replyPowers()
which calls back to Powers.sol'sfulfill()
functionThe law records the execution in its storage
Final Execution
Powers.sol's
fulfill()
function:Verifies the caller is an active law
Verifies the action was requested
Executes all the calls returned by the law
Marks the action as fulfilled
Emits an
ActionExecuted
event
ActionId
The actionId
is a crucial component that:
Is created when
request()
is called by hashinglawId
,lawCalldata
, andnonce
Is used to track the action throughout its lifecycle
Is used by laws to check the status of specific actions
Ensures uniqueness of actions and prevents replay attacks
Important Considerations
Role Restrictions
All actions are role-restricted
The caller must have the appropriate role to call the law
Role checks happen at both the Powers and Law level
State Management
Laws can maintain their own state
State changes are applied before execution
Each execution is recorded in the law's storage
Error Handling
If any check fails, the entire execution reverts
Laws can implement custom validation logic
Failed executions are recorded in the law's storage
Gas Considerations
Each step in the execution flow consumes gas
Complex laws with many state changes will cost more
Failed executions still consume gas up to the point of failure
Last updated