MoreRSS

site iconHacker Noon

We are an open and international community of 45,000+ contributing writers publishing stories and expertise for 4+ million curious and insightful monthly readers.
Please copy the RSS to your reader, or quickly subscribe to:

Inoreader Feedly Follow Feedbin Local Reader

Rss preview of Blog of Hacker Noon

Extending Stochastic Gradient Optimization with ADAM

2024-11-23 01:00:13

Gradient Descent. Image taken from - https://community.deeplearning.ai/t/difference-between-rmsprop-and-adam/310187

What Is Gradient Descent?

Gradient descent is like hiking downhill with your eyes closed, following the slope until you hit the bottom (or at least a nice flat spot to rest). Technically, it is a method to minimize an objective function F(θ), parameterized by a model’s parameters θ∈Rn, by updating them in the opposite direction of the gradient ∇F(θ).

\ The size of each step is controlled by the learning rate α. Think of α as the cautious guide who ensures you don’t tumble down too fast. If this sounds like Greek, feel free to check out my previous article, Quick Glance At Gradient Descent In Machine Learning — I promise it’s friendlier than it sounds! 🙂

\

Circle back: An objective function is the mathematical formula or function that your model aims to minimize (or maximize, depending on the goal) during training. It represents a measure of how far off your model’s predictions are from the actual outcomes or desired values.

\ For example:

\ In machine learning, it could be a loss function like Mean Squared Error (MSE) for regression tasks or Cross-Entropy Loss for classification tasks.

\ The objective function maps the model’s predictions to a numerical value, where smaller values indicate better performance.

\ In simpler terms:

\ It’s like a “fitness tracker” for your model — it tells you how good or bad your model’s predictions are. During optimization, gradient descent helps adjust the model’s parameters θ to reduce this value step by step, moving closer to an ideal solution. Got it? 😄

\

Gradient Descent Variants

Gradient descent isn’t a one-size-fits-all deal. It comes in three variants, each like a different hiker — some take the scenic route, others sprint downhill, and a few prefer shortcuts (like me 😅). These variants balance accuracy and speed, depending on how much data they use to calculate the gradient.

1. Batch Gradient Descent

Batch gradient descent, the “all-or-nothing” hiker, uses the entire dataset to compute the gradient of the cost function:

\ Imagine stopping to look 👀 at every rock 🪨, tree 🌴, and bird 🕊 before deciding where to place your foot 🦶🏽next. It’s thorough, but not ideal if your dataset is as big as, say, the Amazon rainforest 😩. It’s also not great if you need to learn on the fly — like updating your hiking route after spotting a bear 🐻‍❄️.

\ Code Example:

for i in range(nb_epochs):
    params_grad = evaluate_gradient(loss_function, data, params)
    params = params - learning_rate * params_grad

\ Batch gradient descent shines when you have all the time in the world and a dataset that fits neatly into memory. It’s guaranteed to find the global minimum for convex surfaces (smooth hills) or a local minimum for non-convex surfaces (rugged mountains).

\

2. Stochastic Gradient Descent (SGD)

SGD is the “impulsive” hiker who takes one step at a time based on the current terrain:

\ It’s faster because it doesn’t bother calculating gradients for the entire landscape. Instead, it uses one training example at a time. While this saves time, the frequent updates can make SGD look like it’s zigzagging downhill, which can be both exciting and a little chaotic. 😅

Imagine updating your grocery list after each aisle — you get to the essentials faster, but your cart might look wild in the process. However, with a learning rate that slows down over time, SGD can eventually reach the bottom (or the best local minimum).

\ Code Example:

for i in range(nb_epochs):
    np.random.shuffle(data)
    for example in data:
        params_grad = evaluate_gradient(loss_function, example, params)
        params = params - learning_rate * params_grad

\

3. The Hero of the Day: Adam 🙌🏽

Now let’s talk about Adam — the “hiking guru” who combines the wisdom of Momentum and RMSprop. Adaptive Moment Estimation (Adam) is like having a smart guide who tracks the terrain and adjusts your steps based on past experiences and current conditions. It’s the go-to optimizer when you want to train neural networks and still have time for coffee.

\

Why You’ll Love Adam

  • Low Memory Requirements: It’s like carrying a lightweight backpack — efficient but still packed with essentials.

    \

  • Minimal Hyperparameter Tuning: Adam works well out of the box, so you won’t need to fiddle with too many knobs (just keep an eye on the learning rate).

    \

  • Practical Use: From improving product recommendations to recognizing images of cats on the internet, Adam powers machine learning systems that make your everyday tech smarter.

\

How Adam Works

Adam maintains moving averages of gradients (mt​) and squared gradients (vt​) to adapt learning rates for each parameter:

Here’s the cool part: Adam corrects biases to ensure accuracy, and updates parameters using this formula:

where m^t and v^t are bias-corrected estimates, and epsilon ϵ is a small number to prevent division by zero.

\

Conclusion

Adam is the Swiss Army knife of optimizers — versatile, efficient, and reliable. Whether you’re training neural networks to detect fraud or create next-gen chatbots, Adam helps you get there faster and with fewer headaches. So, embrace Adam, take confident steps, and enjoy the view from the summit of machine learning success!

\ References:

https://www.ceremade.dauphine.fr/~waldspurger/tds/22_23_s1/advanced_gradient_descent.pdf

https://www.geeksforgeeks.org/rmsprop-optimizer-in-deep-learning/

#AI-chatbot Writing Contest Sponsor, Coze, Shares Secrets for Success as Contest Deadline Approaches

2024-11-23 00:25:57

Hey Hackers,

\ Great news—the submission deadline for the AI-Chatbot Writing Contest has been extended to November 25, 2024, giving you a few extra days to wrap up and submit your #ai-chatbot stories to compete for over $7,000 in prizes. If you’ve already submitted an entry, you now have more time to draw attention to it or work on a new one to improve your chances of winning.


:::tip Hurry! Enter now using this writing template.

:::


To make the most of this extra time, we hosted an AMA with Coze, the contest sponsors, where we discussed AI chatbots and agents, and other key topics a winning entry should cover. \n

Let’s get started!

\

Meet our guest - Gary Zhen!

Gary is the Developer Operation Manager from the leading AI agent platform Coze.

\

In this AMA, our guest:

  • Shares Coze’s innovative ideas and practical experiences in building AI chatbots and agents.
  • Explains how to easily upgrade existing software into AI-driven solutions by collaborating with Coze.
  • How to quickly create AI applications by Coze.
  • Partner with Coze: Get access to ecosystem support and promotional opportunities for your AI product.
  • Talks about how the chatbot is going to help people in a better way.
  • The AI-Chatbot Writing Contest

1. What unique features do Coze chatbots have that differentiate them from other AI chatbot solutions on the market?

Coze stands out with features that make building and using AI Agents simple and powerful:

  1. You don’t need coding skills—just use the drag-and-drop interface to create your AI Agent.

  2. There are over 500 plugins, plus you can create your own to add any functionality you need.

  3. Teach your AI Agent by uploading documents or linking live web resources for personalized responses.

  4. Use the workflow builder to break tasks into steps without writing any code.

  5. Create multiple agents that can collaborate to handle complex tasks.

  6. Schedule actions like reminders or updates to automate processes.

  7. Deploy your AI Agent across platforms like Discord or Telegram, or package it as an API or Web SDK for easy integration into your product.

    \

2. What are some specific examples of the out-of-box tools provided by Coze that help users improve the end-user experience in their applications?

Coze makes end-user interactions more engaging with its Card Feature. This lets AI Agents deliver responses with images, videos, buttons, and links—not just plain text.

\n It means users don’t have to type everything out; they can click and interact directly, which makes the experience simpler and much more enjoyable. This tool helps AI Agents look modern, feel user-friendly, and keep users engaged.

\

3. How does Coze facilitate the scaling of AI applications, and what are some common challenges users might face when attempting to scale their applications?

Coze simplifies scaling by handling the backend challenges, so users can focus on building their apps.

  1. Cloud-Native Scaling: Coze manages server expansions and global performance optimization for you.

  2. Customizable Plugins: With 500+ built-in plugins and custom options, it’s easy to expand capabilities as needed.

  3. Simple Deployment: Integrate with platforms or package your AI Agent as an API or Web SDK with minimal effort.

  4. Efficient Resource Sharing: Teams can manage and update workflows, plugins, and knowledge bases across all agents instantly.

    \

4. Does Coze leverage any partnerships within the AI ecosystem to enhance its products?

Yes, Coze encourages companies to publish their APIs as plugins, with platforms like Yelp and Instacart already part of our ecosystem. Many Silicon Valley startups are also integrating their services. This benefits our million-plus users with diverse features while giving partners greater visibility and reach.

\

5. How does Coze facilitate access to real-time data for its AI agents?

Plugins. Users can enable real-time data access by simply activating plugins. Once a plugin is added, the AI Agent gains the capability to retrieve live data from external sources instantly.\

6. In your experience, what are the most common mistakes users make when building AI agents, and how can Coze help avoid them?

One common mistake users make is writing large, multi-step tasks directly into the prompt section of Coze’s building interface. Current AI models often struggle to execute tasks with multiple steps effectively.

To avoid this, I recommend using Coze’s workflow feature. Workflows allow users to break down tasks into precise steps, enabling AI Agents to execute each step accurately and reliably.

\

7. How does Coze incorporate user feedback into its development process, and what mechanisms are in place for users to suggest improvements or new features?

Coze collects feedback via email ([email protected]) and the feedback-and-support tab on Discord. A dedicated team reviews and shares this input with product managers. We also conduct user interviews to understand needs better and welcome anyone interested in connecting directly with our product team to email us. \n

8. Can users without any programming experience effectively build AI agents with Coze?

Yes, anyone can easily create AI Agents on Coze, regardless of their programming or AI experience. Our mission is to enable everyone on the planet to build their own AI Agent.

\

9. On average, how long would you say it takes to build a simple AI agent on Coze?

On average, it takes about 10 minutes. You just need to write prompts to tell Coze AI how you want it to work and respond. The Coze Agent will handle the rest efficiently.

\

10. How do you foresee low-code AI solutions like Coze impacting the future of AI development?

When you experience how effortlessly you can create an agent with Coze and see it automate various tasks for you every day, you’ll realize that “the future will undoubtedly be driven by countless AI agents.”

\

11. What are some of your favorite bots on Coze? What do you like most about them?

There are so many great bots, but let me give you one example:

One of my favorites is a language-learning AI Agent called ChatBird. It uses Coze’s features to the fullest. You can practice learning a new language by speaking to it using the voice function. Additionally, users can click buttons to select the language they want to learn and choose vocabulary words accompanied by images.

\ The chat interface is dynamic and engaging, making learning both fun and interactive.

You can check it out here: ChatBird.

\

\

12. Why did you decide to launch the AI chatbot writing contest? And why is this the best time to explore this theme?

We want to inspire users to share their creative bots and insights, helping them gain recognition while providing learning opportunities for others. AI Agents are the hottest topic globally, making this the perfect time to spotlight their potential.

\

13. For contest participants looking to leverage Coze, what are the key features they should focus on to maximize their chances of winning the #AI-Chatbot Writing Contest?

Focus on sharing detailed insights and your personal thoughts. The content doesn’t need to be overly advanced, but we value how participants envision using AI Agents to improve their lives.\

14. What techniques can participants use to optimize their AI chatbots for speed and user engagement?

Simplify workflows or prompts—too many steps can make the AI take longer to “think.” To boost user engagement, connect the chatbot to real-life scenarios and create appealing avatars and background images.

\

15. How can participants evaluate the success of their AI chatbots, both in terms of functionality and engagement?

Refer to the contest guidelines, which emphasize using more Coze features, solving real problems effectively, and delivering a great user experience. A good user experience directly drives engagement, making it a key success factor.

\

16. What would a high-quality submission look like? What would you call a low-quality submission?

A high-quality submission solves real problems, creates significant impact, and utilizes various Coze features effectively. Detailed explanations, and even a demo video, can be great bonus points.

In contrast, a low-quality submission may lack an engaging theme, use few features, and provide only minimal text explanations.

\

17. If there’s one thing you want people to remember from this AMA and the contest, what would it be?

I hope everyone remembers the exceptional HackerNoon team members—their outstanding skills and great attitude left a lasting impression on me.


That’s a wrap for this AMA! Thank you Coze for your time and thoughtful answers. We’re excited to follow your journey from here on out and see what you do next! \n \n To all the writers on HackerNoon, make sure to leverage the valuable insights shared during this conversation when crafting your entries for the **#ai-chatbot **writing contest. \n \n We can’t wait to read what you come up with!

The HackerNoon Newsletter: Whats Next for AI: Interpreting Anthropic CEOs Vision (11/22/2024)

2024-11-23 00:05:24

How are you, hacker?


🪐 What’s happening in tech today, November 22, 2024?


The HackerNoon Newsletter brings the HackerNoon homepage straight to your inbox. On this day, U.S. President John F. Kennedy was Assassination in 1963, Toy Story was Released in 1995, Mike Tyson Became the Youngest Heavyweight Champion Ever in 1986, and we present you with these top quality stories. From Whats Next for AI: Interpreting Anthropic CEOs Vision to Experts Skeptical of Huawei Silicon May Be Missing the Forest for the Trees, let’s dive right in.

Whats Next for AI: Interpreting Anthropic CEOs Vision


By @learning2survive [ 6 Min read ] Anthropic CEO, Dario Amodei talked about his predictions with Lex Fridman: Expect AGI by 2027, Scaling works, AI safety, Mechanistic Interprability (mind of AI Read More.

Experts Skeptical of Huawei Silicon May Be Missing the Forest for the Trees


By @markpelf [ 3 Min read ] For months, headlines have fixated on Huaweis limitations in producing advanced 7nm chips, while Apple excels with its cutting-edge 3nm technology. Read More.

Why storyarb Pivoted From Ghostwriting for Founders to Producing Niche Content for Customers’ ICP


By @businessbarista [ 5 Min read ] We pivoted Storyarb from a ghostwriting agency for founders to B2B companies outsourced Head of Content Marketing. Heres our journey and lessons learned. Read More.


🧑‍💻 What happened in your world this week?

It's been said that writing can help consolidate technical knowledge, establish credibility, and contribute to emerging community standards. Feeling stuck? We got you covered ⬇️⬇️⬇️


ANSWER THESE GREATEST INTERVIEW QUESTIONS OF ALL TIME


We hope you enjoy this worth of free reading material. Feel free to forward this email to a nerdy friend who'll love you for it.See you on Planet Internet! With love, The HackerNoon Team ✌️


How to Build and Deploy a Decentralized Crowdfunding Smart Contract on the Linea Blockchain

2024-11-23 00:00:12

\ Crowdfunding has become a revolutionary way to pool resources for projects, causes, or businesses, it enables creators to bypass traditional funding barriers. With blockchain technology, crowdfunding takes a leap forward, offering transparency, decentralization, and immutability to ensure fairness for both creators and contributors.

\ This article introduces a Solidity-based Crowdfunding Smart Contract designed to operate on the Linea blockchain. This contract allows users to create campaigns, contribute funds securely, withdraw contributions when goals are met, and even request refunds when campaigns fail. The contract emphasizes accountability by leveraging smart contract features to automate processes, eliminate intermediaries, and ensure funds are used as intended.

\ This article aims to provide developers with a robust foundation for building decentralized crowdfunding platforms by walking through the contract's implementation, features, and functionality. Whether you're a blockchain enthusiast, developer, or entrepreneur, this guide will demonstrate how smart contracts can transform crowdfunding into a secure, efficient, and trustless experience.

Prerequisite

  • You should have a basic understanding of Solidity
  • You should have Nodejs and Foundry installed on your PC.

Overview of the Contract

This contract enables:

\

  1. Campaign Creation: Users can initiate fundraising campaigns by setting a goal and duration.
  2. Contributions: Users can contribute funds to active campaigns.
  3. Fund Withdrawal: Campaign creators can withdraw funds if the fundraising goal is met after the campaign deadline.
  4. Refunds: Contributors can reclaim their contributions if the goal is not met within the deadline.

Project Setup

  1. Run the command below to initiate a foundry project, we will be using foundry framework to build the smart contract.
  2. forge init crowdfunding
  3. Open the crowdfunding folder on Vscode or your favorite code editor, and delete the scripts/counter.s.sol, src/counter.sol, and test/counter.t.sol.
  4. Install all dependencies
  5. forge install foundry-rs/forge-std --no-commit

Full code of the crowdfunding smart contract

Create a crowdfunding.sol file in the src folder and add the code below to the file.

\

// SPDX-License-Identifier: MIT
   pragma solidity 0.8.18;

   contract Crowdfunding {
       struct Campaign {
           address creator;
           uint256 goal;
           uint256 deadline;
           uint256 amountRaised;
           bool isWithdrawn;
           mapping(address => uint256) contributions;
       }

       uint256 public campaignCount = 0;
       mapping(uint256 => Campaign) public campaigns;
       event CampaignCreated(uint256 campaignId, address creator, uint256 goal, uint256 deadline);
       event ContributionMade(uint256 campaignId, address contributor, uint256 amount);
       event FundsWithdrawn(uint256 campaignId, uint256 amount);
       event RefundIssued(uint256 campaignId, address contributor, uint256 amount);

       modifier campaignExists(uint256 campaignId) {
           require(campaignId < campaignCount, "Campaign does not exist");
           _;
       }

       modifier onlyCreator(uint256 campaignId) {
           require(msg.sender == campaigns[campaignId].creator, "Only the campaign creator can perform this action");
           _;
       }

       modifier beforeDeadline(uint256 campaignId) {
           require(block.timestamp <= campaigns[campaignId].deadline, "Campaign deadline has passed");
           _;
       }

       modifier afterDeadline(uint256 campaignId) {
           require(block.timestamp > campaigns[campaignId].deadline, "Campaign deadline has not passed yet");
           _;
       }


       // Create a new crowdfunding campaign
       function createCampaign(uint256 goal, uint256 duration) external {
           require(goal > 0, "Goal must be greater than zero");
           require(duration > 0, "Duration must be greater than zero");
           Campaign storage newCampaign = campaigns[campaignCount];
           newCampaign.creator = msg.sender;
           newCampaign.goal = goal;
           newCampaign.deadline = block.timestamp + duration;
           emit CampaignCreated(campaignCount, msg.sender, goal, newCampaign.deadline);
           campaignCount++;
       }

       // Contribute funds to a campaign
       function contribute(uint256 campaignId) external payable campaignExists(campaignId) beforeDeadline(campaignId) {
           require(msg.value > 0, "Contribution must be greater than zero");
           Campaign storage campaign = campaigns[campaignId];
           campaign.amountRaised += msg.value;
           campaign.contributions[msg.sender] += msg.value;
           emit ContributionMade(campaignId, msg.sender, msg.value);
       }

       // Withdraw funds if the campaign meets its goal
       function withdrawFunds(uint256 campaignId) external campaignExists(campaignId) onlyCreator(campaignId) afterDeadline(campaignId) {
           Campaign storage campaign = campaigns[campaignId];
           require(campaign.amountRaised >= campaign.goal, "Funding goal not reached");
           require(!campaign.isWithdrawn, "Funds already withdrawn");
           campaign.isWithdrawn = true;
           (bool sent, ) = campaign.creator.call{value: campaign.amountRaised}("");
           require(sent, "Failed to send Ether");
           emit FundsWithdrawn(campaignId, campaign.amountRaised);
       }

       // Request a refund if the campaign fails
       function requestRefund(uint256 campaignId) external campaignExists(campaignId) afterDeadline(campaignId) {
           Campaign storage campaign = campaigns[campaignId];
           require(campaign.amountRaised < campaign.goal, "Campaign succeeded, refunds not allowed");
           uint256 contribution = campaign.contributions[msg.sender];
           require(contribution > 0, "No contributions found for this campaign");
           campaign.contributions[msg.sender] = 0;
           (bool sent, ) = msg.sender.call{value: contribution}("");
           require(sent, "Failed to send Ether");
           emit RefundIssued(campaignId, msg.sender, contribution);
       }
   }

Key Features of the Code

Campaign Structure

The contract utilizes a struct named Campaign to store campaign details.

\

struct Campaign {
       address creator;            // Campaign creator
       uint256 goal;               // Fundraising goal
       uint256 deadline;           // Deadline to achieve the goal
       uint256 amountRaised;       // Total contributions raised
       bool isWithdrawn;           // Tracks if funds were withdrawn
       mapping(address => uint256) contributions; // Tracks contributions by users
   }

\

CampaignCount

Each campaign is uniquely identified by an incremental campaignId. This ensures scalability and makes managing multiple campaigns straightforward.

\

 uint256 public campaignCount = 0;
    mapping(uint256 => Campaign) public campaigns;

Campaign Creation

The createCampaign function allows a user to initiate a campaign. The function takes in two parameter, goal and duration, the goal is the target amount that the user wants to raise, and the duration is the time in seconds that the user wants to use to raise the goal specified.

\ The function ensures that the goal and duration are greater than zero to prevent users from entering zero values. The campaign struct details are updated and the campaignId is linked to the Campaign struct.

\ The campaignCount is incremented to make sure that new campaign created do not have the same campaignId as old campaigns.

\

 function createCampaign(uint256 goal, uint256 duration) external {
       require(goal > 0, "Goal must be greater than zero");
       require(duration > 0, "Duration must be greater than zero");

       Campaign storage newCampaign = campaigns[campaignCount];
       newCampaign.creator = msg.sender;
       newCampaign.goal = goal;
       newCampaign.deadline = block.timestamp + duration;

       emit CampaignCreated(campaignCount, msg.sender, goal, newCampaign.deadline);
       campaignCount++;
   }

\

Contribution Mechanism

The contribute function allows users to fund active campaigns. The function takes in one parameter, the campaignId, this is the unique identifier for each campaign, it determines which campaign users have decided to contribute into.

\ The function ensures that users do not contribute zero amount to the campaign, it tracks the amountRaised in the campaign and the amount each user has contributed to the campaign.

\

function contribute(uint256 campaignId) external payable campaignExists(campaignId) beforeDeadline(campaignId) {
       require(msg.value > 0, "Contribution must be greater than zero");

       Campaign storage campaign = campaigns[campaignId];
       campaign.amountRaised += msg.value;
       campaign.contributions[msg.sender] += msg.value;

       emit ContributionMade(campaignId, msg.sender, msg.value);
   }

\ The campaignExists modifier on the contribute function checks that the campaignId exists and throws an error if the campaignId does not exist.

\

 modifier campaignExists(uint256 campaignId) {
           require(campaignId < campaignCount, "Campaign does not exist");
           _;
       }

\ The beforeDeadline modifier checks if the deadline of the campaign has passed and throws an error if the deadline has passed.

\

 modifier beforeDeadline(uint256 campaignId) {
           require(block.timestamp <= campaigns[campaignId].deadline, "Campaign deadline has passed");
           _;
       }

\

Withdrawing Funds

Campaign creators can withdraw funds using withdrawFunds. The function takes in one parameter, the campaignId, which is the unique identifier for each campaign.

\ The funds can only be withdrawn by the campaign creator, if any other user tries to withdraw the fund, the function will throw an error.

\ The function ensures that the funding goal was met and that the funds haven't already been withdrawn. If the funding goal is not met, the function will throw an error and if the funds have been withdrawn, the function will throw an error.

\ The function changes the isWithdrawn status to true and sends the funds to the campaign creator.

\

   function withdrawFunds(uint256 campaignId) external campaignExists(campaignId) onlyCreator(campaignId) afterDeadline(campaignId) {
       Campaign storage campaign = campaigns[campaignId];
       require(campaign.amountRaised >= campaign.goal, "Funding goal not reached");
       require(!campaign.isWithdrawn, "Funds already withdrawn");

       campaign.isWithdrawn = true;
       (bool sent, ) = campaign.creator.call{value: campaign.amountRaised}("");
       require(sent, "Failed to send Ether");

       emit FundsWithdrawn(campaignId, campaign.amountRaised);
   }

\ The onlyCreator modifier checks if the user calling the function is the campaign creator and throws an error if the user is not the campaign creator.

\

 modifier onlyCreator(uint256 campaignId) {
           require(msg.sender == campaigns[campaignId].creator, "Only the campaign creator can perform this action");
           _;
       }

\ The afterDeadline modifier checks if the deadline of the campaign has not passed and throws an error if the deadline has not passed.

\

modifier afterDeadline(uint256 campaignId) {
           require(block.timestamp > campaigns[campaignId].deadline, "Campaign deadline has not passed yet");
           _;
       }

\ Refunds for Failed Campaigns

Contributors can retrieve their contributions if the campaign fails. The function takes in one parameter, the campaignId, which is the unique identifier for each campaign.

\ The function ensures that the campaign failed to meet its goal and that the user contributed to the campaign. It resets the user contribution to the campaign to zero and refunds the user contribution.

\

 function requestRefund(uint256 campaignId) external campaignExists(campaignId) afterDeadline(campaignId) {
        Campaign storage campaign = campaigns[campaignId];
        require(campaign.amountRaised < campaign.goal, "Campaign succeeded, refunds not allowed");

        uint256 contribution = campaign.contributions[msg.sender];
        require(contribution > 0, "No contributions found for this campaign");

        campaign.contributions[msg.sender] = 0;
        (bool sent, ) = msg.sender.call{value: contribution}("");
        require(sent, "Failed to send Ether");

        emit RefundIssued(campaignId, msg.sender, contribution);
    }

\ Events

The contract emits events for key actions:

\

  • CampaignCreated: Logs details of a new campaign.
  • ContributionMade: Logs contributions to a campaign.
  • FundsWithdrawn: Logs successful fund withdrawals.
  • RefundIssued: Logs refunds issued to contributors.

\

event CampaignCreated(uint256 campaignId, address creator, uint256 goal, uint256 deadline);
       event ContributionMade(uint256 campaignId, address contributor, uint256 amount);
       event FundsWithdrawn(uint256 campaignId, uint256 amount);
       event RefundIssued(uint256 campaignId, address contributor, uint256 amount);

\

Tests

Create a crowdfunding.t.sol file in the test folder and add the code below to the file.

\

// SPDX-License-Identifier: UNLICENSED
   pragma solidity ^0.8.13;
   import {Test, console} from "forge-std/Test.sol";
   import {Crowdfunding} from "../src/Crowdfunding.sol";
   contract CounterTest is Test {
       Crowdfunding public crowd;
       address public user1 = makeAddr("user1");
       address public user2 = makeAddr("user2");
       address public user3 = makeAddr("user3");

       function setUp() public {
           crowd = new Crowdfunding();
       }

       function test_createCampaign() public {
           vm.startPrank(user1);
           crowd.createCampaign(10 ether, 10 hours);
       }

       function test_contributeCampaign() public {
           vm.startPrank(user1);
           crowd.createCampaign(10 ether, 10 hours);
           deal(user2, 10 ether);
           deal(user3, 10 ether);
           vm.startPrank(user2);
           crowd.contribute{value: 6 ether}(0);
            vm.startPrank(user3);
           crowd.contribute{value: 6 ether}(0);
       }

        function test_withdrawCampaign() public {
           vm.startPrank(user1);
           crowd.createCampaign(10 ether, 10 hours);
           deal(user2, 10 ether);
           deal(user3, 10 ether);
           vm.startPrank(user2);
           crowd.contribute{value: 6 ether}(0);
            vm.startPrank(user3);
           crowd.contribute{value: 6 ether}(0);
           skip(11 hours);
           console.log("b4", user1.balance);
           vm.startPrank(user1);
           crowd.withdrawFunds(0);
           console.log("after",user1.balance);
       }

       function test_requestCampaign() public {
           vm.startPrank(user1);
           crowd.createCampaign(10 ether, 10 hours);
           deal(user2, 10 ether);
           deal(user3, 10 ether);
           vm.startPrank(user2);
           crowd.contribute{value: 2 ether}(0);
            vm.startPrank(user3);
           crowd.contribute{value: 2 ether}(0);
           skip(11 hours);
           vm.startPrank(user2);
           crowd.requestRefund(0);
           vm.startPrank(user3);
           crowd.requestRefund(0);
           console.log("after",user2.balance);
           console.log("after",user3.balance);
       }

   }

\ The test suite above ensures that the Crowdfunding contract operates as intended across its core functionalities. Here’s a breakdown of the tests:

\

test_createCampaign

This test verifies that a user can successfully create a crowdfunding campaign. In the test, the campaign was created and no errors were thrown.

\

test_contributeCampaign

This test verifies that multiple users can contribute to a specific campaign. In the test, user1 creates a campaign, and user2 and user3 get 10 ether each with the foundry deal function. user2 and user3 contributed 6 ether to the campaign. Both contributions were accepted and the contract updates the campaign’s total amount raised.

\

test_withdrawCampaign

This test verifies that the campaign creator can withdraw funds once the campaign meets its funding goal and the deadline has passed. After user2 and user3 has contributed to campaign and 11 hours has passed (done through simulation with skip). User1 calls withdrawFunds to withdraw the raised funds. The funds are transferred to user1 and the balance after withdrawal reflects this change.

\

test_requestCampaign

This test verifies that the contributors can request refunds if the campaign fails to meet its funding goal. After user2 and user3 has contributed to campaign and 11 hours has passed (done through simulation with skip). User2 and user3 call requestRefund, each user receives their contributed ether back.

\

How to run Test

\

forge test

\

Deployment and Verification on Linea

Add the necessary variables to .env, the .env file should be at the root level:

\

LINEA_RPC_URL=https://linea-sepolia.blockpi.network/v1/rpc/public
PRIVATE_KEY=*************************************************
LINEA_API_KEY=*************************

\ Add the details below to foundry.toml:

\

 [etherscan]
   linea = { key = "${LINEA_API_KEY}", url = "https://api-sepolia.lineascan.build/api" }

\ Create a Makefile and add the details below:

\

deploy:
    forge create src/Crowdfunding.sol:Crowdfunding --rpc-url $(LINEA_RPC_URL) --private-key $(PRIVATE_KEY)

verify:; forge verify-contract --rpc-url $(LINEA_RPC_URL) --chain linea <contract address> src/Crowdfunding.sol:Crowdfunding

\ Deployment

\

make deploy

\ Verification

\

make verify

\

Conclusion

This article demonstrates the transformative potential of blockchain in decentralized fundraising. By offering transparency, immutability, and autonomy, it empowers campaign creators and contributors with a system free of intermediaries.

\ This contract serves as an excellent foundation for real-world crowdfunding applications and highlights the possibilities for building more robust and feature-rich decentralized systems. With Web3 adoption on the rise, such smart contracts will likely become pivotal in democratizing access to funding globally. Developers and businesses can leverage this solution to innovate further and expand its usability for a wide range of industries.

Zircuit Launches ZRC Token: Pioneering The Next Era Of Decentralized Finance

2024-11-22 23:26:50

GEORGE TOWN, Grand Cayman, November 22nd, 2024/Chainwire/--Zircuit, the chain where innovation meets security, today announced its ZRC Token Launch on Monday, November 25th—a key step in building a thriving, decentralized ecosystem.

\ ZRC serves as the foundation of Zircuit’s architecture, enabling participants to receive additional rewards, participate in network app fair launches, and drive its growth. As the ecosystem’s cornerstone, ZRC aligns incentives across developers and users, fostering active collaboration and innovation.

\ The ZRC launch follows a series of notable achievements for Zircuit, including the successful rollout of Mainnet, a $2 billion TVL ecosystem, the groundbreaking EIGEN fairdrop with over 190,000 participants, the liquidity hub launch, and strategic investment from Binance Labs, Pantera, and other strategic partners.

\ Together, these milestones underscore Zircuit’s position as a leader in decentralized finance and staking.

\

“The ZRC token is more than a milestone; it’s a gateway to the decentralized future we’ve been building at Zircuit,” said Martin Derka, co-founder of Zircuit. “By aligning incentives across our ecosystem, ZRC empowers developers and users to shape the network collaboratively.”

\ Designed with transparency and accessibility in mind, the ZRC Token Launch ensures participants can seamlessly engage with staking partners through Seasons 1-3 of Zircuit’s ecosystem. This includes staking through the Liquidity Hub, offering the potential to earn rewards.

\ Zircuit protects users from hacks through its built-in, automated AI techniques that guard users against smart contract exploits and malicious actors.

\ This system automatically guards against smart contract exploits and malicious actors, making Zircuit one of the safest blockchain platforms available.

\ As the safest chain for DeFi and staking, Zircuit is the premier liquidity hub for various assets, including ETH, BTC, LSTs, and LRTs, while providing robust security guarantees. Zircuit’s strong infrastructure allows users to earn competitive yields natively, combining safety with attractive returns.

\ Users can explore the ZRC token’s role in Zircuit’s ecosystem by engaging with staking and reward opportunities through the Liquidity Hub. For more information, users can visit zircuit.com and follow Zircuit on Twitter/X at @ZircuitL2.

About Zircuit

Zircuit: Where innovation meets security, designed for everyone. Zircuit offers developers powerful features while giving users peace of mind.

\ Designed by a team of web3 security veterans and PhDs, Zircuit combines high performance with unmatched security. Experience the safest chain for DeFi and staking. To learn more about Zircuit, visit zircuit.com, and follow us on Twitter/X @ZircuitL2.

Contact

Head of Communications

Jennifer Zheng

Zircuit

[email protected]

:::tip This story was distributed as a release by Chainwire under HackerNoon’s Business Blogging Program. Learn more about the program here

:::

\