C#でethereumのクライアントを実装する


はじめに

Nethereumを使って、C#でethereumのクライアントを作成します。
Quorumのクライアントも同様に作成できます。

以下の手順は、Macで確認しました。Windowsでも基本的に同じだと思います。
また、リモートから開発する場合は、以下の記事を参考にしてください。

用意するもの

以下の環境を事前に準備してください。

  1. .Net Core3.1 SDK
  2. VS Code

(NuGetしたnethereum3.8.0は、.Net 5に対応していませんでした。)

2021年前半に書いたので内容的に古くなっている可能性があります。

スマートコントラクトのコンパイルとC#コードの生成

VS Codeと.Net Core3.1を使用して、ethereumのクライアントを作成します。
スマートコントラクトアクセス用のC#のコードを生成する方法は、以下の記事を参考にしました。

生成されたC#のコードを.Net Frameworkで利用することもできます。

拡張機能のインストール

VS Codeで、拡張機能のsolidityをインストールします。
似た名前の拡張がいくつかあるので気をつけてください。

フォルダの作成

以下のようにフォルダを作成してから、VS CodeでEthereumSmartContractsフォルダを開きます。すでにフォルダを開いている場合は、一旦閉じで開き直します。このフォルダがカレントパスになり、ファイルが生成されます。出力するフォルダが設定できないのが少し不便です。
Contractsフォルダに、Solidityで記述したスマートコントラクトのsolファイルを配置します。

NethereumCodeGenDemo/
├ EthereumSmartContracts/
  ├ Contracts/
    | SimpleStorage.sol

設定ファイルの生成

VS CodeのView->Command Paletteから
Solidity:Create 'nethereum-gen.settings' with default values at root
を選択し、C#のコード生成の設定ファイルを生成します。


projectNameとnamespaceは、C#のコード生成時に使用されます。作成するプロジェクトに応じて変更してください。ここでは、projectPathをCSharpに変更しています。

nethereum-gen.setting
{
    "projectName": "EthereumSmartContracts",
    "namespace": "EthereumSmartContracts.Contracts",
    "lang": 0,
    "autoCodeGen": true,
    "projectPath": "./CSharp"
}

コンパイルとコード生成

solファイルを選択した状態で、VS CodeのView->Command Paletteから
Solidity:Compile and Code generate CSharp contract definition
を選択し、solファイルのコンパイルとC#のコード生成を行います。
Contractsフォルダに、スマートコントラクトをコンパイルした結果、CSharpフォルダにC#のコードがそれぞれ作成されます。

ターゲットフレームワークの修正

TargetFrameworkを確認して、netcoreapp3.1でなければ変更します。

EthereumSmartContracts.csproj
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>netcoreapp3.1</TargetFramework>     
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include = "Nethereum.Web3" Version="3.8.0" />
    </ItemGroup>

</Project>

また、複数のバージョンの.Netがインストールされている場合は、global.jsonをNethereumCodeGenDemoフォルダに置きます。

global.json
{
    "sdk": {
      "version": "3.1"
    }
}

コード生成時に追加されるNethereum.Web3のバージョンが古いので最新に更新します。

dotnet add package Nethereum.Web3

テストプロジェクトの作成

ターミナルでNethereumCodeGenDemoフォルダに移動して、以下のコマンドを実行します。

ソリューションファイルを作成します
dotnet new sln --name NethereumCodeGenDemo

テスト用のコンソールアプリプロジェクトを作成します。
dotnet new console --name SimpleStorageConsole

ソリューションにプロジェクトを追加します。
dotnet sln add ./SimpleStorageConsole/SimpleStorageConsole.csproj
dotnet sln add ./EthereumSmartContracts/EthereumSmartContracts.csproj

cd SimpleStorageConsole

Nethereum.Web3のパッケージを追加します。
dotnet add package Nethereum.Web3

生成されたスマートコントラクトのC#クラスを参照する設定を行います。
dotnet add reference ../EthereumSmartContracts/CSharp/EthereumSmartContracts.csproj

テストコードの追加

スマートコントラクトから値を読み込むコードをProgram.csに追加します。

Program.cs
using QuorumSample.Contracts.simplestorage;
using Nethereum.Web3;
using System;
using System.Threading.Tasks;

class Program
{
    static void Main(string[] args)
    {
        Demo().Wait();
    }

    static async Task Demo()
    {
        try
        {
            // アクセスするノードのIP
            var url = "http://127.0.0.1:8545";
            var web3 = new Web3(url);
            //スマートコントラクトのアドレス
            var contractAddress = "0x0123456789ABCDEF0123456789ABCDEFF0123456";
            //生成されたスマートコントラクトのクラス
            var service = new SampleService(web3, contractAddress);
            // スマートコントラクトのget()メソッドで値を取得します
            var currentStoredValue = await service.GetQueryAsync();
            Console.WriteLine($"Contract has value stored: {currentStoredValue}");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }

        Console.WriteLine("Finished");
        Console.ReadLine();
    }
}

実行

VS CodeのRun and Debugで実行します。

まとめ

Netereumを使って、C#からスマートコントラクトにアクセスすることができました。スマートコントラクトからC#のコードを生成する必要があるので少し面倒です。

Quorumの場合は、書き込みの際注意が必要です。 Raftを使用するとタイムスタンプの単位がmsになってうまくいかないためIBFTを使用します。 nethereumでは、プロトコルはEIP1559がデフォルトになっているので、エラーになる場合はレガシーモードに設定します。 書き込みについては、別の記事で説明したいと思います。