github.com/iotexproject/iotex-core@v1.14.1-rc1/tools/multisend/multisend.go (about) 1 // Copyright (c) 2019 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package main 7 8 import ( 9 "encoding/hex" 10 "encoding/json" 11 "fmt" 12 "math/big" 13 "os" 14 "strings" 15 16 "github.com/ethereum/go-ethereum/accounts/abi" 17 "github.com/ethereum/go-ethereum/common" 18 "github.com/spf13/cobra" 19 20 "github.com/iotexproject/iotex-core/pkg/util/addrutil" 21 ) 22 23 func main() { 24 if err := rootCmd.Execute(); err != nil { 25 fmt.Println(err) 26 os.Exit(1) 27 } 28 } 29 30 // rootCmd represents the base command when called without any subcommands 31 var rootCmd = &cobra.Command{ 32 Use: "multisend 'JSON_DATA'", 33 Short: "multisend bytecode generator", 34 Args: cobra.ExactArgs(1), 35 RunE: func(cmd *cobra.Command, args []string) error { 36 output, err := multiSend(args) 37 if err == nil { 38 fmt.Println(output) 39 } 40 return err 41 }, 42 } 43 44 var abiJSON = `[{"constant":false,"inputs":[{"name":"recipients","type":"address[]"}, 45 {"name":"amounts","type":"uint256[]"},{"name":"payload","type":"string"}], 46 "name":"multiSend","outputs":[],"payable":true,"stateMutability":"payable","type":"function"}, 47 {"anonymous":false,"inputs":[{"indexed":false,"name":"recipient","type":"address"}, 48 {"indexed":false,"name":"amount","type":"uint256"}],"name":"Transfer","type":"event"}, 49 {"anonymous":false,"inputs":[{"indexed":false,"name":"refund","type":"uint256"}], 50 "name":"Refund","type":"event"},{"anonymous":false, 51 "inputs":[{"indexed":false,"name":"payload","type":"string"}],"name":"Payload","type":"event"}]` 52 var abiFunc = "multiSend" 53 54 type targets struct { 55 Targets []target `json:"targets"` 56 Payload string `json:"payload"` 57 } 58 type target struct { 59 Recipient string `json:"recipient"` 60 Amount string `json:"amount"` 61 } 62 63 func multiSend(args []string) (string, error) { 64 var targetSet targets 65 if err := json.Unmarshal([]byte(args[0]), &targetSet); err != nil { 66 return "", err 67 } 68 recipients := make([]common.Address, 0) 69 amounts := make([]*big.Int, 0) 70 for _, target := range targetSet.Targets { 71 recipient, err := addrutil.IoAddrToEvmAddr(target.Recipient) 72 if err != nil { 73 return "", err 74 } 75 recipients = append(recipients, recipient) 76 amount, ok := new(big.Int).SetString(target.Amount, 10) 77 if !ok { 78 return "", fmt.Errorf("failed to convert string to big int") 79 } 80 amounts = append(amounts, amount) 81 } 82 reader := strings.NewReader(abiJSON) 83 multisendABI, err := abi.JSON(reader) 84 if err != nil { 85 return "", err 86 } 87 bytecode, err := multisendABI.Pack(abiFunc, recipients, amounts, targetSet.Payload) 88 if err != nil { 89 return "", err 90 } 91 return hex.EncodeToString(bytecode), nil 92 }