github.com/ethersphere/bee/v2@v2.2.0/pkg/settlement/swap/erc20/erc20.go (about) 1 // Copyright 2021 The Swarm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package erc20 6 7 import ( 8 "context" 9 "errors" 10 "math/big" 11 12 "github.com/ethereum/go-ethereum/accounts/abi" 13 "github.com/ethereum/go-ethereum/common" 14 "github.com/ethersphere/bee/v2/pkg/sctx" 15 "github.com/ethersphere/bee/v2/pkg/transaction" 16 "github.com/ethersphere/bee/v2/pkg/util/abiutil" 17 "github.com/ethersphere/go-sw3-abi/sw3abi" 18 ) 19 20 var ( 21 erc20ABI = abiutil.MustParseABI(sw3abi.ERC20ABIv0_6_5) 22 errDecodeABI = errors.New("could not decode abi data") 23 ) 24 25 type Service interface { 26 BalanceOf(ctx context.Context, address common.Address) (*big.Int, error) 27 Transfer(ctx context.Context, address common.Address, value *big.Int) (common.Hash, error) 28 } 29 30 type erc20Service struct { 31 transactionService transaction.Service 32 address common.Address 33 } 34 35 func New(transactionService transaction.Service, address common.Address) Service { 36 return &erc20Service{ 37 transactionService: transactionService, 38 address: address, 39 } 40 } 41 42 func (c *erc20Service) BalanceOf(ctx context.Context, address common.Address) (*big.Int, error) { 43 callData, err := erc20ABI.Pack("balanceOf", address) 44 if err != nil { 45 return nil, err 46 } 47 48 output, err := c.transactionService.Call(ctx, &transaction.TxRequest{ 49 To: &c.address, 50 Data: callData, 51 }) 52 if err != nil { 53 return nil, err 54 } 55 56 results, err := erc20ABI.Unpack("balanceOf", output) 57 if err != nil { 58 return nil, err 59 } 60 61 if len(results) != 1 { 62 return nil, errDecodeABI 63 } 64 65 balance, ok := abi.ConvertType(results[0], new(big.Int)).(*big.Int) 66 if !ok || balance == nil { 67 return nil, errDecodeABI 68 } 69 return balance, nil 70 } 71 72 func (c *erc20Service) Transfer(ctx context.Context, address common.Address, value *big.Int) (common.Hash, error) { 73 callData, err := erc20ABI.Pack("transfer", address, value) 74 if err != nil { 75 return common.Hash{}, err 76 } 77 78 request := &transaction.TxRequest{ 79 To: &c.address, 80 Data: callData, 81 GasPrice: sctx.GetGasPrice(ctx), 82 GasLimit: 90000, 83 Value: big.NewInt(0), 84 Description: "token transfer", 85 } 86 87 txHash, err := c.transactionService.Send(ctx, request, transaction.DefaultTipBoostPercent) 88 if err != nil { 89 return common.Hash{}, err 90 } 91 92 return txHash, nil 93 }