Skip to content

Commit

Permalink
Verify with Blockscout (#1413)
Browse files Browse the repository at this point in the history
* example foundry contract

* programmatic verification

* docs

* update regex in reload
  • Loading branch information
skudasov authored Dec 2, 2024
1 parent 3f05a10 commit 702527f
Show file tree
Hide file tree
Showing 21 changed files with 585 additions and 9 deletions.
1 change: 1 addition & 0 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- [Creating your own components](./developing/developing_components.md)
- [Fork Testing](./framework/fork.md)
- [Quick Contracts Deployment](./framework/quick_deployment.md)
- [Verifying Contracts](./framework/verify.md)
- [NodeSet with External Blockchain]()
- [CLI](./framework/cli.md)
- [Configuration](./framework/configuration.md)
Expand Down
7 changes: 1 addition & 6 deletions book/src/framework/observability/blockscout.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,4 @@ ctf bs -r http://host.docker.internal:8555 d
Blockscout isn’t ideal for local, ephemeral environments, as it won’t re-index blocks and transactions on test reruns. The easiest approach is to set up Blockscout first, initialize the test environment, switch to the [cache](../components/caching.md) config, and run tests without restarting RPC nodes.

Otherwise, use `ctf bs r` each time you restart your test with a fresh docker environment.
</div>

<div class="warning">

Blockscout integration is still WIP, for now Blockscout reads only one node that is on `:8545`, all our blockchain implementation expose this port by default.
</div>
</div>
16 changes: 16 additions & 0 deletions book/src/framework/verify.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Verifying Contracts

Check out our [example](https://github.com/smartcontractkit/chainlink-testing-framework/blob/main/framework/examples/myproject/verify_test.go) of programmatically verifying contracts using `Blockscout` and `Foundry`. You'll need to provide:

- The path to your Foundry directory
- The path to the contract
- The contract name

```golang
err := blockchain.VerifyContract(blockchainComponentOutput, c.Addresses[0].String(),
"example_components/onchain",
"src/Counter.sol",
"Counter",
)
require.NoError(t, err)
```
3 changes: 2 additions & 1 deletion framework/.changeset/v0.3.1.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
- Use docker cmd instead of testcontainers
- Use docker cmd for building instead of testcontainers-go
- Add "CHAINLINK_IMAGE" flag to override NodeSet image
- Add Go wrapper for Blockscout verification (foundry)
1 change: 1 addition & 0 deletions framework/cmd/observability/blockscout/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ services:
ETHEREUM_JSONRPC_VARIANT: 'geth'
ETHEREUM_JSONRPC_HTTP_URL: ${BLOCKSCOUT_RPC_URL}
ETHEREUM_JSONRPC_TRACE_URL: ${BLOCKSCOUT_RPC_URL}
CHAIN_ID: ${BLOCKSCOUT_CHAIN_ID:-1337}

visualizer:
extends:
Expand Down
22 changes: 22 additions & 0 deletions framework/components/blockchain/verify.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package blockchain

import (
"fmt"
"github.com/smartcontractkit/chainlink-testing-framework/framework"
)

// VerifyContract wraps the forge verify-contract command.
func VerifyContract(out *Output, address, foundryDir, contractFile, contractName string) error {
args := []string{
"verify-contract",
"--rpc-url", out.Nodes[0].HostHTTPUrl,
"--chain-id",
out.ChainID,
"--compiler-version=0.8.24",
address,
fmt.Sprintf("%s:%s", contractFile, contractName),
"--verifier", "blockscout",
"--verifier-url", "http://localhost/api/",
}
return framework.RunCommandDir(foundryDir, "forge", args...)
}
2 changes: 1 addition & 1 deletion framework/components/simple_node_set/reload.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
// UpgradeNodeSet updates nodes configuration TOML files
// this API is discouraged, however, you can use it if nodes require restart or configuration updates, temporarily!
func UpgradeNodeSet(in *Input, bc *blockchain.Output, wait time.Duration) (*Output, error) {
_, err := chaos.ExecPumba("rm --volumes=false re2:node.*|ns-postgresql.*", wait)
_, err := chaos.ExecPumba("rm --volumes=false re2:^node.*|ns-postgresql.*", wait)
if err != nil {
return nil, err
}
Expand Down
11 changes: 11 additions & 0 deletions framework/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,17 @@ func runCommand(name string, args ...string) error {
return cmd.Run()
}

// RunCommandDir executes a command in some directory and prints the output
func RunCommandDir(dir, name string, args ...string) error {
cmd := exec.Command(name, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if dir != "" {
cmd.Dir = dir
}
return cmd.Run()
}

// DockerClient wraps a Docker API client and provides convenience methods
type DockerClient struct {
cli *client.Client
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: test

on: workflow_dispatch

env:
FOUNDRY_PROFILE: ci

jobs:
check:
strategy:
fail-fast: true

name: Foundry project
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Run Forge build
run: |
forge --version
forge build --sizes
id: build

- name: Run Forge tests
run: |
forge test -vvv
id: test
14 changes: 14 additions & 0 deletions framework/examples/myproject/example_components/onchain/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Compiler files
cache/
out/

# Ignores development broadcast logs
!/broadcast
/broadcast/*/31337/
/broadcast/**/dry-run/

# Docs
docs/

# Dotenv file
.env
66 changes: 66 additions & 0 deletions framework/examples/myproject/example_components/onchain/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
## Foundry

**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.**

Foundry consists of:

- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools).
- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data.
- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network.
- **Chisel**: Fast, utilitarian, and verbose solidity REPL.

## Documentation

https://book.getfoundry.sh/

## Usage

### Build

```shell
$ forge build
```

### Test

```shell
$ forge test
```

### Format

```shell
$ forge fmt
```

### Gas Snapshots

```shell
$ forge snapshot
```

### Anvil

```shell
$ anvil
```

### Deploy

```shell
$ forge script script/Counter.s.sol:CounterScript --rpc-url <your_rpc_url> --private-key <your_private_key>
```

### Cast

```shell
$ cast <subcommand>
```

### Help

```shell
$ forge --help
$ anvil --help
$ cast --help
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package onchain

import (
"github.com/ethereum/go-ethereum/common"
"github.com/smartcontractkit/chainlink-testing-framework/framework/examples/example_components/onchain/gethwrappers"
"github.com/smartcontractkit/chainlink-testing-framework/seth"
)

func NewCounterDeployment(c *seth.Client, in *Input) (*Output, error) {
if in.Out != nil && in.Out.UseCache {
return in.Out, nil
}
counterABI, err := gethwrappers.GethwrappersMetaData.GetAbi()
if err != nil {
return nil, err
}
dd, err := c.DeployContract(c.NewTXOpts(),
"TestCounter",
*counterABI,
common.FromHex(gethwrappers.GethwrappersMetaData.Bin),
)
if err != nil {
return nil, err
}
out := &Output{
UseCache: true,
// save all the addresses to output, so it can be cached
Addresses: []common.Address{dd.Address},
}
in.Out = out
return out, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[profile.default]
chain_id = "1337"
src = "src"
out = "out"
libs = ["lib"]

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
Loading

0 comments on commit 702527f

Please sign in to comment.