Skip to content

Commit 3a65c86

Browse files
committed
add metadata with build details for contract verification
1 parent 5922343 commit 3a65c86

File tree

29 files changed

+260
-8
lines changed

29 files changed

+260
-8
lines changed

contracts/scripts/native_solc_compile_all_shared

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ compileContract() {
2020
local contract
2121
contract=$(basename "$path")
2222
echo "Compiling" "$contract"
23+
dir=$CONTRACTS_DIR/solc/$PROJECT/$contract
2324

2425
local current_project="$PROJECT"
2526
if [ -n "$project" ]; then
@@ -31,7 +32,9 @@ compileContract() {
3132
local command
3233
command="forge build $CONTRACTS_DIR/src/v0.8/$current_project/"$path.sol" \
3334
--root $CONTRACTS_DIR \
34-
--extra-output-files bin abi"
35+
--extra-output-files bin abi metadata \
36+
--build-info \
37+
--build-info-path $dir/build"
3538

3639
# Add version if provided
3740
if [ -n "$version" ]; then
@@ -41,9 +44,12 @@ compileContract() {
4144

4245
# Output directory
4346
command="$command \
44-
-o $CONTRACTS_DIR/solc/$PROJECT/$contract"
47+
-o $dir"
4548

4649
$command
50+
51+
# Move the build info to an expected file name
52+
mv $(find $dir/build -type f -name '*.json' ! -name 'build.json') $dir/build/build.json
4753
}
4854

4955
# Various contracts are compiled with v0.8.19 instead of the default specified in foundry.toml.

gethwrappers/abigen.go

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package gethwrappers
22

33
import (
44
"bytes"
5+
"encoding/json"
56
"fmt"
67
"go/ast"
78
"go/format"
@@ -11,6 +12,7 @@ import (
1112
"os/exec"
1213
"path/filepath"
1314
"regexp"
15+
"strconv"
1416
"strings"
1517

1618
"github.com/ethereum/go-ethereum/accounts/abi"
@@ -28,7 +30,29 @@ var GethVersion = fmt.Sprintf("%d.%d.%d", version.Major, version.Minor, version.
2830
// AbigenArgs is the arguments to the abigen executable. E.g., Bin is the -bin
2931
// arg.
3032
type AbigenArgs struct {
31-
Bin, ABI, Out, Type, Pkg string
33+
Bin, ABI, BuildInfo, Metadata, Out, BuildInfoOut, Type, Pkg string
34+
}
35+
36+
// compiler defines the compiler section of contract metadata.
37+
type compiler struct {
38+
Version string `json:"version"`
39+
}
40+
41+
// metadata defines the sections of the contract metadata required for verification.
42+
type metadata struct {
43+
Compiler compiler `json:"compiler"`
44+
}
45+
46+
// standardInput defines the sections of the Solidity standard input required for verification.
47+
type standardInput struct {
48+
Version string `json:"version"`
49+
Language string `json:"language"`
50+
Settings map[string]any `json:"settings"`
51+
Sources map[string]any `json:"sources"`
52+
}
53+
54+
type buildInfo struct {
55+
Input standardInput `json:"input"`
3256
}
3357

3458
// Abigen calls Abigen with the given arguments
@@ -70,6 +94,55 @@ func Abigen(a AbigenArgs) {
7094
}
7195

7296
ImproveAbigenOutput(a.Out, a.ABI)
97+
98+
// Add build info to exported package
99+
info, err := os.ReadFile(a.BuildInfo)
100+
if err != nil {
101+
Exit("Error while reading build info file", err)
102+
}
103+
// Unmarshal into BuildInfo struct to filter out unnecessary fields
104+
// and marshal back to JSON bytes afterwards
105+
var build buildInfo
106+
err = json.Unmarshal(info, &build)
107+
if err != nil {
108+
Exit("Error while unmarshalling build info JSON", err)
109+
}
110+
// Get version from metadata file, as it contains the commit hash required by etherscan
111+
metadataBytes, err := os.ReadFile(a.Metadata)
112+
if err != nil {
113+
Exit("Error while reading metadata file", err)
114+
}
115+
var metadata metadata
116+
err = json.Unmarshal(metadataBytes, &metadata)
117+
if err != nil {
118+
Exit("Error while unmarshalling metadata JSON", err)
119+
}
120+
121+
if !strings.HasPrefix(metadata.Compiler.Version, "v") {
122+
// Verification requires the version to be prefixed with "v"
123+
metadata.Compiler.Version = "v" + metadata.Compiler.Version
124+
}
125+
build.Input.Version = metadata.Compiler.Version
126+
127+
refinedMeta, err := json.Marshal(build.Input)
128+
if err != nil {
129+
Exit("Error while marshalling build info JSON", err)
130+
}
131+
// Export the metadata as a variable in the generated Go file
132+
var buf bytes.Buffer
133+
if err := json.Compact(&buf, refinedMeta); err != nil {
134+
Exit("Error while compacting build info JSON", err)
135+
}
136+
code := fmt.Sprintf(
137+
"%s\npackage %s\n\nvar SolidityStandardInput = %s\n",
138+
headerComment,
139+
a.Pkg,
140+
strconv.Quote(buf.String()),
141+
)
142+
err = os.WriteFile(a.BuildInfoOut, []byte(code), 0600)
143+
if err != nil {
144+
Exit("Error while writing build info file", err)
145+
}
73146
}
74147

75148
func ImproveAbigenOutput(path string, abiPath string) {

gethwrappers/generation/generate/genwrapper/genwrapper.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
// <project>/generated/<pkgName>/<pkgName>.go. The suffix will take place after
2525
// the <project>/generated, so the overridden location would be
2626
// <project>/generated/<outDirSuffixInput>/<pkgName>/<pkgName>.go.
27-
func GenWrapper(abiPath, binPath, className, pkgName, outDirSuffixInput string) {
27+
func GenWrapper(abiPath, binPath, buildInfoPath, metadataPath, className, pkgName, outDirSuffixInput string) {
2828
fmt.Println("Generating", pkgName, "contract wrapper")
2929

3030
cwd, err := os.Getwd() // gethwrappers directory
@@ -38,9 +38,17 @@ func GenWrapper(abiPath, binPath, className, pkgName, outDirSuffixInput string)
3838
mkdErr)
3939
}
4040
outPath := filepath.Join(outDir, pkgName+".go")
41+
metadataOutPath := filepath.Join(outDir, pkgName+"_metadata.go")
4142

4243
gethwrappers.Abigen(gethwrappers.AbigenArgs{
43-
Bin: binPath, ABI: abiPath, Out: outPath, Type: className, Pkg: pkgName,
44+
Bin: binPath,
45+
ABI: abiPath,
46+
BuildInfo: buildInfoPath,
47+
Metadata: metadataPath,
48+
Out: outPath,
49+
BuildInfoOut: metadataOutPath,
50+
Type: className,
51+
Pkg: pkgName,
4452
})
4553

4654
// Build succeeded, so update the versions db with the new contract data

gethwrappers/generation/generate/wrap.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@ func main() {
1717
outDirSuffix = os.Args[5]
1818
}
1919

20-
genwrapper.GenWrapper(abiPath, binPath, className, pkgName, outDirSuffix)
20+
genwrapper.GenWrapper(abiPath, binPath, "", "", className, pkgName, outDirSuffix)
2121
}

gethwrappers/generation/generate_automation/wrap.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ func main() {
1717
pkgName := os.Args[3]
1818

1919
abiPath := rootDir + project + "/" + inputClassName + "/" + inputClassName + ".sol/" + inputClassName + ".abi.json"
20+
metadataPath := rootDir + project + "/" + inputClassName + "/" + inputClassName + ".sol/" + inputClassName + ".metadata.json"
2021
binPath := rootDir + project + "/" + inputClassName + "/" + inputClassName + ".sol/" + inputClassName + ".bin"
22+
buildInfoPath := rootDir + project + "/" + inputClassName + "/build/build.json"
2123

22-
genwrapper.GenWrapper(abiPath, binPath, outputClassName, pkgName, "")
24+
genwrapper.GenWrapper(abiPath, binPath, buildInfoPath, metadataPath, outputClassName, pkgName, "")
2325
}

gethwrappers/generation/wrap.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ func main() {
2626
}
2727

2828
abiPath := rootDir + project + "/" + className + "/" + className + ".sol/" + className + ".abi.json"
29+
metadataPath := rootDir + project + "/" + className + "/" + className + ".sol/" + className + ".metadata.json"
2930
binPath := rootDir + project + "/" + className + "/" + className + ".sol/" + className + ".bin"
31+
buildInfoPath := rootDir + project + "/" + className + "/build/build.json"
3032

31-
genwrapper.GenWrapper(abiPath, binPath, className, pkgName, outDirSuffix)
33+
genwrapper.GenWrapper(abiPath, binPath, buildInfoPath, metadataPath, className, pkgName, outDirSuffix)
3234
}

gethwrappers/shared/generated/latest/aggregator_v3_interface/aggregator_v3_interface_metadata.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gethwrappers/shared/generated/latest/burn_mint_erc20/burn_mint_erc20_metadata.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gethwrappers/shared/generated/latest/burn_mint_erc20_pausable_freezable_transparent/burn_mint_erc20_pausable_freezable_transparent_metadata.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gethwrappers/shared/generated/latest/burn_mint_erc20_pausable_freezable_uups/burn_mint_erc20_pausable_freezable_uups_metadata.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)