ERC1400はセキュリティトークンの規格として現在提案されています。提案段階ではありますが、すでにConsenSys社のチームはERC1400を実装しています。そこで今回は、完成しているERC1400を動かしていこうと思います。使用しているソースコードは2019年9月12日時点のものです。
本記事は、『ConsenSys社のERC1400実装を動かす』を前編・後編に分けて掲載します。
(1)ERC1400を動かす為の環境構築を行います。
(2)コントラクトをブロックチェーンにデプロイします。
(3)デプロイしたコントラクトを操作して、セキュリティトークンの発行・移転・償還を実行し、またセキュリティトークンならではの機能を動かして体験できます。
サマリー
本記事では、『ConsenSys社のERC1400実装を動かす』の後編として、以下を実行していきます。
(3)デプロイしたコントラクトを操作して、セキュリティトークンの発行・移転・償還を実行し、またセキュリティトークンならではの機能を動かして体験できます。
参考
本記事は以下、ConsenSysのGitHubを参考にしています。
https://github.com/ConsenSys/ERC1400
前提事項
PC : Mac
Node v8.15.0
yarn 1.17.3
homebrew(v1.6.7以上)がインストール済み
git : インストール済み
デプロイ後の動作を確認する
コンソール画面
デプロイしたスマートコントラクトを操作していきます。コンソール画面を開きます。
$truffle console
以下のようになります。
$truffle console
truffle(development)>
コントラクトのインスタンスを取得
まずデプロイしたコントラクトのインスタンスを取得して、変数に格納します。うまくいくと長いレスポンスが返ってきます。インスタンスを入れた変数を覚えておいてください。変数名をinstanceにします。
[操作したいコントラクトの名前].deploed().then(i=>[代入する変数]=i)
truffle(development)> ERC1400ERC20.deployed().then(i=>instance=i)
アカウントアドレスを取得
これからコントラクトと通信して関数を実行していくため、操作するアカウントアドレスを取得してこれも変数に格納します。
truffle(development)> web3.eth.getAccounts().then(i=>accounts=i)
成功すると以下の画面になります。
truffle(development)> web3.eth.getAccounts().then(i=>accounts=i)
[ '0x29652B62CC3374F68f8d1e9d17eB76561E78512C',
'0x6DC0ee40E7C668f938d4F2834DA49751E7bD0Ffc',
'0x6F9af9dADE1f2d0046fC0975e5930bE02B161269',
'0x51C2265264517882d704052F9e0359507B1d84Fc',
'0x0AB81A2F8EC21C8959423f4679f05d9e5995B3a2',
'0xA733C81D851060d5a59307DAEcBa142732078D06',
'0x443017567946B6899C04A0Fc7Fe857cc329d8FB3',
'0x8827f5D8997BE926871bfF258EBf27B0c2AAA508',
'0x4D6f7a7C8F13fA306188373E8511CC3c711B23ef',
'0xf009489408E5fdEb8A869CC6A83557AefF829e03' ]
トークンの情報を取得
関数を実行して、コントラクトが持っている状態変数を確認していきます。
nameの取得
デプロイしたトークンの名前を取得します。ドット記法でコントラクト(instance)がもつ関数・name()を呼び出します。関数の呼び出しは基本この方法をとります。
truffle(development)> instance.name()
'ERC1400Token'
symbolの取得
デプロイしたトークンのシンボルを取得します。自分が決めたものと一致しましたか?
truffle(development)> instance.symbol()
'DAU'
totalSupplyの取得
デプロイしたトークンのtotalSupplyを取得します。ganacheでは出力される数値がether単位で出力される為、それをweiに変換します。つまり単位を変換しています。まだ0ですね、これから発行して増やしていきます。
truffle(development)> instance.totalSupply().then(i=>totalSupply=i)
truffle(development)> web3.utils.fromWei(totalSupply)
'0'
decimalsの取得
decimalsを確認します。decimalsは、トークンを幾つの単位まで分割できるかを示しています。decimalsが0であれば、そのトークンは全く分割できないです。ERC20トークンでは、decimalsは18がデフォルトになっています。decimalsが18ということは、トークンを小数点第18位まで、分割できることを意味しています。
以下のように18が確認できました。
truffle(development)> instance.decimals().then(i=>decimals=i)
truffle(development)> web3.utils.fromWei(decimals)*(10**18)
18
セキュリティトークンの発行
issueByPartition()を実行して、セキュリティトークンを発行します。また以降は関数を実行して、ブロックチェーン上の状態変数を変更していきます。
引数
- partition
- 資産の種類を表します。
- tokenHolder
- 新規発行のSTを所有するアカウントです。
- value
- 発行する額です。
- data
- 発行・移転・償還を許可された証明として特定のバイト列を渡します。
- 今回はすでに許可されてそれを持っているということにします。
操作
partition(資産の種類)を取得して、変数に格納します。
truffle(development)> instance.getDefaultPartitions().then(i=>partitions=i)
発行額を決めて、変数に格納します。単位をweiに変換してます。100トークン発行する予定です。
truffle(development)> value = web3.utils.toBN(100*(10**18))
発行証明書を変数に格納します。
truffle(development)>data = "0x11000100110000"
宛先も指定して、引数にそれぞれの値を持った変数を渡します。うまくいくとトランザクションが作成されるためターミナルにトランザクションの情報が表示されます。
truffle(development)> instance.issueByPartition(partitions[0],accounts[0],value,data)
{ tx: '0xeb2df8ce08fca26d64f9fdee0ef0569b84ce9e774fc0674f6533362d7533cddf',
receipt:
{ transactionHash: '0xeb2df8ce08fca26d64f9fdee0ef0569b84ce9e774fc0674f6533362d7533cddf',
transactionIndex: 0,
blockHash: '0x522b66b2e3776e9d7cdf3453fc0dc6c71088c4f1438acd79df999a6a8d630c8b',
blockNumber: 8,
from: '0x29652b62cc3374f68f8d1e9d17eb76561e78512c',
to: '0x3e9b34638e59a85a85c87e29516b3ea0f84c27e0',
gasUsed: 272850,
cumulativeGasUsed: 272850,
contractAddress: null,
logs: [ [Object], [Object], [Object], [Object] ],
status: true,
logsBloom: '0x00000000000000010000000000000000000000000000800000000000000000000000000000000000000000000000400000000000000000002040000000000000000000000000100000008008000000000000000000000000000000000010000000000000020000000000000000010800000000000000000000001010000000000000000000000000000008000000000000000000000000000400000000000040000000000000000201000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000020000000000000000000000000000000028000000000000000000200000000000000',
v: '0x1c',
r: '0xc58ab42ca045d5d5dc7c8c0d95076579c099aa969ddb70a410e56593ed29cfd9',
s: '0x3741347ab7f5b57c18c23e108c2b4573780cd446f19955b65470ba9f4cb8d75c',
rawLogs: [ [Object], [Object], [Object], [Object] ] },
logs:
[ { logIndex: 0,
transactionIndex: 0,
transactionHash: '0xeb2df8ce08fca26d64f9fdee0ef0569b84ce9e774fc0674f6533362d7533cddf',
blockHash: '0x522b66b2e3776e9d7cdf3453fc0dc6c71088c4f1438acd79df999a6a8d630c8b',
blockNumber: 8,
address: '0x3E9b34638E59A85a85C87E29516B3Ea0f84c27E0',
type: 'mined',
id: 'log_c09c8f36',
event: 'Checked',
args: [Object] },
{ logIndex: 1,
transactionIndex: 0,
transactionHash: '0xeb2df8ce08fca26d64f9fdee0ef0569b84ce9e774fc0674f6533362d7533cddf',
blockHash: '0x522b66b2e3776e9d7cdf3453fc0dc6c71088c4f1438acd79df999a6a8d630c8b',
blockNumber: 8,
address: '0x3E9b34638E59A85a85C87E29516B3Ea0f84c27E0',
type: 'mined',
id: 'log_70fca0cd',
event: 'Issued',
args: [Object] },
{ logIndex: 2,
transactionIndex: 0,
transactionHash: '0xeb2df8ce08fca26d64f9fdee0ef0569b84ce9e774fc0674f6533362d7533cddf',
blockHash: '0x522b66b2e3776e9d7cdf3453fc0dc6c71088c4f1438acd79df999a6a8d630c8b',
blockNumber: 8,
address: '0x3E9b34638E59A85a85C87E29516B3Ea0f84c27E0',
type: 'mined',
id: 'log_7896f4bd',
event: 'Transfer',
args: [Object] },
{ logIndex: 3,
transactionIndex: 0,
transactionHash: '0xeb2df8ce08fca26d64f9fdee0ef0569b84ce9e774fc0674f6533362d7533cddf',
blockHash: '0x522b66b2e3776e9d7cdf3453fc0dc6c71088c4f1438acd79df999a6a8d630c8b',
blockNumber: 8,
address: '0x3E9b34638E59A85a85C87E29516B3Ea0f84c27E0',
type: 'mined',
id: 'log_769b884e',
event: 'IssuedByPartition',
args: [Object] } ] }
トークン残高確認
balanceOf()関数を使ってaccounts[0]の残高を確認します。
truffle(development)> instance.balanceOf(accounts[0]).then(i=>balance0=i)
truffle(development)> web3.utils.fromWei(balance0)
'100'
無事100ST所持していることが確認できました。しかしこれでは、なんの種類のSTを所持しているのかわかりません。
partition残高の確認
balanceOfByPartition()を使って、あるアカウントが特定のpartitionをいくつ持っているか知ることができます。
truffle(development)> instance.balanceOfByPartition(partitions[0], accounts[0]).then(i=>balance0=i)
truffle(development)> web3.utils.fromWei(balance0)
'100'
accounts[0]はpartitons[0]のトークンを持っていることが確認できました。
トークンの移転
トークンを発行して、保有するところまでできました。次はトークンをaccounts[0]からaccounts[1]に移転したいと思います。transferWithData()関数を使います。
引数
- to
- 送り先のアカウントアドレスを指定します。
- value
- 移転する額を指定します。10トークン移転します。
- data
- 発行・移転・償還を許可された証明として特定のバイト列を渡します。
- 今回はすでに許可されてそれを知っているということにします。
操作
truffle(development)> to = accounts[1]
truffle(development)> value10 = web3.utils.toBN(10*(10**18))
data = "0x11000100110000"
truffle(development)> instance.transferWithData(to, value10, data)
うまくいくと以下のようになります。あとはaccounts[1]のトークン残高を確認して本当に成功しているかを確かめてください。
truffle(development)> instance.transferWithData(to, value10, data)
{ tx: '0x38a09fc683dccc073fd740bc899e9bbe912ab4e20792b38709510b2c0dd1f354',
receipt:
{ transactionHash: '0x38a09fc683dccc073fd740bc899e9bbe912ab4e20792b38709510b2c0dd1f354',
transactionIndex: 0,
blockHash: '0x7af53facc1903044c40472fe268d287e22a9a6f89c33f5ad3bf10d60cee982fa',
blockNumber: 9,
from: '0x29652b62cc3374f68f8d1e9d17eb76561e78512c',
to: '0x3e9b34638e59a85a85c87e29516b3ea0f84c27e0',
gasUsed: 184835,
cumulativeGasUsed: 184835,
contractAddress: null,
logs: [ [Object], [Object], [Object], [Object] ],
status: true,
logsBloom: '0x80000000000000010000000000000004000000000000800200000000000000000004000000000000000000000000000000000000000000000040000800000000000000000000000000008008000000000000000000000000000000000010000000000000000000000000000000010000000040000000000040001010000000000000000000000000000008000000000000000000000000000000000000000004000000000000000201000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000002000000000000000000000000000000000000000008000000000000000000200000000000000',
v: '0x1b',
r: '0x4eb864a76454f37785018d012ebef9724f0a64c8cb5cfca7e5729f75df459abd',
s: '0x7c0276b4f854a7ac27d664bfe88c1ef8691ba95239d11767d567d2f763c1ba0c',
rawLogs: [ [Object], [Object], [Object], [Object] ] },
logs:
[ { logIndex: 0,
transactionIndex: 0,
transactionHash: '0x38a09fc683dccc073fd740bc899e9bbe912ab4e20792b38709510b2c0dd1f354',
blockHash: '0x7af53facc1903044c40472fe268d287e22a9a6f89c33f5ad3bf10d60cee982fa',
blockNumber: 9,
address: '0x3E9b34638E59A85a85C87E29516B3Ea0f84c27E0',
type: 'mined',
id: 'log_489e9002',
event: 'Checked',
args: [Object] },
{ logIndex: 1,
transactionIndex: 0,
transactionHash: '0x38a09fc683dccc073fd740bc899e9bbe912ab4e20792b38709510b2c0dd1f354',
blockHash: '0x7af53facc1903044c40472fe268d287e22a9a6f89c33f5ad3bf10d60cee982fa',
blockNumber: 9,
address: '0x3E9b34638E59A85a85C87E29516B3Ea0f84c27E0',
type: 'mined',
id: 'log_d7ebe921',
event: 'TransferWithData',
args: [Object] },
{ logIndex: 2,
transactionIndex: 0,
transactionHash: '0x38a09fc683dccc073fd740bc899e9bbe912ab4e20792b38709510b2c0dd1f354',
blockHash: '0x7af53facc1903044c40472fe268d287e22a9a6f89c33f5ad3bf10d60cee982fa',
blockNumber: 9,
address: '0x3E9b34638E59A85a85C87E29516B3Ea0f84c27E0',
type: 'mined',
id: 'log_e6e7313e',
event: 'Transfer',
args: [Object] },
{ logIndex: 3,
transactionIndex: 0,
transactionHash: '0x38a09fc683dccc073fd740bc899e9bbe912ab4e20792b38709510b2c0dd1f354',
blockHash: '0x7af53facc1903044c40472fe268d287e22a9a6f89c33f5ad3bf10d60cee982fa',
blockNumber: 9,
address: '0x3E9b34638E59A85a85C87E29516B3Ea0f84c27E0',
type: 'mined',
id: 'log_d1e6e116',
event: 'TransferByPartition',
args: [Object] } ] }
お気づきだと思いますが、今のやり方では複数のpartitionsを保有している場合、partitionsを指定できません。
partitionsの移転
transferByPartition()関数を使って、移転するpartitionsを指定することができます。引数に指定のpartitionsを渡します。
truffle(development)> instance.transferByPartition(partitions[0],to, value10, data)
トークンの償還
説明
償還機能は指定した分のトークンを消してしまうことです。償還が行われると、償還した分だけ、総発行数が減少します。どんな用途に利用できるでしょうか?
例えば企業は自社株買いを行い、購入した株を償還して総発行数を減らし、企業の指標が自社に有利になるように仕向けることに利用できます。
また債券の場合、5年物や10年物というようにセキュリティトークンの存在期間が決まっています。そのため実装される場合は、ある期間の最後の時点で、そのSTが保有者に元本と利子の支払いを行い、それと同時に自動償還されるなどの用途で利用されることが想定されます。
操作
以下のようにで実行してください。実行後、accounts[0]のトークン残高を確認して、accounts[0]のトークンが10減っていることを確かめてください。
truffle(development)> instance.redeem(value10,data)
truffle(development)> instance.redeemByPartition(partitions[0],value10,data)
またaccounts[1]のSTを償還したい場合は以下です。
truffle(development)> instance.redeem(value10,data,{from:accounts[1]})
truffle(development)> instance.redeemByPartition(partitions[0],value10,data,{from:accounts[1]})
トークンの管理者
ERC1400やERC777では、規制当局などの管理者が強制的にトークンを管理(移転・償還)する手段が用意されています。
Operator
1つのアカウントにつき1つOperator(第3者のアカウントアドレス)を設定することができます。operatorはトークン保有者に変わって、トークンを管理(移転・償還)することができます。この強制移転や強制償還の機能は主に、規制当局がもつ機能になります。投資家が法律違反を犯した場合に投資家の資産を没収するケースなどで、この機能が必要になります。
では、まずoperatorを設定します。authorizeOperator()を実行します。
truffle(development)> instance.authorizeOperator(accounts[2])
これで、accounts[0]のoperatorはaccounts[2]になりました。以下のようにoperatorを上書きすることもできます。
truffle(development)> instance.authorizeOperator(accounts[3])
またoperatorが必要ない時は、operatorをなしにすることもできます。revokeOperator()を実行します。
truffle(development)> instance.revokeOperator(accounts[3])
そのアカウントが他のアカウントのoperatorかどうかを確認できます。isOperator()を実行できます。
truffle(development)> instance.isOperator(accounts[3], accounts[0])
false
これで、revokeOperator()の動作の有効性が確かめられました。これらの機能はトークン保有者本人がOperatorを登録管理できてしまうことから、強制移転等を念頭に実装された訳ではなそうです。
Operatorは特定のアカウントのトークンの管理者です。実際にセキュリティトークンを管理する場合は、特定のアカウントに加えて特定のpartitions(資産の種類)も指定して、Operatorを指定する必要があります。authorizeOperatorByPartition()を実行します。
truffle(development)> instance.authorizeOperatorByPartition(accounts[0],accounts[3])
強制移転
では、operator(accounts[3])に特定のアカウント(accounts[0])のpartition(資産)を移転させてます。operatorTransferByPartition()を実行します。以下では、引数に今までの操作で定義ずみの変数を利用します。partitionの種類、移転元、移転先、トークンの量、証明書、operatorが渡す証明書、関数の実行元アドレスを引数に渡しています。ここでは、証明書は2つとも同じバイト列認証を通ることができます。実行者(operator)がトークンの発行・移転・償還を許可されて証明書は発行されている前提で行います。なぜ同じデータを2つ渡さないといけないのかはわかりません。
truffle(development)> instance.operatorTransferByPartition(partitions[0],accounts[0], accounts[1], value10, data, data, {from:accounts[3]})
{ tx: '0x8a03de76df4273e796fbcdcc076b48a73ab3ab36831d85bd31a6a58af59d1682',
receipt:
{ transactionHash: '0x8a03de76df4273e796fbcdcc076b48a73ab3ab36831d85bd31a6a58af59d1682',
transactionIndex: 0,
blockHash: '0xe03e8ee0bcededad0fdadc22987eab69a51829f2b8376aedd217c93281253293',
blockNumber: 28,
from: '0x51c2265264517882d704052f9e0359507b1d84fc',
to: '0x3e9b34638e59a85a85c87e29516b3ea0f84c27e0',
gasUsed: 114387,
cumulativeGasUsed: 114387,
contractAddress: null,
logs: [ [Object], [Object], [Object], [Object] ],
status: true,
logsBloom: '0x80000000000000010000000000000004000000000100800200000000000000000004000000000000000000000000000000000000000000000040000800000000000000000000000000008008000000000000000000000000000000000010000000000000000000000000000000010000000040000000000040001010000000000000000000000000000008000000000000000000000000000000000000000004000000000000000201000000000000000000000000000000000000000004000000000002000000000000000004000000000000000000000000002000000000000000000000000000000000000000008000000000000000000200000000000000',
v: '0x1c',
r: '0xff7627e26f989e00efb4b99678500a88b7259bf0589b6425392dacb342e87c84',
s: '0x79d787063f3102202fc8be5db233031847e51459584211add250f507b99afc58',
rawLogs: [ [Object], [Object], [Object], [Object] ] },
logs:
[ { logIndex: 0,
transactionIndex: 0,
transactionHash: '0x8a03de76df4273e796fbcdcc076b48a73ab3ab36831d85bd31a6a58af59d1682',
blockHash: '0xe03e8ee0bcededad0fdadc22987eab69a51829f2b8376aedd217c93281253293',
blockNumber: 28,
address: '0x3E9b34638E59A85a85C87E29516B3Ea0f84c27E0',
type: 'mined',
id: 'log_ed87cdd6',
event: 'Checked',
args: [Object] },
{ logIndex: 1,
transactionIndex: 0,
transactionHash: '0x8a03de76df4273e796fbcdcc076b48a73ab3ab36831d85bd31a6a58af59d1682',
blockHash: '0xe03e8ee0bcededad0fdadc22987eab69a51829f2b8376aedd217c93281253293',
blockNumber: 28,
address: '0x3E9b34638E59A85a85C87E29516B3Ea0f84c27E0',
type: 'mined',
id: 'log_adf1357f',
event: 'TransferWithData',
args: [Object] },
{ logIndex: 2,
transactionIndex: 0,
transactionHash: '0x8a03de76df4273e796fbcdcc076b48a73ab3ab36831d85bd31a6a58af59d1682',
blockHash: '0xe03e8ee0bcededad0fdadc22987eab69a51829f2b8376aedd217c93281253293',
blockNumber: 28,
address: '0x3E9b34638E59A85a85C87E29516B3Ea0f84c27E0',
type: 'mined',
id: 'log_05e2b2b4',
event: 'Transfer',
args: [Object] },
{ logIndex: 3,
transactionIndex: 0,
transactionHash: '0x8a03de76df4273e796fbcdcc076b48a73ab3ab36831d85bd31a6a58af59d1682',
blockHash: '0xe03e8ee0bcededad0fdadc22987eab69a51829f2b8376aedd217c93281253293',
blockNumber: 28,
address: '0x3E9b34638E59A85a85C87E29516B3Ea0f84c27E0',
type: 'mined',
id: 'log_340f4d00',
event: 'TransferByPartition',
args: [Object] } ] }
accounts[0]からaccount[1]に10トークン移転できました。operatorはトークンの償還も行えます。operatorRedeemByPartition()を使います。引数には、partition(資産)、償還元アカウント、償還するトークン量、証明書、証明書、関数の実行元アカウント(operator)を渡します。
truffle(development)> instance.operatorRedeemByPartition(partitions[0],accounts[0], value10, data,data,{from:accounts[3]})
コントラクトの管理者
Controllers
コンストラクターにアカウントアドレス(accounts[0])を渡し、初期設定ですでにControllersを設定してあります。Controllersは投資家アドレスをホワイトリストに登録できる権限を持ちます。またセキュリティトークンのドキュメントを設定することができます。まず現在のControllersを確認します。
truffle(development)> instance.controllers()
[ '0x29652B62CC3374F68f8d1e9d17eB76561E78512C' ]
accounts[0]がcontrollersに設定されていることが確認できました。
Controllersは複数のアカウントアドレスを配列にして保存できるため、Controllersを増やしてみることにします。
truffle(development)> instance.setControllers([accounts[0],accounts[1]])
これでControllersはaccounts[0]とaccounts[1]になりました。Controllersの権限を無効化することもできます。ただし一度行うと以降有効化はできなくなるので、注意してください。
trufflle(development)> instance.renounceControl()
ホワイトリスト
セキュリティトークンは証券の為、誰でも購入することができる訳ではありません。セキュリティトークンを購入するにはKYCなどを満たし、ホワイトリストに登録される必要があります。Controllersアドレスは、特定の投資家アドレスをホワイトリストに登録することができます。
まずaccounts[0]がホワイトリストに登録されているか確認します。whitelisted()を実行します。
truffle(development)> instance.whitelisted(accounts[0])
false
未登録なのがわかったので、accounts[0]を登録します。setWhitelisted()に登録するアカウントと論理型trueを渡します。falseを渡すと登録解除になります。
truffle(development)> instance.setWhitelisted(accounts[0],true)
トークンの移転時は移転元と移転先と両方のアドレスがホワイトリストに登録されている必要があります。なのでaccounts[1]も登録しておきます。
では、ホワイトリストに登録されたaccounts[0]からaccounts[1]にトークンを移転します。transfer()を実行します。引数に宛先アカウントとトークン量を渡します。
truffle(development)> instance.transfer(accounts[1],value10)
現在の実装では、移転時にホワイトリストのチェックが行われる関数はtransfer()とtransferFrom()のみになっています。他の関数では証明データが実行に必要だったりしました。
トークンのドキュメント管理(設定・取得)
ERC1400では、セキュリティトークンの情報をブロックチェーン上に登録することができます。情報とは、その証券に関する参考情報や法的文書が該当します。ドキュメントの設定は、Controllerに設定されているアカウントのみが行えます。それではこのERC1400トークンにドキュメントを登録してみます。setDocument()を利用します。
引数
- name
- 文書名をバイトデータで、渡します。
- uri
- 文書のURI(URLと同義です。)を渡します。
- documentHash
- ドキュメントのハッシュを渡します。
- URI先のドキュメントの改ざん防止に役立ちます。
- この引数はオプションとなっています。
まず引数の為の変数を準備します。nameにはバイトデータが必要です。今回は文字列”document”を他の場所でバイト列に変換してきたものを利用します。uriには、このERC1400の実装が行われているConsenSysのGitHubページのURLを利用します。documentHashはオプションの為、空にしてあります。
truffle(development)> name = "0x646f63756d656e74000000000000000000000000000000000000000000000000"
truffle(development)> uri = "https://github.com/ConsenSys/ERC1400"
truffle(development)> documentHash = "0x0000000000000000000000000000000000000000000000000000000000000000"
truffle(development)> instance.setDocument(name, uri, documentHash)
セキュリティトークンにドキュメントが登録できました。投資家になった気分で、登録済みのドキュメントをみてみましょう。
truffle(development)> instance.getDocument(name)
Result {
'0': 'https://github.com/ConsenSys/ERC1400',
'1': '0x0000000000000000000000000000000000000000000000000000000000000000' }
登録してあるURLが確認できました。
まとめ
本記事は、『ConsenSys社のERC1400実装を動かす』後編をお送りしました。デプロイしたコントラクトの関数を利用して、セキュリティトークンの発行・移転・償還を実行しました。またセキュリティトークンならではの機能を動かして、ERC1400の理解を深めてました。
ERC1400を中心としたセキュリティトークンの実装はまだ安全に利用できる標準規格が存在するとは言えず、これからもSTに関連する規格が複数、提案されることが予想されます。本連載のERC1400の理解を基礎にして、新しい規格にもキャッチアップできるようにしていきましょう。