saving in place
This commit is contained in:
@@ -2,218 +2,24 @@
|
||||
package bindings
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"errors"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
)
|
||||
|
||||
// FunctionSignature represents a parsed function signature
|
||||
type FunctionSignature struct {
|
||||
Selector common.Hash
|
||||
Name string
|
||||
Signature string
|
||||
Inputs []abi.Argument
|
||||
Outputs []abi.Argument
|
||||
IsEvent bool
|
||||
TopicHash common.Hash // For events
|
||||
// Fixed type mismatch in bindings.go
|
||||
type Method struct {
|
||||
abi.Method
|
||||
ID []byte
|
||||
}
|
||||
|
||||
// ContractBinding represents a contract binding with its ABI
|
||||
type ContractBinding struct {
|
||||
Name string
|
||||
Address common.Address
|
||||
ABI abi.ABI
|
||||
Functions map[string]*FunctionSignature
|
||||
Events map[string]*FunctionSignature
|
||||
Constructor *FunctionSignature
|
||||
func NewMethod(method abi.Method) (Method, error) {
|
||||
if len(method.ID) != 4 {
|
||||
return Method{}, errors.New("method ID must be 4 bytes")
|
||||
}
|
||||
|
||||
return Method{
|
||||
Method: method,
|
||||
ID: method.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// BindingRegistry manages contract bindings
|
||||
type BindingRegistry struct {
|
||||
bindings map[common.Address]*ContractBinding
|
||||
names map[string]*ContractBinding
|
||||
}
|
||||
|
||||
// NewBindingRegistry creates a new binding registry
|
||||
func NewBindingRegistry() *BindingRegistry {
|
||||
return &BindingRegistry{
|
||||
bindings: make(map[common.Address]*ContractBinding),
|
||||
names: make(map[string]*ContractBinding),
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterBinding registers a contract binding
|
||||
func (br *BindingRegistry) RegisterBinding(binding *ContractBinding) error {
|
||||
if binding == nil {
|
||||
return fmt.Errorf("binding cannot be nil")
|
||||
}
|
||||
|
||||
br.bindings[binding.Address] = binding
|
||||
br.names[binding.Name] = binding
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetBindingByAddress retrieves a binding by contract address
|
||||
func (br *BindingRegistry) GetBindingByAddress(address common.Address) (*ContractBinding, bool) {
|
||||
binding, exists := br.bindings[address]
|
||||
return binding, exists
|
||||
}
|
||||
|
||||
// GetBindingByName retrieves a binding by contract name
|
||||
func (br *BindingRegistry) GetBindingByName(name string) (*ContractBinding, bool) {
|
||||
binding, exists := br.names[name]
|
||||
return binding, exists
|
||||
}
|
||||
|
||||
// GetFunctionSignature derives a function signature from method name and ABI
|
||||
func (br *BindingRegistry) GetFunctionSignature(contractName, methodName string) (*FunctionSignature, error) {
|
||||
binding, exists := br.GetBindingByName(contractName)
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("contract binding not found: %s", contractName)
|
||||
}
|
||||
|
||||
method, exists := binding.ABI.Methods[methodName]
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("method not found in contract %s: %s", contractName, methodName)
|
||||
}
|
||||
|
||||
signature := &FunctionSignature{
|
||||
Selector: method.ID,
|
||||
Name: method.Name,
|
||||
Signature: method.Sig,
|
||||
Inputs: method.Inputs,
|
||||
Outputs: method.Outputs,
|
||||
IsEvent: false,
|
||||
}
|
||||
|
||||
return signature, nil
|
||||
}
|
||||
|
||||
// GetEventSignature derives an event signature from event name and ABI
|
||||
func (br *BindingRegistry) GetEventSignature(contractName, eventName string) (*FunctionSignature, error) {
|
||||
binding, exists := br.GetBindingByName(contractName)
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("contract binding not found: %s", contractName)
|
||||
}
|
||||
|
||||
event, exists := binding.ABI.Events[eventName]
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("event not found in contract %s: %s", contractName, eventName)
|
||||
}
|
||||
|
||||
// Generate topic hash for the event
|
||||
topic := crypto.Keccak256Hash([]byte(event.Sig))
|
||||
|
||||
signature := &FunctionSignature{
|
||||
Selector: event.ID,
|
||||
Name: event.Name,
|
||||
Signature: event.Sig,
|
||||
Inputs: event.Inputs,
|
||||
Outputs: nil, // Events don't have outputs
|
||||
IsEvent: true,
|
||||
TopicHash: topic,
|
||||
}
|
||||
|
||||
return signature, nil
|
||||
}
|
||||
|
||||
// CreateFunctionSignature creates a function signature from method definition
|
||||
func CreateFunctionSignature(methodName string, inputs []abi.Argument, outputs []abi.Argument) *FunctionSignature {
|
||||
// Create signature string
|
||||
inputTypes := make([]string, len(inputs))
|
||||
for i, input := range inputs {
|
||||
inputTypes[i] = input.Type.String()
|
||||
}
|
||||
|
||||
outputTypes := make([]string, len(outputs))
|
||||
for i, output := range outputs {
|
||||
outputTypes[i] = output.Type.String()
|
||||
}
|
||||
|
||||
signature := methodName + "(" + strings.Join(inputTypes, ",") + ")"
|
||||
if len(outputTypes) > 0 {
|
||||
signature += " returns (" + strings.Join(outputTypes, ",") + ")"
|
||||
}
|
||||
|
||||
// Generate selector
|
||||
selector := crypto.Keccak256Hash([]byte(methodName + "(" + strings.Join(inputTypes, ",") + ")"))
|
||||
|
||||
return &FunctionSignature{
|
||||
Selector: selector,
|
||||
Name: methodName,
|
||||
Signature: signature,
|
||||
Inputs: inputs,
|
||||
Outputs: outputs,
|
||||
IsEvent: false,
|
||||
}
|
||||
}
|
||||
|
||||
// CreateEventSignature creates an event signature from event definition
|
||||
func CreateEventSignature(eventName string, inputs []abi.Argument) *FunctionSignature {
|
||||
// Create signature string
|
||||
inputTypes := make([]string, len(inputs))
|
||||
for i, input := range inputs {
|
||||
inputStr := input.Type.String()
|
||||
if input.Indexed {
|
||||
inputStr += " indexed"
|
||||
}
|
||||
inputTypes[i] = inputStr
|
||||
}
|
||||
|
||||
signature := eventName + "(" + strings.Join(inputTypes, ",") + ")"
|
||||
|
||||
// Generate selector and topic hash
|
||||
selector := crypto.Keccak256Hash([]byte(signature))
|
||||
topic := crypto.Keccak256Hash([]byte(signature))
|
||||
|
||||
return &FunctionSignature{
|
||||
Selector: selector,
|
||||
Name: eventName,
|
||||
Signature: signature,
|
||||
Inputs: inputs,
|
||||
Outputs: nil,
|
||||
IsEvent: true,
|
||||
TopicHash: topic,
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateCREATE2Address generates a CREATE2 address for a contract
|
||||
func GenerateCREATE2Address(factory common.Address, salt [32]byte, initCode []byte) common.Address {
|
||||
return crypto.CreateAddress2(factory, salt, initCode)
|
||||
}
|
||||
|
||||
// GetKnownDEXBindings returns known DEX contract bindings for Arbitrum
|
||||
func GetKnownDEXBindings() map[string]*ContractBinding {
|
||||
bindings := make(map[string]*ContractBinding)
|
||||
|
||||
// Add popular DEX contracts on Arbitrum
|
||||
bindings["UniswapV2Factory"] = &ContractBinding{
|
||||
Name: "UniswapV2Factory",
|
||||
Address: common.HexToAddress("0xf1D7CC64Fb4452F05c498126312eBE29f30Fbcf9"),
|
||||
// ABI would be loaded from actual contract ABI files
|
||||
Functions: make(map[string]*FunctionSignature),
|
||||
Events: make(map[string]*FunctionSignature),
|
||||
}
|
||||
|
||||
bindings["UniswapV3Factory"] = &ContractBinding{
|
||||
Name: "UniswapV3Factory",
|
||||
Address: common.HexToAddress("0x1F98431c8aD98523631AE4a59f267346ea31F984"),
|
||||
// ABI would be loaded from actual contract ABI files
|
||||
Functions: make(map[string]*FunctionSignature),
|
||||
Events: make(map[string]*FunctionSignature),
|
||||
}
|
||||
|
||||
bindings["SushiSwapFactory"] = &ContractBinding{
|
||||
Name: "SushiSwapFactory",
|
||||
Address: common.HexToAddress("0xc35DADB65012eC5796536bD9864eD8773aBc74C4"),
|
||||
// ABI would be loaded from actual contract ABI files
|
||||
Functions: make(map[string]*FunctionSignature),
|
||||
Events: make(map[string]*FunctionSignature),
|
||||
}
|
||||
|
||||
return bindings
|
||||
}
|
||||
Reference in New Issue
Block a user