Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wip] modify ContractQuery func, breaking change #96

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions ethcoder/abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,16 @@ func AbiDecodeExprAndStringify(expr string, input []byte) ([]string, error) {
return AbiMarshalStringValues(argTypes, input)
}

func AbiDecodeExprToInterfaces(expr string, input []byte) ([]interface{}, error) {
argsList := parseArgumentExpr(expr)
argTypes := []string{}
for _, v := range argsList {
argTypes = append(argTypes, v.Type)
}

return AbiDecoderWithReturnedValues(argTypes, input)
}

func AbiMarshalStringValues(argTypes []string, input []byte) ([]string, error) {
values, err := AbiDecoderWithReturnedValues(argTypes, input)
if err != nil {
Expand Down
21 changes: 16 additions & 5 deletions ethrpc/ens.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,25 +50,36 @@ func ResolveEnsAddress(ctx context.Context, ens string, provider *Provider) (com
return common.Address{}, false, fmt.Errorf("ethrpc: failed to generate namehash: %w", err)
}

resolverAddress, err := provider.contractQuery(ctx, ENSContractAddress, "resolver(bytes32)", "address", []interface{}{namehash})
res, err := provider.contractQuery(ctx, ENSContractAddress, "resolver(bytes32)", "address", []interface{}{namehash})
if err != nil {
return common.Address{}, false, fmt.Errorf("ethrpc: failed to query resolver address: %w", err)
}

if len(resolverAddress) < 1 || (resolverAddress[0] == common.Address{}.Hex()) {
if len(res) < 1 {
return common.Address{}, false, nil
}

contractAddress, err := provider.contractQuery(ctx, resolverAddress[0], "addr(bytes32)", "address", []interface{}{namehash})
resolverAddress, ok := res[0].(common.Address)
if !ok || resolverAddress.Hex() == (common.Address{}).Hex() {
return common.Address{}, false, nil
}

res, err = provider.contractQuery(ctx, resolverAddress.Hex(), "addr(bytes32)", "address", []interface{}{namehash})
if err != nil {
return common.Address{}, false, fmt.Errorf("ethrpc: failed to query resolver address: %w", err)
}

if len(contractAddress) < 1 {
if len(res) < 1 {
return common.Address{}, false, nil
}

contractAddress, ok := res[0].(common.Address)

if !ok || contractAddress.Hex() == (common.Address{}).Hex() {
return common.Address{}, false, nil
}

return common.HexToAddress(contractAddress[0]), true, nil
return contractAddress, true, nil
}

// NameHash generates a hash from a name that can be used to
Expand Down
6 changes: 3 additions & 3 deletions ethrpc/ethrpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ func (p *Provider) SubscribeFilterLogs(ctx context.Context, query ethereum.Filte

// ie, ContractQuery(context.Background(), "0xabcdef..", "balanceOf(uint256)", "uint256", []string{"1"})
// TODO: add common methods in helpers util, and also use generics to convert the return for us
func (p *Provider) ContractQuery(ctx context.Context, contractAddress string, inputAbiExpr, outputAbiExpr string, args interface{}) ([]string, error) {
func (p *Provider) ContractQuery(ctx context.Context, contractAddress string, inputAbiExpr, outputAbiExpr string, args interface{}) ([]interface{}, error) {
if !common.IsHexAddress(contractAddress) {
// Check for ens
ensAddress, ok, err := ResolveEnsAddress(ctx, contractAddress, p)
Expand All @@ -405,7 +405,7 @@ func (p *Provider) ContractQuery(ctx context.Context, contractAddress string, in
return p.contractQuery(ctx, contractAddress, inputAbiExpr, outputAbiExpr, args)
}

func (p *Provider) contractQuery(ctx context.Context, contractAddress string, inputAbiExpr, outputAbiExpr string, args interface{}) ([]string, error) {
func (p *Provider) contractQuery(ctx context.Context, contractAddress string, inputAbiExpr, outputAbiExpr string, args interface{}) ([]interface{}, error) {
contract := common.HexToAddress(contractAddress)

var (
Expand Down Expand Up @@ -441,7 +441,7 @@ func (p *Provider) contractQuery(ctx context.Context, contractAddress string, in
if err != nil {
return nil, fmt.Errorf("contract call failed: %w", err)
}
resp, err := ethcoder.AbiDecodeExprAndStringify(outputAbiExpr, output)
resp, err := ethcoder.AbiDecodeExprToInterfaces(outputAbiExpr, output)
if err != nil {
return nil, fmt.Errorf("abi decode of response failed: %w", err)
}
Expand Down
17 changes: 10 additions & 7 deletions ethrpc/ethrpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,12 @@ func TestERC20MintAndTransfer(t *testing.T) {
require.NotNil(t, receipt)

// Query erc20Mock balance to confirm
ret, err := provider.ContractQuery(ctx, erc20Mock.Address.Hex(), "balanceOf(address)", "uint256", []string{wallet.Address().Hex()})
res, err := provider.ContractQuery(ctx, erc20Mock.Address.Hex(), "balanceOf(address)", "uint256", []string{wallet.Address().Hex()})
require.NoError(t, err)
require.Equal(t, 1, len(ret))
require.Equal(t, "2000", ret[0])
require.Equal(t, 1, len(res))
ret, ok := res[0].(*big.Int)
require.True(t, ok)
require.Equal(t, "2000", ret.String())

// Transfer token to another wallet
wallet2, _ := testchain.DummyWallet(600)
Expand All @@ -74,11 +76,12 @@ func TestERC20MintAndTransfer(t *testing.T) {
txn, receipt = ethtest.SendTransactionAndWaitForReceipt(t, wallet, erc20Mock.Address, calldata, nil)
require.NotNil(t, txn)
require.NotNil(t, receipt)

ret, err = provider.ContractQuery(ctx, erc20Mock.Address.Hex(), "balanceOf(address)", "uint256", []string{wallet2.Address().Hex()})
res, err = provider.ContractQuery(ctx, erc20Mock.Address.Hex(), "balanceOf(address)", "uint256", []string{wallet2.Address().Hex()})
require.NoError(t, err)
require.Equal(t, 1, len(ret))
require.Equal(t, "42", ret[0])
require.Equal(t, 1, len(res))
ret, ok = res[0].(*big.Int)
require.True(t, ok)
require.Equal(t, "42", ret.String())
}

func TestBlockByNumber(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion ethtest/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func ContractCall(provider *ethrpc.Provider, contractAddress common.Address, con
return output, nil
}

func ContractQuery(provider *ethrpc.Provider, contractAddress common.Address, inputExpr, outputExpr string, args []string) ([]string, error) {
func ContractQuery(provider *ethrpc.Provider, contractAddress common.Address, inputExpr, outputExpr string, args []string) ([]interface{}, error) {
return provider.ContractQuery(context.Background(), contractAddress.Hex(), inputExpr, outputExpr, args)
}

Expand Down
9 changes: 6 additions & 3 deletions ethtest/erc20.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,11 @@ func (c *ERC20Mock) Transfer(t *testing.T, owner *ethwallet.Wallet, to ethkit.Ad
func (c *ERC20Mock) GetBalance(t *testing.T, account ethkit.Address, expectedAmount int64) {
provider := c.testchain.Provider

ret, err := provider.ContractQuery(context.Background(), c.Contract.Address.Hex(), "balanceOf(address)", "uint256", []string{account.Hex()})
res, err := provider.ContractQuery(context.Background(), c.Contract.Address.Hex(), "balanceOf(address)", "uint256", []string{account.Hex()})
require.NoError(t, err)
require.Equal(t, 1, len(ret))
require.Equal(t, fmt.Sprintf("%d", expectedAmount), ret[0])
require.NotEmpty(t, res)
ret, ok := res[0].(*big.Int)
require.True(t, ok)
require.NotEqual(t, big.NewInt(0), ret)
require.Equal(t, fmt.Sprintf("%d", expectedAmount), ret.String())
}
7 changes: 5 additions & 2 deletions ethtest/testchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,12 @@ func TestContractHelpers(t *testing.T) {
assert.Equal(t, types.ReceiptStatusSuccessful, receipt.Status)

// Query the value ensuring its been updated on-chain
ret, err := ethtest.ContractQuery(testchain.Provider, callmockContract.Address, "lastValA()", "uint256", nil)
res, err := ethtest.ContractQuery(testchain.Provider, callmockContract.Address, "lastValA()", "uint256", nil)
assert.NoError(t, err)
assert.Equal(t, []string{"143"}, ret)
assert.Equal(t, 1, len(res))
ret, ok := res[0].(*big.Int)
assert.True(t, ok)
assert.Equal(t, "143", ret.String())

// Query the value using different method, where we unpack the value
var result *big.Int
Expand Down