[TWIL] Week of July 7, 2024
![[TWIL] Week of July 7, 2024](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1722035971592%2F83b8bd99-d48f-47d8-a95e-853090737d97.png&w=3840&q=75)
Search for a command to run...
![[TWIL] Week of July 7, 2024](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1722035971592%2F83b8bd99-d48f-47d8-a95e-853090737d97.png&w=3840&q=75)
No comments yet. Be the first to comment.
This series is about my weekly learning experiences, covering a broad range of topics with a focus on sharing engineering tips and techniques whenever possible.
This week, the first after the OCS Buildathon, I dedicated my time to refactoring and researching upgradability access controls for our smart contracts. Here are the key insights and lessons I learned during this process. Smart Contract Address Confl...
This year, I decided to attend ETHDenver, one of the most well-known crypto conferences in the world, from February 25th to March 1st. Although I wasn’t there for the entire week, I made it a priority to experience as much as possible within the few ...

AI has become an unavoidable topic in tech, with models like OpenAI’s ChatGPT, DeepSeek, and Gemini dominating headlines. Since ChatGPT’s release in November 2022, AI has rapidly changed how we work and build software. Naturally, I’ve been using it e...

Hello builders! I hope you all had a fantastic week. Mine was a bit more laid-back. I decided to turn off my "build mode" and dive into some reading. I picked up two books: one technical and one non-technical (though still focused on NFTs). In this p...
![[TWIL] Week of August 11, 2024](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1724192926501%2F2ba38d69-5f89-4c41-b2fe-7f994fa97f71.png&w=3840&q=75)
Hello Builders! Hope you had a wonderful week! For this week’s TWIL post, I’d like to share a slight change to the series moving forward. As I mentioned in my previous post, I’ll continue writing one TWIL post each week, but the content might shift a...
![[TWIL] Week of August 04, 2024](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1723410046529%2F77c9c1f6-e0e2-4422-aa2c-0b82b769631c.png&w=3840&q=75)
Hello builders! This past week has been one of the most emotionally charged experiences I've had in a while. After much thought, I've made the difficult decision to leave Ourkive, the startup I co-founded alongside two other incredible people. While ...
![[TWIL] Week of July 28, 2024](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1723335244607%2F22b5f8ee-4c35-4cf0-9666-405c09aae03c.png&w=3840&q=75)
This week, I delved into the intricacies of multi-sig contracts to enhance smart contract upgradability and streamline on-chain data updates. Along the way, I picked up some valuable insights that I'd like to share with you.
As the name implies, the core feature of a multi-sig contract is to require multiple signatures to authorize a transaction. Here’s a typical workflow:
Submission: One of the contract owners submits a transaction onchain.
Approval: Other owners approve the submitted transaction.
Execution: Once the transaction receives enough approvals (i.e., meets a set threshold), one of the owners executes it.
When submitting a transaction, the smart contract must know the essential details, such as the contract address and the encoded function data. The encoded function data can be generated with the following code:
function getEncodedFunctionData() {
const Contract = await ethers.getContractFactory("<contract-name>");
const contract = await Contract.attach("<deployed-contract-address>");
return contract.interface.encodeFunctionData(
"<function-name>",
[/* args in order */]
);
}
With the contract address and encoded function data in hand, the transaction is processed using this line of code:
(bool success, bytes memory returnData) = transaction.to.call{
value: transaction.value
}(transaction.data);
Here’s a breakdown:
transaction.to points to the contract address.
call is a low-level method used to interact with another smart contract. If you're familiar with Solidity, you've likely seen it used for sending native tokens to an address. Now, how I'm using it here isn't generally recommended due to several potential issues, but I opted to use call over delegatecall to maintain the context of the called contract.
value is the native token amount being sent, often 0 if not required.
transaction.data is the encoded function data being passed along.
The returnData is useful for two purposes:
Handling data returned by the called function.
Capturing errors from the callee contract, though some reverts may not bubble up correctly.
The Universal Upgradeable Proxy Standard (UUPS) is a method for upgrading smart contracts. It's similar to the Transparent Proxy Pattern but has key differences in where the authorization and upgrading logic are located.
Here’s an example using OpenZeppelin's UUPSUpgradeable contract:
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
contract Example is OwnableUpgradeable, UUPSUpgradeable {
function initialize(
address owner
) public initializer {
__Ownable_init(owner);
}
// ...
function _authorizeUpgrade(address) internal override onlyOwner {}
}
Let's take a closer look:
The Example contract inherits UUPSUpgradeable from OpenZeppelin.
Override the _authorizeUpgrade method from UUPSUpgradeable to include custom authorization logic, such as the onlyOwner modifier, ensuring only the owner can upgrade the contract.
I applied this template to all our smart contracts, ensuring that our multi-sig contract is the only way to authorize upgrades. This means upgradeability authorization relies on the multi-sig mechanism, preventing any single entity from compromising our smart contracts.
That's it! This brief overview hopefully provides a starting point for understanding how multi-sig contracts are implemented and how they can serve as an upgradeability medium. I plan to write a more detailed technical blog on multi-sig contracts in the future. For now, happy hacking! ☕️