新しいJava APIを利用してCorda Tokensを簡単に作成する

R3のデベロッパーエンジニアAnthony Nixonにより書かれた記事をTaira Nakamuraが日本語訳しました。

 


2020年5月21日

四半期リリースで新たなToken SDKが実装された。洗練されたAPIと2つの新しいtokenbuilderという形で、Java開発者にとってうれしい機能が追加されました。この投稿では、これらの変更点のいくつかを取り上げ、Cordaでデジタルアセットを使用することがこれまでになく簡単にできる例を示します。

Spaceships sample projectで提供されているCode snippetsとそのサンプルはこちらのリンクから入手可能です。

まず、始める前に、Cordaでトークンを発行するプロセスを簡単にまとめます。 発行には、fungibleとnon-fungibleの2種類があります。たとえば、代替可能なトークンは、分割や統合のできるトークンで、ペソや米ドルなどの法定通貨、または株のシェアがあげられます。non-fungible tokenは、分割できず、全体として発行、移動、引き換えられるものです。例として家や自転車など、現実世界でユニークなものを表現するのに役立ちます(Token SDKの完全な要約と無料のCordaトレーニングについては、こちらをご参照ください。)。

トークンの各タイプはビルディングブロックで構成されており、開発者はより柔軟に台帳上のデジタルアセットを表現することができます。

Fungible tokenは次の要素で構成されています。

fungible_token.png

Non-fungible tokenは次のように構成されています。

 non-fungible_token.png

これらの各コンポーネントは、発行前にfinal tokenを作成するために定義及びインスタンス化する必要があるオブジェクトです。なれるととても簡単ですが、以前は少し面倒でした。

以下はもとのToken-SDKで作成されたfungible tokenの例です。

TokenType myToken = new TokenType("My Token", 2);

IssuedTokenType issuedMyToken = new IssuedTokenType(issuingParty, myToken);

Amount<IssuedTokenType> amountMyIssuedToken = new Amount<>(100, issuedMyToken);

FungibleToken fungibleMyToken = new FungibleToken(amountMyIssuedToken, holder);

現在はすごく簡単に発行できるようになっています。

お金と通貨のユーティリティ

Cordaで作成する最も一般的なToken Types1つは、実際のISO標準の法定通貨の表現です。 Corda Token SDKにこれらのトークンを迅速にインスタンス化するためのユーティリティクラスが含まれていることに気付かない人も多いと思います。[Source code]

__.jpg

MoneyUtilitiesクラスは主要なフィアット通貨とデジタル通貨に対して正しく定義されたTokenTypesAmouts of TokenTypesを取得します。これはFiatCurrencyおよびDigitalCurrencyの定義を利用しています。

import com.r3.corda.lib.tokens.money.MoneyUtilities;

// Instantiating currencies and amounts

TokenType usdTokenType = MoneyUtilities.getUSD();

TokenType rippleTokenType = MoneyUtilities.getXRP();

Amount<TokenType> amountAUD = MoneyUtilities.getAUD(100.22);

これらの標準通貨がトークン発行にどのように供給されるかについての基本的なデモについてはこちらをご参照ください。

Javaを使ってAmountをハンドリングする

前のコードブロックから、MoneyUtilitiesの呼び出しでAmount <TokenType>のインスタンスをすばやく生成できたと思いますが、独自でカスタムをするTokenTypes、または動的TokenTypeについては生成できたでしょうか?これらを生成するために、AmountUtilitiesを利用します。

最も単純な形式では、任意のTokenTypeの量をすばやく返すことができます。

import com.r3.corda.lib.tokens.contracts.utilities.AmountUtilities;

// Creating an amount of customTokenType

double amount = 102.00;
TokenType customTokenType = new TokenType("Bob Token", 2);

Amount<TokenType> myAmount = AmountUtilities.amount(newValue, customTokenType);

より発展的な方法として、fixed exchange ratesを用いてTokenTypeを別のTokenTypeに換金するサンプルについては こちらをご参照ください。[Source code]

/**
* exchangeCurrency calculates an amount back in targetCurrency that is fair exchange with an itemCurrency
* This allows a buyer to know how much of his held currency to give to a seller to satisfy the price.
*
@param amount
* @param targetCurrency
* @return
*/
static Amount<TokenType> exchangeCurrency(Amount<TokenType> amount, TokenType targetCurrency) {
   
int itemCurrFractionDigits = amount.getToken().getFractionDigits();
   
double newValue = (amount.getQuantity()/Math.pow(10,itemCurrFractionDigits)) * (rates.get(amount.getToken().getTokenIdentifier()) / rates.get(targetCurrency.getTokenIdentifier()));
   
return AmountUtilities.amount(newValue, targetCurrency);
}

Amountsを作るだけよりもAmountUtilitiesは繰り返し合算可能な関数の機能を持っています 。合算したい金額がたくさんある?。問題はありません。

List<Amount<TokenTypes>> myAmounts = ...;

Amount<TokenType> mySum = AmountUtilities.sumTokensOrThrow(myAmounts);

 

Java Token Builders

______.png

基礎的な通貨TokenTypesは理解できましたか?心強いヘルメットをかぶって、Java開発者にとってこのリリースで最大の難関を始めましょう!新しいFungibleTokenBuilderNon-FungibleTokenBuilderクラスへすすみます。

 完成されたトークンの構成方法をどのように説明したか覚えていますか(上の図を参照)?構築は多段階なプロセスでした。
Kotlinでは、Token SDKの最初のリリース以降、言語の修正内記法を利用して、次のような構文でトークンを迅速に構築できました。

val myFungibleToken = 10.GBP issuedBy issuingParty heldBy holder

しかし、Javaに類似するものは何もありませんでした。今までは。

TokenBuilderクラスはJava開発者にとっては使い慣れたビルダーパラダイムを使用して、この呼び出しを複製化しています。

FungibleTokenを作っていきましょう。

Party issuingParty = ...;
Party holder = ...;
FungibleToken token = new FungibleTokenBuilder()
.ofTokenType(MoneyUtilities.getGBP())
.withAmount(10)
.issuedBy(issuingParty)
.heldBy(holder)
.buildFungibleToken();
Let’s build a NonFungibleToken:
Party manufacturer = ...;
Party owner = ...;
NonFungibleToken token = new NonFungibleTokenBuilder()
.ofTokenType(new BicycleTokenType())
.issuedBy(manufacturer)
.heldBy(owner)
.buildNonFungibleToken();

とても読みやすくて簡潔ですね。さらに、ビルダーは構成が正しいかを確認してくれるので、トークン作成でステージを逃す心配はありません。

ビルダーの使用方法の詳細については、spaceshipsのreference sampleを参照してください。これらのビルダーを使用して、fungibleおよびnon-fungibleなspace craftをトークン化します。[Source code]

 

Flowをよりフレキシブルにする

Javaで簡単に構築できるのはトークンだけではありません。Flowにおいても力を発揮します。トランザクションを作るところから、アセットのクエリと操作をするところまでカバーしています。ここに利用可能なツールをいくつかご紹介したいと思います。

NotaryUtilities:NotaryはCordaのワークフローにおいて、根幹をなす部分です。(もし、復習が必要であればこちらをご参照ください。)。Token SDKには、あなたのトランザクションを承認するNotaryNotaryを、アルゴリズムを用いて決める機能を持ったユーティリティが含まれています。もしあなたがCordaを始めたばかりなら、次のようなコードに慣れ親しんでいるかもしれません。

getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);

このコードはネットワーク上で利用可能な最初のNotaryを得ることができます。NotaryUtilitiesクラスでは推奨されたNotaryを定義することができます。デフォルトでは一番はじめのNotaryですが、静的、アルゴリズム、ランダムに選択するを選んでオーバーライドすることができます。(注:Notary選択の作製は発行時しか行えません。通常、ライフサイクル全体を通じて、同じNotaryに結びつける必要があります。したがって、後続の操作のために、Notaryからinput-stateを切り離します。)

トークンのクエリ ー 台帳のうえには何があるでしょうかShow_me_the_money.png

CordaはVault(またの名をledger)に対するクエリのパターンが用意されています。(復習はこちらのリンクから)。基本的なことはすべて適用されますが、トークンはとても標準化され、定義されているため、QueryUtilitiesを介してJavaで必要な情報を素早く簡単に提供しています。

QUeryUtilities.pngQueryUtilitiesを用いてトークン上でクエリが利用可能

上記のように、ノードの観点からFlowで呼び出されると、FungibleまたはNonFungibleの状態、量、およびQueryCriteriaオブジェクトをすばやく取得できます(より複雑なqueryBy操作を構築するため)。 シンプルで簡単です。 spaceshipサンプルから取得した以下のcode-snippetは、保有するSpaceShipTokenTypeの量とその値(プロパティ)を相手方に送信します。[Source code]

@Suspendable
@Override
public Void call() throws FlowException {
   
// receive request for value of the given shipId
   
String shipId = counterpartySession.receive(String.class).unwrap(it -> it);
    UUID shipUUID = UUID.
fromString(shipId);

    SpaceshipTokenType spaceshipTokenType = FlowHelpers.
uuidToSpaceShipTokenType(getServiceHub().getVaultService(), shipUUID);

    Amount<TokenType> amountOfSpaceShipTokens = QueryUtilities.
tokenBalance(getServiceHub().getVaultService(), spaceshipTokenType.toPointer());

   
counterpartySession.send(new Pair<>(amountOfSpaceShipTokens, spaceshipTokenType.getValue()));
   
return null;
}

トークン選択とトランザクションを構築する

Token SDKベースは、Javaの姉妹言語Kotlinでプログラムされています。これには多くの利点があり2つは100%相互運用可能です。SDKの初期バージョンを使用すると、提供されたFlowによってトークンの発行、移動、または引き換えが楽しいものであることが理解できたはずです。 たとえば、私は Ashutoshにいくつかのトークンを1行で送信できます。

new MoveFungibleTokens(new PartyAndAmount<>(ashutosh, amount))); 

しかし、もっと複雑なトランザクション(例えば要素をTransction Builderに手動で加える )ことになると、デフォルトのパラメーターがオーバーロードできない事実にイライラしていたかもしれません。

tokenSelection.generateMove(getRunId().getUuid(), Collections.singletonList(sendingPartyAndAmount), getOurIdentity(), null

ーあれ、()がいっぱいみれらます。どうして引数がnullばかりなんでしょう

その答えはすごくシンプルでConstructorとfunction signatureは今はオーバーロードできるのです。もう一度試してみましょう。

tokenSelection.generateMove(Collections.singletonList(sendingPartyAndAmount), getOurIdentity());

あなたはすでに追加されたパラメーターすべてにアクセスすることができます。

飛び込む準備はいい?spaceshipの例でatomic性(単一トランザクション)と支払いの交換について確認してください。[Source code]

 

新しいクエリはシンプルな設計に

新しいトークンを作ったり基本的な操作やクエリなどを行うことがとても簡単なのが確認できましたね。でも、ほかに何ができるのでしょうか?ターゲットが選定された、カスタムクエリの操作にラムダを使用するのはどうでしょうか?これは標準のクエリを超えることができます。TokenQueryByクラスを入力しましょう。

ここに基本的なフォーマットがあります。TokenQueryByをインスタンス化し、自分の想像力だけに限定され作成したpredicates(SQLにおける述語)を渡します。それをtoken Selectorに渡します。

TokenQueryBy tokenQueryBy = new TokenQueryBy(
        issuer,
        it -> {...condition...}
);
Selector selector =
new DatabaseTokenSelection(getServiceHub());
return selector.selectTokens(totalAmountHeld, tokenQueryBy);

spaceshipのサンプルでは、このパターンをシンプルでクリエイティブに使用しています。ユーティリティ関数は、すべてのfungible tokensを小数で返します。これは「なめらかな変更ファインダー」です。これを例として使用すると、任意のタイプのpredicatesを作成できます。[Source code]

 

今後は?

これまで最新のリリースによって変更されたToken SDKのAPIの一部を紹介してきました。まだまだ 、開発の際に躓きやすいポジティブな変更や機能がたくさんあります。

リリース初期段階から、世界中にある大企業がCorda tokenをCorDappに統合しています。今回ご紹介したものはデジタル資産の表現をもっとの効果的に標準化できる方法の1つだと思います。構築と開発をつづけ、将来のリリースに引き続き注目ください。それまでの間、新しい無料のCordaトレーニングプラットフォームをご覧ください。

Corda上のアプリケーション構築をさらに学びたい方はcorda.netcommunity pageでほかのCorda開発者とつながりましょう。また、sign upしていただければ最新のアップデートのニュースレターをお送りします。

 

 

Written by Taira Nakamura

Updated:2020/6/18

この記事は役に立ちましたか?
0人中0人がこの記事が役に立ったと言っています