From 0613df34a269663c618290d381f9096f48657ecd Mon Sep 17 00:00:00 2001 From: Ryo Manzoku Date: Fri, 11 Jun 2021 23:20:28 +0900 Subject: [PATCH] sendEther command --- cmd/sendEther/main.go | 83 ++++++++++++++++++++++++++++--------------- go.mod | 1 + go.sum | 5 ++- utils.go | 26 ++++++++++++++ 4 files changed, 83 insertions(+), 32 deletions(-) diff --git a/cmd/sendEther/main.go b/cmd/sendEther/main.go index 52277d0..5198adf 100644 --- a/cmd/sendEther/main.go +++ b/cmd/sendEther/main.go @@ -2,65 +2,90 @@ package main import ( "context" + "flag" "fmt" - "math/big" "os" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/kms" - "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" "github.com/rmanzoku/go-awseoa/v2" + "github.com/rmanzoku/go-awseoa/v2/kmsutil" ) var ( - rpc = os.Getenv("RPC") - to = common.HexToAddress("0xd868711BD9a2C6F1548F5f4737f71DA67d821090") - keyID = os.Getenv("KEYID") + rpc = os.Getenv("RPC") + + valueEther float64 = 0 + from = "" + to = "" + gasGwei float64 = 1 ) -func main() { - ctx := context.TODO() +func handler(ctx context.Context) (err error) { cfg, err := config.LoadDefaultConfig(ctx) if err != nil { - panic(err) + return } - svc := kms.NewFromConfig(cfg) - ethcli, _ := ethclient.Dial(rpc) + fmt.Printf("Sending %f Ether from %s to %s gas: %f gwei\n", valueEther, from, to, gasGwei) + + ethcli, err := ethclient.Dial(rpc) + if err != nil { + return err + } chainID, err := ethcli.NetworkID(ctx) if err != nil { - panic(err) + return } - topts, _ := awseoa.NewKMSTransactor(svc, keyID, chainID) - topts.GasPrice, _ = new(big.Int).SetString("1000000000", 10) + if !common.IsHexAddress(from) { + return fmt.Errorf("invalid from address: %s", from) + } + svc := kms.NewFromConfig(cfg) + keyId, err := kmsutil.KeyIDFromAddress(svc, common.HexToAddress(from)) + if err != nil { + return err + } + + topts, err := awseoa.NewKMSTransactor(svc, keyId, chainID) + if err != nil { + return err + } topts.Context = context.TODO() + topts.GasPrice, err = awseoa.GweiToWei(gasGwei) + if err != nil { + return err + } + + amount, err := awseoa.EtherToWei(valueEther) + if err != nil { + return err + } - amount, _ := new(big.Int).SetString("1000000000000", 10) + if !common.IsHexAddress(to) { + return fmt.Errorf("invalid to address: %s", to) + } + toAddr := common.HexToAddress(to) - tx, err := sendEther(ethcli, topts, to, amount) + tx, err := awseoa.SendEther(ethcli, topts, toAddr, amount) if err != nil { - panic(err) + return } fmt.Println(tx.Hash().String()) + return } -func sendEther(client *ethclient.Client, transactOpts *bind.TransactOpts, to common.Address, amount *big.Int) (*types.Transaction, error) { - ctx := transactOpts.Context - nonce, err := client.NonceAt(ctx, transactOpts.From, nil) - if err != nil { - return nil, err - } - tx := types.NewTransaction(nonce, to, amount, 21000, transactOpts.GasPrice, nil) +func main() { + ctx := context.TODO() + flag.Float64Var(&valueEther, "value", valueEther, "Sending value unit Ether") + flag.StringVar(&from, "from", from, "From address") + flag.StringVar(&to, "to", to, "To address") + flag.Parse() - tx, err = transactOpts.Signer(transactOpts.From, tx) - if err != nil { - return nil, err + if err := handler(ctx); err != nil { + panic(err) } - - return tx, client.SendTransaction(transactOpts.Context, tx) } diff --git a/go.mod b/go.mod index 88fd4d9..54b027e 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/kms v1.1.1 github.com/btcsuite/btcd v0.21.0-beta // indirect github.com/ethereum/go-ethereum v1.9.25 + github.com/shopspring/decimal v1.2.0 github.com/stretchr/testify v1.4.0 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect golang.org/x/sys v0.0.0-20210218085108-9555bcde0c6a // indirect diff --git a/go.sum b/go.sum index 4751dcb..ccda720 100644 --- a/go.sum +++ b/go.sum @@ -45,7 +45,6 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxq github.com/aws/smithy-go v1.1.0 h1:D6CSsM3gdxaGaqXnPgOBCeL6Mophqzu7KJOu7zW78sU= github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6 h1:Eey/GGQ/E5Xp1P2Lyx1qj007hLZfbi0+CoVeJruGCtI= github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M= @@ -207,6 +206,8 @@ github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubr github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shirou/gopsutil v2.20.5+incompatible h1:tYH07UPoQt0OCQdgWWMgYHy3/a9bcxNpBIysykNIP7I= github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 h1:Gb2Tyox57NRNuZ2d3rmvB3pcmbu7O1RS3m8WRx7ilrg= @@ -234,7 +235,6 @@ golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= @@ -270,7 +270,6 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8 h1:AvbQYmiaaaza3cW3QXRyPo5kYgpFIzOAfeAAN7m3qQ4= golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210218085108-9555bcde0c6a h1:+Kiu2GijIw0WaCBk1i7AcqqRx8Xg3HIYaheQazXOu8w= golang.org/x/sys v0.0.0-20210218085108-9555bcde0c6a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/utils.go b/utils.go index a53c626..0a28c92 100644 --- a/utils.go +++ b/utils.go @@ -10,6 +10,8 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/params" + "github.com/shopspring/decimal" ) func recover(hash, sig []byte) (common.Address, error) { @@ -49,3 +51,27 @@ func SendEther(client *ethclient.Client, transactOpts *bind.TransactOpts, to com return tx, client.SendTransaction(ctx, tx) } + +func EtherToWei(ether float64) (*big.Int, error) { + etherDecimal := decimal.NewFromFloat(ether) + base := decimal.NewFromInt(params.Ether) + + retDecimal := etherDecimal.Mul(base).Floor() + ret, ok := new(big.Int).SetString(retDecimal.String(), 10) + if !ok { + return nil, errors.New("Invalit number " + retDecimal.String()) + } + return ret, nil +} + +func GweiToWei(gwei float64) (*big.Int, error) { + gweiDecimal := decimal.NewFromFloat(gwei) + base := decimal.NewFromInt(params.GWei) + + retDecimal := gweiDecimal.Mul(base).Floor() + ret, ok := new(big.Int).SetString(retDecimal.String(), 10) + if !ok { + return nil, errors.New("Invalit number " + retDecimal.String()) + } + return ret, nil +}