[TWIL] Week of May 26, 2024

[TWIL] Week of May 26, 2024

·

3 min read

This week, I mainly focused on integrating the smart contracts I deployed last week into our website. I didn't learn much new, so I'll share some useful knowledge I gained in the past that I haven't shared yet.

Solidity Immutable Variable

While I was skimming through Base's tutorials on gas optimization, I noticed the usage of an immutable variable. Since I was curious, I did a bit of research on what it does.

What is it?

As the name suggests, an immutable variable cannot be changed after the contract is deployed. You can assign a value while declaring it or within the constructor, but it cannot be accessed until the contract is deployed. In other words, it is not accessible within the constructor; it can only be assigned a value. Here's an example of how it's used:

contract Example {
    address immutable addressOne;

    address immutable addressTwo = address(0);

    address immutable addressThree;

    address immutable addressFour;

    constructor(address _anotherOwner) {
        addressOne = msg.sender;
        addressThree = _anotherOwner;
        // The line below will throw an error
        // addressFour = addressOne;
    }
}

Vs. Constant Variable

Here's a brief table that explains the differences:

CategoryConstantImmutable
Possible ValuesAny values other than external ones (ex. msg.sender, block.timestamp, etc.)Any values other than dynamic ones (ex. string, bytes, etc.)
Gas EfficiencyMost efficientLess efficient than a constant variable
Value AssignmentMust be assigned at compilationCan be assigned at runtime (i.e. within the constructor)

Stuck Transaction

When using Hardhat to interact with the Polygon PoS network, I frequently faced issues with transactions getting stuck due to low gas prices. This occurred because Polygon Labs set a minimum gas price of 30 gwei to mitigate spam transactions. To prevent transactions from getting stuck, you can use one of the following methods:

  1. Set an explicit gas price for all transactions: If you're using Hardhat, you can set it in hardhat.config.ts:

     const config: HardhatUserConfig = {
       // ...
       matic: {
         // ...
         gasPrice: Number(ethers.parseUnits("30", "gwei"))
       }
     }
    
  2. Set an explicit gas price for a specific transaction:

     contract Example {
         address immutable owner;
         constructor() {
             owner = msg.sender;
         }
    
         function setOwner(address newOwner) external {
             owner = newOwner;
         }
     }
    
     async function main() {
         const example = await ethers.deployContract("Example");
         await example.waitForDeployment();
    
         const txOptions = {gasPrice: ethers.parseUnits("30", "gwei")};
         const tx = await example.setOwner(ethers.ZeroAddress, txOptions);
         await tx.wait();
         // ...
     }
    
     main();
    

If you want to resolve a stuck transaction, you need to provide the nonce of the stuck transaction as well.

async function main() {
    const example = await ethers.deployContract("Example");
    await example.waitForDeployment();

    const signer = new ethers.Wallet(
        `<account-private-key>`,
        ethers.provider,
    );
    const nonce = await ethers.provider.getTransactionCount(
        signer.address,
        "latest",
    );

    const txOptions = {gasPrice: ethers.parseUnits("30", "gwei"), nonce};
    const tx = await example.setOwner(ethers.ZeroAddress, txOptions);
    await tx.wait();
    // ...
}

main();

That wraps up this week's TWIL. Happy hacking! ☕️