Create And Fund Task: Implementation Guide
Hey guys! Let's dive into implementing the create_and_fund_task
method. This is a crucial part of our project, allowing us to create and fund tasks in one smooth transaction. This guide will walk you through the requirements, implementation details, and dependencies to make sure you nail it. So, let's get started and make some magic happen!
Description
The primary goal here is to implement the create_and_fund_task
method. This method will handle the creation of a new task and immediately fund it, all within a single transaction. Think of it as a one-stop-shop for task creation and funding! This approach ensures that a task is created and funded atomically, reducing the chances of inconsistencies and making the process more efficient. This method's reliability is essential for maintaining the integrity of our platform.
Requirements
Before we start coding, let's break down the requirements. The create_and_fund_task
method needs to adhere to the following signature:
fn create_and_fund_task(
ref self: TContractState,
task_id: felt252,
creator: ContractAddress,
token_address: ContractAddress,
description: felt252,
reward_per_completion: u256,
required_completions: u32,
) -> bool;
Let's dissect each parameter:
self
: A reference to the contract state.task_id
: A unique identifier for the task (felt252
).creator
: The address of the task creator (ContractAddress
).token_address
: The address of the ERC20 token used for funding (ContractAddress
).description
: A brief description of the task (felt252
).reward_per_completion
: The reward amount for each completion (u256
).required_completions
: The number of completions required for the task (u32
).
The method should return a bool
indicating whether the operation was successful. Simple enough, right? But the devil is in the details, so let's keep digging!
Implementation Details
Now comes the fun part – actually implementing the method! Here’s a step-by-step breakdown of what we need to do.
1. Validation
First, we need to validate the inputs to ensure everything is in order. This is crucial for preventing errors and maintaining the integrity of our contract. Here are the checks we need to perform:
-
Verify Caller is the Creator: Make sure that the person calling the method is indeed the creator of the task. This prevents unauthorized users from creating tasks on behalf of others. Think of it as verifying the identity at the door before letting someone in.
assert(get_caller_address() == creator, 'Only the creator can fund the task');
-
Check
task_id
Doesn't Already Exist: Ensure that thetask_id
is unique. We don't want to overwrite existing tasks or create confusion. It's like making sure you don't have duplicate usernames in a system.assert(tasks.read(task_id).is_none(), 'Task already exists');
-
Validate
reward_per_completion
"> 0: The reward amount must be greater than zero. It wouldn't make sense to create a task with no reward, would it?assert(reward_per_completion > 0, 'Reward per completion must be greater than 0');
-
Validate
required_completions
"> 0: Similarly, the number of required completions must be greater than zero. A task with no required completions is, well, pointless.assert(required_completions > 0, 'Required completions must be greater than 0');
2. Token Transfer
Next up, we need to handle the token transfer. This involves moving the tokens from the creator's account to the contract's account. Here’s how we’ll do it:
-
Calculate Total Amount: We need to calculate the total amount of tokens required to fund the task. This is simply the
reward_per_completion
multiplied by therequired_completions
.let total_amount = reward_per_completion * required_completions.into();
-
Use ERC20
transferFrom
: We'll use thetransferFrom
function from the ERC20 token standard to move the tokens. This function allows the contract to transfer tokens on behalf of the creator, provided the creator has approved the contract to do so.let (success,) = ERC20::transferFrom( token_address, creator, get_contract_address(), total_amount ).unwrap();
-
Handle Transfer Failures Gracefully: If the token transfer fails, we need to handle it gracefully. This might involve reverting the transaction and emitting an error event.
if (!success) { // Revert transaction or emit error event assert(false, 'Token transfer failed'); }
3. Storage Updates
Once the tokens are transferred, we need to update the contract's storage to reflect the new task. This involves:
-
Create
TaskDetails
with StatusActive
: We’ll create a struct containing the details of the task, including its status, which will initially be set toActive
.let task_details = TaskDetails { creator, token_address, description, reward_per_completion, required_completions, status: TaskStatus::Active, total_funded_amount: total_amount, };
-
Set
total_funded_amount
to Calculated Total: We’ll store the total amount of tokens funded for the task. This helps us keep track of the funds available for task completion.// The total_funded_amount is already included in the TaskDetails struct
-
Store in
tasks
Mapping: Finally, we’ll store theTaskDetails
in thetasks
mapping, using thetask_id
as the key. This allows us to retrieve the task details later.tasks.write(task_id, task_details);
4. Events
Last but not least, we need to emit events to notify the outside world about what's happening. This is crucial for transparency and allows other contracts and applications to react to task creation and funding.
-
Emit
TaskCreated
Event: This event will be emitted when a new task is created.emit TaskCreated { task_id, creator, token_address, description, reward_per_completion, required_completions };
-
Emit
TaskFunded
Event: This event will be emitted when the task is funded.emit TaskFunded { task_id, token_address, total_amount };
Dependencies
To implement the create_and_fund_task
method, we have a couple of key dependencies:
-
ERC20 Token Interface Integration: We need to interact with an ERC20 token contract to transfer tokens. This means we need to have an interface defined for the ERC20 functions we'll be using, such as
transferFrom
. -
Error Handling for Token Transfers: As mentioned earlier, we need to handle potential failures during token transfers. This might involve reverting the transaction or emitting an error event.
Putting It All Together
Okay, guys, we've covered a lot! Let's recap the whole process to make sure everything is crystal clear. Implementing the create_and_fund_task
method involves:
- Validating the inputs to ensure they're legitimate.
- Transferring the tokens from the creator to the contract using
transferFrom
. - Updating the contract's storage with the new task details.
- Emitting events to notify the world about the task creation and funding.
And remember, we have dependencies on the ERC20 token interface and error handling for token transfers.
By following these steps, we can create a robust and reliable create_and_fund_task
method. Keep up the awesome work, and let's make this happen! If you have any questions along the way, don't hesitate to ask. We're in this together!
This is how a comprehensive implementation guide should look like. Good luck with your coding!