区块链项目(algorand)开发过程全记录(二)

使用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实现。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值