# Solidity Tinkering w/Scaffold-ETH

By [BuidlGuidl](https://paragraph.com/@news.buidlguidl) · 2023-01-09

---

🏗 [**Scaffold-ETH**](https://github.com/scaffold-eth/scaffold-eth/tree/master) is a Decentralized Application(dApp) toolkit to learn and build on Ethereum without the overhead of setting up every piece of the application yourself.

You can use Scaffold-ETH to learn about Solidity by taking the initial [_YourContract.sol_](https://github.com/scaffold-eth/scaffold-eth/blob/master/packages/hardhat/contracts/YourContract.sol) smart contract & start iterating on it by adding more complex concepts onto it. Below are some quests to follow along.

You can also check out the BG Labs video on Solidity Deep Dive over [here](https://www.youtube.com/watch?v=-qAtRhVDMfM&ab_channel=AustinGriffith). 👇

[![]({{DOMAIN}}/editor/youtube/play.png)](https://www.youtube.com/watch?v=-qAtRhVDMfM)

* * *

1\. Getting started with Scaffold-ETH: Add totalCounter
-------------------------------------------------------

*   Spin up [Scaffold-ETH](https://github.com/scaffold-eth/scaffold-eth/tree/master). Check out the Burner wallet, get funds for your wallet, and try out the example UI and contract component page.
    

**Exercise:** Add a counter called 'totalCounter' to your smart Contract that keeps track of how many times the purpose changes.

    uint256 public totalCounter;
    
    function setPurpose(string memory newPurpose) public payable {
        totalCounter += 1;
        // ....
    }
    

2\. Array of Structs
--------------------

_Structs_: Structs are a data type that allows you to group related data together. _Mappings_: A mapping is a data type that associates values with keys and stores them. Mappings cannot be looped over. [Here's](https://solidity-by-example.org/app/iterable-mapping/) how you can iterate through a mapping.

**Exercise:** We want to store all the purposes sent by a given address and the block timestamp. We need a Struct & a mapping with an array of those structs. Go to [Solidity by example](https://solidity-by-example.org/), copy/paste and modify.

    struct PurposeSubmission {
        string text;
        uint256 timestamp;
    }
    
    mapping(address => PurposeSubmission[]) public userSubmissions;
    
    function setPurpose(string memory newPurpose) public payable {
        userSubmissions[msg.sender].push(PurposeSubmission(newPurpose, block.timestamp));
        // ....
    }
    

3\. Inheritance
---------------

Inheritance allows us to override or extend the behavior of the original contract. The most common use case is inheriting from battle-tested 3rd party contracts (like OpenZeppelin); these are audited and commonly used contracts.

**Exercise:** Inherit the OpenZeppelin Ownable Contract. Check all the new functions/variables that appear in the UI.

    contract YourContract is Ownable {...}
    

_We'll come back to the_ **_owner_** _that comes with the Ownable contract._

**Exercise:** Solidity supports multiple inheritances. On the same Contract, inherit the OpenZeppelin Pausable contract as well.

    import "@openzeppelin/contracts/security/Pausable.sol";
    
    contract YourContract is Ownable, Pausable {...}
    

4\. Deploy script
-----------------

The deploy script is where we prepare our contract for deployment (arguments, one-time tx after deploy, etc). You can edit your deployment scripts in `packages/hardhat/deploy`

**Exercise:** Call transferOwnership from the deploy script.

    await YourContract.transferOwnership(
      "FRONTEND_ADDRESS_HERE"
    );
    

**Exercise:** transferOwnership from the constructor.

    // contract
    constructor(address _initialOwner) payable {
        Ownable._transferOwnership(_initialOwner);
    }
    

    // deploy script
    await deploy("YourContract", {
      //..
      args: ["FRONTEND_ADDRESS_HERE"],
      //..
    });
    

5\. New Contract + Contract Interaction
---------------------------------------

You can have multiple contracts on your project and look into contract to contract interaction.

**Exercise:** Create a new contract called **WithdrawerContract** to get money from our PurposeContract.

1.  Create the Contract
    
        pragma solidity >=0.8.0 <0.9.0;
        //SPDX-License-Identifier: MIT
        
        // Create a blueprint first
        contract WithdrawerContract {
            function withdrawFrom(address _contractAddress) public {
                //
            }
        
            // to support receiving ETH by default
            receive() external payable {}
            fallback() external payable {}
        }
        
    
2.  Create a new deploy script to deploy the Withdrawer Contract.
    
        module.exports = async ({ getNamedAccounts, deployments }) => {
          const { deploy } = deployments;
          const { deployer } = await getNamedAccounts();
        
          await deploy("WithdrawerContract", {
            from: deployer,
            log: true,
            waitConfirmations: 5,
          });
        };
        module.exports.tags = ["withdrawFrom"];
        
    
3.  Add the Withdrawer Contract to the UI on \`App.jsx\`
    
          < Contract
            name="WithdrawerContract"
            price={price}
            signer={userSigner}
            provider={localProvider}
            address={address}
            blockExplorer={blockExplorer}
            contractConfig={contractConfig}
          />
        
    
4.  Implement a withdraw function on the Purpose contract & try to call it from the UI.
    
        function withdraw() public {
            require(msg.sender != tx.origin, "Not a contract");
        
            (bool sent,) = msg.sender.call{value: address(this).balance}("");
            require(sent, "Failed to send Ether");
        }
        
    
5.  Contract to Contract call on WithdrawerContract
    
        interface IYourContract {
            function withdraw() external;
        }
        
        contract WithdrawerContract {
            function withdrawFrom(address _contractAddress) public {
                IYourContract(_contractAddress).withdraw();
            }
        
            // ...
        }
        
    

* * *

Hope this was helpful! These were some sample tasks & you can continue to try out new concepts from [Solidity by example](https://solidity-by-example.org/) with [Scaffold-ETH](https://github.com/scaffold-eth/scaffold-eth/tree/master). Next up, why not take on [SpeedRunEthereum](https://speedrunethereum.com/)! 😉

---

*Originally published on [BuidlGuidl](https://paragraph.com/@news.buidlguidl/solidity-tinkering-w-scaffold-eth)*
