Skip to content

Commit

Permalink
Merge branch 'master' into sprice/creator-provenance
Browse files Browse the repository at this point in the history
  • Loading branch information
sprice authored May 20, 2023
2 parents 714d76c + 9230fe3 commit fb3d8aa
Show file tree
Hide file tree
Showing 59 changed files with 4,360 additions and 1,783 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ jobs:
- name: Checkout EIP Repository
uses: actions/checkout@47fbe2df0ad0e27efb67a70beac3555f192b062f

- uses: ethereum/eipw-action@59cdee4fc5d37c9391f3a0b52857fd5b021a39c2
- uses: ethereum/eipw-action@70379db401cbb3197454d8e02589af42d4ac5d21
id: eipw
with:
token: ${{ secrets.GITHUB_TOKEN }}
Expand Down
35 changes: 18 additions & 17 deletions EIPS/eip-107.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ type: Standards Track
category: Interface
---

Abstract
========
## Abstract

This draft EIP describes the details of an authorization method that if provided by rpc enabled ethereum nodes would allow regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS. Instead, user would be asked to confirm the transaction via an html popup.

Every read only rpc call the dapp wants to perform is redirected to an invisible iframe from the node's domain and for every transaction that the dapp wish to execute, an html popup is presented to the user to allow him/her to cancel or confirm the transaction. This allows the dapp to connect to the node's rpc api without being granted any kind of privileges. This allows users to safely interact with dapps running in their everyday web browser while their accounts are unlocked. In case the account is not unlocked, and the node has allowed the "personal" api via rpc,the html page also allow the user to enter their password to unlock the account for the scope of the transaction.

Motivation
==========
## Motivation

Currently, if a user navigates to a dapp running on a website using her/his everyday browser, the dapp will by default have no access to the rpc api for security reasons. The user will have to enable CORS for the website's domain in order for the dapp to work. Unfortunately if the user does so, the dapp will be able to send transactions from any unlocked account without the need for any user consent. In other words, not only does the user need to change the node's default setting, but the user is also forced to trust the dapp in order to use it. This is of course not acceptable and forces existing dapps to rely on the use of workarounds like:
- if the transaction is a plain ether transfer, the user is asked to enter it in a dedicated trusted wallet like "Mist"
- For more complex case, the user is asked to enter the transaction manually via the node command line interface.
Expand All @@ -25,27 +25,27 @@ This proposal aims to provide a safe and user friendly alternative.

Here are some screenshots of the provided implementation of that html popup:

Account unlocked :
-----------------
### Account unlocked

When the account is already unlocked, the user is presented with the following popup for every transaction that the dapp attempts to make:

![](../assets/eip-107/authorization.png)

Account locked and no "personal" api exposed via rpc:
-----------------
### Account locked and no "personal" api exposed via rpc:

When the account is locked, and the node does not provide access to account unlocking via its rpc interface, the following popup will be presented. This is not ideal since this requires the user to know how to unlock an account:

![](../assets/eip-107/authorization-locked.png)

Account locked but node exposing the "personal" api via rpc :
-----------------
### Account locked but node exposing the "personal" api via rpc :

A better option is to ask the user for their password, but this is only possible if the node allows access to the "personal" api via rpc. In such case, the following dialog will be presented to the user so he/she can accept the transaction by providing the password required to unlock the account:

![](../assets/eip-107/authorization-password.png)


Specification
=============
## Specification

In order for the mechanism to work, the node needs to serve an html file via http at the url \<node url\>/authorization.html

This file will then be used by the dapp in 2 different modes (invisible iframe and popup window).
Expand Down Expand Up @@ -90,22 +90,22 @@ the error object cannot be a javascript Error object due to postMessage limitati
```


Rationale
=========
## Rationale

The design for that proposal was chosen for its simplicity and security. A previous idea was to use an oauth-like protocol in order for the user to accept or deny a transaction request. It would have required deeper code change in the node and some geth contributors argues that such change did not fit into geth code base as it would have required dapp aware code.
The current design, instead has a very simple implementation (self contained html file that can be shared across node's implementation) and its safeness is guarantess by browsers' cross domain policies.

The use of iframe/ window was required to have both security and user friendliness. The invisible iframe allows the dapp to execute read only calls without the need for user input, and the window ensures user approval before making a call. While we could have made it without the window mode by making the iframe confirmation use the native browser ```window.confirm``` dialog, this would have prevented the use of a more elegant confirmation popup that the current design allows. It also happens to be that the ```window.confirm``` is not safe in some browsers, as it gives focus to the accept option and can be triggered automatically (https://bugs.chromium.org/p/chromium/issues/detail?id=260653).


Implementations
===============
## Implementations

In order to implement this design, the following html file or an equivalent one needs to be served at the url \<node url\>/authorization.html

That's it.


```
```html
<!DOCTYPE html>
<html>
<head>
Expand Down Expand Up @@ -612,6 +612,7 @@ That's it.
</body>
</html>
```

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
134 changes: 50 additions & 84 deletions EIPS/eip-2015.md
Original file line number Diff line number Diff line change
@@ -1,108 +1,74 @@
---
eip: 2015
title: Wallet Update Ethereum Chain RPC Method (`wallet_updateEthereumChain`)
author: Pedro Gomes (@pedrouid), Erik Marks (@rekmarks)
title: wallet_updateEthereumChain RPC Method
description: Adds an RPC method to switch betweeen EVM-compatible chains
author: Pedro Gomes (@pedrouid), Erik Marks (@rekmarks), Pandapip1 (@Pandapip1)
discussions-to: https://ethereum-magicians.org/t/eip-2015-wallet-update-chain-json-rpc-method-wallet-updatechain/3274
status: Stagnant
status: Review
type: Standards Track
category: Interface
created: 2019-05-12
requires: 155, 1474
requires: 155
---

## Simple Summary
Wallets can update the active chain when connected to a Dapp but not vice-versa, with `wallet_updateEthereumChain` the Dapp will be able to request this change from the Wallet.

## Abstract
Dapp can request the Wallet to switch chains by providing the minimal parameters of `chainId`, `chainName`, `rpcUrl`, `nativeCurrency` and `blockExplorerUrl`. The Wallet will display a UI element to inform the user of this change.

## Motivation
Wallet and Dapp communication rely on the present provider that acts as middleware between the two. Using JSON-RPC methods, the Dapp is able to access not only the active accounts but also the active chain. With [EIP-1102](./eip-1102.md) we introduced the ability for Dapps to request access to the active accounts and the Wallet is able to provide a simple UI to inform the user of this action however the same is not currently possible for switching chains. The current pattern is to display some UI to request the user to switch chains within the Dapp, however this could be easily improved by triggering a UI from the Wallet side that can be approved or rejected by the user instead.
This EIP adds a wallet-namespaced RPC endpoint, `wallet_updateEthereumChain`, providing a standard interface for switching chains. The method takes the minimal parameters of `chainId`, `chainName`, `rpcUrl`, `nativeCurrency` and `blockExplorerUrl`.

## Specification
The JSON RPC method will be part of `wallet_` namespaced methods which aim to improve the UX and interoperability between Dapps and Wallets.

### Required Parameters
- chainId (string): the id of the chain compliant with EIP-155
- chainName (string): the name of the chain to update
- rpcUrl (string): the url endpoint for RPC requests for this chain
- nativeCurrency (Object): includes three fields for `name` (string), `symbol` (string) and `decimals` (number)
- blockExplorerUrl (string): the url endpoint for a block explorer web site for the chain.

### Best Practices
- The Wallet should display a UI view similar to a [EIP-1102](./eip-1102.md) informing the user that the currently connected Dapp wants to switch to the specified chain.
- the Wallet should default the rpcUrl to any existing endpoints matching a chainId known previously to the wallet, otherwise it will use the provided rpcUrl as a fallback.
- the Wallet should call the rpcUrl with `net_version` and `eth_chainId` to verify the provided chainId and networkId match the responses from the rpcUrl
- the Wallet should change all nativeCurrency symbols to the provided parameter

### Example 1
A JSON-RPC request from a Dapp to switch the Ethereum Goerli chain would be as follows:
```json
{
"id":1,
"jsonrpc": "2.0",
"method": "wallet_updateChain",
"params": [
{
"chainId": 0x5,
"chainName": "Goerli",
"rpcUrl": "https://goerli.infura.io/v3/406405f9c65348f99d0d5c27104b2213",
"nativeCurrency": {
"name": "Goerli ETH",
"symbol": "gorETH"
},
"blockExplorerUrl": "https://goerli.etherscan.io"
}
]

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

This proposal adds a method to a wallet's web3 provider API: `wallet_updateEthereumChain`.

### `wallet_updateEthereumChain`

The `wallet_updateEthereumChain` method is used to switch to a network, and registering it with the wallet if it isn't already recognized.

The `wallet_updateEthereumChain` method takes one parameter, an `EthereumChainSwitchRequest` object, defined below:

```typescript
interface NativeCurrencyData {
name: string;
symbol: string;
decimals: number;
}
```

### Example 2
A JSON-RPC request from a Dapp to switch the POA Network's xDAI chain would be as follows:
```json
{
"id":1,
"jsonrpc": "2.0",
"method": "wallet_updateChain",
"params": [
{
"chainId": "0x5",
"chainName": "Goerli",
"rpcUrl": "https://goerli.infura.io/v3/406405f9c65348f99d0d5c27104b2213",
"nativeCurrency": {
"name": "Goerli ETH",
"symbol": "gorETH"
},
"blockExplorerUrl": "https://goerli.etherscan.io"
}
]
interface EthereumChainSwitchRequest {
chainId: string;
chainName?: string;
rpcUrls?: string[];
nativeCurrency?: NativeCurrencyData;
blockExplorerUrl?: string;
}
```

### Responses
The `chainId` is the `0x`-prefixed [EIP-155](./eip-155.md)-compliant chain ID. The `chainName` is a suggested human-readable name of the chain, to be displayed to the user. The `rpcUrls` array is a list of RPC endpoints for the given `chainId`. The `nativeCurrency` object suggests how the native currency should be displayed. Its parameters, `name`, `symbol`, and `decimals`, should be interpreted like in [ERC-20](./eip-20.md). Finally, the `blockExplorerUrl` should link to a block explorer compatible with the given `chainId`.

A success response:
All keys other than the `chainId` are optional. All keys other than `chainId` are suggestions to the wallet. Wallets can choose to ignore or display other data to users. Wallets should prompt the user before switching or adding chains. Wallets should also store a default list of data for commonly-used chains, in order to avoid phishing attacks. Wallets MUST sanitize each RPC url before using it to send other requests, including ensuring that it responds correctly to the `net_version` and `eth_chainId` methods.

```json
{
"id": 1,
"jsonrpc": "2.0",
"result": true
}
```
The `wallet_updateEthereumChain` method returns `true` if the chain was successfully added or switched to, and an error with code `4001` if the user rejected the request.

A failure response:
## Rationale

```json
{
"id": 1,
"jsonrpc": "2.0",
"error": {
"code": 4001,
"message": "The user rejected the request."
}
}
```
The `wallet_updateEthereumChain` method is designed to be as simple as possible, while still providing the necessary information for a wallet to switch to a new chain. The `chainId` is the only required parameter, as it is the only parameter that is guaranteed to be unique. The `chainName` is included to provide a human-readable name for the chain, and the `rpcUrls` array is included to provide a list of RPC endpoints for the chain. The `nativeCurrency` object is included to provide a suggestion for how the native currency should be displayed. Finally, the `blockExplorerUrl` is included to provide a link to a block explorer for the chain.

The `wallet_updateEthereumChain` method is namespaced under `wallet_` to avoid conflicts with other methods. The `wallet_` prefix is used by other methods that are wallet-specific, such as `wallet_addEthereumChain` and `wallet_switchEthereumChain`.

## Backwards Compatibility

This EIP is fully backwards compatible.

## Security Considerations

### Server-Side Request Forgery (SSRF)

The `rpcUrls` parameter is a list of RPC endpoints for the chain. Wallets should sanitize each RPC url before using it to send other requests, including ensuring that it responds correctly to the `net_version` and `eth_chainId` methods.

### Phishing

Wallets should store a default list of data for commonly-used chains, in order to avoid phishing attacks.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
43 changes: 32 additions & 11 deletions EIPS/eip-4788.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ Store each of these roots in a contract that lives in the execution state and ad

## Motivation

Roots of the beacon chain blocks are crytographic accumulators that allow proofs of arbitrary consensus state. Exposing these roots inside the EVM allows for trust-minimized access to the consensus layer. This functionality supports a wide variety of use cases that improve trust assumptions of staking pools, restaking constructions, smart contract bridges, MEV mitigations and more.
Roots of the beacon chain blocks are cryptographic accumulators that allow proofs of arbitrary consensus state.
Exposing these roots inside the EVM allows for trust-minimized access to the consensus layer.
This functionality supports a wide variety of use cases that improve trust assumptions of staking pools,
restaking constructions, smart contract bridges, MEV mitigations and more.

## Specification

Expand All @@ -34,37 +37,55 @@ Roots of the beacon chain blocks are crytographic accumulators that allow proofs

The high-level idea is that each execution block contains the parent beacon block root. Even in the event of missed slots since the previous block root does not change,
we only need a constant amount of space to represent this "oracle" in each execution block. To improve the usability of this oracle, block roots are stored
in a canonical place in the execution state analogous to a `SSTORE` in given contract's storage for each update. Roots are stored keyed by the slot(s) they pertain to.
in a canonical place in the execution state analogous to a `SSTORE` in the given contract's storage for each update.
Roots are keyed by the slot(s) they pertain to.
To bound the amount of storage this construction consumes, a ring buffer is used that mirrors a block root accumulator on the consensus layer.
The method for exposing the root data via opcode is inspired by [EIP-2935](./eip-2935.md).

### Block structure and validity

Beginning at the execution timestamp `FORK_TIMESTAMP`, execution clients **MUST**:

1. set 32 bytes of the execution block header after the `withdrawals_root` to the 32 byte [hash tree root](https://github.com/ethereum/consensus-specs/blob/fa09d896484bbe240334fa21ffaa454bafe5842e/ssz/simple-serialize.md#merkleization) of the parent beacon block.
1. set 32 bytes of the execution block header after the `excess_data_gas` to the 32 byte [hash tree root](https://github.com/ethereum/consensus-specs/blob/fa09d896484bbe240334fa21ffaa454bafe5842e/ssz/simple-serialize.md#merkleization) of the parent beacon block.

*NOTE*: this field is appended to the current block header structure with this EIP so that the size of the header grows after (and including) the `FORK_TIMESTAMP`.
2. set the 8 bytes after the previous 32 byte extension to the slot number as a big-endian uint64 of the current slot.

*NOTE*: these fields are appended to the current block header structure with this EIP so that the size of the header grows after (and including) the `FORK_TIMESTAMP`.

### EVM changes

#### Block processing

At the start of processing any execution block where `block.timestamp >= FORK_TIMESTAMP` (i.e. before processing any transactions), write the parent beacon root provided in the block header into the storage of the contract at `HISTORY_STORAGE_ADDRESS`. This data is keyed by the slot number.
At the start of processing any execution block where `block.timestamp >= FORK_TIMESTAMP` (i.e. before processing any transactions),
write the parent beacon root provided in the block header into the storage of the contract at `HISTORY_STORAGE_ADDRESS`.

In pseudocode:
This data is keyed by the slots containing the parent beacon block root which in general could be multiple slots for the
same root. To find the starting slot of the range, read the storage slot `SLOTS_PER_HISTORICAL_ROOT` (interpreted as a
256-bit byte array) which contains the big-endian encoding of the last slot value written to. This encoding should be interpreted
as a 64-bit big-endian integer that yields the starting slot.
Clients then iterate from the start slot (inclusive) to the end slot (exclusive) found in the header
and write the beacon block root into each slot value.

```python
start_timestamp = get_block(block_header.parent_hash).header.timestamp
start_slot = convert_to_slot(start_timestamp)
*NOTE*: if the slot stored at `SLOTS_PER_HISTORICAL_ROOT` is all zeros, clients should use set the start slot to one less than the
slot in the header, e.g. `header.beacon_block_root_slot - 1`.

After writing the block root in the relevant slots, store the current slot for use during the next update in the same storage slot
`SLOTS_PER_HISTORICAL_ROOT`.

end_timestamp = block_header.timestamp
end_slot = convert_to_slot(end_timestamp)
In Python pseudocode:

```python
start_slot = to_uint64(sload(HISTORY_STORAGE_ADDRESS, SLOTS_PER_HISTORICAL_ROOT))
end_slot = block_header.beacon_slot
if start_slot == 0:
start_slot = max(end_slot - 1, 0)

parent_beacon_block_root = block_header.parent_beacon_block_root

for slot in range(start_slot, end_slot):
sstore(HISTORY_STORAGE_ADDRESS, slot % SLOTS_PER_HISTORICAL_ROOT, parent_beacon_block_root)

sstore(HISTORY_STORAGE_ADDRESS, SLOTS_PER_HISTORICAL_ROOT, end_slot)
```

When using any slot value as a key to the storage, the value under consideration must be converted to 32 bytes with big-endian encoding.
Expand Down
Loading

0 comments on commit fb3d8aa

Please sign in to comment.