Skip to content

Commit

Permalink
📝 Blog: Eip 1193 the standard (#1487)
Browse files Browse the repository at this point in the history
## Description

_Concise description of proposed changes_

## Testing

Explain the quality checks that have been done on the code changes

## Additional Information

- [ ] I read the [contributing docs](../docs/contributing.md) (if this
is your first contribution)

Your ENS/address:



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Introduced a comprehensive overview of EIP-1193, enhancing
interoperability for Ethereum development.
- Added practical examples for implementing EIP-1193 and creating a
custom optimistic transport.

- **Documentation**
- Updated documentation for the `getBlockFromRpc` function, clarifying
parameters and return types.
- Removed the file exploring Layer 2 scaling solutions and the "VM Wars"
in Ethereum.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
roninjin10 authored Oct 21, 2024
1 parent dc52267 commit e605859
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 131 deletions.
44 changes: 44 additions & 0 deletions Debugger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
```typescript
import {createMemoryClient, http} from 'tevm'
import {numberToHex} from 'tevm/utils'
import MyContract from '<chain-id>:<contract-address>?rpcUrl=https://my.rpc.url'

main()

async function main() {
const client = createMemoryClient({
fork: { transport: http('https://my.rpc.url') },
})
setupDebugger()
await client.contract({
abi: MyContract.abi,
functionName: 'someMethod',
args: ['method', 'args'],
})
}

// registers a debugger on the evm
function setupDebugger() {
const vm = await client.getVm()

vm.evm.events.on('step', async (step, next) => {
console.log({
pc: step.pc,
op: step.opcode.name,
gasCost: BigInt(step.opcode.fee) + (step.opcode.dynamicFee ?? 0n),
gas: step.gasLeft,
depth: step.depth,
stack: step.stack.map((code) => numberToHex(code)),
})
// here we would track things like stack depth etc.
await stopForDebuggerOrBreakpoint()
})
}

// here is where we plug in the ui to stop execution for the debugger
// for now just use a javascript debugger
async function stopForDebuggerOrBreakpoint () {
debugger
}
```

164 changes: 164 additions & 0 deletions docs/src/content/docs/blog/0_eip-1193-the-unsung-hero.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
---
title: "EIP-1193: The Unsung Hero of Ethereum Development"
description: "Discover how EIP-1193 is revolutionizing JavaScript libraries in the Ethereum ecosystem, with practical examples and a vision for the future."
date: 2024-10-20
author: "fucory"
---

### The Power of Standards in Ethereum Development

In the ever-evolving world of blockchain technology, standards are the unsung heroes that keep our digital universe from descending into chaos. They're the silent guardians of interoperability, the champions of frictionless development, and the backbone of seamless integration. Among these standards, one stands out as a beacon of hope for JavaScript libraries interacting with Ethereum: EIP-1193.

If you're developing JavaScript libraries for Ethereum and you're not leveraging EIP-1193 at every turn, you might be missing out on a revolutionary approach to blockchain interaction. Let's dive into why this standard is not just important, but essential for the future of Ethereum development.

#### Demystifying EIP-1193: The Swiss Army Knife of Ethereum Providers

At its core, EIP-1193 is a standardized interface for Ethereum providers in JavaScript applications. Think of it as a universal language that allows your code to communicate with Ethereum nodes, regardless of the underlying implementation. It's like having a Swiss Army knife for blockchain interactions – versatile, reliable, and always ready for action.

The heart of EIP-1193 is a simple yet powerful `request` function. This function is your gateway to the Ethereum blockchain, allowing you to send JSON-RPC requests and listen for critical events like network changes or new blocks.

Let's see EIP-1193 in action with a practical example:

```typescript
import { createMemoryClient } from 'tevm';
import { http } from 'viem';

// Create an EIP-1193 compatible transport
const eip1193ForkTransport = http('https://mainnet.optimism.io')({});

// Initialize a Tevm client with our transport
const tevmClient = createMemoryClient({
fork: { transport: eip1193ForkTransport }
}) satisfies EIP1193Provider;

// Listen for blockchain events
tevmClient.on('connect', () => {
console.log('Blockchain connection established. Ready for action!');
});

// Fetch an account balance
const balance = await tevmClient.request({
method: 'eth_getBalance',
params: ['0x1234567890abcdef1234567890abcdef12345678', 'latest'],
});
console.log('Account balance:', balance);

// Set a balance (using a custom method)
await tevmClient.request({
method: 'anvil_setBalance',
params: ['0x1234567890abcdef1234567890abcdef12345678', '0xDE0B6B3A7640000'], // 1 ETH
});
console.log('Balance updated. Time to make it rain!');
```

In this example, we're not just making API calls; we're orchestrating a symphony of blockchain interactions. We're setting up an HTTP transport, initializing a Tevm client, listening for network events, fetching balances, and even manipulating the blockchain state – all through the elegant simplicity of EIP-1193.

#### The EIP-1193 Advantage: Flexibility, Composability, and Future-Proofing

You might be wondering, "Why go through all this trouble? Can't I just use a simple RPC URL and call it a day?" Well, you could, but you'd be missing out on a world of possibilities. Here's why EIP-1193 is the secret sauce to superior Ethereum development:

1. **Unparalleled Flexibility**: With EIP-1193, you're not tied to a single node or network. You can seamlessly switch between different transports – be it WebSocket, HTTP, or even an in-memory client – without rewriting your core logic.

2. **Composability at Its Finest**: EIP-1193 providers are the LEGO blocks of Ethereum development. You can mix and match different tools and libraries with ease. Imagine using a Viem client as a transport for Tevm, or vice versa. The possibilities are endless!

3. **Future-Proof Your Code**: As the Ethereum ecosystem evolves, EIP-1193 ensures your code won't be left behind. New features? No problem. Just update your provider, and you're good to go.

Let's contrast this with a more traditional approach:

```typescript
class LegacySDK {
constructor(rpcUrl) {
this.rpcUrl = rpcUrl;
}

async getBalance(address) {
const response = await fetch(this.rpcUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
method: 'eth_getBalance',
params: [address, 'latest'],
id: 1,
}),
});
return await response.json();
}

// ... other methods
}

const sdk = new LegacySDK('https://mainnet.infura.io/v3/YOUR_API_KEY');
const balance = await sdk.getBalance('0x1234567890abcdef1234567890abcdef12345678');
```

This approach, while simple, is a relic of the past. It's inflexible, hard to extend, and ties you to a specific node. It's like trying to build a skyscraper with a hammer and nails – it might work, but it's far from optimal.

#### Embracing the Future: Building an Optimistic Transport

To truly appreciate the power of EIP-1193, let's push the boundaries and create a custom transport that handles optimistic updates. This isn't just a theoretical exercise – it's a glimpse into the future of Ethereum development:

```typescript
import { custom, http, loadBalance, rateLimit } from 'viem';
import { createMemoryClient } from 'tevm';

// Set up a load-balanced and rate-limited HTTP transport
const httpTransport = loadBalance([
rateLimit(http('https://cloudflare-eth.com'), { requestsPerSecond: 75 }),
rateLimit(http('https://eth-mainnet.public.blastapi.io'), { requestsPerSecond: 75 }),
]);

let pendingTxs = [];

// Create our optimistic transport
const optimisticTransport = custom({
request: async (request) => {
const { method, params } = request;

if (method === 'eth_sendRawTransaction') {
pendingTxs.push(params[0]);
return '0xFakeTxHashForPending';
}

if (method === 'eth_getTransactionReceipt') {
const pendingIndex = pendingTxs.indexOf(params[0]);
if (pendingIndex > -1) {
const receipt = await httpTransport.request(request);
if (receipt) pendingTxs.splice(pendingIndex, 1);
return receipt;
}
}

if (method === 'eth_call' && params[1] === 'pending') {
const tevmClient = createMemoryClient({
fork: { transport: httpTransport },
});
return tevmClient.request(request);
}

return httpTransport.request(request);
}
});

// Use our optimistic transport with a Viem client
const viemClient = createPublicClient({
chain: mainnet,
transport: optimisticTransport,
});
```

This isn't just code – it's a masterpiece of Ethereum interaction. We're load balancing, rate limiting, handling pending transactions, and even simulating blockchain state – all through the power of EIP-1193. It's like conducting an orchestra where every instrument is a different blockchain operation.

#### The Road Ahead: EIP-1193 and the Future of Ethereum Tooling

As we stand on the cusp of a new era in blockchain technology, EIP-1193 is poised to play a pivotal role. Imagine a world where light client transports seamlessly integrate with Tevm, enabling trustless execution at unprecedented speeds. Picture Tevm providing lightning-fast local execution transports to Viem, revolutionizing the way we interact with the blockchain.

This isn't just a dream – it's the future that EIP-1193 is helping to build. By embracing this standard, we're not just writing better code; we're shaping the future of decentralized applications.

#### Conclusion: Embrace the EIP-1193 Revolution

EIP-1193 isn't just another technical standard – it's a paradigm shift in Ethereum development. It's the key to unlocking a world of composable, flexible, and future-proof blockchain interactions. Whether you're building the next DeFi revolution or just dipping your toes into Web3, EIP-1193 is your ticket to the cutting edge of Ethereum development.

So, the next time you're reaching for that RPC URL, pause for a moment. Ask yourself: "Am I ready to embrace the future?" Because with EIP-1193, the future of Ethereum development is not just bright – it's dazzling.

Remember, in the world of blockchain, standards aren't just guidelines – they're superpowers. And EIP-1193? It might just be the most powerful superpower in JavaScript-Ethereum.
Loading

0 comments on commit e605859

Please sign in to comment.