Skip to content

Commit

Permalink
added frontier chain
Browse files Browse the repository at this point in the history
  • Loading branch information
asiniscalchi committed Oct 13, 2023
1 parent 1211760 commit a2ced58
Show file tree
Hide file tree
Showing 46 changed files with 25,304 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ members = [
"evolution-chain/primitives",
"bridge/relays/*",
"bridge/primitives/*",
"frontier-chain/runtime",
]

[workspace.dependencies]
parity-scale-codec = { version = "3.2.2", default-features = false, features = ["derive"] }
scale-codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = ["derive"] }
hex-literal = "0.4.1"
hex = { version = "0.4.3", default-features = false }
scale-info = { version = "2.7.0", default-features = false, features = ["derive"] }
Expand Down Expand Up @@ -151,6 +153,9 @@ pallet-ethereum = { git = "https://github.com/paritytech/frontier", branch = "po
pallet-evm-chain-id = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v1.0.0", default-features = false }
pallet-evm-precompile-modexp = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v1.0.0", default-features = false }
pallet-evm-precompile-simple = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v1.0.0", default-features = false }
pallet-hotfix-sufficients = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v1.0.0", default-features = false }
pallet-evm-precompile-sha3fips = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v1.0.0", default-features = false }
pallet-dynamic-fee = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v1.0.0", default-features = false }
fp-self-contained = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v1.0.0", default-features = false }
fp-rpc = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v1.0.0", default-features = false }
fp-evm = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v1.0.0", default-features = false }
Expand Down
2 changes: 2 additions & 0 deletions frontier-chain/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
**/target/
Dockerfile
36 changes: 36 additions & 0 deletions frontier-chain/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Note: This is currently designed to simplify development
# To get a smaller docker image, there should be 2 images generated, in 2 stages.

FROM rustlang/rust:nightly


ARG PROFILE=release
WORKDIR /frontier

# Upcd dates core parts
RUN apt-get update -y && \
apt-get install -y cmake pkg-config libssl-dev git gcc build-essential clang libclang-dev protobuf-compiler

# Install rust wasm. Needed for substrate wasm engine
RUN rustup target add wasm32-unknown-unknown

# Download Frontier repo
RUN git clone https://github.com/paritytech/frontier /frontier
RUN cd /frontier && git submodule init && git submodule update

# Download rust dependencies and build the rust binary
RUN cargo build "--$PROFILE"

# 30333 for p2p traffic
# 9933 for RPC call
# 9944 for Websocket
# 9615 for Prometheus (metrics)
EXPOSE 30333 9933 9944 9615


ENV PROFILE ${PROFILE}

# The execution will re-compile the project to run it
# This allows to modify the code and not have to re-compile the
# dependencies.
CMD cargo run --bin frontier-template-node "--$PROFILE" -- --dev
24 changes: 24 additions & 0 deletions frontier-chain/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to <http://unlicense.org>
220 changes: 220 additions & 0 deletions frontier-chain/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
# Substrate Frontier Node Template

A [FRAME](https://docs.substrate.io/v3/runtime/frame)-based
[Substrate](https://substrate.io) node with the Ethereum RPC support, ready for hacking
:rocket:

## Generation & Upstream

This template is maintained in the
[Frontier](https://github.com/paritytech/frontier/tree/master/template) project repository, and can
be used to generate a stand-alone template for use in an independent project via the included
[template generation script](https://github.com/paritytech/frontier/blob/master/docs/node-template-release.md).

A ready-to-use template generated this way is hosted for each Frontier release on the
[substrate-developer-hub/frontier-node-template](https://github.com/substrate-developer-hub/frontier-node-template)
repository.

This template was originally forked from the
[Substrate Node Template](https://github.com/substrate-developer-hub/substrate-node-template). You
can find more information on features on this template there, and more detailed usage on the
[Substrate Developer Hub Tutorials](https://docs.substrate.io/tutorials/v3/) that use this heavily.

## Build & Run

To build the chain, execute the following commands from the project root:

```
$ cargo build --release
```

To execute the chain, run:

```
$ ./target/release/frontier-template-node --dev
```

The node also supports to use manual seal (to produce block manually through RPC).
This is also used by the ts-tests:

```
$ ./target/release/frontier-template-node --dev --sealing=manual
# Or
$ ./target/release/frontier-template-node --dev --sealing=instant
```

### Docker Based Development

Optionally, You can build and run the frontier node within Docker directly.
The Dockerfile is optimized for development speed.
(Running the `docker run...` command will recompile the binaries but not the dependencies)

Building (takes 5-10 min):

```bash
docker build -t frontier-node-dev .
```

Running (takes 1 min to rebuild binaries):

```bash
docker run -t frontier-node-dev
```

## Genesis Configuration

The development [chain spec](node/src/chain_spec.rs) included with this project defines a genesis
block that has been pre-configured with an EVM account for
[Alice](https://docs.substrate.io/v3/tools/subkey#well-known-keys). When
[a development chain is started](https://github.com/substrate-developer-hub/substrate-node-template#run),
Alice's EVM account will be funded with a large amount of Ether. The
[Polkadot UI](https://polkadot.js.org/apps/#?rpc=ws://127.0.0.1:9944) can be used to see the details
of Alice's EVM account. In order to view an EVM account, use the `Developer` tab of the Polkadot UI
`Settings` app to define the EVM `Account` type as below. It is also necessary to define the
`Address` and `LookupSource` to send transaction, and `Transaction` and `Signature` to be able to
inspect blocks:

```json
{
"Address": "MultiAddress",
"LookupSource": "MultiAddress",
"Account": {
"nonce": "U256",
"balance": "U256"
},
"Transaction": {
"nonce": "U256",
"action": "String",
"gas_price": "u64",
"gas_limit": "u64",
"value": "U256",
"input": "Vec<u8>",
"signature": "Signature"
},
"Signature": {
"v": "u64",
"r": "H256",
"s": "H256"
}
}
```

Use the `Developer` app's `RPC calls` tab to query `eth > getBalance(address, number)` with Alice's
EVM account ID (`0xd43593c715fdd31c61141abd04a99fd6822c8558`); the value that is returned should be:

```text
x: eth.getBalance
340,282,366,920,938,463,463,374,607,431,768,211,455
```

> Further reading:
> [EVM accounts](https://github.com/danforbes/danforbes/blob/master/writings/eth-dev.md#Accounts)
Alice's EVM account ID was calculated using
[an included utility script](utils/README.md#--evm-address-address).

## Example 1: ERC20 Contract Deployment using EVM dispatchable

The following steps are also available as a [Typescript script](examples/contract-erc20) using
Polkadot JS SDK

### Step 1: Contract creation

The [`truffle`](examples/contract-erc20/truffle) directory contains a
[Truffle](https://www.trufflesuite.com/truffle) project that defines
[an ERC-20 token](examples/contract-erc20/truffle/contracts/MyToken.sol). For convenience, this
repository also contains
[the compiled bytecode of this token contract](examples/contract-erc20/truffle/contracts/MyToken.json#L259),
which can be used to deploy it to the Substrate blockchain.

> Further reading:
> [the ERC-20 token standard](https://github.com/danforbes/danforbes/blob/master/writings/eth-dev.md#EIP-20-ERC-20-Token-Standard)
Use the Polkadot UI `Extrinsics` app to deploy the contract from Alice's account (submit the
extrinsic as a signed transaction) using `evm > create` with the following parameters:

```
source: 0xd43593c715fdd31c61141abd04a99fd6822c8558
init: <raw contract bytecode, a very long hex value>
value: 0
gas_limit: 4294967295
gas_price: 1
nonce: <empty> {None}
```

The values for `gas_limit` and `gas_price` were chosen for convenience and have little inherent or
special meaning. Note that `None` for the nonce will increment the known nonce for the source
account, starting from `0x0`, you may manually set this but will get an "evm.InvalidNonce" error if
not set correctly.

Once the extrinsic is in a block, navigate to the `Network` -> `Explorer` tab in the UI, or open up
the browser console to see that the EVM pallet has fired a `Created` event with an `address` field
that provides the address of the newly-created contract:

```bash
# console:
... {"phase":{"applyExtrinsic":2},"event":{"index":"0x0901","data":["0x8a50db1e0f9452cfd91be8dc004ceb11cb08832f"]} ...

# UI:
evm.Created
A contract has been created at given [address]
H160: 0x8a50db1e0f9452cfd91be8dc004ceb11cb08832f
```

In this case, however, it is trivial to
[calculate this value](https://ethereum.stackexchange.com/a/46960):
`0x8a50db1e0f9452cfd91be8dc004ceb11cb08832f`. That is because EVM contract account IDs are
determined solely by the ID and nonce of the contract creator's account and, in this case, both of
those values are well-known (`0xd43593c715fdd31c61141abd04a99fd6822c8558` and `0x0`, respectively).

### Step 2: Check Contract Storage

Use the `Chain State` UI tab to query`evm > accountCodes` for both Alice's and the contract's
account IDs; notice that Alice's account code is empty and the contract's is equal to the bytecode
of the Solidity contract.

The ERC-20 contract that was deployed inherits from
[the OpenZeppelin ERC-20 implementation](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol)
and extends its capabilities by adding
[a constructor that mints a maximum amount of tokens to the contract creator](examples/contract-erc20/truffle/contracts/MyToken.sol#L8).
Use the `Chain State` app to query `evm > accountStorage` and view the value associated with Alice's
account in the `_balances` map of the ERC-20 contract; use the ERC-20 contract address
(`0x8a50db1e0f9452cfd91be8dc004ceb11cb08832f`) as the first parameter and the storage slot to read
as the second parameter (`0x045c0350b9cf0df39c4b40400c965118df2dca5ce0fbcf0de4aafc099aea4a14`). The
value that is returned should be
`0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`.

The storage slot was calculated using
[a provided utility](utils/README.md#--erc20-slot-slot-address). (Slot 0 and alice address:
`0xd43593c715fdd31c61141abd04a99fd6822c8558`)

> Further reading:
> [EVM layout of state variables in storage](https://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage)
### Step 3: Contract Usage

Use the `Developer` -> `Extrinsics` tab to invoke the `transfer(address, uint256)` function on the
ERC-20 contract with `evm > call` and transfer some of the ERC-20 tokens from Alice to Bob.

```text
target: 0x8a50db1e0f9452cfd91be8dc004ceb11cb08832f
source: 0xd43593c715fdd31c61141abd04a99fd6822c8558
input: 0xa9059cbb0000000000000000000000008eaf04151687736326c9fea17e25fc528761369300000000000000000000000000000000000000000000000000000000000000dd
value: 0
gas_limit: 4294967295
gas_price: 1
```

The value of the `input` parameter is an EVM ABI-encoded function call that was calculated using
[the Remix web IDE](http://remix.ethereum.org); it consists of a function selector (`0xa9059cbb`)
and the arguments to be used for the function invocation. In this case, the arguments correspond to
Bob's EVM account ID (`0x8eaf04151687736326c9fea17e25fc5287613693`) and the number of tokens to be
transferred (`0xdd`, or 221 in hex).

> Further reading:
> [the EVM ABI specification](https://solidity.readthedocs.io/en/latest/abi-spec.html)
### Step 4: Check Bob Contract Storage

After the extrinsic has finalized, use the `Chain State` app to query `evm > accountStorage` to see
the ERC-20 balances for both Alice and Bob.
2 changes: 2 additions & 0 deletions frontier-chain/examples/contract-erc20/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/build/
/node_modules/
76 changes: 76 additions & 0 deletions frontier-chain/examples/contract-erc20/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# ERC20 contract creation

This directory contains typescript script describing the different
topics presented by the frontier node template.

## Basic

### Installation and Usage

Use `npm i` to install dependencies. To create an ERC20 contract,
execute `node_modules/.bin/ts-node create-erc20.ts` while your
template node is running in `--dev` mode.

### Expected output

The ouput of the command should look similar to this:

```
└────╼ ts-node create-erc20.ts
Initiating the API (ignore message "Unable to resolve type B..." and "Unknown types found...")
Unable to resolve type B, it will fail on construction
Unknown types found, no types for B, Receipt, Transaction
Initialiation done
Genesis at block: 0x8455be17576e759feb9f027d79185d4e51fe91113185ef9a315614a35f0f86d8
Alice Substrate Account: 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
Alice Substrate Account (nonce: 0) balance, free: 0x00000000000000001000000000000000
Alice EVM Account: 0x57d213d0927ccc7596044c6ba013dd05522aacba
Alice EVM Account (nonce: 0) balance: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Step 1: Creating Smart Contract
Contract creation is Ready
Contract creation is {"InBlock":"0xb7f31941812cfddede61918a219d472d3b953e05b619a6baa2bd6847a6140bad"}
Contract included at blockHash 0xb7f31941812cfddede61918a219d472d3b953e05b619a6baa2bd6847a6140bad
Waiting for finalization... (can take a minute)
Contract creation is {"Finalized":"0xb7f31941812cfddede61918a219d472d3b953e05b619a6baa2bd6847a6140bad"}
Contract finalized at blockHash 0xb7f31941812cfddede61918a219d472d3b953e05b619a6baa2bd6847a6140bad
Contract address: 0x11650d764feb44f78810ef08700c2284f7e81dcb
Step 2: Retrieving Contract from evm address: 0x11650d764feb44f78810ef08700c2284f7e81dcb
Alice Substrate Account (nonce: 1) balance, free: 1152921500186875190
Contract account code: 0x60806040523480...6c63430005100032
Alice Contract storage key: 0xa7473b24b6fd8e15602cfb2f15c6a2e2770a692290d0c5097b77dd334132b7ce
Alice Contract account storage: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Step 3: Transfering Tokens to Bob EVM Account: 0x8bc395119f39603402d0c85bc9eda5dfc5ae2160
Preparing transfer of 0xdd
Sending call input: 0xa9059cbb0000000000000000000000008bc395119f39603402d0c85bc9eda5dfc5ae216000000000000000000000000000000000000000000000000000000000000000dd
Transfer is Ready
Transfer is {"InBlock":"0x22dcfc5b497bd1ea42ef38a33ebaee959a9fbd4337389c8a6a0961fc0af4910b"}
Transfer included at blockHash 0x22dcfc5b497bd1ea42ef38a33ebaee959a9fbd4337389c8a6a0961fc0af4910b
Waiting for finalization... (can take a minute)
Transfer is {"Finalized":"0x22dcfc5b497bd1ea42ef38a33ebaee959a9fbd4337389c8a6a0961fc0af4910b"}
Transfer finalized at blockHash 0x22dcfc5b497bd1ea42ef38a33ebaee959a9fbd4337389c8a6a0961fc0af4910b
Step 4: Retrieving Bob tokens
Bob Substrate Account (nonce: 0) balance, free: 1152921504606846976
Bob EVM Account: 0x8bc395119f39603402d0c85bc9eda5dfc5ae2160
Bob EVM Account (nonce: 0) balance: 0x0000000000000000000000000000000000000000000000000000000000000000
Bob Contract storage key: 0x0e4b5229940f8e2bf475520e854b789139893f70ee7b5ec9006de746028449fe
Bob Contract account storage: 0x00000000000000000000000000000000000000000000000000000000000000dd
```

## RPC

This section describes how to use the web3.js SDK to interact with
Frontier.

## Installation and Usage

Use `npm i` to install dependencies. To create an ERC20 contract,
execute `node_modules/.bin/ts-node create-erc20.ts` while your
template node is running in `--dev` mode.

## Expected output

WIP
Loading

0 comments on commit a2ced58

Please sign in to comment.