Cordaの入門資料が網羅的に知ることができます。
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をアカウントにマッピングする際に使用されます。
Corda ノードのアカウントは、同じ UUID に割り当てられた PublicKey の集まりです。この UUID は AccountInfo ステートの linearId です (上で説明しています)。これらの PublicKeys は ContractStates に参加するために使用することができます。ContractStateを含むトランザクションが台帳にコミットされると、そのContractState`は、そのPublicKeyを持つアカウントによって所有または参加されていると言えます。
鍵とプライバシーに関する検討事項
Cordaでアカウントを使用することを検討する際に、重要な点を説明します。
- 取引の署名は、アカウントではなく、Corda のノードの法的な ID で行われます。(
- ノードのオペレータはすべてのStateを見ることができます。
- CorDapp内のデータへのアクセスの制限は開発者の責任であり、その実装はCordaの範囲外です。
アカウントをホストしているノードは、そのアカウントの公開鍵とペアとなる秘密鍵を所有しています。トランザクションは、必要に応じて、そのアカウントを所有するCordaノードによって署名されます。ネットワークレベルでは、トランザクションはホストノードのリーガルアイデンティティに解決されます。)
アカウントの利用方法:代表的なワークフロー
CorDappにAccounts libraryを追加
ルートの build.gradle
に以下を追加します。
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")
}
}
そして、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)
// 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()
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
<ご質問・ご要望の例>
- Corda Portalの記事について質問したい
- ブロックチェーンを活用した新規事業を相談したい
- 企業でのブロックチェーン活用方法を教えて欲しい 等々