This is the old Algorand Developer Portal. Please head over to dev.algorand.co to explore our newly rebuilt documentation site. Please excuse us as we continue to transition content to the new portal

创建文章

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.