Skip to content

Commit 3fdd859

Browse files
committed
Random changes
1 parent 75a7a6d commit 3fdd859

File tree

17 files changed

+530
-28
lines changed

17 files changed

+530
-28
lines changed

abi/contract.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@ func (b *Builder) processContract(contract *ir.Contract) (*Contract, error) {
5656
if stateVar.Name == "" && stateVar.GetTypeDescription() == nil {
5757
continue
5858
}
59-
method := b.processStateVariable(stateVar)
60-
toReturn = append(toReturn, method)
59+
60+
if method := b.processStateVariable(stateVar); method != nil {
61+
toReturn = append(toReturn, method)
62+
}
6163
}
6264

6365
// Process events.

abi/state_variable.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ func (b *Builder) processStateVariable(stateVar *ir.StateVariable) *Method {
1616
StateMutability: b.normalizeStateMutability(stateVar.GetStateMutability()),
1717
}
1818

19+
if stateVar.GetTypeDescription() == nil {
20+
return nil
21+
}
22+
1923
typeName := b.resolver.ResolveType(stateVar.GetTypeDescription())
2024

2125
switch typeName {

accounts/account.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ func (a *Account) GetClient() *clients.Client {
7575
// This method is mainly used for testing purposes in simulation environments like Anvil.
7676
// It does not affect the real balance on the Ethereum network.
7777
func (a *Account) SetAccountBalance(ctx context.Context, amount *big.Int) error {
78-
amountHex := common.Bytes2Hex(amount.Bytes())
79-
return a.client.GetRpcClient().CallContext(ctx, nil, "anvil_setBalance", a.GetAddress(), amountHex)
78+
return a.client.GetRpcClient().CallContext(ctx, nil, "anvil_setBalance", a.GetAddress(), amount.String())
8079
}
8180

8281
// Balance retrieves the account's balance from the Ethereum network at a specified block number.

ast/function.go

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ func (f *Function) ComputeSignature() {
151151

152152
if f.GetParameters() != nil {
153153
for _, param := range f.GetParameters().GetParameters() {
154+
/* if param.TypeName.TypeDescription == nil {
155+
utils.DumpNodeWithExit(param)
156+
}*/
154157
typeString := param.TypeName.TypeDescription.TypeString
155158
actualParam := param.TypeName.Name
156159

@@ -187,27 +190,27 @@ func (f *Function) ComputeSignature() {
187190
}
188191
}
189192
}
190-
case *StructDefinition:
191-
for _, member := range node.GetMembers() {
192-
if strings.Contains(member.GetTypeDescription().GetString(), "contract") {
193-
if strings.Contains(member.GetTypeDescription().GetString(), "[]") {
194-
structParams = append(structParams, "address[]")
195-
} else {
196-
structParams = append(structParams, "address")
197-
}
198-
} else if strings.Contains(member.GetTypeDescription().GetString(), "enum") {
199-
if strings.Contains(member.GetTypeDescription().GetString(), "[]") {
200-
structParams = append(structParams, "uint8[]")
201-
} else {
202-
structParams = append(structParams, "uint8")
203-
}
193+
case *StructDefinition:
194+
for _, member := range node.GetMembers() {
195+
if strings.Contains(member.GetTypeDescription().GetString(), "contract") {
196+
if strings.Contains(member.GetTypeDescription().GetString(), "[]") {
197+
structParams = append(structParams, "address[]")
204198
} else {
205-
structParams = append(structParams, member.GetTypeDescription().GetString())
199+
structParams = append(structParams, "address")
206200
}
201+
} else if strings.Contains(member.GetTypeDescription().GetString(), "enum") {
202+
if strings.Contains(member.GetTypeDescription().GetString(), "[]") {
203+
structParams = append(structParams, "uint8[]")
204+
} else {
205+
structParams = append(structParams, "uint8")
206+
}
207+
} else {
208+
structParams = append(structParams, member.GetTypeDescription().GetString())
207209
}
210+
}
208211
}
209212
}
210-
actualParam = "("+strings.Join(structParams, ",")+")"
213+
actualParam = "(" + strings.Join(structParams, ",") + ")"
211214
} else if strings.Contains(typeString, "enum") {
212215
if strings.Contains(typeString, "[]") {
213216
actualParam = "uint8[]"
@@ -740,7 +743,6 @@ func (f *Function) getVirtualState(ctx *parser.FunctionDefinitionContext) bool {
740743
return false
741744
}
742745

743-
744746
// translateMapping translates a Solidity mapping type string into a slice of data types.
745747
func translateMapping(mappingType string) []string {
746748
var result []string
@@ -763,4 +765,4 @@ func translateMapping(mappingType string) []string {
763765
}
764766

765767
return result
766-
}
768+
}

ast/visitor.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package ast
22

33
import (
4+
"github.com/pkg/errors"
45
ast_pb "github.com/unpackdev/protos/dist/go/ast"
56
)
67

@@ -49,6 +50,9 @@ func (t *Tree) WalkNodes(startNodes []Node[NodeType], visitor *NodeVisitor) erro
4950

5051
// ExecuteTypeVisit executes a visitation function on all nodes of a specific type in the AST, starting from the root.
5152
func (t *Tree) ExecuteTypeVisit(nodeType ast_pb.NodeType, visitFunc func(node Node[NodeType]) (bool, error)) (bool, error) {
53+
if t.astRoot == nil || t.astRoot.GetNodes() == nil {
54+
return false, errors.New("cannot execute type visit on empty tree")
55+
}
5256
return t.executeTypeVisitRecursive(t.astRoot.GetNodes(), nodeType, visitFunc)
5357
}
5458

bindings/manager.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ func NewManager(ctx context.Context, clientPool *clients.ClientPool) (*Manager,
4040
ctx: ctx,
4141
clientPool: clientPool,
4242
bindings: make(map[utils.Network]map[BindingType]*Binding),
43+
mu: sync.RWMutex{},
4344
}, nil
4445
}
4546

@@ -297,7 +298,6 @@ func (m *Manager) CallContractMethodUnpackMap(ctx context.Context, network utils
297298
return unpackedResults, nil
298299
}
299300

300-
301301
// CallContractMethodUnpackMap executes a contract method call and unpacks the results into a map, providing
302302
// a flexible interface for handling contract outputs.
303303
func (m *Manager) CallContractMethodUnpackMapAtBlock(ctx context.Context, network utils.Network, blockNumber *big.Int, bindingType BindingType, toAddr common.Address, methodName string, params ...interface{}) (map[string]any, error) {

bindings/simulator.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package bindings
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/ethereum/go-ethereum/accounts/abi"
7+
"github.com/ethereum/go-ethereum/accounts/abi/bind"
8+
"github.com/ethereum/go-ethereum/common"
9+
"github.com/ethereum/go-ethereum/common/hexutil"
10+
"github.com/unpackdev/solgo/clients"
11+
"github.com/unpackdev/solgo/utils"
12+
)
13+
14+
type JSONRPCRequest struct {
15+
JSONRPC string `json:"jsonrpc"`
16+
Method string `json:"method"`
17+
Params []interface{} `json:"params"`
18+
ID int `json:"id"`
19+
}
20+
21+
func (m *Manager) ImpersonateAccount(network utils.Network, contract common.Address) (common.Address, error) {
22+
client := m.clientPool.GetClientByGroup(string(network))
23+
if client == nil {
24+
return contract, fmt.Errorf("client not found for network %s", network)
25+
}
26+
27+
rpcClient := client.GetRpcClient()
28+
if err := rpcClient.Call(nil, "anvil_impersonateAccount", contract.Hex()); err != nil {
29+
return contract, fmt.Errorf("failed to impersonate account: %v", err)
30+
}
31+
32+
return contract, nil
33+
}
34+
35+
func (m *Manager) StopImpersonateAccount(network utils.Network, contract common.Address) (common.Address, error) {
36+
client := m.clientPool.GetClientByGroup(string(network))
37+
if client == nil {
38+
return contract, fmt.Errorf("client not found for network %s", network)
39+
}
40+
41+
rpcClient := client.GetRpcClient()
42+
if err := rpcClient.Call(nil, "anvil_stopImpersonatingAccount", contract.Hex()); err != nil {
43+
return contract, fmt.Errorf("failed to stop impersonating account: %v", err)
44+
}
45+
46+
return contract, nil
47+
}
48+
49+
func (m *Manager) SendSimulatedTransaction(opts *bind.TransactOpts, network utils.Network, simulatorType utils.SimulatorType, client *clients.Client, contract *common.Address, method abi.Method, input []byte) (*common.Hash, error) {
50+
txArgs := map[string]interface{}{
51+
"from": opts.From.Hex(),
52+
"to": contract.Hex(),
53+
"data": hexutil.Encode(input), // method + arguments...
54+
}
55+
56+
if opts.Value != nil {
57+
txArgs["value"] = hexutil.EncodeBig(opts.Value)
58+
}
59+
60+
var txHash common.Hash
61+
if err := client.GetRpcClient().Call(&txHash, "eth_sendTransaction", txArgs); err != nil {
62+
return nil, fmt.Errorf("failed to send transaction: %v - contract: %v - args: %v", err, contract.Hex(), txArgs)
63+
}
64+
65+
return &txHash, nil
66+
}

bindings/token.go

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ package bindings
33
import (
44
"context"
55
"fmt"
6+
"github.com/ethereum/go-ethereum/accounts/abi/bind"
7+
"github.com/ethereum/go-ethereum/core/types"
8+
"github.com/pkg/errors"
9+
"github.com/unpackdev/solgo/clients"
10+
"go.uber.org/zap"
611
"math/big"
712

813
"github.com/ethereum/go-ethereum/common"
@@ -212,6 +217,121 @@ func (t *Token) GetOptionsByNetwork(network utils.Network) *BindOptions {
212217
return nil
213218
}
214219

220+
func (t *Token) Transfer(ctx context.Context, network utils.Network, simulatorType utils.SimulatorType, client *clients.Client, opts *bind.TransactOpts, to common.Address, amount *big.Int, atBlock *big.Int) (*types.Transaction, *types.Receipt, error) {
221+
binding, err := t.GetBinding(utils.Ethereum, Erc20)
222+
if err != nil {
223+
return nil, nil, err
224+
}
225+
bindingAbi := binding.GetABI()
226+
227+
method, exists := bindingAbi.Methods["transfer"]
228+
if !exists {
229+
return nil, nil, errors.New("transfer method not found")
230+
}
231+
232+
select {
233+
case <-ctx.Done():
234+
return nil, nil, ctx.Err()
235+
default:
236+
input, err := bindingAbi.Pack(method.Name, to, amount)
237+
if err != nil {
238+
return nil, nil, err
239+
}
240+
241+
tx, err := t.Manager.SendTransaction(opts, t.network, simulatorType, client, &binding.Address, input)
242+
if err != nil {
243+
return nil, nil, fmt.Errorf("failed to send transfer transaction: %w", err)
244+
}
245+
246+
receipt, err := t.Manager.WaitForReceipt(t.ctx, network, simulatorType, client, tx.Hash())
247+
if err != nil {
248+
return nil, nil, fmt.Errorf("failed to get transfer transaction receipt: %w", err)
249+
}
250+
251+
return tx, receipt, nil
252+
}
253+
}
254+
255+
func (t *Token) Approve(ctx context.Context, network utils.Network, simulatorType utils.SimulatorType, client *clients.Client, opts *bind.TransactOpts, from common.Address, spender common.Address, amount *big.Int, atBlock *big.Int) (*types.Transaction, *types.Receipt, error) {
256+
binding, err := t.GetBinding(utils.Ethereum, Erc20)
257+
if err != nil {
258+
return nil, nil, err
259+
}
260+
bindingAbi := binding.GetABI()
261+
262+
method, exists := bindingAbi.Methods["approve"]
263+
if !exists {
264+
return nil, nil, errors.New("approve method not found")
265+
}
266+
267+
input, err := bindingAbi.Pack(method.Name, spender, amount)
268+
if err != nil {
269+
return nil, nil, err
270+
}
271+
272+
select {
273+
case <-ctx.Done():
274+
return nil, nil, ctx.Err()
275+
default:
276+
tx, err := t.Manager.SendTransaction(opts, t.network, simulatorType, client, &from, input)
277+
if err != nil {
278+
return nil, nil, fmt.Errorf("failed to send approve transaction: %w", err)
279+
}
280+
281+
receipt, err := t.Manager.WaitForReceipt(t.ctx, network, simulatorType, client, tx.Hash())
282+
if err != nil {
283+
return nil, nil, fmt.Errorf("failed to get approve transaction receipt: %w", err)
284+
}
285+
286+
zap.L().Debug(
287+
"Approve transaction sent and receipt received",
288+
zap.String("tx_hash", tx.Hash().Hex()),
289+
zap.String("tx_from", spender.Hex()),
290+
zap.String("tx_to", tx.To().Hex()),
291+
zap.String("tx_nonce", fmt.Sprintf("%d", tx.Nonce())),
292+
zap.String("tx_gas_price", tx.GasPrice().String()),
293+
zap.String("tx_gas", fmt.Sprintf("%d", tx.Gas())),
294+
)
295+
296+
return tx, receipt, nil
297+
}
298+
}
299+
300+
func (t *Token) TransferFrom(ctx context.Context, network utils.Network, simulatorType utils.SimulatorType, client *clients.Client, opts *bind.TransactOpts, from, to common.Address, amount *big.Int, atBlock *big.Int) (*types.Transaction, *types.Receipt, error) {
301+
binding, err := t.GetBinding(utils.Ethereum, Erc20)
302+
if err != nil {
303+
return nil, nil, err
304+
}
305+
bindingAbi := binding.GetABI()
306+
307+
method, exists := bindingAbi.Methods["transferFrom"]
308+
if !exists {
309+
return nil, nil, errors.New("transfer method not found")
310+
}
311+
312+
input, err := bindingAbi.Pack(method.Name, from, to, amount)
313+
if err != nil {
314+
return nil, nil, err
315+
}
316+
317+
select {
318+
case <-ctx.Done():
319+
return nil, nil, ctx.Err()
320+
default:
321+
tx, err := t.Manager.SendTransaction(opts, t.network, simulatorType, client, &binding.Address, input)
322+
if err != nil {
323+
return nil, nil, fmt.Errorf("failed to send transfer transaction: %w", err)
324+
}
325+
326+
receipt, err := t.Manager.WaitForReceipt(t.ctx, network, simulatorType, client, tx.Hash())
327+
if err != nil {
328+
return nil, nil, fmt.Errorf("failed to get transfer transaction receipt: %w", err)
329+
}
330+
331+
return tx, receipt, nil
332+
}
333+
}
334+
215335
// DefaultTokenBindOptions generates a default set of BindOptions for ERC20 and ERC20Ownable tokens. It presets
216336
// configurations such as networks, network IDs, types, contract addresses, and ABIs based on standard
217337
// implementations. This function simplifies the setup process for common token types.

bindings/trace.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,8 @@ func (m *Manager) TraceBlock(ctx context.Context, network utils.Network, number
5555

5656
if err := rpcClient.CallContext(ctx, &result, "trace_block", numberHex); err != nil {
5757
if err := rpcClient.CallContext(ctx, &tmp, "trace_block", numberHex); err != nil {
58-
fmt.Println(err)
5958
return nil, errors.Wrap(err, "failed to execute trace_block")
6059
}
61-
//utils.DumpNodeWithExit(tmp)
6260
return nil, errors.Wrap(err, "failed to execute trace_block")
6361
}
6462

0 commit comments

Comments
 (0)