-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
36 changed files
with
1,223 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
name: Sync | ||
on: | ||
push: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
sync-branches: | ||
runs-on: ubuntu-latest | ||
name: Syncing branches | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v2 | ||
- name: Set up Node | ||
uses: actions/setup-node@v1 | ||
with: | ||
node-version: 12 | ||
- name: Opening pull request | ||
id: pull | ||
uses: tretuna/[email protected] | ||
with: | ||
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} | ||
FROM_BRANCH: "main" | ||
TO_BRANCH: "develop" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ Precompile-EVM is a repository for registering precompiles to Subnet-EVM without | |
## Environment Setup | ||
|
||
To effectively build, run, and test Precompile-EVM, the following is a (non-exhaustive) list of dependencies that you will need: | ||
|
||
- Golang | ||
- Node.js | ||
- [AvalancheGo](https://github.com/ava-labs/avalanchego) | ||
|
@@ -16,7 +17,7 @@ To get started easily, we provide a Dev Container specification, that can be use | |
|
||
Codespaces is a development environment service offered by GitHub that allows developers to write, run, test, and debug their code directly on a cloud machine provided by GitHub. The developer can edit the code through a VS Code running in the browser or locally. | ||
|
||
To run a Codespace click on the **Code** and switch to the **Codespaces** tab. There, click **Create Codespace on branch [...]**. | ||
To run a Codespace click on the **Code** and switch to the **Codespaces** tab. There, click **Create Codespace on branch [...]**. | ||
|
||
### Local Dev Container | ||
|
||
|
@@ -34,10 +35,111 @@ To get a comprehensive introduction to Precompile-EVM, take the Avalanche Academ | |
|
||
There is an example branch [hello-world-example](https://github.com/ava-labs/precompile-evm/tree/hello-world-example) in this repository. You can check the example branch to see how to register precompiles and test them. | ||
|
||
### Clone the Repo | ||
|
||
```zsh | ||
git clone https://github.com/ava-labs/precompile-evm.git | ||
cd precompile-evm/ # change directory to the precompile-evm/ directory | ||
``` | ||
|
||
### Checkout the `hello-world-example` Branch | ||
|
||
```zsh | ||
git checkout hello-world-example | ||
|
||
branch 'hello-world-example' set up to track 'origin/hello-world-example'. | ||
Switched to a new branch 'hello-world-example' | ||
``` | ||
|
||
### Install NodeJS Dependencies | ||
|
||
First you have to `cd contracts/` and run `npm install` to get the dependencies. | ||
|
||
```zsh | ||
cd contracts/ # change directory to the contracts/ directory | ||
npm install | ||
``` | ||
|
||
### Create a New Contract | ||
|
||
`hello-world-example` branch has already a precompile contract called `HelloWorld.sol`. All necessary files were already created for you. You can check existing files and see how a fully implemented precompile should look like. If you'd like to redo steps to create a new precompile contract, you can follow the steps below. | ||
|
||
Copy the existing `IHelloWorld.sol` interface to a new file called `IHolaMundo.sol`. | ||
|
||
```zsh | ||
cd .. # change directory back to the root of the repo | ||
cp contracts/contracts/interfaces/IHelloWorld.sol contracts/contracts/interfaces/IHolaMundo.sol | ||
``` | ||
|
||
### Install `solc` and Confirm Dependency Version | ||
|
||
Install the `solc` dependency. | ||
|
||
```zsh | ||
brew install solidity | ||
``` | ||
|
||
Confirm `solc` is >=0.8.8. | ||
|
||
```zsh | ||
solc --version | ||
|
||
solc, the solidity compiler commandline interface | ||
Version: 0.8.17+commit.8df45f5f.Darwin.appleclang | ||
``` | ||
|
||
### Generate an `.abi` | ||
|
||
Now generate a `.abi` from a `.sol` using `solc`. | ||
|
||
Passing in the following flags | ||
|
||
- `--abi` | ||
- ABI specification of the contracts. | ||
- `--base-path path` | ||
- Use the given path as the root of the source tree instead of the root of the filesystem. | ||
- `--include-path path` | ||
- Make an additional source directory available to the default import callback. Use this option if you want to import contracts whose location is not fixed in relation to your main source tree, e.g. third-party libraries installed using a package manager. Can be used multiple times. Can only be used if base path has a non-empty value. | ||
- `--output-dir path` | ||
- If given, creates one file per output component and contract/file at the specified directory. | ||
- `--overwrite` | ||
- Overwrite existing files (used together with `--output-dir`). | ||
|
||
```zsh | ||
cd contracts/ # change directory to the contracts/ directory | ||
solc --abi contracts/interfaces/IHolaMundo.sol --output-dir abis --base-path . --include-path ./node_modules --overwrite | ||
|
||
Compiler run successful. Artifact(s) can be found in directory "abis". | ||
``` | ||
|
||
### Generate Precompile Files | ||
|
||
First, you need to create your precompile contract interface in the `contracts` directory and build the ABI. Then you can generate your precompile files with `./scripts/generate_precompile.sh --abi {abiPath} --out {outPath}`. This script installs the `precompilegen` tool from Subnet-EVM and runs it to generate your precompile. | ||
|
||
```zsh | ||
cd .. # change directory back to the root directory of the repo | ||
./scripts/generate_precompile.sh --abi contracts/abis/IHolaMundo.abi --out holamundo/ | ||
|
||
Using branch: hello-world-example | ||
installing precompilegen from Subnet-EVM v0.5.2 | ||
generating precompile with Subnet-EVM v0.5.2 | ||
Precompile files generated successfully at: holamundo/ | ||
``` | ||
|
||
Confirm that the new `holamundo/` directory has the appropriate files. | ||
|
||
```zsh | ||
ls -lh helloworld | ||
|
||
-rw-r--r-- 1 user group 2.3K Jul 5 13:26 README.md | ||
-rw-r--r-- 1 user group 2.3K Jul 5 13:26 config.go | ||
-rw-r--r-- 1 user group 2.8K Jul 5 13:26 config_test.go | ||
-rw-r--r-- 1 user group 963B Jul 5 13:26 contract.abi | ||
-rw-r--r-- 1 user group 8.1K Jul 5 13:26 contract.go | ||
-rw-r--r-- 1 user group 8.3K Jul 5 13:26 contract_test.go | ||
-rw-r--r-- 1 user group 2.7K Jul 5 13:26 module.go | ||
``` | ||
|
||
### Register Precompile | ||
|
||
In `plugin/main.go` Subnet-EVM is already imported and ready to be Run from the main package. All you need to do is explicitly register your precompiles to Subnet-EVM in `plugin/main.go` and build it together with Subnet-EVM. Precompiles generated by `precompilegen` tool have a self-registering mechanism in their `module.go/init()` function. All you need to do is to force-import your precompile packprecompile package in `plugin/main.go`. | ||
|
@@ -59,5 +161,6 @@ In order to upgrade the Subnet-EVM version, you need to change the version in `g | |
```text | ||
[v0.1.0-v0.1.1] [email protected] (Protocol Version: 26) | ||
[v0.1.2] [email protected] (Protocol Version: 27) | ||
[v0.1.3] [email protected] (Protocol Version: 28) | ||
[v0.1.3] [email protected] (Protocol Version: 28) | ||
[v0.1.4] [email protected] (Protocol Version: 28) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
{ | ||
"rpcChainVMProtocolVersion": { | ||
"v0.1.4": 28, | ||
"v0.1.3": 28, | ||
"v0.1.2": 27, | ||
"v0.1.1": 26, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
[{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"readAllowList","outputs":[{"internalType":"uint256","name":"role","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setNone","outputs":[],"stateMutability":"nonpayable","type":"function"}] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
[{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"readAllowList","outputs":[{"internalType":"uint256","name":"role","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sayHello","outputs":[{"internalType":"string","name":"result","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"response","type":"string"}],"name":"setGreeting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setNone","outputs":[],"stateMutability":"nonpayable","type":"function"}] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
//SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import "./interfaces/IHelloWorld.sol"; | ||
|
||
address constant HELLO_WORLD_ADDRESS = 0x0300000000000000000000000000000000000000; | ||
|
||
// ExampleHelloWorld shows how the HelloWorld precompile can be used in a smart contract. | ||
contract ExampleHelloWorld { | ||
IHelloWorld helloWorld = IHelloWorld(HELLO_WORLD_ADDRESS); | ||
|
||
function sayHello() public view returns (string memory) { | ||
return helloWorld.sayHello(); | ||
} | ||
|
||
function setGreeting(string calldata greeting) public { | ||
helloWorld.setGreeting(greeting); | ||
} | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity >=0.8.0; | ||
import "@avalabs/subnet-evm-contracts/contracts/interfaces/IAllowList.sol"; | ||
|
||
interface IHelloWorld is IAllowList { | ||
// sayHello returns the stored greeting string | ||
function sayHello() external view returns (string calldata result); | ||
|
||
// setGreeting stores the greeting string | ||
function setGreeting(string calldata response) external; | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
//SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import "../ExampleHelloWorld.sol"; | ||
import "../interfaces/IHelloWorld.sol"; | ||
import "@avalabs/subnet-evm-contracts/contracts/test/AllowListTest.sol"; | ||
|
||
contract ExampleHelloWorldTest is AllowListTest { | ||
IHelloWorld helloWorld = IHelloWorld(HELLO_WORLD_ADDRESS); | ||
|
||
function step_getDefaultHelloWorld() public { | ||
ExampleHelloWorld example = new ExampleHelloWorld(); | ||
address exampleAddress = address(example); | ||
|
||
assertRole(helloWorld.readAllowList(exampleAddress), AllowList.Role.None); | ||
assertEq(example.sayHello(), "Hello World!"); | ||
} | ||
|
||
function step_doesNotSetGreetingBeforeEnabled() public { | ||
ExampleHelloWorld example = new ExampleHelloWorld(); | ||
address exampleAddress = address(example); | ||
|
||
assertRole(helloWorld.readAllowList(exampleAddress), AllowList.Role.None); | ||
|
||
try example.setGreeting("testing") { | ||
assertTrue(false, "setGreeting should fail"); | ||
} catch {} // TODO should match on an error to make sure that this is failing in the way that's expected | ||
} | ||
|
||
function step_setAndGetGreeting() public { | ||
ExampleHelloWorld example = new ExampleHelloWorld(); | ||
address exampleAddress = address(example); | ||
|
||
assertRole(helloWorld.readAllowList(exampleAddress), AllowList.Role.None); | ||
helloWorld.setEnabled(exampleAddress); | ||
assertRole(helloWorld.readAllowList(exampleAddress), AllowList.Role.Enabled); | ||
|
||
string memory greeting = "testgreeting"; | ||
example.setGreeting(greeting); | ||
assertEq(example.sayHello(), greeting); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { | ||
Contract, | ||
ContractFactory | ||
} from "ethers" | ||
import { ethers } from "hardhat" | ||
|
||
const main = async (): Promise<any> => { | ||
const contractFactory: ContractFactory = await ethers.getContractFactory("ExampleHelloWorld") | ||
const contract: Contract = await contractFactory.deploy() | ||
|
||
await contract.deployed() | ||
console.log(`Contract deployed to: ${contract.address}`) | ||
} | ||
|
||
main() | ||
.then(() => process.exit(0)) | ||
.catch(error => { | ||
console.error(error) | ||
process.exit(1) | ||
}) |
Oops, something went wrong.