Create And Fund Task: Implementation Guide

by Marta Kowalska 43 views

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 the task_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 the required_completions.

    let total_amount = reward_per_completion * required_completions.into();
    
  • Use ERC20 transferFrom: We'll use the transferFrom 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 Status Active: We’ll create a struct containing the details of the task, including its status, which will initially be set to Active.

    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 the TaskDetails in the tasks mapping, using the task_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:

  1. Validating the inputs to ensure they're legitimate.
  2. Transferring the tokens from the creator to the contract using transferFrom.
  3. Updating the contract's storage with the new task details.
  4. 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!