Skip to content

Commit

Permalink
Adding initial framework
Browse files Browse the repository at this point in the history
  • Loading branch information
yashnevatia committed Dec 2, 2024
1 parent 4d31dea commit 0bf13d1
Show file tree
Hide file tree
Showing 4 changed files with 201 additions and 2 deletions.
80 changes: 80 additions & 0 deletions core/gethwrappers/abigen.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ func ImproveAbigenOutput(path string, abiPath string) {
}
contractName := getContractName(fileNode)
fileNode = addContractStructFields(contractName, fileNode)
fileNode = addZKSyncLogic(contractName, fset, fileNode)
fileNode = replaceAnonymousStructs(contractName, fileNode)
bs = generateCode(fset, fileNode)
bs = writeAdditionalMethods(contractName, logNames, abi, bs)
Expand Down Expand Up @@ -467,3 +468,82 @@ func writeInterface(contractName string, fileNode *ast.File) *ast.File {
func addHeader(code []byte) []byte {
return utils.ConcatBytes([]byte(headerComment), code)
}

func getZKSyncBlock(contractName, paramList string) string {
zkSyncBlock := `if generated_zks.IsZKSync(backend) {
address, ethTx, contractBind, _ := generated_zks.DeployContract(auth, *parsed, common.FromHex(%sZKBin), backend, %params)
contractReturn := &%s{address: address, abi: *parsed, %sCaller: %sCaller{contract: contractBind}, %sTransactor: %sTransactor{contract: contractBind},%sFilterer: %sFilterer{contract: contractBind}}
return address, ethTx, contractReturn, err
}`
zkSyncBlock = strings.ReplaceAll(zkSyncBlock, "%s", contractName)
zkSyncBlock = strings.ReplaceAll(zkSyncBlock, "%params", paramList)
return strings.ReplaceAll(zkSyncBlock, "%s", contractName)
}

func getConstructorParams(x ast.FuncDecl) string {
params := []string{}
for i, param := range x.Type.Params.List {
if i > 1 { // Skip auth and backend
for _, name := range param.Names {
params = append(params, name.Name)
}
}
}
paramList := strings.Join(params, ", ")
return paramList
}

func addZKSyncBlock(x ast.FuncDecl, zkSyncBlock string) ast.FuncDecl {
for i, stmt := range x.Body.List {

ifStmt, ok := stmt.(*ast.IfStmt)
if !ok {
continue
}
binaryExpr, ok := ifStmt.Cond.(*ast.BinaryExpr)
if !ok {
continue
}
if ident, ok := binaryExpr.X.(*ast.Ident); ok && ident.Name == "parsed" {
// Creating new statement to insert
newStmt := &ast.ExprStmt{
X: &ast.BasicLit{
Kind: token.STRING,
Value: zkSyncBlock,
},
}

// Insert the new statement after the current statement
x.Body.List = append(x.Body.List[:i+1], append([]ast.Stmt{newStmt}, x.Body.List[i+1:]...)...)
break
}
}
return x
}

func addZKSyncLogic(contractName string, fset *token.FileSet, fileNode *ast.File) *ast.File {
astutil.AddImport(fset, fileNode, "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated_zks")

return astutil.Apply(fileNode, func(cursor *astutil.Cursor) bool {
x, is := cursor.Node().(*ast.FuncDecl)
if !is {
return true
} else if x.Name.Name != "Deploy"+contractName {
return false
}

// Extract the parameters from the existing function x
paramList := getConstructorParams(*x)
zkSyncBlock := getZKSyncBlock(contractName, paramList)
addZKSyncBlock(*x, zkSyncBlock)

x.Type.Results.List[1].Type = &ast.StarExpr{
X: &ast.SelectorExpr{
X: &ast.Ident{Name: "generated_zks"},
Sel: &ast.Ident{Name: "CustomTransaction"},
},
}

return false
}, nil).(*ast.File)
}
27 changes: 27 additions & 0 deletions core/gethwrappers/ccip/gen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# utility to convert go_generate.go to zksync version

def update_go_generate(file_path):
updated_lines = []

with open(file_path, 'r') as file:
for line in file:
if "//go:generate" in line:
parts = line.strip().split() # Split the line into parts
bin_path = parts[5]
# Generate the .zbin path with `.sol` insertion
zbin_path = bin_path.replace("solc", "zksolc").replace("/v0.8.24/", "/v1.5.6/").replace(".bin", ".sol/") + bin_path.split('/')[-1].replace(".bin", ".zbin")
parts.append(zbin_path)

parts[3] = "./generation/generate_zks/wrap.go"

line = " ".join(parts) + "\n"
print(line)

updated_lines.append(line)

# Write back to the file
with open(file_path, 'w') as file:
file.writelines(updated_lines)

# Example usage
update_go_generate('go_generate_zks.go')
87 changes: 87 additions & 0 deletions core/gethwrappers/ccip/generated_zks/generated_zks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package generated_zks

import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
// zkSyncAccounts "github.com/zksync-sdk/zksync2-go/accounts"
// zkSyncClient "github.com/zksync-sdk/zksync2-go/clients"
// zktypes "github.com/zksync-sdk/zksync2-go/types"
)

type CustomTransaction struct {
*types.Transaction
CustomHash common.Hash
}

func (tx *CustomTransaction) Hash() common.Hash {
return tx.CustomHash
}

// func ConvertToTransaction(resp zktypes.TransactionResponse) *CustomTransaction {
// dtx := &types.DynamicFeeTx{
// ChainID: resp.ChainID.ToInt(),
// Nonce: uint64(resp.Nonce),
// GasTipCap: resp.MaxPriorityFeePerGas.ToInt(),
// GasFeeCap: resp.MaxFeePerGas.ToInt(),
// To: &resp.To,
// Value: resp.Value.ToInt(),
// Data: resp.Data,
// Gas: uint64(resp.Gas),
// }

// tx := types.NewTx(dtx)
// customTransaction := CustomTransaction{Transaction: tx, CustomHash: resp.Hash}
// return &customTransaction
// }

// func IsZkSync(backend bind.ContractBackend) bool {
// client, ok := backend.(*ethclient.Client)
// if !ok {
// return false
// }
// chainId, err := client.ChainID(context.Background())
// if err != nil {
// return false
// }
// switch chainId.Uint64() {

// case 324, 280, 300:
// return true
// }
// return false
// }

// type ZkSyncContract struct {
// zkclient *zkSyncClient.Client
// wallet *zkSyncAccounts.Wallet
// }

// // NewZkSyncContract creates and returns a new ZkSyncContract instance.
// func NewZkSyncContract(auth *bind.TransactOpts, backend bind.ContractBackend, contractBytes []byte, contractAbi *abi.ABI, params ...interface{}) (common.Address, *CustomTransaction, *bind.BoundContract, error) {
// client, ok := backend.(*ethclient.Client)
// if !ok {
// return common.Address{}, nil, nil, fmt.Errorf("backend is not an *ethclient.Client")
// }

// // Retrieve wallet from context safely
// walletValue := auth.Context.Value("wallet")
// wallet, ok := walletValue.(*zkSyncAccounts.Wallet)
// if !ok || wallet == nil {
// return common.Address{}, nil, nil, fmt.Errorf("wallet not found in context or invalid type")
// }

// zkclient := zkSyncClient.NewClient(client.Client())

// constructor, _ := contractAbi.Pack("", params...)

// hash, _ := wallet.DeployWithCreate(nil, zkSyncAccounts.CreateTransaction{
// Bytecode: contractBytes,
// Calldata: constructor,
// })
// receipt, _ := zkclient.WaitMined(context.Background(), hash)
// tx, _, _ := zkclient.TransactionByHash(context.Background(), hash)
// ethTx := ConvertToTransaction(*tx)
// address := receipt.ContractAddress
// contractBind := bind.NewBoundContract(address, *contractAbi, backend, backend, backend)
// return address, ethTx, contractBind, nil
// }

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 0bf13d1

Please sign in to comment.