Usage

What You're Building

Think of TargetBase as your smart contract's security bouncer. It's a battle-tested foundation that gives you signature-based authorization, smart account enforcement, and all the protection you need for EIP-7702 delegated accounts—without having to reinvent the wheel.

This guide walks you through extending TargetBase to build your own secure contracts. We'll use the RealEstateInvestment contract as our real-world example because, well, nothing teaches better than actual code.

What TargetBase Does For You

Here's what you get out of the box:

  • Signature-based authorization – Only calls signed by your master key get through

  • Smart account validation – Enforces EIP-7702 compliance (no random EOAs sneaking in)

  • Replay attack protection – Nonces and hash tracking ensure each authorization works exactly once

  • Time-bound authorizations – Set expiry timestamps so old signatures can't haunt you

  • Emergency recovery – Because sometimes you need a backup plan

  • Multi-source execution chains – Perfect for when you need to aggregate data from multiple sources

Think of it as a security framework that handles all the hard parts so you can focus on your business logic.

The Core Building Blocks

AuthData

Every protected function needs one of these. It's like a VIP pass that proves the caller has permission:

The Authorization Players

  • Master Key – The VIP who signs everything. This is your authorization authority.

  • Recovery Key – Your emergency contact. Can rotate the master key if things go wrong.

  • Owner – The admin. Controls contract settings and upgrades.

  • DelegatedAccount – The only type of account allowed to call your protected functions (EIP-7702 smart accounts only)

How to Extend TargetBase (The Three-Step Implementation)

Step 1: Set Up Your Contract

Start by inheriting from TargetBase. You can mix in other contracts too—we're using ERC20 in our real estate example:

Pro tip: Pass those four addresses to TargetBase first, then handle your own initialization. Order matters!

Step 2: Define Your Data Structures

Before you do anything else, define the structs that will carry your data which is basically the result your are expected from the KRNL node as a part of the workflow execution. These are what you'll encode/decode in authData.result:

Important: The fields in your struct should be alphabetically ordered when you're working with external data sources. This ensures consistent encoding/decoding across different systems.

Step 2: Protect Your Functions

Now when you integrate KRNL to your smart contract, you use requireAuth(authData) modifier to do the basic validation check like your nonce, expiry, etc and make AuthData your first parameter:

Step 3: Decode Your Data (When You Need It)

If you're working with multi-source execution chains or need to extract data from the authorization:

Real-World Example: Tokenizing Real Estate

Let's look at how the RealEstateInvestment contract does it. This contract lets people buy fractional ownership of properties using USDC. It needs TargetBase because property analysis data comes from multiple sources (Zillow, Census data, AI analysis) and needs to be verified before allowing investments.

What's happening here?

  • The constructor handles both TargetBase and ERC20 initialization

  • submitPropertyAnalysis decodes complex multi-source data and validates it

  • purchaseTokens combines authorization with business parameters

  • Events include authData.nonce and authData.id for complete traceability

Things to Avoid

When Setting Up Your Constructor

  • No zero addresses – TargetBase will reject them. Every address parameter matters.

  • DelegatedAccount must be real – It needs to be an actual deployed contract with code. No empty addresses or EOAs.

  • Order matters – Pass the four TargetBase parameters first, in order: _authKey, _recoveryKey, _owner, _delegatedAccountImpl

When Writing Protected Functions

  • AuthData always comes first – It's not just convention, it's how the pattern works. function myFunc(AuthData calldata authData, ...)

  • Use the modifier – Don't forget requireAuth(authData). That's where all the magic happens.

  • Include context in events – Always emit authData.nonce and authData.id in your events. Future you will thank present you when debugging!

The Security Guarantees

Here's what TargetBase enforces automatically:

  • EIP-7702 only – No EOAs allowed. Only properly delegated smart accounts get through.

  • Sequential nonces – Can't skip ahead or go backward. If Alice is on nonce 5, her next call must use nonce 5, then 6, then 7...

  • Expiry matters – That timestamp isn't just for show. Expired = rejected.

  • One-time use – Each authorization is like a ticket. Once it's used, it's burned. No replays, no exceptions.

Best Practices

Emit meaningful events Include authData.nonce and authData.id in every event. Six months from now when you're debugging a production issue, you'll want that audit trail. Trust me.

Validate everything Just because data made it through authorization doesn't mean it's correct. Always validate decoded results before using them. Check ranges, verify checksums, enforce business rules.

Use custom errors TargetBase uses them for a reason—they're gas-efficient and more descriptive. revert InsufficientFunds() beats require(balance > 0, "Insufficient funds") every time.

Protect against reentrancy TargetBase includes nonReentrant protection. Use it on any function that changes state or moves value around.

Keep view functions simple Don't use requireAuth on view or pure functions. They don't change state, so they don't need authorization. Save the gas.

Use Ownable for admin stuff TargetBase inherits from Ownable, so you get onlyOwner for free. Use it for administrative functions that shouldn't go through the auth flow.

Three Common Patterns You Can Use

Pattern 1: Simple Authorization (Just Verify, No Data)

Pattern 2: Multi-Source Data Pipeline

Pattern 3: Authorization + Business Parameters

When to use each:

  • Pattern 1: Permission changes, state toggles, simple actions

  • Pattern 2: External data validation, multi-API aggregation, complex analysis

  • Pattern 3: Most common! Authorized actions with user-provided parameters

Last updated