使用sdk对algorand区块链进行交易、建立账户等基本操作
可以选用python、js、java、go语言的sdk,我这里使用的是go-sdk,所以我下面执行的主程序都是在go-algorand-sdk环境下运行的
package main
import (
"fmt"
"github.com/algorand/go-algorand-sdk/crypto"
"github.com/algorand/go-algorand-sdk/mnemonic"
)
func main() {
account := crypto.GenerateAccount()
passphrase, err := mnemonic.FromPrivateKey(account.PrivateKey)
if err != nil {
fmt.Printf("Error creating transaction: %s\n", err)
} else {
fmt.Printf("My address: %s\n", account.Address)
fmt.Printf("My passphrase: %s\n", passphrase)
}
}
```输出
My address: DRQLINNRAGANYEVK5BCYVTOERMBV7LQU3ZYFGACA3XCX3AB24H7OKCZ7AM
My passphrase: essay broccoli sunset upon midnight hope paper picnic choice pulp chalk fluid they plug scan coffee curious around yellow depart feel bacon matter above differ
- 查询账户余额:(执行前请在此为账户添加资金)增加资金
package main
import (
"context"
"crypto/ed25519"
"fmt"
"github.com/algorand/go-algorand-sdk/client/v2/algod"
"github.com/algorand/go-algorand-sdk/mnemonic"
"github.com/algorand/go-algorand-sdk/types"
)
const algodAddress = "http://127.0.0.1:8080"
const algodToken = "adaad27f70e451e97d0fbbbbe2095220e8798099fe69252e88e51db11d0cd97c"
func main() {
algodClient, err := algod.MakeClient(algodAddress, algodToken)
if err != nil {
fmt.Printf("Issue with creating algod client: %s\n", err)
return
}
passphrase := "essay broccoli sunset upon midnight hope paper picnic choice pulp chalk fluid they plug scan coffee curious around yellow depart feel bacon matter above differ"
privateKey, err := mnemonic.ToPrivateKey(passphrase)
if err != nil {
fmt.Printf("Issue with mnemonic conversion: %s\n", err)
return
}
var myAddress types.Address
publicKey := privateKey.Public()
cpk := publicKey.(ed25519.PublicKey)
copy(myAddress[:], cpk[:])
fmt.Printf("My address: %s\n", myAddress.String())
accountInfo, err := algodClient.AccountInformation(myAddress.String()).Do(context.Background())
if err != nil {
fmt.Printf("Error getting account info: %s\n", err)
return
}
fmt.Printf("Account balance: %d microAlgos\n", accountInfo.Amount)
}
输出:
My address: DRQLINNRAGANYEVK5BCYVTOERMBV7LQU3ZYFGACA3XCX3AB24H7OKCZ7AM
Account balance: 10000000 microAlgos
- 进行你的第一笔交易:
package main
import (
"context"
"github.com/algorand/go-algorand-sdk/mnemonic"
//"crypto/ed25519"
"encoding/json"
"fmt"
"github.com/algorand/go-algorand-sdk/client/v2/algod"
"github.com/algorand/go-algorand-sdk/crypto"
//"github.com/algorand/go-algorand-sdk/mnemonic"
"github.com/algorand/go-algorand-sdk/transaction"
//"github.com/algorand/go-algorand-sdk/types"
)
const algodAddress = "http://127.0.0.1:8080"
const algodToken = "adaad27f70e451e97d0fbbbbe2095220e8798099fe69252e88e51db11d0cd97c"
// Function that waits for a given txId to be confirmed by the network
func waitForConfirmation(txID string, client *algod.Client) {
status, err := client.Status().Do(context.Background())
if err != nil {
fmt.Printf("error getting algod status: %s\n", err)
return
}
lastRound := status.LastRound
for {
pt, _, err := client.PendingTransactionInformation(txID).Do(context.Background())
if err != nil {
fmt.Printf("error getting pending transaction: %s\n", err)
return
}
if pt.ConfirmedRound > 0 {
fmt.Printf("Transaction "+txID+" confirmed in round %d\n", pt.ConfirmedRound)
break
}
fmt.Printf("waiting for confirmation\n")
lastRound++
status, err = client.StatusAfterBlock(lastRound).Do(context.Background())
}
}
func main() {
algodClient, err := algod.MakeClient(algodAddress, algodToken)
if err != nil {
fmt.Printf("Issue with creating algod client: %s\n", err)
return
}
passphrase := "essay broccoli sunset upon midnight hope paper picnic choice pulp chalk fluid they plug scan coffee curious around yellow depart feel bacon matter above differ"
privateKey, err := mnemonic.ToPrivateKey(passphrase)
if err != nil {
fmt.Printf("Issue with mnemonic conversion: %s\n", err)
return
}
/* var myAddress types.Address
publicKey := privateKey.Public()
cpk := publicKey.(ed25519.PublicKey)
copy(myAddress[:], cpk[:])
fmt.Printf("My address: %s\n", myAddress.String())
*/
// Construct the transaction
*/ txParams, err := algodClient.SuggestedParams().Do(context.Background())
if err != nil {
fmt.Printf("Error getting suggested tx params: %s\n", err)
return
}
// comment out the next two (2) lines to use suggested fees
txParams.FlatFee = true
txParams.Fee = 1000
fromAddr := "DRQLINNRAGANYEVK5BCYVTOERMBV7LQU3ZYFGACA3XCX3AB24H7OKCZ7AM"
toAddr := "GD64YIY3TWGDMCNPP553DZPPR6LDUSFQOIJVFDPPXWEG3FVOJCCDBBHU5A"
var amount uint64 = 1000000
var minFee uint64 = 1000
note := []byte("Hello World")
genID := txParams.GenesisID
genHash := txParams.GenesisHash
firstValidRound := uint64(txParams.FirstRoundValid)
lastValidRound := uint64(txParams.LastRoundValid)
txn, err := transaction.MakePaymentTxnWithFlatFee(fromAddr, toAddr, minFee, amount, firstValidRound, lastValidRound, note, "", genID, genHash)
if err != nil {
fmt.Printf("Error creating transaction: %s\n", err)
return
}
// Sign the transaction
txID, signedTxn, err := crypto.SignTransaction(privateKey, txn)
if err != nil {
fmt.Printf("Failed to sign transaction: %s\n", err)
return
}
fmt.Printf("Signed txid: %s\n", txID)
// Submit the transaction
sendResponse, err := algodClient.SendRawTransaction(signedTxn).Do(context.Background())
if err != nil {
fmt.Printf("failed to send transaction: %s\n", err)
return
}
fmt.Printf("Submitted transaction %s\n", sendResponse)
// Wait for confirmation
waitForConfirmation(txID, algodClient)
// Read transaction
confirmedTxn, stxn, err := algodClient.PendingTransactionInformation(txID).Do(context.Background())
if err != nil {
fmt.Printf("Error retrieving transaction %s\n", txID)
return
}
txnJSON, err := json.MarshalIndent(confirmedTxn.Transaction.Txn, "", "\t")
if err != nil {
fmt.Printf("Can not marshall txn data: %s\n", err)
}
fmt.Printf("Transaction information: %s\n", txnJSON)
fmt.Printf("Decoded note: %s\n", string(stxn.Txn.Note))
}
输出:
Signed txid: OHNIWTIUCRZBGIPDRJCPX7M36SUNDSA5OMEFLUHZQICABKYGRAZA
Submitted transaction OHNIWTIUCRZBGIPDRJCPX7M36SUNDSA5OMEFLUHZQICABKYGRAZA
waiting for confirmation
Transaction OHNIWTIUCRZBGIPDRJCPX7M36SUNDSA5OMEFLUHZQICABKYGRAZA confirmed in round 13343745
Transaction information: {
"Type": "pay",
"Sender": [
28,96,180,53,177,1,128,220,18,170,232,69,138,205,196,139,3,95,174,20,222,112,83,0,64,221,197,125,128,58,225,254
],
"Fee": 1000,
"FirstValid": 13343743,
"LastValid": 13344743,
"Note": "SGVsbG8gV29ybGQ=",
"GenesisID": "testnet-v1.0",
"GenesisHash": [
72,99,181,24,164,179,200,78,200,16,242,45,79,16,129,203,15,113,240, 89,167,172,32,222,198,47,127,112,229,9,58,34
],
...
进行一笔多重签名交易:
package main
import (
"fmt"
"github.com/algorand/go-algorand-sdk/client/algod"
"github.com/algorand/go-algorand-sdk/crypto"
"github.com/algorand/go-algorand-sdk/transaction"
"github.com/algorand/go-algorand-sdk/types"
)
// Change these values for your own algod.token and algod.net values
const algodAddress = "http://127.0.0.1:8080"
const algodToken = "adaad27f70e451e97d0fbbbbe2095220e8798099fe69252e88e51db11d0cd97c"
func main() {
// Initialize an algodClient
algodClient, err := algod.MakeClient(algodAddress, algodToken)
if err != nil {
fmt.Printf("failed to make algod client: %v\n", err)
return
}
txParams, err := algodClient.SuggestedParams()
if err != nil {
fmt.Printf("error getting suggested tx params: %s\n", err)
return
}
// Generate Accounts
acct1 := crypto.GenerateAccount()
acct2 := crypto.GenerateAccount()
acct3 := crypto.GenerateAccount()
// Decode the account addresses
addr1, _ := types.DecodeAddress(acct1.Address.String())
addr2, _ := types.DecodeAddress(acct2.Address.String())
addr3, _ := types.DecodeAddress(acct3.Address.String())
ma, err := crypto.MultisigAccountWithParams(1, 2, []types.Address{
addr1,
addr2,
addr3,
})
if err != nil {
panic("invalid multisig parameters")
}
// declare txn parameters
fee := txParams.Fee
firstRound := txParams.LastRound
lastRound := txParams.LastRound + 1000
genesisID := txParams.GenesisID // replace me
genesisHash := txParams.GenesisHash // replace me
const amount1 = 2000
const amount2 = 1500
var note []byte
closeRemainderTo := ""
fromAddr, _ := ma.Address()
toAddr := "GD64YIY3TWGDMCNPP553DZPPR6LDUSFQOIJVFDPPXWEG3FVOJCCDBBHU5A"
// Create the transaction
txn, err := transaction.MakePaymentTxn(fromAddr.String(), toAddr, fee, amount1, firstRound, lastRound, note, closeRemainderTo, genesisID, genesisHash)
// First signature on PST
txid, preStxBytes, err := crypto.SignMultisigTransaction(acct1.PrivateKey, ma, txn)
if err != nil {
panic("could not sign multisig transaction")
}
fmt.Printf("Made partially-signed multisig transaction with TxID %s \n", txid)
// Second signature on PST
txid2, stxBytes, err := crypto.AppendMultisigTransaction(acct2.PrivateKey, ma, preStxBytes)
if err != nil {
panic("could not sign multisig transaction")
}
fmt.Printf("Made partially-signed multisig transaction with TxID %s \n", txid2)
// Print multisig account
fmt.Printf("Here is your multisig address : %s \n", fromAddr)
fmt.Println("Please go to: https://bank.testnet.algorand.network/ to fund your multisig account.")
fmt.Scanln() // wait for Enter Key
// Send transaction to the network
sendResponse, err := algodClient.SendRawTransaction(stxBytes)
if err != nil {
fmt.Printf("Failed to create payment transaction: %v\n", err)
return
}
fmt.Printf("Transaction ID: %s\n", sendResponse.TxID)
}
输出:
Made partially-signed multisig transaction with TxID SGFLXVNYM3RXY6FAXH54QLPFY4YXJJYG3SA73MU7GOI5AX6745SQ
Made partially-signed multisig transaction with TxID SGFLXVNYM3RXY6FAXH54QLPFY4YXJJYG3SA73MU7GOI5AX6745SQ
Here is your multisig address : FFNL2YUDFP5X253RGPDQ7X4MWL77MM7XS6SGXA7BNUZ6P3IPCYBARIIXYU
Please go to: https://bank.testnet.algorand.network/ to fund your multisig account.
//注意这里需要跳转到上述网站分发资金后,回到IDE按回车才会输出交易ID
Transaction ID: SGFLXVNYM3RXY6FAXH54QLPFY4YXJJYG3SA73MU7GOI5AX6745SQ
Process finished with exit code 0
- (未)签名交易保存到文件中:-这里将两项操作合并到一个文件中,执行时注意区分
package main
import (
"fmt"
"io/ioutil"
"golang.org/x/crypto/ed25519"
"github.com/algorand/go-algorand-sdk/client/algod"
"github.com/algorand/go-algorand-sdk/crypto"
"github.com/algorand/go-algorand-sdk/mnemonic"
"github.com/algorand/go-algorand-sdk/transaction"
"github.com/algorand/go-algorand-sdk/types"
)
// Function that waits for a given txId to be confirmed by the network
func waitForConfirmation(algodClient algod.Client, txID string) {
for {
pt, err := algodClient.PendingTransactionInformation(txID)
if err != nil {
fmt.Printf("waiting for confirmation... (pool error, if any): %s\n", err)
continue
}
if pt.ConfirmedRound > 0 {
fmt.Printf("Transaction "+pt.TxID+" confirmed in round %d\n", pt.ConfirmedRound)
break
}
nodeStatus, err := algodClient.Status()
if err != nil {
fmt.Printf("error getting algod status: %s\n", err)
return
}
algodClient.StatusAfterBlock( nodeStatus.LastRound + 1)
}
}
// utility function to recover account and return sk and address
func recoverAccount()(string, ed25519.PrivateKey) {
const passphrase = "essay broccoli sunset upon midnight hope paper picnic choice pulp chalk fluid they plug scan coffee curious around yellow depart feel bacon matter above differ"
sk, err := mnemonic.ToPrivateKey(passphrase)
if err != nil {
fmt.Printf("error recovering account: %s\n", err)
return "", nil
}
pk := sk.Public()
var a types.Address
cpk := pk.(ed25519.PublicKey)
copy(a[:], cpk[:])
fmt.Printf("Address: %s\n", a.String())
address := a.String()
return address, sk
}
// utility funciton to setup connection to node
func setupConnection()( algod.Client ){
const algodAddress = "http://127.0.0.1:8080"
const algodToken = "adaad27f70e451e97d0fbbbbe2095220e8798099fe69252e88e51db11d0cd97c"
algodClient, err := algod.MakeClient(algodAddress, algodToken)
if err != nil {
fmt.Printf("failed to make algod client: %s\n", err)
}
return algodClient
}
func saveUnsignedTransaction() {
// setup connection
algodClient := setupConnection()
// recover account for example
addr, _ := recoverAccount();
// get network suggested parameters
txParams, err := algodClient.SuggestedParams()
if err != nil {
fmt.Printf("error getting suggested tx params: %s\n", err)
return
}
// create transaction
toAddr := "GD64YIY3TWGDMCNPP553DZPPR6LDUSFQOIJVFDPPXWEG3FVOJCCDBBHU5A"
genID := txParams.GenesisID
tx, err := transaction.MakePaymentTxn(addr, toAddr, 1, 100000,
txParams.LastRound, txParams.LastRound+100, nil, "",
genID, txParams.GenesisHash)
if err != nil {
fmt.Printf("Error creating transaction: %s\n", err)
return
}
unsignedTx := types.SignedTxn{
Txn: tx,
}
// save unsigned Transaction to file
err = ioutil.WriteFile("./unsigned.txn", msgpack.Encode(unsignedTx), 0644)
if err == nil {
fmt.Printf("Saved unsigned transaction to file\n")
return
}
fmt.Printf("Failed in saving trx to file, error %s\n", err)
}
func readUnsignedTransaction(){
// setup connection
algodClient := setupConnection()
// read unsigned transaction from file
dat, err := ioutil.ReadFile("./unsigned.txn")
if err != nil {
fmt.Printf("Error reading transaction from file: %s\n", err)
return
}
var unsignedTxRaw types.SignedTxn
var unsignedTxn types.Transaction
msgpack.Decode(dat, &unsignedTxRaw)
unsignedTxn = unsignedTxRaw.Txn
// recover account and sign transaction
addr, sk := recoverAccount();
fmt.Printf("Address is: %s\n", addr)
txid, stx, err := crypto.SignTransaction(sk, unsignedTxn)
if err != nil {
fmt.Printf("Failed to sign transaction: %s\n", err)
return
}
fmt.Printf("Transaction id: %s\n", txid)
// send transaction to the network
sendResponse, err := algodClient.SendRawTransaction(stx)
if err != nil {
fmt.Printf("failed to send transaction: %s\n", err)
return
}
fmt.Printf("Transaction ID: %s\n", sendResponse.TxID)
waitForConfirmation(algodClient, sendResponse.TxID)
}
func saveSignedTransaction() {
// setup connection
algodClient := setupConnection()
// recover account
addr, sk := recoverAccount();
// get network suggested parameters
txParams, err := algodClient.SuggestedParams()
if err != nil {
fmt.Printf("error getting suggested tx params: %s\n", err)
return
}
// create transaction
toAddr := "GD64YIY3TWGDMCNPP553DZPPR6LDUSFQOIJVFDPPXWEG3FVOJCCDBBHU5A"
genID := txParams.GenesisID
tx, err := transaction.MakePaymentTxn(addr, toAddr, 1, 100000,
txParams.LastRound, txParams.LastRound+100, nil, "",
genID, txParams.GenesisHash)
if err != nil {
fmt.Printf("Error creating transaction: %s\n", err)
return
}
// sign the Transaction, msgpack encoding happens in sign
txid, stx, err := crypto.SignTransaction(sk, tx)
if err != nil {
fmt.Printf("Failed to sign transaction: %s\n", err)
return
}
fmt.Printf("Made signed transaction with TxID %s: %x\n", txid, stx)
//Save the signed transaction to file
err = ioutil.WriteFile("./signed.stxn", stx, 0644)
if err == nil {
fmt.Printf("Saved signed transaction to file\n")
return
}
fmt.Printf("Failed in saving trx to file, error %s\n", err)
}
func readSignedTransaction(){
// setup connection
algodClient := setupConnection()
// read unsigned transaction from file
dat, err := ioutil.ReadFile("./signed.stxn")
if err != nil {
fmt.Printf("Error reading signed transaction from file: %s\n", err)
return
}
// send the transaction to the network
sendResponse, err := algodClient.SendRawTransaction(dat)
if err != nil {
fmt.Printf("failed to send transaction: %s\n", err)
return
}
fmt.Printf("Transaction ID: %s\n", sendResponse.TxID)
waitForConfirmation(algodClient, sendResponse.TxID)
}
func main() {
//saveUnsignedTransaction()
//readUnsignedTransaction()
saveSignedTransaction()
readSignedTransaction()
}
输出:
未签名交易保存到文件中:
Address: DRQLINNRAGANYEVK5BCYVTOERMBV7LQU3ZYFGACA3XCX3AB24H7OKCZ7AM
Saved unsigned transaction to file
Address: DRQLINNRAGANYEVK5BCYVTOERMBV7LQU3ZYFGACA3XCX3AB24H7OKCZ7AM
Address is: DRQLINNRAGANYEVK5BCYVTOERMBV7LQU3ZYFGACA3XCX3AB24H7OKCZ7AM
Transaction id: D72GNKEOFSGQ7G7AHYV67YDTTXLGK6GCOVLP64UEI4MZKVK7J2TA
Transaction ID: D72GNKEOFSGQ7G7AHYV67YDTTXLGK6GCOVLP64UEI4MZKVK7J2TA
Transaction D72GNKEOFSGQ7G7AHYV67YDTTXLGK6GCOVLP64UEI4MZKVK7J2TA confirmed in round 13369740
Process finished with exit code 0
签名交易保存到文件中
Address: DRQLINNRAGANYEVK5BCYVTOERMBV7LQU3ZYFGACA3XCX3AB24H7OKCZ7AM
Made signed transaction with TxID 2277MTRKGJJOMDJMBMPRFUUPGAW5K5DFMTIIDHPHVZWPWMM52SRA: 82a3736967c44089ac1676e8a784d75a50f4f1a892fbf7a42458b3e10a03b7aa76c18099d664e05ebc194b6ec0825c1d8dca94946add9cb91052a509ce1262b9d11f0993a03a01a374786e89a3616d74ce000186a0a3666565cd03e8a26676ce00cc01caa367656eac746573746e65742d76312e30a26768c4204863b518a4b3c84ec810f22d4f1081cb0f71f059a7ac20dec62f7f70e5093a22a26c76ce00cc022ea3726376c42030fdcc231b9d8c3609af7f7bb1e5ef8f963a48b07213528defbd886d96ae4884a3736e64c4201c60b435b10180dc12aae8458acdc48b035fae14de70530040ddc57d803ae1fea474797065a3706179
Saved signed transaction to file
Transaction ID: 2277MTRKGJJOMDJMBMPRFUUPGAW5K5DFMTIIDHPHVZWPWMM52SRA
Transaction 2277MTRKGJJOMDJMBMPRFUUPGAW5K5DFMTIIDHPHVZWPWMM52SRA confirmed in round 13369804
Process finished with exit code 0
- 生成参与密钥:
~/node$ ./goal account addpartkey -a "DRQLINNRAGANYEVK5BCYVTOERMBV7LQU3ZYFGACA3XCX3AB24H7OKCZ7AM" --roundFirstValid="13391134" --roundLastValid="13392134" --keyDilution="10000" -d ~/node/data
Participation key generation successful
$ ./goal account listpartkeys -d ~/node/data
Registered Filename Parent address First round Last round First key
no DRQLINNRAGANYEVK5BCYVTOERMBV7LQU3ZYFGACA3XCX3AB24H7OKCZ7AM.13389730.13390730.partkey DRQLINNRAGANYEVK5BCYVTOERMBV7LQU3ZYFGACA3XCX3AB24H7OKCZ7AM 13389730 13390730 1340.1150
no DRQLINNRAGANYEVK5BCYVTOERMBV7LQU3ZYFGACA3XCX3AB24H7OKCZ7AM.13391134.13392134.partkey DRQLINNRAGANYEVK5BCYVTOERMBV7LQU3ZYFGACA3XCX3AB24H7OKCZ7AM 13391134 13392134 1339.0
-创建在线密钥注册交易:
package main
import (
"encoding/base64"
"fmt"
"github.com/algorand/go-algorand-sdk/crypto"
"github.com/algorand/go-algorand-sdk/encoding/msgpack"
"github.com/algorand/go-algorand-sdk/mnemonic"
"io/ioutil"
"golang.org/x/crypto/ed25519"
"github.com/algorand/go-algorand-sdk/client/algod"
"github.com/algorand/go-algorand-sdk/transaction"
"github.com/algorand/go-algorand-sdk/types"
)
// Function that waits for a given txId to be confirmed by the network
func waitForConfirmation(algodClient algod.Client, txID string) {
for {
pt, err := algodClient.PendingTransactionInformation(txID)
if err != nil {
fmt.Printf("waiting for confirmation... (pool error, if any): %s\n", err)
continue
}
if pt.ConfirmedRound > 0 {
fmt.Printf("Transaction "+pt.TxID+" confirmed in round %d\n", pt.ConfirmedRound)
break
}
nodeStatus, err := algodClient.Status()
if err != nil {
fmt.Printf("error getting algod status: %s\n", err)
return
}
algodClient.StatusAfterBlock( nodeStatus.LastRound + 1)
}
}
// utility function to recover account and return sk and address
func recoverAccount()(string, ed25519.PrivateKey) {
const passphrase = "essay broccoli sunset upon midnight hope paper picnic choice pulp chalk fluid they plug scan coffee curious around yellow depart feel bacon matter above differ"
sk, err := mnemonic.ToPrivateKey(passphrase)
if err != nil {
fmt.Printf("error recovering account: %s\n", err)
return "", nil
}
pk := sk.Public()
var a types.Address
cpk := pk.(ed25519.PublicKey)
copy(a[:], cpk[:])
fmt.Printf("Address: %s\n", a.String())
address := a.String()
return address, sk
}
// utility funciton to setup connection to node
func setupConnection()( algod.Client ){
const algodAddress = "http://127.0.0.1:8080"
const algodToken = "adaad27f70e451e97d0fbbbbe2095220e8798099fe69252e88e51db11d0cd97c"
algodClient, err := algod.MakeClient(algodAddress, algodToken)
if err != nil {
fmt.Printf("failed to make algod client: %s\n", err)
}
return algodClient
}
func saveUnsignedTransaction() {
// setup connection
algodClient := setupConnection()
// get network suggested parameters
txParams, err := algodClient.SuggestedParams()
if err != nil {
fmt.Printf("error getting suggested tx params: %s\n", err)
return
}
// create transaction
fromAddr := "DRQLINNRAGANYEVK5BCYVTOERMBV7LQU3ZYFGACA3XCX3AB24H7OKCZ7AM"
genID := txParams.GenesisID
genesisHash := base64.StdEncoding.EncodeToString(txParams.GenesisHash)
voteKey := "eXq34wzh2UIxCZaI1leALKyAvSz/+XOe0wqdHagM+bw="
selKey := "X84ReKTmp+yfgmMCbbokVqeFFFrKQeFZKEXG89SXwm4="
voteFirst := uint64(13389730)
voteLast := uint64(16389730)
keyDilution := uint64(10000)
tx, err := transaction.MakeKeyRegTxnWithFlatFee(fromAddr, 2000, 13391134,
13392134, nil, genID, genesisHash, voteKey, selKey, voteFirst, voteLast,
keyDilution)
if err != nil {
fmt.Printf("Error creating transaction: %s\n", err)
return
}
unsignedTx := types.SignedTxn{
Txn: tx,
}
// save unsigned Transaction to file
err = ioutil.WriteFile("./unsigned.txn", msgpack.Encode(unsignedTx), 0644)
if err == nil {
fmt.Printf("Saved unsigned transaction to file\n")
return
}
fmt.Printf("Failed in saving trx to file, error %s\n", err)
}
func readUnsignedTransaction(){
// setup connection
algodClient := setupConnection()
// read unsigned transaction from file
dat, err := ioutil.ReadFile("./unsigned.txn")
if err != nil {
fmt.Printf("Error reading transaction from file: %s\n", err)
return
}
var unsignedTxRaw types.SignedTxn
var unsignedTxn types.Transaction
msgpack.Decode(dat, &unsignedTxRaw)
unsignedTxn = unsignedTxRaw.Txn
// recover account and sign transaction
addr, sk := recoverAccount();
fmt.Printf("Address is: %s\n", addr)
txid, stx, err := crypto.SignTransaction(sk, unsignedTxn)
if err != nil {
fmt.Printf("Failed to sign transaction: %s\n", err)
return
}
fmt.Printf("Transaction id: %s\n", txid)
// send transaction to the network
sendResponse, err := algodClient.SendRawTransaction(stx)
if err != nil {
fmt.Printf("failed to send transaction: %s\n", err)
return
}
fmt.Printf("Transaction ID: %s\n", sendResponse.TxID)
waitForConfirmation(algodClient, sendResponse.TxID)
}
func main() {
saveUnsignedTransaction()
readUnsignedTransaction()
}
输出:
Saved unsigned transaction to file
Address: DRQLINNRAGANYEVK5BCYVTOERMBV7LQU3ZYFGACA3XCX3AB24H7OKCZ7AM
Address is: DRQLINNRAGANYEVK5BCYVTOERMBV7LQU3ZYFGACA3XCX3AB24H7OKCZ7AM
Transaction id: AXQEMH7KSI55I5LP4XCZS2AYKJOB372DSZ7Y2LKE5NQMK7HZUXDA
Transaction ID: AXQEMH7KSI55I5LP4XCZS2AYKJOB372DSZ7Y2LKE5NQMK7HZUXDA
Transaction AXQEMH7KSI55I5LP4XCZS2AYKJOB372DSZ7Y2LKE5NQMK7HZUXDA confirmed in round 13391174
Process finished with exit code 0
至此algorand区块链的一些基本操作均已在go-sdk实现。