Logo
    Logo

    Search

    R3-Solana連携

    Blockchainトレンド

    Corda活用事例

    Corda技術

    おすすめ記事

    記事を探す

    その他

    お客様サポート

    SBI R3 Japan HP

    お問い合わせ

    アカウントライブラリ(Accounts library)入門

    公開日
    Apr 24, 2021
    カテゴリ
    Corda技術を知る
    タグ
    🧑‍💻CorDapp開発🔰Corda入門
    筆者
    image
    icon
    この記事で学べること

    Cordaの入門資料が網羅的に知ることができます。

    icon
    目次
    • Cordaのアカウントとは
    • デザイン
    • 鍵とプライバシーに関する検討事項
    • アカウントの利用方法:代表的なワークフロー
    • CorDappにAccounts libraryを追加
    • 新規アカウントの作成(例:AccountInfoのState)
    • IDまたは名前でアカウントを検索
    • アカウントの公開鍵をリクエストする
    • アカウントを別のノードと共有する
    • アカウントIDでVaultを照会します
    • トランザクションへの署名
    • もっと詳しく知る

    Cordaのアカウントとは

    Corda 4.3以前では、Stateの参加者が利用できるデータタイプはAbstractParty、つまりPartyやAnonymousPartyのみでした。そのため、各参加者は自分のCordaノードを実行する必要があり、高い運用コストが発生していました。

    Accounts Libraryはこの問題を解決します。このライブラリは、CordaノードのVaultを、ホストされているアカウントに関連付けられた論理的なサブセットに分割する方法を提供します。アカウントは CordaX500Name を持っていませんが、ホスティングノードが所有するアカウントに関連付けられています。

    デザイン

    アカウントとは、単純に[AccountInfo]というタイプのStateで、以下の属性を持っています。

    • Party host :これはアカウントをホストしているノードで、PublicKeysをホストノードにマッピングするために使用されます。
    • String name :これはユーザ名に似ています。Account ライブラリは、AccountInfo.name がすべてのホストノードで一意であることを保証します。
    • UniqueIdentifier identifier: ライブラリは AccountInfo.identifier がネットワーク内で一意であることを保証します。これは128ビットのランダムなIDです。このアカウントIDは、CordaがPublicKeyをアカウントにマッピングする際に使用されます。
    image

    Corda ノードのアカウントは、同じ UUID に割り当てられた PublicKey の集まりです。この UUID は AccountInfo ステートの linearId です (上で説明しています)。これらの PublicKeys は ContractStates に参加するために使用することができます。ContractStateを含むトランザクションが台帳にコミットされると、そのContractState`は、そのPublicKeyを持つアカウントによって所有または参加されていると言えます。

    鍵とプライバシーに関する検討事項

    Cordaでアカウントを使用することを検討する際に、重要な点を説明します。

    1. 取引の署名は、アカウントではなく、Corda のノードの法的な ID で行われます。(
    2. アカウントをホストしているノードは、そのアカウントの公開鍵とペアとなる秘密鍵を所有しています。トランザクションは、必要に応じて、そのアカウントを所有するCordaノードによって署名されます。ネットワークレベルでは、トランザクションはホストノードのリーガルアイデンティティに解決されます。)

    3. ノードのオペレータはすべてのStateを見ることができます。
    4. CorDapp内のデータへのアクセスの制限は開発者の責任であり、その実装はCordaの範囲外です。

    アカウントの利用方法:代表的なワークフロー

    CorDappにAccounts libraryを追加

    ルートの build.gradle に以下を追加します。

    そして、contract/build.gradleとworkflows/build.gradleにもこれらを追加します:

    dependencies {
    // in contracts build.gradle
    cordaCompile "$accounts_release_group:accounts-contracts:$accounts_release_version"
    
    // in workflows build.gradle
    cordaCompile "$confidential_id_release_group:ci-workflows:$confidential_id_release_version"
    cordaCompile "$accounts_release_group:accounts-workflows:$accounts_release_version"
    }

    新規アカウントの作成(例:AccountInfoのState)

    IDまたは名前でアカウントを検索

    新しいアカウントを作成したら、次の方法を使用して、 AccountServiceを使用して、名前またはアカウントIDでAccountInfoを取得できます。

    fun accountInfo(id: UUID): StateAndRef<AccountInfo>?
    fun accountInfo(name: String): List<StateAndRef<AccountInfo>>?

    アカウントは、次のflowを使用して名前とアカウントIDで検索することもできます。:

    subFlow(AccountInfoByName(id: UUID)): StateAndRef<AccountInfo>?
    subFlow(AccountInfoByUUID(name: String)): List<StateAndRef<AccountInfo>>?

    アカウントの公開鍵をリクエストする

    アカウントにはデフォルトの公開鍵が付属していません。 したがって、アカウントと取引したり、アカウントを使用したりする前に、ホスティングノードに公開鍵を要求する必要があります。

    // Requestor flow.
    // Assumption is that we already have the AccountInfo.
    val accountInfo: StateAndRef<AccountInfo> = accountService.accountInfo("Some account name")
    val newKey: AnonymousParty = subFlow(RequestKeyForAccountFlow(accountInfo = accountInfo,
    hostSession = initiateFlow(accountInfo.state.data.host)
    ))
    
    // Responder flow.
    subFlow(SendKeyForAccountFlow(otherSideSession))

    注:RequestKeyForAccountFlowが呼び出されると、常に新しい公開鍵が生成されます

    アカウントの新しい公開鍵を生成する必要は必ずしもなく、古い公開鍵は再利用できます。これは、CorDappのニーズによって異なります。 次に例を示します。

    // retrieve the public keys associated with the account ID
    val accountKeys = accountService.accountKeys(accountInfo.identifier.id)
    return if (accountKeys.isEmpty()) {
    // generate a new key if no other keys are found
    subFlow(RequestKeyForAccount(accountInfo))
    } else {
    // return an AnonymousParty reusing an old one
    AnonymousParty(accountKeys.first())
    }

    アカウントを別のノードと共有する

    トランザクションを開始する前に、 AccountInfosを必要とするCordaノードとアカウントを共有することが重要です。 アカウントを他のノードと共有するには、次のようにします。

    // party is another Corda node <Party>
    subFlow(ShareAccountInfo(account, party))

    アカウントIDでVaultを照会します

    Vaultにクエリを実行して、指定したアカウントIDに関連付けられているStateを返すことができます。 アカウントIDが不明な場合、またはStateが見つからない場合、クエリは空のリストを返します。

    rpcProxy.vaultQueryByCriteria(
    QueryCriteria.VaultQueryCriteria(externalIds = listOf(accountId)), StateClass::class.java
    )
    
    serviceHub.vaultService.queryBy(
    QueryCriteria.VaultQueryCriteria(externalIds = listOf(accountId)),StateClass::class.java
    )

    トランザクションへの署名

    秘密鍵を持つ唯一のエンティティであるため、ホスティングノードのみがトランザクションに署名できます。 では、Cordaアカウントではどのように機能しますか?

    // retrieve the public key of the account from its AccountInfo.
    // This returns an AnonymousParty.
    val account : AnonymousParty = subFlow(RequestKeyForAccount(accountInfo))
    
    // initially sign the transaction using the public key of the account
    val partiallySignedTx : SignedTransaction = serviceHub.signInitialTransaction(txBuilder,listOf(account.owningKey))

    signInitialTransactionは、アカウントの公開鍵からホスティングノードの秘密鍵を取得します。

    CollectSignatureFlowを使用してリモートアカウントの署名を収集する必要がある場合は、そのホスティングノードのIDを取得してから、それとのセッションを開く必要があります。

    // retrieve the identity of the hosting node of the remote account
    val remoteHost : Party? = serviceHub.identityService.partyFromKey(remote-account.owningKey)
    
    // open the session with the hosting node
    val session : FlowSession = initiateFlow(remoteHost)
    
    // call the CollectSignatureFlow using this session
    subFlow(CollectSignaturesFlow(partiallySignedTx, session))

    もっと詳しく知る

    • Corda Training Webサイト:https://training.corda.net/libraries/accounts-lib/ Accounts libraryとは何か、およびその使用方法を学ぶためのウォークスルーハンズオントレーニング。
    • 設計ドキュメント:https://github.com/corda/accounts/blob/master/docs.md アカウントライブラリAccounts libraryのすべての技術的な詳細を説明する、R3のエンジニアによって書かれた公式の設計ドキュメント。
    • githubのCorDappサンプル:https://github.com/corda/samples-kotlin/tree/master/Accounts
    • R3 Corda Bootcamp video: https://www.youtube.com/watch?v=WTvBuLljCgM
    📬
    最後までお読みいただきありがとうございます。当社へのご質問・ご要望がございましたら、📪SBI R3 Japan お問い合わせフォーム📪よりお気軽にお問い合わせください!

    <ご質問・ご要望の例>

    • Corda Portalの記事について質問したい
    • ブロックチェーンを活用した新規事業を相談したい
    • 企業でのブロックチェーン活用方法を教えて欲しい 等々
    📢
    また、厳選されたCordaに関する最新情報をお伝えるするメールマガジンやX、当社主催のイベントコミュニティを運営しております。ぜひご登録ください。
    • Cordaメールマガジンに登録
    • X(旧Twitter)をフォロー
    • 弊社イベントコミュニティ(Connpass)に参加
    Logo

    © copyright SBI R3 Japan 2025

    GitHubYouTubeXFacebookLinkedIn
    buildscript {
    ext {
    accounts_release_group = 'com.r3.corda.lib.accounts'
    accounts_release_version = '1.0'
    confidential_id_release_group = "com.r3.corda.lib.ci"
    confidential_id_release_version = "1.0"
    }
    }
    
    dependencies {
    cordapp "$confidential_id_release_group:ci-workflows:$confidential_id_release_version"
    cordapp "$accounts_release_group:accounts-contracts:$accounts_release_version"
    cordapp "$accounts_release_group:accounts-workflows:$accounts_release_version"
    }
    
    task deployNodes() {
    nodeDefaults {
    cordapp("$accounts_release_group:accounts-contracts:$accounts_release_version")
    cordapp("$accounts_release_group:accounts-workflows:$accounts_release_version")
    }
    }
    // Create account by invoking flow via RPC.
    val accountInfo: StateAndRef<AccountInfo> = rpcProxy.startFlow(::CreateAccount, "Roger's account").returnValue.getOrThrow()
    
    // Create account by using sub flow (from inside a flow).
    val accountInfo: StateAndRef<AccountInfo> = subFlow(CreateAccount("Roger's account"))
    
    // The AccountService provides access to triggering Account related flows from within a Corda Service.
    val accountInfo: StateAndRef<AccountInfo> = accountService.createAccount("Roger's account").getOrThrow()