资讯专栏INFORMATION COLUMN

.net平台下开发以太坊的实战示例(C#)

marser / 3355人阅读

摘要:我以后会在这篇文章中添加更多内容,但就目前而言,正在使用它发布的系列示例,介绍如何使用库执行针对以太坊区块链平台的最常见任务。

这是一篇文章的早期版本,旨在帮助那些对以太坊区块链平台有基本了解的开发人员,如果想学习如何使用Nethereum .NET库对Ethereum平台进行编程。

我以后会在这篇文章中添加更多内容,但就目前而言,正在使用它发布.NET 10+的系列C#示例,介绍如何使用Nethereum库执行针对以太坊区块链平台的最常见任务。

最常见任务列表包括以下内容:

1.获取协议版本

2.获取最大块数

3.获取帐户余额

4.发送以太

5.等待交易收据

6.在区块链中扫描块

7.列出个人账户(及其余额)

8.在区块链中扫描交易

9.与现有(已部署)合同互动

10.用事件和现有(已部署)合约交互

11.获取所有活动更改

12.获取合约金额历史

这里是c#的主文件:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

using Nethereum.Hex.HexTypes;
using Nethereum.Web3;

namespace MWH.MyNethereum.QuickRef
{
 static public class TaskExamples
 {
 const int UNLOCK_TIMEOUT = 2 * 60; // 2 minutes (arbitrary)
 const int SLEEP_TIME = 5 * 1000; // 5 seconds (arbitrary)
 const int MAX_TIMEOUT = 2 * 60 * 1000; // 2 minutes (arbirtrary)

// These static public variables do not represent a recommended pattern
 static public string LastProtocolVersion = "";
 static public string LastTxHash = "";
 static public Nethereum.RPC.Eth.DTOs.TransactionReceipt LastTxReceipt = null;
 static public HexBigInteger LastMaxBlockNumber = new HexBigInteger(0);

static public async Task GetProtocolVersionExample(Web3 web3)
 {
 Console.WriteLine("GetProtocolVersionExample:");

var protocolVersion = await web3.Eth.ProtocolVersion.SendRequestAsync();
 Console.WriteLine("protocolVersion:	" + protocolVersion.ToString());
 LastProtocolVersion = protocolVersion;
 }

static public async Task GetMaxBlockExample(Web3 web3)
 {
 Console.WriteLine("GetMaxBlockExample:");

var maxBlockNumber = await web3.Eth.Blocks.GetBlockNumber.SendRequestAsync();
 Console.WriteLine("maxBlockNumber:	" + maxBlockNumber.Value.ToString());
 LastMaxBlockNumber = maxBlockNumber;
 }

static public async Task ScanBlocksExample(Web3 web3, ulong startBlockNumber, ulong endBlockNumber)
 {
 Console.WriteLine("ScanBlocksExample:");

long txTotalCount = 0;
 for (ulong blockNumber = startBlockNumber; blockNumber <= endBlockNumber; blockNumber++)
 {
 var blockParameter = new Nethereum.RPC.Eth.DTOs.BlockParameter(blockNumber);
 var block = await web3.Eth.Blocks.GetBlockWithTransactionsByNumber.SendRequestAsync(blockParameter);
 var trans = block.Transactions;
 int txCount = trans.Length;
 txTotalCount += txCount;
 if (blockNumber % 1000 == 0) Console.Write(".");
 if (blockNumber % 10000 == 0)
 {
 DateTime blockDateTime = Helpers.UnixTimeStampToDateTime((double)block.Timestamp.Value);
 Console.WriteLine(blockNumber.ToString() + " " + txTotalCount.ToString() + " " + blockDateTime.ToString());
 }
 }
 Console.WriteLine();
 }

static public async Task ScanTxExample(Web3 web3, ulong startBlockNumber, ulong endBlockNumber)
 {
 Console.WriteLine("ScanTxExample:");

long txTotalCount = 0;
 for (ulong blockNumber = startBlockNumber; blockNumber <= endBlockNumber; blockNumber++)
 {
 var blockParameter = new Nethereum.RPC.Eth.DTOs.BlockParameter(blockNumber);
 var block = await web3.Eth.Blocks.GetBlockWithTransactionsByNumber.SendRequestAsync(blockParameter);
 var trans = block.Transactions;
 int txCount = trans.Length;
 txTotalCount += txCount;
 foreach (var tx in trans)
 {
 try
 {
 var bn = tx.BlockNumber.Value;
 var th = tx.TransactionHash;
 var ti = tx.TransactionIndex.Value;

var rpt = await web3.Eth.Transactions.GetTransactionReceipt.SendRequestAsync(th);
 var status = rpt.Status.Value;

var nc = tx.Nonce.Value;
 var from = tx.From;

Console.WriteLine(th.ToString() + " " + ti.ToString() + " " + from.ToString() + " " + status.ToString());

var to = tx.To;
 if (to == null) to = "to:NULL";
 var v = tx.Value.Value;
 var g = tx.Gas.Value;
 var gp = tx.GasPrice.Value;
 Console.WriteLine(th.ToString() + " " + ti.ToString() + " " + nc.ToString() + " " + from.ToString() + " " + to.ToString() + " " + v.ToString() + " " + g.ToString() + " " + gp.ToString());
 }
 catch (Exception ex)
 {
 Console.WriteLine("ScanTxExample.Tx:	" + ex.ToString());
 if (ex.InnerException != null) Console.WriteLine("ScanTxExample.Tx:	" + ex.InnerException.ToString());
 }
 }
 Console.WriteLine();
 }
 }

static public async Task GetAccountBalanceExample(Web3 web3, string accountAddress)
 {
 Console.WriteLine("GetAccountBalanceExample:");

var balanceWei = await web3.Eth.GetBalance.SendRequestAsync(accountAddress);
 var balanceEther = Web3.Convert.FromWei(balanceWei.Value);
 Console.WriteLine("accountAddress:	" + accountAddress.ToString());
 Console.WriteLine("balanceEther:	" + balanceEther.ToString());
 }

static public async Task ListPersonalAccountsExample(Web3 web3)
 {
 Console.WriteLine("ListPersonalAccountsExample:");

var accounts = await web3.Personal.ListAccounts.SendRequestAsync();
 foreach (var account in accounts)
 {
 var balanceWei = await web3.Eth.GetBalance.SendRequestAsync(account);
 var balanceEther = Web3.Convert.FromWei(balanceWei.Value);
 Console.WriteLine("account:	" + account + " balanceEther:	" + balanceEther.ToString());
 }
 }

static public async Task SendEtherExample(Web3 web3, string fromAddress, string fromPassword, string toAddress, long amountWei)
 {
 Console.WriteLine("SendEtherExample:");

var unlockResult = await web3.Personal.UnlockAccount.SendRequestAsync(fromAddress, fromPassword, UNLOCK_TIMEOUT);
 var sendTxHash = await web3.Eth.TransactionManager.SendTransactionAsync(fromAddress, toAddress, new HexBigInteger(amountWei));
 Console.WriteLine("fromAddress:	" + fromAddress.ToString());
 Console.WriteLine("toAddress:	" + toAddress.ToString());
 Console.WriteLine("amountWei:	" + amountWei.ToString());
 Console.WriteLine("sendTxHash:	" + sendTxHash.ToString());
 LastTxHash = sendTxHash;
 }

static public async Task WaitForTxReceiptExample(Web3 web3, string txHash)
 {
 Console.WriteLine("WaitForTxReceiptExample:");

int timeoutCount = 0;
 var txReceipt = await web3.Eth.Transactions.GetTransactionReceipt.SendRequestAsync(txHash);
 while (txReceipt == null && timeoutCount < MAX_TIMEOUT)
 {
 Console.WriteLine("Sleeping...");
 Thread.Sleep(SLEEP_TIME);
 txReceipt = await web3.Eth.Transactions.GetTransactionReceipt.SendRequestAsync(txHash);
 timeoutCount += SLEEP_TIME;
 }
 Console.WriteLine("timeoutCount " + timeoutCount.ToString());
 LastTxReceipt = txReceipt;
 }

static public async Task InteractWithExistingContractExample(Web3 web3, string fromAddress, string fromPassword, string contractAddress, string contractAbi)
 {
 Console.WriteLine("InteractWithExistingContractExample:");

var contract = web3.Eth.GetContract(contractAbi, contractAddress);

var setMessageFunction = contract.GetFunction("setMsg");
 var getMessageFunction = contract.GetFunction("getMsg");

string nowTimestamp = DateTime.UtcNow.ToString() + " UTC";
 Console.WriteLine("now:	" + nowTimestamp);

var unlockResult = await web3.Personal.UnlockAccount.SendRequestAsync(fromAddress, fromPassword, UNLOCK_TIMEOUT);
 var txHash1 = await setMessageFunction.SendTransactionAsync(fromAddress, new HexBigInteger(900000), null, 1, "Hello World");
 Console.WriteLine("txHash1:	" + txHash1.ToString());
 var txHash2 = await setMessageFunction.SendTransactionAsync(fromAddress, new HexBigInteger(900000), null, 2, nowTimestamp);
 Console.WriteLine("txHash2:	" + txHash2.ToString());

var txReceipt2 = await web3.Eth.Transactions.GetTransactionReceipt.SendRequestAsync(txHash2);
 int timeoutCount = 0;
 while (txReceipt2 == null && timeoutCount < MAX_TIMEOUT)
 {
 Console.WriteLine("Sleeping...");
 Thread.Sleep(SLEEP_TIME);
 txReceipt2 = await web3.Eth.Transactions.GetTransactionReceipt.SendRequestAsync(txHash2);
 timeoutCount += SLEEP_TIME;
 }
 Console.WriteLine("timeoutCount:	" + timeoutCount.ToString());

var txReceipt3 = await setMessageFunction.SendTransactionAndWaitForReceiptAsync(fromAddress, new HexBigInteger(900000), null, null, 2, nowTimestamp + " Wait");
 Console.WriteLine("txReceipt3:	" + txReceipt3.TransactionHash.ToString());
 Console.WriteLine("txReceipt3:	" + txReceipt3.CumulativeGasUsed.Value.ToString());

var getResult1 = await getMessageFunction.CallAsync(1);
 Console.WriteLine("getResult1:	" + getResult1.ToString());
 var getResult2 = await getMessageFunction.CallAsync(2);
 Console.WriteLine("getResult2:	" + getResult2.ToString());
 }

static public async Task InteractWithExistingContractWithEventsExample(Web3 web3, string fromAddress, string fromPassword, string contractAddress, string contractAbi)
 {
 Console.WriteLine("InteractWithExistingContractWithEventsExample:");

var contract = web3.Eth.GetContract(contractAbi, contractAddress);

var setMessageFunction = contract.GetFunction("setMsg");
 var getMessageFunction = contract.GetFunction("getMsg");
 var multipliedEvent = contract.GetEvent("MultipliedEvent");
 var newMessageEvent = contract.GetEvent("NewMessageEvent");

var filterAllMultipliedEvent = await multipliedEvent.CreateFilterAsync();
 var filterAllNewMessageEvent = await newMessageEvent.CreateFilterAsync();

string nowTimestamp = DateTime.UtcNow.ToString() + " UTC";
 Console.WriteLine("now:	" + nowTimestamp);

var unlockResult = await web3.Personal.UnlockAccount.SendRequestAsync(fromAddress, fromPassword, UNLOCK_TIMEOUT);
 var txHash1 = await setMessageFunction.SendTransactionAsync(fromAddress, new HexBigInteger(900000), null, 1, "Hello World");
 Console.WriteLine("txHash1:	" + txHash1.ToString());
 var txHash2 = await setMessageFunction.SendTransactionAsync(fromAddress, new HexBigInteger(900000), null, 2, nowTimestamp);
 Console.WriteLine("txHash2:	" + txHash2.ToString());

var txReceipt2 = await web3.Eth.Transactions.GetTransactionReceipt.SendRequestAsync(txHash2);
 int timeoutCount = 0;
 while (txReceipt2 == null && timeoutCount < MAX_TIMEOUT)
 {
 Console.WriteLine("Sleeping...");
 Thread.Sleep(SLEEP_TIME);
 txReceipt2 = await web3.Eth.Transactions.GetTransactionReceipt.SendRequestAsync(txHash2);
 timeoutCount += SLEEP_TIME;
 }
 Console.WriteLine("timeoutCount:	" + timeoutCount.ToString());

var txReceipt3 = await setMessageFunction.SendTransactionAndWaitForReceiptAsync(fromAddress, new HexBigInteger(900000), null, null, 2, nowTimestamp + " Wait");
 Console.WriteLine("txReceipt3:	" + txReceipt3.TransactionHash.ToString());
 Console.WriteLine("txReceipt3:	" + txReceipt3.CumulativeGasUsed.Value.ToString());

var getResult1 = await getMessageFunction.CallAsync(1);
 Console.WriteLine("getResult1:	" + getResult1.ToString());
 var getResult2 = await getMessageFunction.CallAsync(2);
 Console.WriteLine("getResult2:	" + getResult2.ToString());

var logMultipliedEvents = await multipliedEvent.GetFilterChanges(filterAllMultipliedEvent);
 foreach (var mea in logMultipliedEvents)
 {
 Console.WriteLine("multipliedEvent:	" +
 mea.Event.sender + " " + mea.Event.oldProduct.ToString() + " " + mea.Event.value.ToString() + " " + mea.Event.newProduct.ToString());
 }

var logNewMessageEvents = await newMessageEvent.GetFilterChanges(filterAllNewMessageEvent);
 foreach (var mea in logNewMessageEvents)
 {
 Console.WriteLine("newMessageEvent:	" +
 mea.Event.sender + " " + mea.Event.ind.ToString() + " " + mea.Event.msg.ToString());
 }
 }

static public async Task GetAllChangesExample(Web3 web3, string fromAddress, string fromPassword, string contractAddress, string contractAbi)
 {
 Console.WriteLine("GetAllChangesExample:");

var contract = web3.Eth.GetContract(contractAbi, contractAddress);
 var newMessageEvent = contract.GetEvent("NewMessageEvent");
 var filterAllNewMessageEvent = await newMessageEvent.CreateFilterAsync(fromAddress);
 var logNewMessageEvents = await newMessageEvent.GetAllChanges(filterAllNewMessageEvent);
 foreach (var mea in logNewMessageEvents)
 {
 Console.WriteLine("newMessageEvent:	" +
 mea.Event.sender + " " + mea.Event.ind.ToString() + " " + mea.Event.msg.ToString());
 }
 }

static public async Task GetContractValuesHistoryUniqueOffsetValueExample(Web3 web3, string contractAddress, HexBigInteger recentBlockNumber, ulong numberBlocks, int offset)
 {
 Console.WriteLine("GetContractValuesHistoryUniqueOffsetValueExample:");

string previousValue = "";
 for (ulong blockNumber = (ulong)recentBlockNumber.Value; blockNumber > (ulong)recentBlockNumber.Value - numberBlocks; blockNumber--)
 {
 var blockNumberParameter = new Nethereum.RPC.Eth.DTOs.BlockParameter(blockNumber);
 var valueAtOffset = await web3.Eth.GetStorageAt.SendRequestAsync(contractAddress, new HexBigInteger(offset), blockNumberParameter);
 if (valueAtOffset != previousValue)
 {
 var block = await web3.Eth.Blocks.GetBlockWithTransactionsByNumber.SendRequestAsync(blockNumberParameter);
 DateTime blockDateTime = Helpers.UnixTimeStampToDateTime((double)block.Timestamp.Value);
 Console.WriteLine("blockDateTime:	" + blockDateTime.ToString());

for (int storageOffset = 0; storageOffset < offset+2; storageOffset++)
 {
 var valueAt = await web3.Eth.GetStorageAt.SendRequestAsync(contractAddress, new HexBigInteger(storageOffset), blockNumberParameter);
 Console.WriteLine("value:	" + blockNumber.ToString() + " " + storageOffset.ToString() + " " + valueAt + " " + Helpers.ConvertHex(valueAt.Substring(2)));
 }
 previousValue = valueAtOffset;
 }
 }
 }
 }
}

以下是一些支持文件:

FunctionOutputHelpers.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Nethereum.Web3;
using Nethereum.ABI.FunctionEncoding.Attributes;

namespace MWH.MyNethereum.QuickRef
{
 static public class FunctionOutputHelpers
 {
 // event MultipliedEvent(
 // address indexed sender,
 // int oldProduct,
 // int value,
 // int newProduct
 // );

[FunctionOutput]
 public class MultipliedEventArgs
 {
 [Parameter("address", "sender", 1, true)]
 public string sender { get; set; }

[Parameter("int", "oldProduct", 2, false)]
 public int oldProduct { get; set; }

[Parameter("int", "value", 3, false)]
 public int value { get; set; }

[Parameter("int", "newProduct", 4, false)]
 public int newProduct { get; set; }

}

//event NewMessageEvent(
 // address indexed sender,
 // uint256 indexed ind,
 // string msg
 //);

[FunctionOutput]
 public class NewMessageEventArgs
 {
 [Parameter("address", "sender", 1, true)]
 public string sender { get; set; }

[Parameter("uint256", "ind", 2, true)]
 public int ind { get; set; }

[Parameter("string", "msg", 3, false)]
 public string msg { get; set; }
 }
 }
}

Helpers.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MWH.MyNethereum.QuickRef
{
 static public class Helpers
 {
 public static string ConvertHex(String hexString)
 {
 try
 {
 string ascii = string.Empty;

for (int i = 0; i < hexString.Length; i += 2)
 {
 String hs = string.Empty;

hs = hexString.Substring(i, 2);
 uint decval = System.Convert.ToUInt32(hs, 16);
 char character = System.Convert.ToChar(decval);
 ascii += character;

}

return ascii;
 }
 catch (Exception ex) { Console.WriteLine(ex.Message); }

return string.Empty;
 }

public static DateTime UnixTimeStampToDateTime(double unixTimeStamp)
 {
 // Unix timestamp is seconds past epoch
 System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
 dtDateTime = dtDateTime.AddSeconds(unixTimeStamp); // .ToLocalTime();
 return dtDateTime;
 }

public static DateTime JavaTimeStampToDateTime(double javaTimeStamp)
 {
 // Java timestamp is milliseconds past epoch
 System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
 dtDateTime = dtDateTime.AddMilliseconds(javaTimeStamp); // .ToLocalTime();
 return dtDateTime;
 }
 }
}

以下是用于实施这些示例时使用的以太坊合约的Solidity代码:

Test3.sol

pragma solidity 0.4.19;

contract Test3 {

int public _product;
string[5] _msgs;
 
event MultipliedEvent(
address indexed sender,
int oldProduct,
int value,
int newProduct
);
 
event NewMessageEvent(
address indexed sender,
uint256 indexed ind,
string msg
);

function Test3() public {
_product = 1;
}

function multiply(int value) public returns(int product) {
int old = _product;
_product = value * _product;
MultipliedEvent( msg.sender, old, value, _product );
return _product;
}
 
function getProduct() public constant returns(int product) {
return _product;
}

function setMsg(uint256 i, string m) public returns(uint256 mi) {
_msgs[i] = m;
NewMessageEvent( msg.sender, i, m);
return -i;
}

function getMsg(uint256 index) public constant returns(string m) {
return _msgs[index];
}
}

我觉得这是发布代码示例的一种相当简单粗暴的方式。有任何更好建议欢迎留言。

如果你想马上使用c#开发以太坊dapp,可以学习下面的教程:

C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和事件等。

这里是原文

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/24284.html

相关文章

  • 2018以太坊智能合约编程语言solidity的最佳IDEs

    摘要:使用基于以太坊的智能合约的集成开发环境。以太坊教程,主要介绍智能合约与应用开发,适合入门。以太坊,主要是介绍使用进行智能合约开发交互,进行账号创建交易转账代币开发以及过滤器和事件等内容。 Solidity是一种以智能合约为导向的编程语言。这是一种只有四年的年轻语言,旨在帮助开发基于以太坊数字货币的智能合约。 理解它官方文档应该是学习Solidity的最佳来源:solidity.read...

    darkerXi 评论0 收藏0
  • 区块链开发中使用的最流行的编程语言

    摘要:我们目前正处于一个新兴的区块链开发行业中。,一种在以太坊开发人员中流行的新的简单编程语言,因为它是用于开发以太坊智能合约的语言。它是全球至少万开发人员使用的世界上最流行的编程语言之一。以太坊,主要是针对工程师使用进行区块链以太坊开发的详解。 我们目前正处于一个新兴的区块链开发行业中。区块链技术处于初期阶段,然而这种颠覆性技术已经成功地风靡全球,并且最近经历了一场与众不同的繁荣。由于许多...

    2shou 评论0 收藏0
  • 以太坊将成为新互联网的支柱

    摘要:以太坊将成为新互联网的支柱,我为什么这么说正在以太坊上构建我们的第层,而不是其他区块链平台这就是原因。以太坊不会牺牲去中心化的原则而下沉权力在区块链方面,有一项称为可扩展性三难的基本法则。 以太坊将成为新互联网的支柱,我为什么这么说?Loom Network正在以太坊上构建我们的第2层,而不是其他区块链平台——这就是原因。 每个月都有其他的公司发布白皮书,声称已经解决了以太坊所面临的可...

    liuhh 评论0 收藏0
  • PHP和树莓派开发一个比特币/以太坊交易机器人

    摘要:注目前我已经扩展了机器人以便能够交易以太坊我希望它能够在不必太多关注的情况下做事,而我想到的第一件事就是为什么不创建一个可以自动进行比特币和以太坊的简单交易机器人。在下一个泡沫破裂的时候自动购买比特币。选择比特币以太坊和欧元美元钱包。 我最近得到了Raspberry Pi Zero Wifi,我告诉你这个东西是改变游戏规则的。我之前使用过RasPis,但由于该设备的占地面积小得多,耗电...

    ShowerSun 评论0 收藏0

发表评论

0条评论

marser

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<