Skip to content

Commit

Permalink
Local to upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
0x19 committed Jun 23, 2024
1 parent 27ff826 commit bbaf95d
Show file tree
Hide file tree
Showing 23 changed files with 517 additions and 103 deletions.
42 changes: 20 additions & 22 deletions accounts/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,17 @@ import (
"context"
"encoding/base64"
"fmt"
"github.com/goccy/go-json"
"log"
"math/big"
"os"
"strings"

account "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/goccy/go-json"
"github.com/unpackdev/solgo/clients"
"github.com/unpackdev/solgo/utils"
"log"
"math/big"
"os"
)

const (
Expand Down Expand Up @@ -112,21 +109,22 @@ func (a *Account) TransactOpts(client *clients.Client, amount *big.Int, simulate

if !simulate {
if a.Type == utils.SimpleAccountType {
privateKey, err := crypto.HexToECDSA(strings.TrimLeft(a.PrivateKey, "0x"))
if err != nil {
return nil, err
}

auth, err := bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(client.GetNetworkID()))
if err != nil {
return nil, err
}

auth.Nonce = big.NewInt(int64(nonce))
auth.GasPrice = gasPrice
auth.GasLimit = DEFAULT_GAS_LIMIT
auth.Value = amount
return auth, nil
/* privateKey, err := crypto.HexToECDSA(strings.TrimLeft(a.PrivateKey, "0x"))
if err != nil {
return nil, err
}*/

/* auth, err := bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(client.GetNetworkID()))
if err != nil {
return nil, err
}
auth.Nonce = big.NewInt(int64(nonce))
auth.GasPrice = gasPrice
auth.GasLimit = DEFAULT_GAS_LIMIT
auth.Value = amount
return auth, nil*/
return nil, nil
} else if a.Type == utils.KeystoreAccountType {
password, _ := a.DecodePassword()

Expand Down
4 changes: 4 additions & 0 deletions ast/reference.go
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,10 @@ func (r *Resolver) byEnums(name string) (int64, *TypeDescription) {
}

func (r *Resolver) byStructs(name string) (int64, *TypeDescription) {
if strings.Contains(name, ".") {
name = strings.Split(name, ".")[1]
}

for _, node := range r.currentStructs {
structNode := node.(*StructDefinition)
if structNode.GetName() == name {
Expand Down
13 changes: 3 additions & 10 deletions ast/type_name.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,8 @@ func (t *TypeName) WithParentNode(p Node[NodeType]) {

// SetReferenceDescriptor sets the reference descriptions of the TypeName node.
func (t *TypeName) SetReferenceDescriptor(refId int64, refDesc *TypeDescription) bool {
if t.TypeDescription == nil {
t.ReferencedDeclaration = refId
t.TypeDescription = refDesc
}
t.ReferencedDeclaration = refId
t.TypeDescription = refDesc

// Lets update the parent node as well in case that type description is not set...
/* parentNodeId := t.GetSrc().GetParentIndex()
Expand Down Expand Up @@ -550,11 +548,6 @@ func (t *TypeName) parseIdentifierPath(unit *SourceUnit[Node[ast_pb.SourceUnit]]
t.TypeDescription = refTypeDescription
}
}

/* if t.Id == 1787 {
fmt.Println("HERE I AM")
utils.DumpNodeWithExit(t)
}*/
}
}

Expand Down Expand Up @@ -990,7 +983,7 @@ func (td *TypeDescription) GetString() string {
}

// ToProto converts the TypeDescription instance to its corresponding protocol buffer representation.
func (td TypeDescription) ToProto() *ast_pb.TypeDescription {
func (td *TypeDescription) ToProto() *ast_pb.TypeDescription {
return &ast_pb.TypeDescription{
TypeString: td.TypeString,
TypeIdentifier: td.TypeIdentifier,
Expand Down
106 changes: 106 additions & 0 deletions bindings/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package bindings
import (
"context"
"fmt"
"math/big"
"strings"
"sync"

Expand Down Expand Up @@ -192,6 +193,58 @@ func (m *Manager) CallContractMethod(ctx context.Context, network utils.Network,
return unpackedResults, nil
}

// CallContractMethodAtBlock executes a method call on a smart contract, handling the data packing, RPC call execution,
// and results unpacking.
func (m *Manager) CallContractMethodAtBlock(ctx context.Context, network utils.Network, blockNumber *big.Int, bindingType BindingType, toAddr common.Address, methodName string, params ...interface{}) (any, error) {
m.mu.RLock()
defer m.mu.RUnlock()

binding, ok := m.bindings[network][bindingType]
if !ok {
return nil, fmt.Errorf("binding %s not found for network %s", bindingType, network)
}

method, ok := binding.ABI.Methods[methodName]
if !ok {
return nil, fmt.Errorf("binding %s method %s not found in ABI", bindingType, methodName)
}

data, err := method.Inputs.Pack(params...)
if err != nil {
return nil, err
}

destinationAddr := toAddr
if destinationAddr == utils.ZeroAddress {
destinationAddr = binding.Address
}

callMsg := ethereum.CallMsg{
To: &destinationAddr,
Data: append(method.ID, data...),
}

var result []byte

client := m.clientPool.GetClientByGroup(network.String())
if client == nil {
return nil, fmt.Errorf("client not found for network %s", network)
}

result, err = client.CallContract(context.Background(), callMsg, blockNumber)
if err != nil {
return nil, fmt.Errorf("failed to call contract: %w", err)
}

var unpackedResults any
err = binding.ABI.UnpackIntoInterface(&unpackedResults, methodName, result)
if err != nil {
return nil, fmt.Errorf("failed to unpack results: %w", err)
}

return unpackedResults, nil
}

// CallContractMethodUnpackMap executes a contract method call and unpacks the results into a map, providing
// a flexible interface for handling contract outputs.
func (m *Manager) CallContractMethodUnpackMap(ctx context.Context, network utils.Network, bindingType BindingType, toAddr common.Address, methodName string, params ...interface{}) (map[string]any, error) {
Expand Down Expand Up @@ -243,3 +296,56 @@ func (m *Manager) CallContractMethodUnpackMap(ctx context.Context, network utils

return unpackedResults, nil
}


// CallContractMethodUnpackMap executes a contract method call and unpacks the results into a map, providing
// a flexible interface for handling contract outputs.
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) {
m.mu.RLock()
defer m.mu.RUnlock()

binding, ok := m.bindings[network][bindingType]
if !ok {
return nil, fmt.Errorf("binding %s not found for network %s", bindingType, network)
}

method, ok := binding.ABI.Methods[methodName]
if !ok {
return nil, fmt.Errorf("binding %s method %s not found in ABI", bindingType, methodName)
}

data, err := method.Inputs.Pack(params...)
if err != nil {
return nil, err
}

destinationAddr := toAddr
if destinationAddr == utils.ZeroAddress {
destinationAddr = binding.Address
}

callMsg := ethereum.CallMsg{
To: &destinationAddr,
Data: append(method.ID, data...),
}

var result []byte

client := m.clientPool.GetClientByGroup(network.String())
if client == nil {
return nil, fmt.Errorf("client not found for network %s", network)
}

result, err = client.CallContract(context.Background(), callMsg, blockNumber)
if err != nil {
return nil, fmt.Errorf("failed to call contract: %w", err)
}

unpackedResults := map[string]any{}
err = binding.ABI.UnpackIntoMap(unpackedResults, methodName, result)
if err != nil {
return nil, fmt.Errorf("failed to unpack results: %w", err)
}

return unpackedResults, nil
}
22 changes: 13 additions & 9 deletions bytecode/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,21 @@ func DecodeLogFromAbi(log *types.Log, abiData []byte) (*Log, error) {
}
}

if len(log.Topics) < len(indexedInputs)+1 {
return nil, fmt.Errorf("insufficient number of topics in log.Topics")
}

decodedTopics := make([]Topic, len(indexedInputs))
for i, indexedInput := range indexedInputs {
decodedTopic, err := decodeTopic(log.Topics[i+1], indexedInput)
if err != nil {
return nil, fmt.Errorf("failed to decode topic: %s", err)
}

decodedTopics[i] = Topic{
Name: indexedInput.Name,
Value: decodedTopic,
}
decodedTopic, err := decodeTopic(log.Topics[i+1], indexedInput)
if err != nil {
return nil, fmt.Errorf("failed to decode topic: %s", err)
}

decodedTopics[i] = Topic{
Name: indexedInput.Name,
Value: decodedTopic,
}
}

eventAbi, err := utils.EventToABI(event)
Expand Down
18 changes: 14 additions & 4 deletions contracts/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package contracts
import (
"context"
"fmt"
"github.com/unpackdev/solgo/bindings"

hypersyncgo "github.com/enviodev/hypersync-client-go"

Check failure on line 6 in contracts/chain.go

View workflow job for this annotation

GitHub Actions / tests

github.com/enviodev/hypersync-client-go@v0.0.0-00010101000000-000000000000: replacement directory ../hypersync-client-go does not exist

Check failure on line 6 in contracts/chain.go

View workflow job for this annotation

GitHub Actions / test (1.22)

github.com/enviodev/hypersync-client-go@v0.0.0-00010101000000-000000000000: replacement directory ../hypersync-client-go does not exist
"github.com/ethereum/go-ethereum/common"
"github.com/pkg/errors"
"github.com/unpackdev/solgo/bindings"
"github.com/unpackdev/solgo/utils"
)

Expand All @@ -30,6 +31,15 @@ func (c *Contract) DiscoverChainInfo(ctx context.Context, otsLookup bool) error
var txHash common.Hash

if info == nil || info.CreationHash == utils.ZeroHash {
cInfo, err := c.hypersync.GetContractCreator(ctx, c.network.GetToHyperSyncNetworkID(), c.addr)
if err != nil && !errors.Is(err, hypersyncgo.ErrContractNotFound) {
return errors.Wrap(err, "failed to get contract creator transaction information")
} else if cInfo != nil {
txHash = cInfo.Hash
}
}

if txHash == utils.ZeroHash || info == nil || info.CreationHash == utils.ZeroHash {
// Prior to continuing with the unpacking of the contract, we want to make sure that we can reach properly
// contract transaction and associated creation block. If we can't, we're not going to unpack it.
cInfo, err := c.etherscan.QueryContractCreationTx(ctx, c.addr)
Expand All @@ -56,11 +66,11 @@ func (c *Contract) DiscoverChainInfo(ctx context.Context, otsLookup bool) error
}
c.descriptor.Receipt = receipt

block, err := c.client.BlockByNumber(ctx, receipt.BlockNumber)
block, err := c.client.HeaderByNumber(ctx, receipt.BlockNumber)
if err != nil {
return fmt.Errorf("failed to get block by number: %s", err)
}
c.descriptor.Block = block.Header()
c.descriptor.Block = block

if len(c.descriptor.ExecutionBytecode) < 1 {
c.descriptor.ExecutionBytecode = c.descriptor.Transaction.Data()
Expand Down
6 changes: 4 additions & 2 deletions contracts/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package contracts
import (
"context"
"fmt"

"github.com/0x19/solc-switch"
hypersyncgo "github.com/enviodev/hypersync-client-go"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/unpackdev/solgo/bindings"
Expand Down Expand Up @@ -33,6 +33,7 @@ type Metadata struct {
type Contract struct {
ctx context.Context
clientPool *clients.ClientPool
hypersync *hypersyncgo.Client
client *clients.Client
addr common.Address
network utils.Network
Expand All @@ -50,7 +51,7 @@ type Contract struct {
// NewContract creates a new instance of Contract for a given Ethereum address and network.
// It initializes the contract's context, metadata, and associated blockchain clients.
// The function validates the contract's existence and its bytecode before creation.
func NewContract(ctx context.Context, network utils.Network, clientPool *clients.ClientPool, stor *storage.Storage, bqp *bitquery.Provider, etherscan *etherscan.Provider, compiler *solc.Solc, bindManager *bindings.Manager, ipfsProvider metadata.Provider, addr common.Address) (*Contract, error) {
func NewContract(ctx context.Context, network utils.Network, clientPool *clients.ClientPool, hypersync *hypersyncgo.Client, stor *storage.Storage, bqp *bitquery.Provider, etherscan *etherscan.Provider, compiler *solc.Solc, bindManager *bindings.Manager, ipfsProvider metadata.Provider, addr common.Address) (*Contract, error) {
if clientPool == nil {
return nil, fmt.Errorf("client pool is nil")
}
Expand Down Expand Up @@ -83,6 +84,7 @@ func NewContract(ctx context.Context, network utils.Network, clientPool *clients
toReturn := &Contract{
ctx: ctx,
network: network,
hypersync: hypersync,
clientPool: clientPool,
client: client,
addr: addr,
Expand Down
3 changes: 3 additions & 0 deletions envio/blocks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package envio

type Block struct{}
Loading

0 comments on commit bbaf95d

Please sign in to comment.