func TestBondTxSignable(t *testing.T) { privKeyBytes := make([]byte, 64) privAccount := acm.GenPrivAccountFromPrivKeyBytes(privKeyBytes) bondTx := &BondTx{ PubKey: privAccount.PubKey.(acm.PubKeyEd25519), Inputs: []*TxInput{ &TxInput{ Address: []byte("input1"), Amount: 12345, Sequence: 67890, }, &TxInput{ Address: []byte("input2"), Amount: 111, Sequence: 222, }, }, UnbondTo: []*TxOutput{ &TxOutput{ Address: []byte("output1"), Amount: 333, }, &TxOutput{ Address: []byte("output2"), Amount: 444, }, }, } signBytes := acm.SignBytes(chainID, bondTx) signStr := string(signBytes) expected := Fmt(`{"chain_id":"%s","tx":[17,{"inputs":[{"address":"696E70757431","amount":12345,"sequence":67890},{"address":"696E70757432","amount":111,"sequence":222}],"pub_key":[1,"3B6A27BCCEB6A42D62A3A8D02A6F0D73653215771DE243A63AC048A18B59DA29"],"unbond_to":[{"address":"6F757470757431","amount":333},{"address":"6F757470757432","amount":444}]}]}`, config.GetString("chain_id")) if signStr != expected { t.Errorf("Unexpected sign string for BondTx. \nGot %s\nExpected %s", signStr, expected) } }
func main() { // Read options privKeyHex, numAccounts, remote := parseFlags() // Print args. // fmt.Println(privKeyHex, numAccounts, remote) privKeyBytes, err := hex.DecodeString(privKeyHex) if err != nil { panic(err) } root := acm.GenPrivAccountFromPrivKeyBytes(privKeyBytes) fmt.Println("Computed address: %X", root.Address) // Get root account. rootAccount, err := getAccount(remote, root.Address) if err != nil { fmt.Println(Fmt("Root account %X does not exist: %v", root.Address, err)) return } else { fmt.Println("Root account", rootAccount) } // Load all accounts accounts := make([]*acm.Account, numAccounts+1) accounts[0] = rootAccount privAccounts := make([]*acm.PrivAccount, numAccounts+1) privAccounts[0] = root for i := 1; i < numAccounts+1; i++ { privAccounts[i] = root.Generate(i) account, err := getAccount(remote, privAccounts[i].Address) if err != nil { fmt.Println("Error", err) return } else { accounts[i] = account } } // Test: send from root to accounts[1] sendTx := makeRandomTransaction(10, rootAccount.Sequence+1, root, 2, accounts) fmt.Println(sendTx) wsClient := cclient.NewWSClient("ws://" + remote + "/websocket") _, err = wsClient.Start() if err != nil { Exit(Fmt("Failed to establish websocket connection: %v", err)) } wsClient.Subscribe(types.EventStringAccInput(sendTx.Inputs[0].Address)) go func() { for { foo := <-wsClient.EventsCh fmt.Println("!!", foo) } }() err = broadcastSendTx(remote, sendTx) if err != nil { Exit(Fmt("Failed to broadcast SendTx: %v", err)) return } // Trap signal TrapSignal(func() { fmt.Println("sim_txs shutting down") }) }
func send_tx() { // Get PrivAccount var privAccount *acm.PrivAccount secret := getString("Enter your secret, or just hit <Enter> to enter a private key in HEX.\n> ") if secret == "" { privKeyBytes := getByteSliceFromHex("Enter your private key in HEX (e.g. E353CAD81134A301A542AEBE2D2E4EF1A64A145117EC72743AE9C9D171A4AA69F3A7DD670A9E9307AAED000D97D5B3C07D90276BFCEEDA5ED11DA089A4E87A81):\n> ") privAccount = acm.GenPrivAccountFromPrivKeyBytes(privKeyBytes) } else { // Auto-detect private key hex if len(secret) == 128 { privKeyBytes, err := hex.DecodeString(secret) if err == nil { fmt.Println("Detected priv-key bytes...") privAccount = acm.GenPrivAccountFromPrivKeyBytes(privKeyBytes) } else { fmt.Println("That's a long seed...") privAccount = acm.GenPrivAccountFromSecret(secret) } } else { privAccount = acm.GenPrivAccountFromSecret(secret) } } pubKey := privAccount.PubKey // Get account data cli := cclient.NewClient("http://localhost:46657", "JSONRPC") res, err := cli.GetAccount(privAccount.Address) if err != nil { Exit(Fmt("Error fetching account: %v", err)) } if res == nil { Exit(Fmt("No account was found with that secret/private-key")) } inputAcc := res.Account fmt.Printf(` Source account: Address: %X PubKey: %v Sequence: %v Balance: %v Permissions: %v `, inputAcc.Address, pubKey, inputAcc.Sequence, inputAcc.Balance, inputAcc.Permissions) output := getByteSliceFromHex("\nEnter the output address in HEX:\n> ") amount := getInt64("Enter the amount to send:\n> ") // Construct transaction tx := types.NewSendTx() tx.AddInputWithNonce(pubKey, amount, inputAcc.Sequence+1) tx.AddOutput(output, amount) tx.Inputs[0].Signature = privAccount.Sign(config.GetString("chain_id"), tx) fmt.Println("Signed SendTx!: ", tx) // Sign up for events wsCli := cclient.NewWSClient("ws://localhost:46657/websocket") wsCli.Start() err = wsCli.Subscribe(types.EventStringAccInput(inputAcc.Address)) if err != nil { Exit(Fmt("Error subscribing to account send event: %v", err)) } // Broadcast transaction _, err = cli.BroadcastTx(tx) if err != nil { Exit(Fmt("Error broadcasting transaction: %v", err)) } fmt.Println("Waiting for confirmation...") _ = <-wsCli.EventsCh fmt.Println("Confirmed.") }