Skip to content

Commit 6a8eea4

Browse files
committed
Merge
2 parents eea9d50 + 3a75eda commit 6a8eea4

File tree

21 files changed

+3991
-30
lines changed

21 files changed

+3991
-30
lines changed

.gitignore

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,5 @@
11
# dependencies
22
node_modules/
3-
tmp/
4-
.pnp
5-
.pnp.js
6-
tools/bin/abigen
7-
8-
/chainlink
9-
core/chainlink
10-
11-
# SQLite
12-
tools/clroot/db.sqlite3-shm
13-
tools/clroot/db.sqlite3-wal
143

154
# Tooling caches
165
*.tsbuildinfo
@@ -19,6 +8,14 @@ tools/clroot/db.sqlite3-wal
198
# Log files
209
*.log
2110

11+
# bin
12+
tools/bin/*
13+
14+
# generated content
15+
**/*.abi
16+
**/*.bin
17+
generated/
18+
2219
# misc
2320
.DS_Store
2421
.envrc
@@ -30,6 +27,7 @@ tools/clroot/db.sqlite3-wal
3027
.idea
3128
.vscode/
3229
*.iml
30+
3331
debug.env
3432
*.txt
3533
operator_ui/install
@@ -97,22 +95,3 @@ contracts/yarn.lock
9795
# Ignore DevSpace cache and log folder
9896
.devspace/
9997
go.work*
100-
101-
# This sometimes shows up for some reason
102-
tools/flakeytests/coverage.txt
103-
104-
# Fuzz tests can create these files
105-
**/testdata/fuzz/*
106-
107-
# Runtime test configuration that might contain secrets
108-
override*.toml
109-
110-
# Python venv
111-
.venv/
112-
113-
ocr_soak_report.csv
114-
115-
vendor/*
116-
117-
*.wasm
118-
contracts/lcov.info

tools/evm-chain-bindings/Makefile

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Name of the binary to be built
2+
BINARY_NAME=evm-chain-bindings
3+
4+
# Default target
5+
all: build
6+
7+
# Build the Go binary with a custom name
8+
build:
9+
go build -o ../bin/$(BINARY_NAME)
10+
11+
# Clean the build artifacts
12+
clean:
13+
rm -f $(BINARY_NAME)
14+
15+
# Install the binary to the system's Go bin directory
16+
install: build
17+
install -m 0755 ../bin/$(BINARY_NAME) $(GOPATH)/bin/
18+
19+
# Uninstall the binary
20+
uninstall:
21+
rm -f $(GOPATH)/bin/$(BINARY_NAME)
22+
23+
# Help information
24+
help:
25+
@echo "Usage:"
26+
@echo " make build Build the binary with the custom name."
27+
@echo " make install Install the binary to the Go bin directory."
28+
@echo " make clean Remove the binary."
29+
@echo " make uninstall Remove the installed binary."
30+
@echo " make help Show this help message."
31+
32+
.PHONY: all build clean install uninstall help

tools/evm-chain-bindings/README.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Go bindings generation EVM smart contracts and CR / CW configuration
2+
3+
This is a POC to improve the UX of ChainReader and ChainWriter by providing a mechanism to create go bindings for smart contracts that use CR / CW as the underlying mechanism for blockchain connectivity.
4+
5+
This project generate a command line tool that can be plugged within the project build system, using go:generate, to generate client code for on-chain connectivity against solidty smart contracts, on top of ChainReader and ChainWriter abstractions.
6+
7+
Given a set of ABI this tool generate:
8+
- ChainReaderConfig needed to create a ChainReader instance
9+
- ChainWriterConfig needed to create a ChainWriter instance
10+
- One go file per smart contract ABI with a struct that represent the smart contract client and functions to read and write to the smart contract
11+
12+
## Features supported
13+
14+
With probably plenty of bugs to be fixed, the POC supports:
15+
16+
- Strongly typed smart contract state reading. Events not yet supported.
17+
- Strongly typed smart contracts method invocation that requires transactions. Payable methods allow to send ETH, Non-payable don't.
18+
- Simple and complex types inputs and outputs.
19+
- Basic chain reader and chain writer configuration but works for simple use cases.
20+
21+
Solidity primitive types to Go primitive types are not fully mapped. If you encounter an issue regarding type mapping you can update the code in internal/gen/evm/solity_types_mapping.go
22+
23+
## Troubleshooting and issue reporting
24+
25+
This is a POC so only use this tool at your own risk and do not use it yet for anything targeting production soon. We are still evaluating the POC and defining if we will productize this tool or not.
26+
The easiest way to get help would be to push a branch with your projects and explain the issue with DM through slack to Pablo La Greca to get a fix.
27+
28+
## installation
29+
30+
To install the command line tool:
31+
32+
```sh
33+
git clone https://github.com/smartcontractkit/chainlink-framework.git
34+
cd chainlink-framework
35+
cd evm-chain-bindings
36+
make install
37+
```
38+
39+
## Usage
40+
41+
### Example project
42+
43+
There's an example project located in the folder examples/basic with a project that leverages the evm-chain-bindings cli using go:generate and a Makefile
44+
45+
### Command line tool
46+
47+
```sh
48+
❯ evm-chain-bindings -h
49+
Usage of evm-bindings:
50+
evm-bindings[flags] -contracts T [directory]
51+
-clean
52+
output folder for the generated code
53+
-contracts string
54+
comma-separated list of directories containing EVM smart contracts source and ABI files; must be set (default "contracts")
55+
-output string
56+
output folder for the generated code (default "generated/evm/bindings")
57+
-silent-if-no-contracts
58+
do not fails if there are not contracts to be processed
59+
-verbose
60+
generates debugging output
61+
```
62+
63+
64+
## Test cases
65+
66+
There's also a test case in [here](https://github.com/smartcontractkit/chainlink/blob/go-bindings-poc/core/services/relay/evm/go_bindings_test.go) that showcase a complete setup of this go bindings using ChainReader and ChainWriter.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Default target
2+
all: build
3+
4+
generate-abi:
5+
solc --abi contracts/ChainReaderTester.sol -o contracts/ --overwrite
6+
7+
build: generate-abi
8+
go generate ./...
9+
go build ./...
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Sample project - Basic
2+
3+
Most simple usage example of evm-chain-bindings tool relying on its default configuration and on a simple Solidity smart contract.
4+
5+
The project Makefile contains the logic to execute evm-chain-bindings script using go generate:
6+
```
7+
all: build
8+
9+
generate-abi:
10+
solc --abi contracts/ChainReaderTester.sol -o contracts/ --overwrite
11+
12+
build: generate-abi
13+
go generate ./...
14+
go build ./...
15+
```
16+
17+
The file `main.go` defines the `go:generate` directive
18+
19+
```
20+
//go:generate evm-chain-bindings
21+
func main() {
22+
}
23+
```
24+
25+
This executes the `evm-chain-bindings` script using all the default options:
26+
- Contracts ABIs will be read from contracts/ folder in the root directory
27+
- Output will be generated in generated/evm/bindings/ folder in the root directory
28+
29+
To build the project and generate bindings run:
30+
```
31+
make
32+
```
33+
34+
Then you can see the generated code in `generated/evm/bindings`
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.0;
3+
4+
// solhint-disable-next-line gas-struct-packing
5+
struct TestStruct {
6+
int32 Field;
7+
string DifferentField;
8+
uint8 OracleId;
9+
uint8[32] OracleIds;
10+
address Account;
11+
address[] Accounts;
12+
int192 BigField;
13+
MidLevelDynamicTestStruct NestedDynamicStruct;
14+
MidLevelStaticTestStruct NestedStaticStruct;
15+
}
16+
17+
struct MidLevelDynamicTestStruct {
18+
bytes2 FixedBytes;
19+
InnerDynamicTestStruct Inner;
20+
}
21+
22+
struct InnerDynamicTestStruct {
23+
int64 IntVal;
24+
string S;
25+
}
26+
27+
struct MidLevelStaticTestStruct {
28+
bytes2 FixedBytes;
29+
InnerStaticTestStruct Inner;
30+
}
31+
32+
struct InnerStaticTestStruct {
33+
int64 IntVal;
34+
address A;
35+
}
36+
37+
contract ChainReaderTester {
38+
event Triggered(
39+
int32 indexed field,
40+
uint8 oracleId,
41+
MidLevelDynamicTestStruct nestedDynamicStruct,
42+
MidLevelStaticTestStruct nestedStaticStruct,
43+
uint8[32] oracleIds,
44+
address Account,
45+
address[] Accounts,
46+
string differentField,
47+
int192 bigField
48+
);
49+
50+
event TriggeredEventWithDynamicTopic(string indexed fieldHash, string field);
51+
52+
// First topic is event hash
53+
event TriggeredWithFourTopics(int32 indexed field1, int32 indexed field2, int32 indexed field3);
54+
55+
// first topic is event hash, second and third topics get hashed before getting stored
56+
event TriggeredWithFourTopicsWithHashed(string indexed field1, uint8[32] indexed field2, bytes32 indexed field3);
57+
58+
TestStruct[] private s_seen;
59+
uint64[] private s_arr;
60+
uint64 private s_value;
61+
62+
constructor() {
63+
// See chain_reader_interface_tests.go in chainlink-relay
64+
s_arr.push(3);
65+
s_arr.push(4);
66+
}
67+
68+
function addTestStruct(
69+
int32 field,
70+
string calldata differentField,
71+
uint8 oracleId,
72+
uint8[32] calldata oracleIds,
73+
address account,
74+
address[] calldata accounts,
75+
int192 bigField,
76+
MidLevelDynamicTestStruct calldata nestedDynamicStruct,
77+
MidLevelStaticTestStruct calldata nestedStaticStruct
78+
) public {
79+
s_seen.push(
80+
TestStruct(
81+
field,
82+
differentField,
83+
oracleId,
84+
oracleIds,
85+
account,
86+
accounts,
87+
bigField,
88+
nestedDynamicStruct,
89+
nestedStaticStruct
90+
)
91+
);
92+
}
93+
94+
function setAlterablePrimitiveValue(uint64 value) public {
95+
s_value = value;
96+
}
97+
98+
function returnSeen(
99+
int32 field,
100+
string calldata differentField,
101+
uint8 oracleId,
102+
uint8[32] calldata oracleIds,
103+
address account,
104+
address[] calldata accounts,
105+
int192 bigField,
106+
MidLevelDynamicTestStruct calldata nestedDynamicStruct,
107+
MidLevelStaticTestStruct calldata nestedStaticStruct
108+
) public pure returns (TestStruct memory) {
109+
return
110+
TestStruct(
111+
field,
112+
differentField,
113+
oracleId,
114+
oracleIds,
115+
account,
116+
accounts,
117+
bigField,
118+
nestedDynamicStruct,
119+
nestedStaticStruct
120+
);
121+
}
122+
123+
function getElementAtIndex(uint256 i) public view returns (TestStruct memory) {
124+
// See chain_reader_interface_tests.go in chainlink-relay
125+
return s_seen[i - 1];
126+
}
127+
128+
function getPrimitiveValue() public pure returns (uint64) {
129+
// See chain_reader_interface_tests.go in chainlink-relay
130+
return 3;
131+
}
132+
133+
function getAlterablePrimitiveValue() public view returns (uint64) {
134+
// See chain_reader_interface_tests.go in chainlink-relay
135+
return s_value;
136+
}
137+
138+
function getDifferentPrimitiveValue() public pure returns (uint64) {
139+
// See chain_reader_interface_tests.go in chainlink-relay
140+
return 1990;
141+
}
142+
143+
function getSliceValue() public view returns (uint64[] memory) {
144+
return s_arr;
145+
}
146+
147+
function triggerEvent(
148+
int32 field,
149+
uint8 oracleId,
150+
MidLevelDynamicTestStruct calldata nestedDynamicStruct,
151+
MidLevelStaticTestStruct calldata nestedStaticStruct,
152+
uint8[32] calldata oracleIds,
153+
address account,
154+
address[] calldata accounts,
155+
string calldata differentField,
156+
int192 bigField
157+
) public {
158+
emit Triggered(
159+
field,
160+
oracleId,
161+
nestedDynamicStruct,
162+
nestedStaticStruct,
163+
oracleIds,
164+
account,
165+
accounts,
166+
differentField,
167+
bigField
168+
);
169+
}
170+
171+
function triggerEventWithDynamicTopic(string calldata field) public {
172+
emit TriggeredEventWithDynamicTopic(field, field);
173+
}
174+
175+
// first topic is the event signature
176+
function triggerWithFourTopics(int32 field1, int32 field2, int32 field3) public {
177+
emit TriggeredWithFourTopics(field1, field2, field3);
178+
}
179+
180+
// first topic is event hash, second and third topics get hashed before getting stored
181+
function triggerWithFourTopicsWithHashed(string memory field1, uint8[32] memory field2, bytes32 field3) public {
182+
emit TriggeredWithFourTopicsWithHashed(field1, field2, field3);
183+
}
184+
}

0 commit comments

Comments
 (0)