この記事は、暗号通貨や分散型金融に関するものではありません。その代わりに、パブリック EVM ブロックチェーンと、特定のニーズや目標に応じて次のプロジェクトでどのように使用できるかについて説明します。私が取り組んでいる0xwebライブラリを使用して、長所、短所、および実用的な例について詳しく説明します。
すでに稼働しています。データ モデルをコントラクトとして定義し、デプロイするだけです。
データがアップロードされると、ブロックチェーンが動作している限り、そのデータにはアクセスできます。他のホスティング サブスクリプションよりもはるかに長くなると考えられます。
ブロックチェーンの読み取りプロセスと書き込みプロセスを分離することで、特に冗長性のために複数の RPC プロバイダーを活用する場合に、読み取り操作の 100% の稼働時間が保証されます。
ブロックチェーンは、本質的に従来のホスティング ソリューションよりも高いレベルのセキュリティを提供します。データの悪用は、データ モデルのロジックに脆弱性が存在する場合にのみ可能です。
暗号化されない限り、データは誰でも公開され、アクセスおよび検証可能な状態となり、透明性が向上します。
このタイプのバックエンドではドメイン名は不要です。代わりに、分散ノード プロバイダーのリストを使用できるため、クライアント ライブラリはエンド ユーザーにとって最も効率的なオプションを選択できます。
上記の機能のおかげで、ブロックチェーン ベースのバックエンドは、プロジェクトのメンテナンスと開発が停止した場合でも、データのセキュリティと 24 時間 365 日の可用性を確保することで、本質的にユーザーの信頼を構築します。
ブロックチェーンに保存されている他のデータ モデルを統合したり、他のプロジェクトをデータ モデル上に構築したりできます。
ユーザーは多数のサードパーティ プロジェクトを活用してアクションを監視または自動化できるため、データ モデルの可能性が大幅に広がります。
過去のどの時点からでもデータにアクセスできます。
履歴カスタム イベントを読み込むか、WebSocket を使用してリアルタイムの受信イベントをリッスンし、動的なアプリケーション応答を有効にします。
「ウォレット」のコンセプトにより、ユーザーはメッセージに署名することで自分自身を認証でき、シームレスで分散化されたユーザー識別が提供されます。
ユーザーは、定義した権限に基づいてストレージ内のデータを変更または拡張できます。重要なのは、これらの変更にかかるコストはユーザー自身が負担することです。低コストのブロックチェーンを選択すると、これらの料金はごくわずかで、多くの場合、トランザクションあたり数セント程度になります。
これは、実際の従量課金モデルに従っていますが、保存するスロットに対してのみ支払います。各スロットは 32 バイトで、新しいデータを書き込むには 20000 GAS、データを更新するには 5000 GAS かかります。例として、GAS 価格が 30 グウェイ、POL 価格が $0.60 の Polygon を見てみましょう。
20000GAS × 30gwei = 0.008 POL × $0.60 = $0.00032
これはかなり大きいため、「フロッピー ディスク」の絵文字はストレージ容量を最もよく表しています。つまり、自分で支払う場合は、小規模なデータセットに最適です。ただし、独自の利点は、ユーザーが自分のストレージとアクションのコストを負担できることです。これは他のテクノロジーには見られない機能です。このアプローチはアプリの大量導入を妨げる可能性がありますが、ブロックチェーン コミュニティでは広く受け入れられています。
ブロックチェーン データ モデルは、データと対話するための機能をサポートしていますが、その計算機能には制約があります。これらの制限は、読み取りアクションに使用する RPC ノードと、書き込みアクション (トランザクション) に課せられる厳格な GAS 制限によって異なります。基本的な操作、ループ、およびより深い呼び出しスタックは通常管理可能ですが、ブロックチェーンは大量の計算ワークロードには適していません。
とはいえ、通常、関係するデータ サイズは比較的小さいため、既存の制限は通常、ほとんどのユース ケースで十分です。
ブロックチェーン開発を初めて行う場合は、複雑で始めるのが難しいと聞いたことがあるかもしれません。しかし、これは真実ではありません。ブロックチェーン開発では、一般的な概念、セマンティクス、構文が使用されるため、見た目よりも簡単に学習できます。
https://github.com/0xweb-org/examples-backend
この記事では、アプリケーション バージョン マネージャー コントラクトを作成しましょう。新しいバージョンが公開されるたびに、バックエンドで新しいバージョンをチェックし、ダウンロード リンクを取得する必要があるデスクトップ アプリケーションがあるとします。以下は、主要な概念のほとんどを示す最終的なコントラクトです。
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; struct Package { uint version; uint timestamp; string url; bytes32 sha256; } contract AppVersionManager is Ownable { // Events that are emitted on data updates event NewApplicationInfo(); event NewPackage(uint version, uint timestamp); // Custom error, when title for the application is empty error TitleIsEmpty(); // Some application information string public title; // @TODO: add further application related properties if required // Latest package Package public package; // Track all versions and their packages mapping (uint => Package) public packages; // List of all previous versions uint[] public versions; constructor () Ownable(msg.sender) { } function updateInfo(string calldata newTitle) external onlyOwner { if (bytes(newTitle).length == 0) { revert TitleIsEmpty(); } title = newTitle; emit NewApplicationInfo(); } function updatePackage(Package calldata newPackage) external onlyOwner { require(newPackage.version > package.version, "Newer package already published"); packages[package.version] = package; package = newPackage; versions.push(package.version); emit NewPackage(package.version, block.timestamp); } function findPackageAtTimestamp (uint timestamp) external view returns (Package memory) { if (package.timestamp <= timestamp) { return package; } // the countdown loop to find the latest package for the timestamp int i = int(versions.length); while (--i > -1) { Package memory pkg = packages[versions[uint(i)]]; if (pkg.timestamp <= timestamp) { return pkg; } } revert("No package found"); } function getPackage (uint version) external view returns (Package memory) { if (version == package.version) { return package; } return packages[version]; } }
すべての開発者は、最小限の労力でこのコードを読んで理解できます。TypeScript に精通している場合は、ここで説明する概念のほとんどはすでに理解できます。さらにわかりやすくするために、同等の TypeScript の例であるAppVersionManager.tsを作成しました🔗 。
簡単に言えば、Solidity のコントラクトは、ステートフルなクラス インスタンスと考えることができます。プロパティ、メソッド、型、継承の概念は、オブジェクト指向プログラミングではすでによく知られています。ここで説明する主な概念は、 onlyOwner
修飾子 (TypeScript のデコレータに似ています) です。
すべてのブロックチェーン アカウントは、基本的に秘密鍵と公開鍵のペアです。アカウントの ID (アドレス)は公開鍵から派生します。トランザクションが実行されると、送信者のアドレスがmsg.sender
として渡されます。これを使用して、コンストラクタにアドレスを保存できます (コントラクトのデプロイ中)。後で、 onlyOwner
修飾子によって、コントラクト所有者であるあなただけがupdateInfo
とupdatePackage
関数を実行できるようになります。他の誰かがこれらのアクションを試行すると、トランザクションは元に戻されます。onlyOwner 修飾子は、広く使用されているOpenZeppelinライブラリの一部であるonlyOwner
Ownable
によって提供されます。このライブラリには、ブロックチェーン開発を効率化するための他の多くの便利なコントラクトが含まれています。
議論すべきもう 1 つの重要なトピックは、ストレージと実装を 2 つの別々のコントラクトに分割するプロキシの概念です。Solidity のコントラクト実装は不変であるため、デプロイ後に新しい関数やプロパティを追加することはできません。この問題を回避するには、「プロキシ」コントラクトをデプロイします。プロキシはストレージを処理し、プロキシのストレージ コンテキストを維持しながら実装コントラクトへの呼び出しを委任するfallback
関数を 1 つだけ含みます。
この概念は複雑に聞こえるかもしれませんが、JavaScript でのthis
と似ています。わかりやすくするために、簡単な例え話を次に示します。
const foo = new Proxy({ bar: 'Lorem' }, { get (obj, prop) { return fooImplementation[prop].bind(obj) }, }); const fooImplementation = { logValue () { console.log('Bar value:', this.bar) } } foo.logValue();
プロキシ コントラクトは、実装コントラクトへの参照を保持します。新しい関数を追加する場合は、新しい実装コントラクトをデプロイし、この新しいコントラクトを参照するようにプロキシを更新して、関数呼び出しを更新されたインスタンスに転送するだけです。これは簡単なプロセスですが、考慮すべきエッジ ケースがあります。それはコンストラクターです。
実装コントラクトをデプロイする場合、そのコンストラクタは実装コントラクト自体のストレージ内で動作します。つまり、 title = "Hello World"
のようなセッターはプロキシのストレージを変更しません。これに対処するために、初期化関数の概念を使用します。
initialize
関数を使用して実装コントラクトをデプロイします。initialize
メソッドを呼び出すことができます。
その結果、たとえばtitle
プロパティを更新すると、プロキシのストレージ内で正しく更新されます。
以下は、AppVersionManager のアップグレードされた実装バージョンです: AppVersionManagerUpgradeable.sol 。
プロキシ コントラクト自体は非常に普遍的であり、実装に依存しません。プロキシのよく知られた標準がいくつか OpenZeppelin ライブラリで利用できます。
これらの概念と上記の例を理解することで、ビジネス ケース用のスマート コントラクトを開発する準備が整います。
まず、契約をデプロイするブロックチェーンを選択する必要があります。この例では、Polygon を選択しました。Polygon はトランザクション コストが低く、長い間存在し、一貫して優れたパフォーマンスを発揮しています。その安定した効率的なインフラストラクチャと、9 億ドルの Total Value Locked (TVL) を組み合わせると、信頼できる選択肢になります。契約をパブリック ブロックチェーンにデプロイするということは、金融機関と共存することを意味します。TVL メトリックは、これらの機関がブロックチェーンの信頼性に置く信頼を反映しています。
さらに、状況が変わった場合は、いつでも将来的に契約を別のブロックチェーンに再デプロイできます。
デモ プロジェクトは CI テスト リポジトリとしても機能するため、すべてのコマンドは次の場所にあります: https://github.com/0xweb-org/examples-backend/blob/master/deploy-cli.sh
# Install 0xweb library from NPM into the prject folder npm i 0xweb # Install required dependencies to compile/deploy *.sol files npx 0xweb init --hardhat --openzeppelin # Create or import the account. Private key will be encrypted with pin AND machine key. npx 0xweb accounts new --name foo --pin test --login # Save the private key securly and ensure the account has some POL tokens # Deploy. The foo account is selected as default. npx 0xweb deploy ./contracts/AppVersionManager.sol --chain polygon --pin test # Set title npx 0xweb c write AppVersionManager updateInfo --newTitle MySuperApp --pin test # Set latest package information npx 0xweb c write AppVersionManager updatePackage --arg0 'load(./data/package.json)' --pin test
ほんの数個のコマンドで、コントラクトをデプロイし、データを更新しました。バックエンドはこれで完了です。これで、ユーザー側でこれ以上の操作を必要とせずに、“永久に” 稼働するようになりました。このデプロイにかかるコストは、GAS 価格が 70 gwei、POL 価格が $0.51 の場合、次のようになります。
| ガス | ポーランド | $ |
---|---|---|---|
展開する | 850352 | 0.059 | 0.03 |
タイトルを保存 | 47517 | 0.0033 | 0.001 |
パッケージデータを保存する | 169549 | 0.0118 | 0.006 |
合計 | | | 0.037 |
わずか 4 セントで、メンテナンス不要の分散型で安全な長期実行サービスを構築できます。
契約データを照会するには、RPC ノード プロバイダーが必要です。 https://chainlist.orgには、多数の無料プロバイダーが用意されています。複数のプロバイダーを選択でき、優れた Web3 ライブラリは実行時にラウンドロビン戦略を利用して、エンド ユーザーにとって最も効率的なプロバイダーを選択できます。0xweb を使用すると、生成された TypeScript または JavaScript クラスは、最適なエンドポイントを選択するだけでなく、すべてのブロックチェーン通信を抽象化します。クライアントには、データを取得するための高レベルのメソッドが含まれているため、プロセスはシームレスかつ効率的になります。
# The deploy command also generates the class, but manual install is also possible npx 0xweb i 0x<address> --name AppVersionManager --chain polygon
import { AppVersionManager } from './0xc/polygon/AppVersionManager/AppVersionManager' const manager = new AppVersionManager(); console.log(`Title`, await manager.title()); console.log(`Package`, await manager.package());
他のプログラミング言語の場合、ブロックチェーンのクエリを簡素化するライブラリが多数あります。デプロイ後、コントラクト アドレスと ABI (インターフェイス) が提供されます。
あるいは、0xweb を使用してミドルウェア サーバーを起動し、契約データを照会することもできます。
npx 0xweb server start --port 3000 curl http://localhost:3000/api/c/read/AppVersionManager/package?chain=polygon
利点の 1 つは、アプリケーションにライブラリ (生の HTTP リクエスト) を含める必要がないことです。ただし、このアプローチでは、管理する必要がある追加のサーバーに依存します。多くの場合、0xweb で生成されたクラスまたは利用可能な他のブロックチェーン ライブラリを使用して、ブロックチェーンを直接クエリする方が適切です。
この記事では、ブロックチェーンがシンプルかつ強力であり、従来のホスティング ソリューションと比較して独自の利点を提供できることを紹介しました。
次の記事では、Greenfield や Arweave などの分散型 BLOB ストレージ ネットワークについて説明し、その機能と利点を強調する予定です。
0xweb ライブラリに追加できる機能についての提案やアイデアがある場合は、お気軽にコメント欄で共有するか、 [email protected]まで直接お問い合わせください。