创建文章

We are looking for publications that demonstrate building dApps or smart contracts!
See the full list of Gitcoin bounties that are eligible for rewards.

Tutorial Thumbnail
入门 · 小于15分钟

使用.net进行Algorand开发系列教程之账号操作

本文是系列教程的第二篇,介绍如何创建账户地址,查询余额,以及发送交易。如果开发环境还没有搭建完成,请参照本系列教程(一)

本教程的配套视频请查看:https://www.bilibili.com/video/BV1pK4y1f7rQ

需要的工具和环境

请参照本系列教程(一),完成开发环境的搭建。

步骤

连接Algorand并获取相关信息

连接Algorand的相关内容已经在教程(一)中有所讨论,这里在原代码的基础上更进一步获取Algorand网络的相关信息。
此部分代码是一个整体,都是加入到创建项目的Program.cs的Main函数中,但为了便于理解,将其分为三部分,分别实现连接Algorand网络及查询代币总供应量/查询网络参数两部分。

连接Algorand网络及查询代币总供应量

这一部分和上一节相同,不再赘述,直接上代码:

string ALGOD_API_ADDR = "ALGOD_API_ADDR";  //在此处添加ALGOD TESTNET API地址
string ALGOD_API_TOKEN = "ALGOD_API_TOKEN";    //在此处添加ALGOD API KEY
AlgodApi algodApiInstance = new AlgodApi(ALGOD_API_ADDR, ALGOD_API_TOKEN);

try
{
    Supply supply = algodApiInstance.GetSupply();
    Console.WriteLine("Total Algorand Supply: " + supply.TotalMoney);
    Console.WriteLine("Online Algorand Supply: " + supply.OnlineMoney);
}catch (ApiException e)
{
    Console.WriteLine("Exception when calling algod#getSupply: " + e.Message);
}

查询网络参数

.net SDK将网络参数封装到TransactionParams 类中,里面有多个参数。参数的具体意义可以参照:https://developer.algorand.org/docs/reference/rest-apis/algod/v1/#transactionparams。具体代码如下:

ulong? feePerByte;
string genesisID;
Digest genesisHash;
ulong? firstRound = 0;
try
{
    TransactionParams transParams = algodApiInstance.TransactionParams();
    feePerByte = transParams.Fee;
    genesisHash = new Digest(Convert.FromBase64String(transParams.Genesishashb64));
    genesisID = transParams.GenesisID;
    Console.WriteLine("Suggested Fee: " + feePerByte);
    NodeStatus s = algodApiInstance.GetStatus();
    firstRound = s.LastRound;
    Console.WriteLine("Current Round: " + firstRound);
}catch (ApiException e)
{
throw new Exception("Could not get params", e);
}

这一部分可以说是非常简单的了,而且为了验证连通性,上面的代码除了连接以外也进行了Algorand网络信息的读取。

账号的使用及获取账号相关信息

连接到Algorand网络并获取到Algorand网络的相关可以是革命已经成功了一半,但实际上如果要进行相关开发的话,账号相关的操作是非常必要的。毕竟如果没有账号,那么只能是Algorand的旁观者,如果真要成为Algorand的参与者,账号是必不可少的。下面我们就从创建账号开始说明账号的使用及相关信息的获取。

在开始之前,先大致介绍一下账号(Account)的概念:

image-20210104183431526

账户:就像你的一个保险箱。在.net SDK中用Account这个类表示。

私钥:私钥可以完全控制账户,所以私钥要妥善保存。私钥有两种表现形式:助记词(Mnemonic)和主密钥(Master Key)。助记词是25个单词,主要作用是帮助你记住密钥。请注意,如果你的助记词泄露,那么你的密钥就已经泄露。主密钥是一个32个字节的2进制数。这个密钥一般在程序中使用,人为使用或记忆比较难。私钥之间的相互操作及与账户的相互操作下文再详细描述。

公钥:可以看成你的账号地址或者银行卡号之类的。别人可以用公钥给你转账,当然也可以查看你的操作流水。

更多关于账户的概念,请参照:https://developer.algorand.org/docs/features/accounts/

下面给出一段示例代码,用于公钥、私钥、账户之间的互操作。代码中有详细的说明,来解释第一行代码的用处:

string SRC_ACCOUNT = "typical permit hurdle hat song detail cattle merge oxygen crowd arctic cargo smooth fly rice vacuum lounge yard frown predict west wife latin absent cup";
// 使用助记词来创建账号
Account src = new Account(SRC_ACCOUNT);
// 账户的公钥(也是地址)
var publicKey = src.Address;            
// 助记词转换为主密钥
var masterKey = Mnemonic.ToKey(SRC_ACCOUNT);
// 使用主密钥来创建账号
Account scr2 = new Account(masterKey);
// 主密钥转换为助记词
var mnemonic = Mnemonic.FromKey(masterKey);
// 产生一个随机的账号
var src3 = new Account();
// 随机账号的助记词
var randomAccountMnemonic = src3.ToMnemonic();

转账操作

无论是转账,还是后面其他的操作,一次交易的一般流程如下:

image-20210105144044109

转账操作和下一节所述的签名操作是账户最常用的操作。但实际上在转账操作中也涉及了对数据的签名,但关于签名的更多细节不会在此节中展开。注:此部分代码只展示了帐户及转账部分的代码,在转账开始前需要连接Algorand网络及获取TransactionParams。

// 向DEST_ADDR转账0.1algo
// 注意转账都是Micro Algos为单位的,1 Algo = 1e6 Micro Algos
// 两者之间的转换可以用Utils.AlgosToMicroalgos及Utils.MicroalgosToAlgos
ulong? amount = 100000;
ulong? lastRound = firstRound + 1000; // 1000 is the max tx window            
string SRC_ACCOUNT = "typical permit hurdle hat song detail cattle merge oxygen crowd arctic cargo smooth fly rice vacuum lounge yard frown predict west wife latin absent cup";
Account src = new Account(SRC_ACCOUNT);
Console.WriteLine("My account address is:" + src.Address.ToString());
string DEST_ADDR = "KV2XGKMXGYJ6PWYQA5374BYIQBL3ONRMSIARPCFCJEAMAHQEVYPB7PL3KU";
// Transaction中包含一次交易中几乎所有的信息
// 需要注意的是Transaction需要经过签名才能发送到区区块链
Transaction tx = new Transaction(src.Address, new Address(DEST_ADDR), amount, firstRound, lastRound, genesisID, genesisHash);
//sign the transaction before send it to the blockchain
SignedTransaction signedTx = src.SignTransactionWithFeePerByte(tx, (ulong)feePerByte);
Console.WriteLine("Signed transaction with txid: " + signedTx.transactionID);// send the transaction to the network
try
{
//交易信息编码
var encodedMsg = Algorand.Encoder.EncodeToMsgPack(signedTx);
//发送交易
    TransactionID id = algodApiInstance.RawTransaction(encodedMsg);
    Console.WriteLine("Successfully sent tx with id: " + id.TxId);
}catch (ApiException e)
{
    // This is generally expected, but should give us an informative error message.
    Console.WriteLine("Exception when calling algod#rawTransaction: " + e.Message);
}

这里有必要对如何创建并填充交易信息来进行一点说明。几乎所有的交易信息都可以直接使用Transaction类来进行创建,上文的代码也是直接用了Transaction类。

在.net SDK中,Utils类下面有若干个GetXXXXTransaction方法。这些方法内部其实也是引用了Transaction来完成操作的,只不过是提升了其使用的便捷性。

编码和发送交易的操作基本都是上面的套路,所以.net SDK为了便于用户使用,增加了一个Utils.SubmitTransaction方法,可以一步完成编码及发送工作。

签名操作

所有操作在发送到网络之前都需要进行一次或多次签名,这里就最常用的签名方法和大家一起进行探讨。

签名都是通过Account类的对象来进行的,如上文中的scr对象。签名最常用的方法scr.SignTransaction方法。这个方法非常简单,只接收一个Transaction类的对象即可。有时你可能希望手动的改变交易时的费用,使交易能够更多快的完成,这时你就需要使用src.SignTransactionWithFeePerByte方法,这个方法会在签名的同时更改网络费用(注意,费用是每个字节的费用,并不是说整个交易的费用)。

总结

本文在第一节搭建的开发环境的基础上,对账户的基本操作:转账和签名进行介绍。特别是签名操作,今天只介绍了其操作方法,其更多用法与作用会在后面的教程中有所展现。

本系列科程的所有代码都可以在https://github.com/RileyGe/algo-samples上找到。欢迎大家提Issues或Pull Request.