はじめに
前回の記事では、Azure Blockchain Serviceのコンソーシアム管理機能を試しました。今回の記事では、コンソーシアムのメンバ間におけるプライバシーを実現する、プライベートなコントラクトおよびトランザクションについて実際に試してみます。
プライベートコントラクト
プライベートコントラクトは特定のメンバのみがアクセス可能なコントラクトです。
コントラクトのデプロイ
Truffleを利用してプライベートコントラクトをデプロイする場合は、デプロイスクリプト内のdeployメソッド呼出しのパラメータにprivateFor
要素を追加します。要素の値には公開先のトランザクションノードの公開鍵を配列で指定します。
トランザクションノードの公開鍵はポータル上で確認が可能です。
デプロイスクリプトを編集します。
const AlisToken = artifacts.require('AlisToken.sol');
module.exports = function deployContracts(deployer) {
deployer.deploy(AlisToken, {
privateFor: ["FZfPQmH3rEwPrrn/qXS6O4riab2uwlFHs5ls862djno=", "8PaJA+G+77dKlbJisrt2Lm9skU3yTuVrbkw9bMzyVSY="]
});
};
デプロイします。
$ truffle deploy
コントラクトにアクセス
以前の記事の手順でコントラクトのメソッドを呼出します。privateFor
で指定したトランザクションノードのエンドポイント経由でメソッドを呼出すと通常通り結果が返ってきますが、それ以外のトランザクションノード経由でメソッドを呼び出すとエラーになります。
privateFor
で指定していないトランザクションノードからメソッドを呼出した場合
$ node get_symbol.js
(node:10543) UnhandledPromiseRejectionWarning: Error: Returned values aren't valid, did it run Out of Gas?
at ABICoder.decodeParameters (/Users/g-hayakawa/workspace/azure-deploy-contract-example/node_modules/web3-eth-abi/src/index.js:226:15)
at Contract._decodeMethodReturn (/Users/g-hayakawa/workspace/azure-deploy-contract-example/node_modules/web3-eth-contract/src/index.js:465:22)
at Method.outputFormatter (/Users/g-hayakawa/workspace/azure-deploy-contract-example/node_modules/web3-eth-contract/src/index.js:818:46)
at Method.formatOutput (/Users/g-hayakawa/workspace/azure-deploy-contract-example/node_modules/web3-core-method/src/index.js:163:54)
at sendTxCallback (/Users/g-hayakawa/workspace/azure-deploy-contract-example/node_modules/web3-core-method/src/index.js:473:33)
at /Users/g-hayakawa/workspace/azure-deploy-contract-example/node_modules/web3-core-requestmanager/src/index.js:147:9
at XMLHttpRequest.request.onreadystatechange (/Users/g-hayakawa/workspace/azure-deploy-contract-example/node_modules/web3-providers-http/src/index.js:96:13)
at XMLHttpRequestEventTarget.dispatchEvent (/Users/g-hayakawa/workspace/azure-deploy-contract-example/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:22)
at XMLHttpRequest._setReadyState (/Users/g-hayakawa/workspace/azure-deploy-contract-example/node_modules/xhr2-cookies/dist/xml-http-request.js:208:14)
at XMLHttpRequest._onHttpResponseEnd (/Users/g-hayakawa/workspace/azure-deploy-contract-example/node_modules/xhr2-cookies/dist/xml-http-request.js:318:14)
at IncomingMessage.<anonymous> (/Users/g-hayakawa/workspace/azure-deploy-contract-example/node_modules/xhr2-cookies/dist/xml-http-request.js:289:61)
at IncomingMessage.emit (events.js:205:15)
at endReadableNT (_stream_readable.js:1154:12)
at processTicksAndRejections (internal/process/task_queues.js:84:9)
(node:10543) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:10543) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
プライベートトランザクション
プライベートコントラクトに対してトランザクションを送信する場合は、プライベートトランザクションとして送信します。
プライベートトランザクションの送信は、コントラクトデプロイ時と同様にトランザクションのパラメータにprivateFor
要素を追加します。
AlisToken.transfer.sendTransaction(
to, amount, {
from: "0x1c3051cd7c8c4203e75d06d9ebdea63d67dc7a96",
privateFor: ["FZfPQmH3rEwPrrn/qXS6O4riab2uwlFHs5ls862djno="]
});
ここでは、コントラクトデプロイ時にprivateFor
で指定した2つのトランザクションノードのうち、一方のみをprivateFor
に指定しています。この場合、トランザクションの実行はprivateFor
で指定したトランザクションノードのみで実行されます。そのため、2つのトランザクションノード間でコントラクトの状態(残高)が異なるという結果になります。
なお、プライベートではないコントラクトに対してプライベートトランザクションは利用できません。同様にプライベートコントラクトに対して、プライベートではないトランザクションを送信することは出来ません。