> For the complete documentation index, see [llms.txt](https://blockchain-journal-hope-mabuza.gitbook.io/blockchain-journal-hope-mabuza-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://blockchain-journal-hope-mabuza.gitbook.io/blockchain-journal-hope-mabuza-docs/smart-contracts/week-8-aa-erc-4337-and-smart-wallets-continuation.md).

# Week 8 : AA, ERC-4337 and Smart Wallets (Smart Accounts)

#### The ERC-4337 Transaction Flow and Smart Accounts

<figure><img src="/files/dBq0hllhWYvs3TIZdoPp" alt=""><figcaption></figcaption></figure>

**The ERC-4337 Flow**

The image above shows the full flow of how ERC-4337 works. In a normal Ethereum transaction, a user signs and sends a transaction directly to the blockchain using their EOA. ERC-4337 works differently. Instead of sending a transaction directly, the user creates a UserOperation, a structured request that describes what they want to do. That UserOperation gets sent to an alternative mempool, a separate waiting area just for smart wallet transactions. From there, the EntryPoint contract acts as the gatekeeper, every UserOperation must pass through it before anything else happens. The EntryPoint validates the UserOperation and only then can the Bundler collect a batch of them and submit the final transaction to the blockchain.

**The Smart Account**

For any of that to work, the user needs a Smart Account. This is the wallet that replaces the EOA in the ERC-4337 world. Unlike an EOA which is just a private key, a Smart Account is an actual smart contract that holds funds and executes logic on behalf of the user. It is what the EntryPoint interacts with when processing a UserOperation.

**The Factory**

If the Smart Account is a smart contract, how does it get deployed in the first place? That is where the Factory comes in. The Factory is a contract responsible for constructing and deploying Smart Account addresses. It does this using two methods, CREATE1 and CREATE2.

CREATE1 is the typical way addresses are created in a normal EOA transaction flow. It uses your EOA address and your nonce to generate an address. You've actually seen this before, when you deploy a contract from your wallet, the address of that contract is determined using your address and your current nonce. The problem with this is that the address changes depending on your nonce, so it is not predictable.

For Smart Accounts we need something better. We need addresses that are unique, secure and deterministic, meaning we can calculate the address before the contract is even deployed. That is why CREATE2 is used. Instead of relying on a nonce, CREATE2 takes in a salt, which is a random byte string generated from an input value, and the bytecode of the contract. The same inputs will always produce the same address, no matter when or where it is deployed.

Here is how the Factory contract actually works:

```solidity
contract AccountFactory {
    function createAccount(address owner) external returns (address) {
        bytes32 salt = bytes32(uint256(uint160(owner)));
        bytes memory creationCode = type(Account).creationCode;
        bytes memory bytecode = abi.encodePacked(creationCode, abi.encode(owner));

        address addr = Create2.computeAddress(salt, keccak256(bytecode));
        uint256 codeSize = addr.code.length;
        if (codeSize > 0) {
            return addr;
        }

        return deploy(salt, bytecode);
    }

    function deploy(bytes32 salt, bytes memory bytecode) internal returns (address addr) {
        require(bytecode.length != 0, "Create2: bytecode length is zero");
        assembly {
            addr := create2(0, add(bytecode, 0x20), mload(bytecode), salt)
        }
        require(addr != address(0), "Create2: Failed on deploy");
    }
}
```

The `createAccount` function takes in the owner's address and uses it to generate the salt. It then gets the bytecode of the Account contract and combines it with the owner's address. Before deploying anything, it first computes what the address would be using CREATE2 and checks if a contract already exists at that address. If it does, it simply returns the existing address without deploying again. If it doesn't exist yet, it calls the `deploy` function which uses assembly to run the actual CREATE2 deployment. This is why the address is deterministic, the same owner will always get the same Smart Account address.

***

#### Signature Verification and Generating Wallet Addresses

*Workshop with Karabo*

Today during our workshop with Karabo we went into a deeper dive into smart wallets and things started becoming more practical. We started by going through code that verifies transaction signatures. After running the script, we were able to recover the addresses that signed the transactions. That made the whole concept feel more real, because instead of just understanding signatures in theory, I could actually see how they are used to prove ownership on-chain.

It also made me realise how important it is to protect your signature. If someone else gets access to it, they essentially have control over your wallet and can authorise transactions on your behalf. So security here is not just important, it is everything.

We then moved on to writing code to generate a wallet address using CREATE1. Applying the theory I've been learning was a bit challenging at first. It's one thing to understand it conceptually, but another to actually implement it. By the end of the session it started making more sense and we were able to get it working. The next step is to focus on writing code for all the UserOperation fields, which I'm looking forward to because it will tie everything together.

***

#### Wrapped APIs, API Security and Solidity Fundamentals

*ABC Session*

Today's session was one of the most engaging we have had at ABC so far. It covered a lot of different ground but everything connected in a useful way.

**Wrapped APIs**

We started by learning about wrapped APIs. A wrapped API is an API that interacts with one or more underlying APIs, processes the data, and presents it to the client in a more structured and simplified format. Instead of the client having to talk to multiple services, it communicates with a single wrapped API that handles all the complexity internally. We used Booking.com as an example, where the platform pulls data from various hotel systems and presents it in a unified way to the user. We also related it back to our previous project CodeClinics, where the application integrated with Google Calendar to show tutor availability in a simplified way. One important thing I clarified during this session is that wrapped APIs don't eliminate error handling, they centralise it. The wrapped API is still responsible for handling errors from the underlying services and returning consistent responses to the client.

**Securing APIs**

We then covered API security concepts including HTTPS, TLS, SSL and SSO. HTTPS is HTTP secured using TLS, which ensures encrypted communication between the client and server. TLS is the protocol responsible for securing data in transit, while SSL is its older deprecated version. SSO, or Single Sign-On, allows users to authenticate once and gain access to multiple systems without needing to log in again. We also looked at TLS certificates, which are issued by trusted Certificate Authorities and allow clients to verify the identity of servers. The key principles here are confidentiality, integrity and authenticity.

**Solidity Fundamentals**

We also revisited `msg.sender` and `msg.value`, which was actually a really useful clarification for me. I had initially thought that when a user interacts with a contract, a JSON object is created for them and that is how we access fields like `msg.sender`. That is not correct. `msg` is a global variable provided by Solidity that represents the current transaction or call context within the EVM. `msg.sender` is the address that called the function and `msg.value` is the amount of ETH sent with it. The confusion came from the fact that when interacting with contracts through a frontend, data is structured as JSON for communication between the client and the node. But once the transaction reaches the EVM, it is no longer JSON and the contract reads it through the `msg` object. That clarification helped a lot.

***
