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

refactor: contract pack and call #775

Merged
merged 2 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 2 additions & 1 deletion app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import (
feemarkettypes "github.com/evmos/ethermint/x/feemarket/types"
"github.com/spf13/cast"

"github.com/functionx/fx-core/v8/contract"
fxtypes "github.com/functionx/fx-core/v8/types"
arbitrumtypes "github.com/functionx/fx-core/v8/x/arbitrum/types"
avalanchetypes "github.com/functionx/fx-core/v8/x/avalanche/types"
Expand Down Expand Up @@ -362,7 +363,7 @@ func NewAppKeeper(
appKeepers.AccountKeeper,
appKeepers.BankKeeper,
appKeepers.EvmKeeper,
appKeepers.EvmKeeper,
contract.NewERC20TokenKeeper(appKeepers.EvmKeeper),
authAddr,
)

Expand Down
8 changes: 3 additions & 5 deletions cmd/delegate.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,16 +141,14 @@ func queryContractBalance(myApp *app.App, ctx sdk.Context, contractAddr, address
if contract.IsZeroEthAddress(contractAddr) {
return
}

var balanceRes struct{ Value *big.Int }
err := myApp.EvmKeeper.QueryContract(ctx, contractAddr, contractAddr, contract.GetFIP20().ABI, "balanceOf", &balanceRes, address)
balance, err := contract.NewERC20TokenKeeper(myApp.EvmKeeper).BalanceOf(ctx, contractAddr, address)
if err != nil {
panic(err)
}
if balanceRes.Value.Cmp(big.NewInt(0)) == 0 {
if balance.Cmp(big.NewInt(0)) == 0 {
return
}
holders[address.Hex()] = sdkmath.NewIntFromBigInt(balanceRes.Value)
holders[address.Hex()] = sdkmath.NewIntFromBigInt(balance)
}

func buildApp(db dbm.DB, height int64) (*app.App, sdk.Context, error) {
Expand Down
File renamed without changes.
File renamed without changes.
100 changes: 79 additions & 21 deletions contract/contract.go

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions x/crosschain/types/abi_test.go → contract/contract_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package types_test
package contract_test

import (
"encoding/hex"
Expand All @@ -8,7 +8,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"

"github.com/functionx/fx-core/v8/x/crosschain/types"
"github.com/functionx/fx-core/v8/contract"
)

func TestPackBridgeCallback(t *testing.T) {
Expand Down Expand Up @@ -52,7 +52,7 @@ func TestPackBridgeCallback(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := types.PackBridgeCallback(tt.args.sender, tt.args.receiver, tt.args._tokens, tt.args._amounts, tt.args.data, tt.args.memo)
result, err := contract.PackBridgeCallback(tt.args.sender, tt.args.receiver, tt.args._tokens, tt.args._amounts, tt.args.data, tt.args.memo)
if tt.err != nil {
require.Error(t, err)
require.EqualValues(t, tt.err.Error(), err.Error())
Expand Down
121 changes: 31 additions & 90 deletions contract/erc20.go → contract/erc20_abi.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
package contract

import (
"errors"
"fmt"
"math/big"

"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
)

type ERC20ABI struct {
ABI abi.ABI
abi abi.ABI
}

func NewERC20ABI() ERC20ABI {
return ERC20ABI{
ABI: GetWFX().ABI,
abi: GetWFX().ABI,
}
}

func (e ERC20ABI) PackName() (data []byte, err error) {
data, err = e.ABI.Pack("name")
data, err = e.abi.Pack("name")
if err != nil {
return nil, fmt.Errorf("pack name: %s", err.Error())
}
Expand All @@ -30,14 +28,14 @@ func (e ERC20ABI) PackName() (data []byte, err error) {

func (e ERC20ABI) UnpackName(ret []byte) (string, error) {
var unpackedRet struct{ Value string }
if err := e.ABI.UnpackIntoInterface(&unpackedRet, "name", ret); err != nil {
if err := e.abi.UnpackIntoInterface(&unpackedRet, "name", ret); err != nil {
return "", fmt.Errorf("unpack name: %s", err.Error())
}
return unpackedRet.Value, nil
}

func (e ERC20ABI) PackSymbol() (data []byte, err error) {
data, err = e.ABI.Pack("symbol")
data, err = e.abi.Pack("symbol")
if err != nil {
return nil, fmt.Errorf("pack symbol: %s", err.Error())
}
Expand All @@ -46,14 +44,14 @@ func (e ERC20ABI) PackSymbol() (data []byte, err error) {

func (e ERC20ABI) UnpackSymbol(ret []byte) (string, error) {
var unpackedRet struct{ Value string }
if err := e.ABI.UnpackIntoInterface(&unpackedRet, "symbol", ret); err != nil {
if err := e.abi.UnpackIntoInterface(&unpackedRet, "symbol", ret); err != nil {
return "", fmt.Errorf("unpack symbol: %s", err.Error())
}
return unpackedRet.Value, nil
}

func (e ERC20ABI) PackDecimals() (data []byte, err error) {
data, err = e.ABI.Pack("decimals")
data, err = e.abi.Pack("decimals")
if err != nil {
return nil, fmt.Errorf("pack decimals: %s", err.Error())
}
Expand All @@ -62,14 +60,14 @@ func (e ERC20ABI) PackDecimals() (data []byte, err error) {

func (e ERC20ABI) UnpackDecimals(ret []byte) (uint8, error) {
var unpackedRet struct{ Value uint8 }
if err := e.ABI.UnpackIntoInterface(&unpackedRet, "decimals", ret); err != nil {
if err := e.abi.UnpackIntoInterface(&unpackedRet, "decimals", ret); err != nil {
return 0, fmt.Errorf("unpack decimals: %s", err.Error())
}
return unpackedRet.Value, nil
}

func (e ERC20ABI) PackBalanceOf(account common.Address) (data []byte, err error) {
data, err = e.ABI.Pack("balanceOf", account)
data, err = e.abi.Pack("balanceOf", account)
if err != nil {
return nil, fmt.Errorf("pack balanceOf: %s", err.Error())
}
Expand All @@ -78,14 +76,14 @@ func (e ERC20ABI) PackBalanceOf(account common.Address) (data []byte, err error)

func (e ERC20ABI) UnpackBalanceOf(ret []byte) (*big.Int, error) {
var unpackedRet struct{ Value *big.Int }
if err := e.ABI.UnpackIntoInterface(&unpackedRet, "balanceOf", ret); err != nil {
if err := e.abi.UnpackIntoInterface(&unpackedRet, "balanceOf", ret); err != nil {
return nil, fmt.Errorf("unpack balanceOf: %s", err.Error())
}
return unpackedRet.Value, nil
}

func (e ERC20ABI) PackTotalSupply() (data []byte, err error) {
data, err = e.ABI.Pack("totalSupply")
data, err = e.abi.Pack("totalSupply")
if err != nil {
return nil, fmt.Errorf("pack totalSupply: %s", err.Error())
}
Expand All @@ -94,30 +92,30 @@ func (e ERC20ABI) PackTotalSupply() (data []byte, err error) {

func (e ERC20ABI) UnpackTotalSupply(ret []byte) (*big.Int, error) {
var unpackedRet struct{ Value *big.Int }
if err := e.ABI.UnpackIntoInterface(&unpackedRet, "totalSupply", ret); err != nil {
if err := e.abi.UnpackIntoInterface(&unpackedRet, "totalSupply", ret); err != nil {
return nil, fmt.Errorf("unpack totalSupply: %s", err.Error())
}
return unpackedRet.Value, nil
}

func (e ERC20ABI) PackApprove(spender common.Address, amount *big.Int) (data []byte, err error) {
data, err = e.ABI.Pack("approve", spender, amount)
data, err = e.abi.Pack("approve", spender, amount)
if err != nil {
return nil, fmt.Errorf("pack approve: %s", err.Error())
}
return data, err
}

func (e ERC20ABI) PackAllowance(owner, spender common.Address) (data []byte, err error) {
data, err = e.ABI.Pack("allowance", owner, spender)
data, err = e.abi.Pack("allowance", owner, spender)
if err != nil {
return nil, fmt.Errorf("pack allowance: %s", err.Error())
}
return data, err
}

func (e ERC20ABI) PackTransferFrom(sender, to common.Address, amount *big.Int) (data []byte, err error) {
data, err = e.ABI.Pack("transferFrom", sender, to, amount)
data, err = e.abi.Pack("transferFrom", sender, to, amount)
if err != nil {
return nil, fmt.Errorf("pack transferFrom: %s", err.Error())
}
Expand All @@ -126,113 +124,56 @@ func (e ERC20ABI) PackTransferFrom(sender, to common.Address, amount *big.Int) (

func (e ERC20ABI) UnpackTransferFrom(ret []byte) (bool, error) {
var unpackedRet struct{ Value bool }
if err := e.ABI.UnpackIntoInterface(&unpackedRet, "transferFrom", ret); err != nil {
if err := e.abi.UnpackIntoInterface(&unpackedRet, "transferFrom", ret); err != nil {
return false, fmt.Errorf("unpack transferFrom: %s", err.Error())
}
return unpackedRet.Value, nil
}

func (e ERC20ABI) PackTransfer(to common.Address, amount *big.Int) (data []byte, err error) {
data, err = e.ABI.Pack("transfer", to, amount)
data, err = e.abi.Pack("transfer", to, amount)
if err != nil {
return nil, fmt.Errorf("pack transfer: %s", err.Error())
}
return data, err
}

func (e ERC20ABI) PackBurn(account common.Address, amount *big.Int) (data []byte, err error) {
data, err = e.ABI.Pack("burn", account, amount)
data, err = e.abi.Pack("burn", account, amount)
if err != nil {
return nil, fmt.Errorf("pack burn: %s", err.Error())
}
return data, err
}

func (e ERC20ABI) PackMint(account common.Address, amount *big.Int) (data []byte, err error) {
data, err = e.ABI.Pack("mint", account, amount)
data, err = e.abi.Pack("mint", account, amount)
if err != nil {
return nil, fmt.Errorf("pack mint: %s", err.Error())
}
return data, err
}

type ERC20Call struct {
ERC20ABI
evm *vm.EVM
caller vm.AccountRef
contract common.Address
maxGas uint64
}

func NewERC20Call(evm *vm.EVM, caller, contract common.Address, maxGas uint64) *ERC20Call {
defMaxGas := DefaultGasCap
if maxGas > 0 {
defMaxGas = maxGas
}
return &ERC20Call{
ERC20ABI: NewERC20ABI(),
evm: evm,
caller: vm.AccountRef(caller),
contract: contract,
maxGas: defMaxGas,
}
}

func (e *ERC20Call) call(data []byte) (ret []byte, err error) {
ret, _, err = e.evm.Call(e.caller, e.contract, data, e.maxGas, big.NewInt(0))
if err != nil {
return nil, err
}
return ret, err
}

func (e *ERC20Call) staticCall(data []byte) (ret []byte, err error) {
ret, _, err = e.evm.StaticCall(e.caller, e.contract, data, e.maxGas)
if err != nil {
return nil, err
}
return ret, err
}

func (e *ERC20Call) Burn(account common.Address, amount *big.Int) error {
data, err := e.ERC20ABI.PackBurn(account, amount)
if err != nil {
return err
}
_, err = e.call(data)
func (e ERC20ABI) PackDeposit() (data []byte, err error) {
data, err = e.abi.Pack("deposit")
if err != nil {
return fmt.Errorf("call burn: %s", err.Error())
return nil, fmt.Errorf("pack deposit: %s", err.Error())
}
return nil
return data, err
}

func (e *ERC20Call) TransferFrom(from, to common.Address, amount *big.Int) error {
data, err := e.ERC20ABI.PackTransferFrom(from, to, amount)
func (e ERC20ABI) PackWithdraw(recipient common.Address, amount *big.Int) (data []byte, err error) {
data, err = e.abi.Pack("withdraw0", recipient, amount)
if err != nil {
return err
return nil, fmt.Errorf("pack withdraw: %s", err.Error())
}
ret, err := e.call(data)
if err != nil {
return fmt.Errorf("call transferFrom: %s", err.Error())
}
isSuccess, err := e.UnpackTransferFrom(ret)
if err != nil {
return err
}
if !isSuccess {
return errors.New("transferFrom failed")
}
return nil
return data, err
}

func (e *ERC20Call) TotalSupply() (*big.Int, error) {
data, err := e.ERC20ABI.PackTotalSupply()
func (e ERC20ABI) PackTransferOwnership(newOwner common.Address) (data []byte, err error) {
data, err = e.abi.Pack("transferOwnership", newOwner)
if err != nil {
return nil, err
return nil, fmt.Errorf("pack transferOwnership: %s", err.Error())
}
ret, err := e.staticCall(data)
if err != nil {
return nil, fmt.Errorf("StaticCall totalSupply: %s", err.Error())
}
return e.ERC20ABI.UnpackTotalSupply(ret)
return data, err
}
Loading