Jun 13, 2023

The Proxy Pattern — A Solution to Smart Contract Upgradability?

I’m always searching for proven patterns and approaches to system design and implementation. These proven strategies can help us design solutions and tackle recurring challenges. Many times old patterns and experiences can be applied in hew contexts. Problem reoccur in new shapes but their underlying essence often remains the same.

Imagine a world where the postman delivering the mail to your mailbox could not be replaced, he falls sick and you get no mails. The mailbox and postoffice here serves as proxies in the overall mail delivery process, how the mail is moved between the mailbox and post office does not matter and can be changed.

In this post, I would like to explore the concept of immutability in smart contracts and discuss how the Proxy pattern emerges as a potential solution to strike a balance.

One challenge that has been on my mind lately is the balance between immutability and updatability in smart contracts. From my observations, it seems like the Proxy Pattern is a solution commonly used to address this challenge.

In the blockchain landscape, smart contracts serve as a significant building block. They function as autonomous programs that execute contract stipulations, inscribed directly into the code and preserved on the blockchain. One interesting aspect of smart contracts is their immutability — once deployed, they remain unalterable, a feature that upholds transparency and security. However, this ‘carved-in-stone’ characteristic, though instrumental in establishing trust, does present its own unique set of challenges. If a bug surfaces or there’s a need to introduce a new feature, you’re faced with a hurdle. Tweaking the existing contract or appending new functions isn’t an option. Instead, deploying a new contract becomes necessary. While not necessarily costly, this can be inconvenient and potentially disruptive. The previously produced data is tied to the original contract, and applications interacting with the contract need to be adjusted to communicate with the new one.

This is where the Proxy Pattern comes into play. It involves creating two contracts — a Proxy Contract that users interact with, and a Logic Contract that carries out the operations. When changes are needed, a new Logic Contract is deployed and the Proxy Contract is updated to point to it. This provides a way to update the system without disrupting the dependent clients.

Proxy Contract Example

Let’s explore a simple implementation of the Proxy Pattern to illustrate the concept. In this example, we have three contracts: Greetings (the proxy contract), GreetingImplementation1, and GreetingImplementation2 (the implementation contracts).

The Greetings contract acts as the proxy, with the implementation contracts GreetingImplementation1 and GreetingImplementation2 providing different greeting messages.

When the Greetings contract is created, the address of an implementation contract is passed through its constructor, allowing flexibility in selecting the desired implementation.

An important feature of the Greetings contract is the updateImplementation method, which enables the dynamic update of the implementation contract address. By invoking this method, the implementation contract can be changed, facilitating upgradability and adaptability.

When the greetings method is called on the Greetings contract, it delegates the execution to the implementation contract specified by the current address stored in the implementationAddress variable. This way, the specific greeting logic within the selected implementation contract is executed.

By implementing the Proxy Pattern in this example, the Greetings contract maintains a consistent interface while enabling seamless changes or upgrades to the underlying implementation contract, providing versatility and ensuring a smooth user experience.

I am still learning and sharing as I explore and would love to get your feedback.

For those of you who’ve worked with smart contracts, how have you managed this balance between immutability and updatability? Have you experimented with the Proxy Pattern, or have you found other innovative solutions? What are your thoughts on applying classic design patterns to the world of blockchain?

I’m eager to hear your experiences, insights, and learn from the collective wisdom of this community. Let’s navigate these intriguing Web3 waters together.