Libraに関するセミナーのご依頼、その他ブロックチェーンに関するコンサルティングのお問い合わせはこちらからお願いいたします。(ページ右下の「サポート」をクリック)
連載全5回のインデックスはこちら。
実践的なプログラムの作成③
今回は実践的なプログラムの作成として、EthereumのERC721を使った独自トークンのようなものがMove言語で作れるかどうかを試してみます。ERC721の詳細は割愛しますが、OpenZeppelinのERC20を扱うためのライブラリでは、以下のような機能が提供されており、これらをMove言語で実装できるか検証してみます。
(第4回のERC20で検証を行ったものは省略します)
- トークンを発行できる
- トークンのオーナーを取得できる
- トークンの移転ができる
- トークンのメタデータを取得できる
検証結果
今回はプログラムは割愛します。というのも、Move言語には連想配列のような複数の情報を管理する仕組みが現状ないため、別々の価値(情報)を持つトークンを複数保持し、それぞれについて、トークンを移転したり、メタデータを参照したり、といったプログラム自体を作成することができませんでした。配列に情報保持については、Move言語の機能拡張を期待したいところです。発行するトークンを1つだけ、という前提で考えるのであれば、検証項目はいずれも実装可能であると考えます。ただし、メタデータについては第4回と同様、文字列を扱うことができないため、バイト配列での操作となります。Move言語内では文字列とバイト配列の変換をするような機能は現状提供されていませんので、Move言語の外で何らかの変換をしてあげる必要がありそうです。
また、トークンの移転について、移転されたトークンは、それを保持するアカウントのリソースとして保存することが望ましいと考えられますが、第4回と同様、別のアカウントのリソースを参照する手段が現状ないため、トランザクション実行者がすべて管理する形になります。
その他の検証
今回はその他の検証として、「1トランザクションにてどのくらいのデータサイズを扱うことができるのか」について検証してみました。検証用に作成したソースコードは以下のとおりです。
modules:
module Storage {
resource T {
value_u64: u64,
value_addr: address,
value_bytes: bytearray,
}
public init() {
move_to_sender(T{ value_u64: 0, value_addr: 0x0, value_bytes: b""});
return;
}
public setValues(v_u64: u64, v_addr: address, v_bytes: bytearray) {
let sender: address;
let storage: &mut R#Self.T;
sender = get_txn_sender();
storage = borrow_global(copy(sender));
*(&mut copy(storage).value_u64) = move(v_u64);
*(&mut copy(storage).value_addr) = move(v_addr);
*(&mut move(storage).value_bytes) = move(v_bytes);
return;
}
}
script:
import Transaction.Storage;
main() {
let v_u64: u64;
let v_addr: address;
let v_bytes: bytearray;
Storage.init();
v_u64 = 18446744073709551615;
v_addr = 0x12345678901234567890123456789012;
v_bytes = b"1234567890abcdef1234567890abcdef・・・(省略)";
Storage.setValues(move(v_u64), move(v_addr), move(v_bytes));
return;
}
リソースに格納する情報として、Move言語でサポートされているプリミティブ型となる、u64、address、bytearrayに情報を格納し、リソースに保存するプログラムとしました。u64には、表現可能な最大値である「18446744073709551615」をセットしました。
addressには、最大バイト数となる32バイトをセットしました。
bytearrayには、プログラム上はいくらでも文字列を指定できるので、このbytearrayに保存するデータを変更しながら検証しました。 検証結果としては、上記3つのデータサイズがおよそ4KBを超えたところで、
Discard(Validation(ExceededMaxTransactionSize(\"max size: 4096, txn size: ・・・
というエラーが発生しました。トランザクションで扱えるデータサイズの上限は4096バイトのようです。
最後に
全5回に渡って、Move言語の特長や実行方法の紹介、プログラムの作成や検証を行ってきました。プログラムを作成していて一番感じたのは、「エラーメッセージが分かりづらい」という点でした。通常の文法エラーの場合には、出力された情報からあたりを付けて調べることができるのですが、Move特有の所有権に関するエラーやリソースのアクセス制御に関するエラーなどは、プログラムのどこに原因があるのか特定しづらく、エラーを取除く時間を多く費やしました。
Libraはまだ始まったばかりで、毎日のようにGitHubのリポジトリが更新されています。開発者にとっても良い改善が行われることを期待したいと思います。
今回検証がうまくいかなかった点についても、引き続き調査し、進展があればまた新しい記事にてお知らせしたいと思っています。