Choosing a Template
Stoffel provides two Solidity templates:| Template | Framework | Best For |
|---|---|---|
solidity-foundry | Foundry | Rust developers, CI/CD pipelines, fast compilation |
solidity-hardhat | Hardhat | JavaScript/TypeScript developers, existing Hardhat workflows |
Creating a Project
Generated Project Structure
Foundry Template
Hardhat Template
Understanding MyMPCApp.sol
The generatedMyMPCApp.sol extends StoffelCoordinator and requires you to implement 4 abstract methods that control the MPC lifecycle.
The 4 Required Methods
Implementing Each Method
1. startPreprocessing()
Called by the designated party to initialize the preprocessing phase.2. gatherInputs()
Transitions the contract to accept client inputs.- Call
reserveInputMask(index)to reserve a slot - Request their input mask from MPC nodes off-chain
- Call
submitMaskedInput(maskedInput, reservedIndex)to submit
3. initiateMPCComputation()
Triggers the off-chain MPC computation.MPC nodes listen for the
MPCComputationInitiated event to begin the off-chain computation. Ensure your event includes all necessary context.4. publishOutputs()
Called after the MPC computation completes to publish results.Complete Implementation Example
Here’s a complete example for a secure voting application:Testing Your Contract
Foundry Tests
test/MyMPCApp.t.sol):
Hardhat Tests
Deployment
Foundry Deployment
Hardhat Deployment
End-to-End Workflow
Here’s the complete flow for running an MPC computation:Handling Optional Public State
When clients submit masked inputs viasubmitMaskedInput, your application may also need to track associated public state - data that doesn’t need privacy protection but is logically tied to the input.
This pattern is optional. Many applications only need the masked input itself and can skip this section entirely.
When You Need Public State
| Use Case | Public State Example |
|---|---|
| Voting | Voter’s preferred language for result notifications |
| Auction | Bidder’s display name (not the bid amount) |
| Survey | Respondent’s demographic category |
| Computation | Input metadata (timestamp, format version) |
When You Don’t Need Public State
- Simple computations where only the masked value matters
- Applications where all metadata is handled off-chain
- Minimal contracts that only need MPC results
Implementation Pattern
Create a wrapper function that callssubmitMaskedInput and stores additional public metadata:
Example: Voting with Voter Preferences
Next Steps
- Security Best Practices - Essential safety considerations
- StoffelCoordinator Reference - Full API documentation
- Access Control - Managing MPC parties
- Input Manager - Client input handling