1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2022-02-07

はじめに

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をインストールします。
似た名前の拡張がいくつかあるので気をつけてください。
スクリーンショット 2021-05-07 185307.png

フォルダの作成

以下のようにフォルダを作成してから、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#のコード生成の設定ファイルを生成します。

スクリーンショット 2021-05-07 190403.png
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#のコードがそれぞれ作成されます。
スクリーンショット 2021-05-10 10.44.19.png

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

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がデフォルトになっているので、エラーになる場合はレガシーモードに設定します。
書き込みについては、別の記事で説明したいと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?