Substrate / Polkadot
Cosmosと並び、異なるブロックチェーンのインターオペラビリティ(相互運用性)で注目を集めているPolkadotについて、試してみました。
インターオペラビリティは、Substrate というフレームワークで実装されますが、これを体験できるPlaygroundがあります。(Node Templateを使用)
https://docs.substrate.io/playground/
Githubアカウントでログインすると、VisualStudio(?)がWebで現れ、ブロックチェーンが起動します。ターミナルを開き、コンソールコマンドも実行できます。CTL-Cで停止でき下記コマンドで再起動できます。
./target/debug/node-template –dev –ws-external
再起動すると新規作成されるため、ブロックチェーンの更新を保持したい場合は、
./target/debug/node-template –dev –ws-external –base-path=/tmp/<任意>
とします。
メニューからPlayGroundを選択すると、新規タブでUI(DApp)が開きます。
6秒ごとに新規ブロックが作成されていきます。
デフォルトでPlaygroundをエンドポイントとしていますが、これ以外のネットワークにもスイッチできるようです。
開発アカウントと残高があかじめ用意されています。今回テストのため一番下の”Tibit”を追加しAliceから送金してみました。
次に今回やりたかった、ストレージへの保存と参照を動画を参考にトライしてみました。
後で説明しますが、doSomethingというメソッドに値を入力するようなイメージになります。
アカウントを作成するとき(説明を省略しましたが他の例にもれずニーモニックの保存やパスワード作成があります)に使用したパスワードを入力します。(開発アカウントの場合はなし)
次にチェーン状態を確認します。
確認できました。これを実行している箇所が以下になります。
動画では、これをカスタマイズしてタイトルやアカウントIDを保存できるようにしています。その際コードの更新を通知するために以下のバージョン情報をインクリメントするようです。
recent eventsでは、履歴をみることができます。
これは、新規でブロックチェーンを起動しても残っているようです。(Playgroundのセッションを終了すれば消えます)
まだ一部の機能しかさわっていませんが、実際の開発する様子がイメージでき、ツール類がよくできていると感じました。
Polkadotの実験ネットワークにKusamaというものがありますが、水玉(Polkadot)模様のアートで有名なアーティスト草間彌生氏からとられたものだといわれています。Blockchain界隈、日本にゆかりがあるものをよく目にします。もともとBlockchain論文の作者がサトシナカモトなのもそうですが、Cardanoプロジェクトの創始者も日本在住だったと聞いています。そのわりに日本の税制がこの業界に厳しく有能なベンチャーが海外に出てかざるをえない状況は皮肉なものです。Polkadotのパラチェーンを運営するAsterNetworkもその一つです。通貨というものが国家のあり方と密接にかかわっているからでしょう。こういった世の中の動きを見ているとこの業界が今とてもホットだということがよくわかります。
国家のあり方といえば、今週ロシアがウクライナの領土に侵攻しました。武力でNATOよりロシアに友好的な国家にすることが目的のようですが、こういう専制主義的、19,20世紀的なやり方に世界中の大勢の人は抵抗を感じるのではないでしょうか。非難するとともに即時撤退を願います。NFTなど物理的なモノからデジタルなモノに、物理的な領土からメタバースの土地に、会社などの組織からDAO(分散型自律組織)に価値感が移転しつつある非中央集権的なシステムBlockchainが、これだけ盛んになってきているのは、これからの時代を暗示しているからだと思います。ロシア・中国は特にマイニングをはじめとするBlockchainプロジェクトが盛んですが、これも皮肉です。
経済制裁によって取引が制限されると、Bitcoinなどの暗号通貨が使われるともいわれていますが、ウクライナに侵攻した途端、一時的にですが価値が暴落したことがまだリスク資産という位置づけであることのあらわれといわれています。
いずれにしろBlockchainをとりまく環境は、ホットであることは間違いないと考えます。
参考動画
Moralis Web3 Platform
これまでBlockchain自体の投稿が多かったのですが、もう一つ上位に位置するBlockchainを利用したアプリの開発プラットフォームについて、”Build Metaverse Unity Web 3.0 App with C#” というとても気になる動画を見つけたので試してみました。
Unityで作られたMetaverseのプログラムと各種ブロックチェーンを連携するライブラリの使い方の説明がされています。
Metaverseといえばアイテムの売買などでNFTが活用される典型的な例ですが、ここまでライブラリができているのかと、ちょっと驚きました。
ここではゲーム中に表示されるQRコードを読み取り、Walletと連携しています。連携できている証拠としてウォレットアドレスをキャラクタの上に表示します。
手順は、まずmoralis.io のアカウントを作り、接続するサーバの作成やブロックチェーンの選択をします。動画のとおりEthereum メインネットで、TrustWalletを使用して実践しました。
Unity側で必要な情報として、サーバは”Veiw Details”をクリックして、Server URL, Application IDを取得。
ブロックチェーンエンドポイントWeb3 Rpc Node URLは、Speedy Nodesから取得します。
iPhone App TrustWalletの設定から”WalletConnect”を選択し、カメラで上のQRコードを読み取ります。(このQRコードの元になっているのは下記ソースのURL。別のQRコードアプリで確認するとメタマスクの起動を要求された。)
Walletと連携後アドレスが表示されました。
QRコードを生成する部分は以下。
ログインが成功するとアドレス表示。
Unityは、プログラミング教育ブログなどでもよく使っており、C#でDAppが作れることで世界が広がります。
これまでのOSでいうところのクロスプラットフォーム開発が、もうブロックチェーンでも起きているということなのでしょうか、どのチェーンかということを意識せず、DAppが作ることができるようです。
この分野、急速に変化していることを感じます。
Starport / Cosmos
今回は、Cosmosの開発環境Starportについて試してみました。
参考: https://docs.starport.com/guide/hello.html
環境: Go 1.17.6, npm 8.1.2, node 16.13.1/Ubuntu20.4/WSL/Windows 11
インストール
sudo curl https://get.starport.network/starport! | bash
starport scaffold chain github.com/cosmonaut/hello
cd hello
starport chain serve
ひとまず動作確認。(AliceとBobのアドレスとニーモニックひかえる。二回目以降は以下のように表示しない)
参考ページにあるように、POSTでtitleとbodyを返すAPIを作成するためコマンド実行。
starport scaffold query posts –response title,body
コマンドを実行するとソースが自動的に変更・追加されます。(git diffで確認。下記は手動で変更)
x/hello/keeper/grpc_query_posts.go
func (k Keeper) Posts(c context.Context, req *types.QueryPostsRequest) (*types.QueryPostsResponse, error) {
//...
return &types.QueryPostsResponse{Title: "Hello!", Body: "Starport"}, nil
}
x/hello/module.go
import (
"encoding/json"
"fmt"
//..
"context"
...
func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {
types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx))
}
Code language: JavaScript (javascript)
もう一度チェーン立ち上げ、下記URLをブラウザでアクセスします。(チェーンを立ち上げっぱなしでコード変更しても動いた)
http://localhost:1317/cosmonaut/hello/hello/posts
ちなみに下記コマンドでも動作するとありますが、そのような実行モジュールがみあたりませんでした。
hellod q hello posts
http://localhost:1317/ にアクセスしてAPIコンソールからも確認することができます。(それぞれクリックするとパラメータを入力する画面がでてきてリクエストを投げることができる)
ちなみにTendermint Node (http://localhost:26657/)は下記画面。
次に、フロントエンドを立ち上げて、AliceからBobに送金してみます。(下に参考動画: バージョンが違うためかコマンドが若干違うのと、上記の流れで作成しているのでネットワーク接続が動画どおりにできず)
cd vue
npm i
npm run serve
http://localhost:8080
AMOUNT 1 でBobに送金した後の画面。WalletはKeplrでChormoe Extensionのものを使用。(最初に控えたAliceのニーモニックを入力して作成)
次に、先ほどのAPIコンソールで、AliceとBobのBalanceを確認しました。
1 ATOM(?)送金されていることは確認しました。(小数入力できなかった)
この画面で、Cosmos Hubを選択しても何も変化が起きなかったためか、うまく接続できていないのかもしれません。(そのためにWalletの方には残高が反映されていない)
コマンド一つでブロックチェーンを作れてしまうのはなかなか強力なツールです。いろいろとやりたいことがでてきますが、今回はここまでとします。
Solana in Rust & TypeScript
Solanaの開発環境について、動画を参考に動作確認とSolanaのウォレット、Phantomとの連携を試してみました。
https://github.com/solana-labs/example-helloworld
環境: Cargo 1.57.0, node 16.13.1 / WSL / Windows 11
インストール
sh -c “$(curl -sSfL https://release.solana.com/v1.9.5/install)”
export PATH=”/home/k/.local/share/solana/install/active_release/bin:$PATH”
solana config set –url localhost
solana-keygen new -o /home/k/.config/solana/id.json
solana-test-validator
Solana CLIをインストールしてデーモンが立ち上げます。そして別コンソールで、オンチェーンコード(Rust or C。ここではRustを選択)をビルド(SharedObject生成)、これをデプロイして、オフチェーンコードのTypeScriptを実行します。
npm install
npm run build:program-rust
solana program deploy dist/program/helloworld.so
npm run start
デプロイのとき、コインがないとエラーがでるので、エアドロップのコマンドを実行して受け取ります。(とりあえず10 SOL)
solana airdrop 10
これで実行されるのは、main.tsです。処理の詳細はhello_world.tsに記述されています。ここではコンソール実行していますが、TypeScriptで書かれているのでWebにもっていきやすいです。オンチェーンコードとオフチェーンコードがコンソールで一通り動作確認できるのは、使いやすいと感じました。
次に、Phantomウォレットとの連携ですが、ウォレットで秘密キーのimportができないので(ニーモニックのimportは当然できる、秘密キーのexportはできるのに・・なぜ)、ウォレットのニーモニックからキーペアを生成して、ここまでで生成したアカウントに上書きします。
参考
[recover] seed phrase .. でウォレットのニーモニックをコピペします。
ウォレットは、ローカルホストを選択します。ウォレットのアドレス(あれ、Localhostの表示がかぶっている^^ ; )とコンソールコマンドでアドレスが一致していることを確認します。また最近の活動はトランザクションIDなので、下記のようにコードを変更して確認できます。(TX: )
export async function sayHello(): Promise<void> {
console.log('Saying hello to', greetedPubkey.toBase58());
const instruction = new TransactionInstruction({
keys: [{pubkey: greetedPubkey, isSigner: false, isWritable: true}],
programId,
data: Buffer.alloc(0), // All instructions are hellos
});
let tx = await sendAndConfirmTransaction(
connection,
new Transaction().add(instruction),
[payer],
);
console.log("TX: " + tx);
}
Code language: JavaScript (javascript)
このような記事を書くとき、いろいろと試しながらやるため手順が前後してしまい、わかりづらくて・・m(_ _)m
C言語でも記述できてしまうところが拡張性を考えたとき面白いのと、Rust + TypeScript の組み合わせはなかないいと思いました。
参考動画
Blockchain in Rust
ブロックチェーンのしくみをもっと実装ベースで理解したいといろいろ調べていたところ、まさにそのものである学習用のRustを使ったコンパクトに実装されたコードとそのデモ動画があったため試してみました。(Solanaのような新しいブロックチェーン開発で使うRustとはまた別の話。いづれテスト予定)
https://github.com/GeekLaunch/blockchain-rust
参考書籍: 「ビットコインとブロックチェーン」(NTT出版)
参考動画: (最下部にリンク)
block作成、blockchain作成、トランザクション作成の機能がそれぞれモジュール化されており、main.rsファイルでそれらを利用して自由に作ることができるようになっています。
main.rs
use blockchainlib::*;
fn main () {
let difficulty = 0x000fffffffffffffffffffffffffffff;
let mut genesis_block = Block::new(0, now(), vec![0; 32], vec![
Transaction {
inputs: vec![ ],
outputs: vec![
transaction::Output {
to_addr: "Alice".to_owned(),
value: 60,
},
transaction::Output {
to_addr: "Bob".to_owned(),
value: 30,
},
],
},
], difficulty);
genesis_block.mine();
let mut last_hash = genesis_block.hash.clone();
let mut blockchain = Blockchain::new();
blockchain.update_with_block(genesis_block).expect("Failed to add genesis block");
println!("{:?}", blockchain);
let mut h = last_hash.clone();
let mut block = Block::new(1, now(), last_hash, vec![
Transaction {
inputs: vec![ ],
outputs: vec![
transaction::Output {
to_addr: "Min1".to_owned(),
value: 20,
},
],
},
Transaction {
inputs: vec![
blockchain.blocks[0].transactions[0].outputs[0].clone(),
],
outputs: vec![
transaction::Output {
to_addr: "Alice".to_owned(),
value: 40,
},
transaction::Output {
to_addr: "Bob".to_owned(),
value: 10,
},
],
},
], difficulty);
block.mine();
last_hash = block.hash.clone();
blockchain.update_with_block(block).expect("Failed to add block");
println!("{:?}", blockchain);
let mut block2 = Block::new(2, now(), last_hash, vec![
Transaction {
inputs: vec![ ],
outputs: vec![
transaction::Output {
to_addr: "Min2".to_owned(),
value: 30,
},
],
},
Transaction {
inputs: vec![
blockchain.blocks[1].transactions[0].outputs[0].clone(),
],
outputs: vec![
transaction::Output {
to_addr: "Alice".to_owned(),
value: 9,
},
],
},
], difficulty);
block2.mine();
last_hash = block2.hash.clone();
blockchain.update_with_block(block2).expect("Failed to add block");
println!("{:?}", blockchain);
}
Code language: PHP (php)
実行結果
デモとは違い出力内容をかなり変えています。(下記変更)
blockchain.rs
#[derive(Debug)]
pub struct Blockchain {
pub blocks: Vec<Block>,
unspent_outputs: HashSet<Hash>,
}
Code language: HTML, XML (xml)
println!("coinbase output value: {:?} total fee: {:?}", coinbase.output_value(), total_fee);
if coinbase.output_value() < total_fee {
return Err(BlockValidationErr::InvalidCoinbaseTransaction);
} else {
block_created.extend(coinbase.output_hashes());
}
Code language: PHP (php)
ブロックチェーンを更新する際に、コインの計算が合わないとエラーになります。
最初はジェネシスブロックで、そこに追加していきます。それぞれのブロックの最初のトランザクションはコインベーストランザクション(INPUTなし)で、マイニングに勝ったマイナーによっておかれることを表現しています。unspent_outputs: にあるハッシュを見てみると、消費されたアウトプットは次になくなっていることも確認できます。
ブロックチェーンの基礎を勉強する教材としてとても素晴らしいため、自分用メモとして残しておきたいと思いました。
Plutus / Cardano
前回につづいてカルダノのPlutusスマートコントラクトを今回はHaskellプログラミングのPlayground環境で試してみました。
デモファイルがいくつもあるのですが、支払いのしくみがわかるStarterを選びました。(最後に参考の動画のリンク)
--validateSpend _myDataValue _myRedeemerValue _ = error () -- Please provide an implementation. validateSpend (MyDatum myDataValue) (MyRedeemer myRedeemerValue) _ = myDataValue == myRedeemerValue
35行目を上記のように変更してもう一度実行します。
成功したので、シミュレーションの結果を見てみます。(12345はパスワード, 30000000ADA送金)
Slot 0, 1, 2とみていきます。
アカウント方式でない、コインの所有者を変更していく、UTXO(ビットコインと同様の未使用トランザクションアウトプット)のしくみが、わかりやすく見ることができます。イーサリアムはUTXOを使っていませんが、後発ゆえにいいとこどりをしている部分でしょうか。
(E)UTXOについて https://iohk.io/jp/blog/posts/2021/04/13/plutus-what-you-need-to-know/
参考動画
コードの細部まで丁寧に説明されており、とてもわかりやすいです。(といっても難解ですが・・)
Playgroundがデフォルトでどこまで実装されているかを確認するために、”HelloWorld”を最初に実行するといいと思います。
Haskellを復習してまたチャレンジしてみたいと思います。(ここまで記録をとっておくと次からやりやすい。Githubアカウントが必要で”Save”で自分のGistに保存してくれる。)
Marlowe / Cardano
Haskellで開発さているカルダノですが、そのHaskellの難易度とは真逆のビジュアルプログラミング環境Marloweがあるのを知り、試してみました。
ブロックチェーンコントラクトの内容なのに、プログラミング教育についてのブログ、http://decode.red/ed/ で扱った方がいいのではと思えるほどのギャップに驚きました。
まるでスクラッチです。それもそのはず、URLからGoogleのBlocklyをベースにしているようです。結合できるプログラミングブロックを制約することによってミスを少なくできるので、セキュリティが要求されるコードに使うことは、ある意味理にかなっているかもしれません。下は、シミュレーション画面。コードが表示されます。
ここでは、下記動画のデモを実行してみました。(挙動をわかりやすくするため数値をかえています。)
以下完成したコード
内容は、Player1,Play2がそれぞれコインを預け入れ、次に両者が別々に入力する数字が一致し、かつPlayer1の数が1なら、Player1が払い戻しをうけ、1以外ならPlayer2が、一致していなかったらもらえない、という一種の賭けです。賭けなので平等な条件にならないといけないのですが、デバッグ表示がわかりづらいので、金額を変えました。ADAというのはカルダノで使われているコインです。
“Start Simulation”ボタンが押されたら、以下の順で画面がすすんでいきます。
Player1,2とも1の場合
Player1,2とも2の場合
Player1が2、Player2が1の場合
slotというのは、プログラムのすすむ時間のようなものと解釈しましたが、何もしないと預けいれたコインがもどされるような仕組みがはいっているようです。(間違っていたらすみません–; )
カルダノネットワークは、イーサリアムネットワークのERC20を変換してもってくることができるようになるということですが、これはとても魅力的に思います。ブロックチェーンの世界はコインも開発環境も個性的で面白いです。
Bitlife Coin
EthereumのERC20 token templateというものを使って、テストネットワーク上のマイコイン(Bitlife Coin)を作ってみました。マイコインをブラウザアドオンのMetaMaskからスマホのMetaMaskに送金します。(Ropstenテストネットワーク)
https://github.com/hackers-live/erc20-token-template
環境) Ubuntu20.04/Docker/Ubuntu20.04/WSL/Windows11
インストール
touch ~/.bash_profile
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
nvm install 11.11.0
nvm use 11.11.0
node -v && npm -v
npm i -g truffle
npm i -g truffle-flattener
最初、WSLのUbuntuで試みましたが、やはり上記バージョンの組み合わせでないとうまくいかないことからdockerで新たに構築しました。
dockerではrootユーザで操作するため以下のコマンドが必要になりました。
npm config set unsafe-perm true
また、開発環境等はいっていないため、gcc, pythonも必要となります。(ネイティブビルドをするため: node-gyp-build)
テンプレートの編集
git clone https://github.com/hackers-live/erc20-token-template.git
cd erc20-token-template/
npm install
vi contracts/MyCoin.sol
// 10 billion
contract MyCoin is ERC20Capped(10000000000 ether) {
string public name = "Bitlife Coin";
string public symbol = "BLC";
uint8 public decimals = 18;
address public CFO;
address public CEO;
Code language: PHP (php)
オリジナルの部分のみ変更する。
設定ファイルの作成
.infura_key infuraのプロジェクトID (https://infura.io/ で登録)
.account アカウントアドレス
.secret ブラウザMetaMaskでアカウント作成するときのニーモニックコード
まずローカルでデプロイテストをします。(truffle単体でシミュレートできるのですね。前はGanacheを使った)
truffle develop
コンソールで、
truffle(develop)> migrate
とするとデプロイします。各コマンドを実行してテストします。(テストネットと同じなので以下で説明)
確認ができたら、テストネットにアクセスします。
truffle console –network ropsten
同じくコンソールで、
truffle(ropsten)> migrate
1_initial_migration.js (Total cost:0.00196019 ETH)
2_deploy_coin.js (total cost:0.00945698 ETH)
がデプロイされる。
アカウント確認
truffle(ropsten)> accounts = await web3.eth.getAccounts()
5つ表示され、一番目がMetaMaskと同じアドレス。
マイコインの確認
truffle(ropsten)> token = await MyCoin.deployed()
truffle(ropsten)> token.name()
‘Bitlife Coin’
truffle(ropsten)> token.symbol()
‘BLC’
truffle(ropsten)> token.address
‘0x0eD1cf4ADc9c9E53Dc1581512ebE971a6501028E’
このアドレスをMetaMaskで”Import Tokens”に入力する。
コインを生成できるアカウントの確認
truffle(ropsten)> token.isMinter(accounts[0])
true
truffle(ropsten)> token.isMinter(accounts[1])
false
マイニング
truffle(ropsten)> token.mint(accounts[0], web3.utils.toWei(“1000”, “ether”))
マイニングするごとにブラウザのMetaMaskのBLCコインが増えていくことを確認。
またブラウザのMetaMaskを操作して、スマホのMetaMaskに送金する。スマホ側も新規トークンアドレスをインポートしておく。
GASS代が必要なので送金する前にETHがない場合は、フォーセットから取得。
https://faucet.egorfine.com/
コンソールで金額の確認(BNはBigNumberの略)
truffle(ropsten)> balance = await token.balanceOf(accounts[0])
undefined
truffle(ropsten)> balance
BN {
negative: 0,
words: [ 65011712, 54678630, 666133, <1 empty item> ],
length: 3,
red: null }
truffle(ropsten)> balance.toString()
‘3000000000000000000000’
truffle(ropsten)> supp = await token.totalSupply()
undefined
truffle(ropsten)> supp
BN {
negative: 0,
words: [ 41943040, 28165598, 888178, <1 empty item> ],
length: 3,
red: null }
truffle(ropsten)> supp.toString()
‘4000000000000000000000’
スマホ画面
スマホアプリでETHとならんで表示されているのを見て、ちょっと感動しました。
これはメインネットでも同様にできるのですが、GASS代がかかるのと今は用途がないので、テストネットで十分です。独自通貨の発行ってなんか夢がありますね。
Dapp Tools
ブロックチェーン技術を使った分散型アプリケーションとしてDappとかdAppとかあらわされますが、Ethereum上で動作するDappの開発言語Solidityのテスト環境としてdapptoolsというものを見つけたの試してみました。
https://github.com/dapphub/dapptools
(下記動画で学習中、テストパターンを与える部分がよくわからなかったので確認してみただけになります。ブロックチェーンは様々な種類があり、それぞれ開発環境も豊富です。それが一気に押し寄せてきた感じがあり、とりあえず気になるものからどんどんためして理解を深めようと思っています。)
動画では、Openzeppelinとか使用している部分もありますが、ここではDapp ToolsといいながらDappとは関係ない純粋にSolidity言語による一般ロジックのテストの部分に注目しています。
環境) VSCode + Ubuntu20.04/WSL/Windows11
インストール
curl -L https://nixos.org/nix/install | sh
. “$HOME/.nix-profile/etc/profile.d/nix.sh”
curl https://dapp.tools/install | sh
初期化
mkdir dapp_test2
cd dapp_test2
dapp init
code .
dappコマンドでファイルは自動生成され、以下の内容に編集します。(*.t.sol がテストコード)
Dapptest2.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.6;
contract Dapptest2 {
uint8[] internal arr;
function remove(uint8 _index) internal{
require(_index < arr.length, "index out of bound");
for(uint i = _index; i < arr.length - 1 ; i++){
arr[i] = arr[i+1];
}
arr.pop();
}
}
Code language: JavaScript (javascript)
Dapptest2.t.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.6;
import "ds-test/test.sol";
import "./Dapptest2.sol";
contract Dapptest2Test is Dapptest2, DSTest {
Dapptest2 test;
//event DebugLogEvent(string);
uint8[] private copy;
function test_remove(uint8[] memory _arr, uint8 _i) public {
/* function test_remove() public {
uint[] memory _arr = new uint[](4);
_arr[0] = 1;
_arr[1] = 2;
_arr[2] = 3;
_arr[3] = 4;
uint _i = 2;
*/
if(_i >= _arr.length){
return;
}
arr = _arr;
// delete copy;
for(uint i=0;i<arr.length;i++){
if(i!=_i){
copy.push(arr[i]);
}
}
remove(_i);
assertEq(arr.length, copy.length);
for(uint i=0;i<arr.length;i++){
assertEq(arr[i], copy[i]);
}
//emit DebugLogEvent("-- end --");
}
function test_length(uint8[] memory _arr, uint8 _i) public{
if(_i >= _arr.length){
return;
}
assert(_arr.length == _i);
}
function setUp() public {
test = new Dapptest2();
}
function testFail_basic_sanity() public {
assertTrue(false);
}
function test_basic_sanity() public {
assertTrue(true);
}
}
Code language: JavaScript (javascript)
動画ではremove()関数のテストの様子がわかりますが、入力の配列とインデックスに何が与えられているのかわかりづらかったため、test_length()という関数を追加して試してみました。
dapp test –fuzz-runs 10
このコマンドを実行しても上記スクリーンショットのように成功するときもあれば、下記のように失敗するときもあります。
失敗したとき[FAIL]のCounterexampleという部分に、配列とインデックスがでてきますが、毎回違うためランダムに入力データが与えられていることが確認できました。(見やすくするためオリジナルのuint256をuint8に変更)
–fuzz-runsを指定しないと100がデフォルトで与えられるようです。
本来の目的のremove()関数のテストでは、リムーブされたことをテストするのが目的のため、配列やインデックスの数はなんでもいいのでチェックする必要はなく、テストしていないため毎回成功することになります。
VSCodeの環境(Solidity機能拡張あり)でSolidityのテストできる環境をためせたことは有益でした。
Cadence / Flow
NFTが得意とされるFlowブロックチェーンの記述言語、Cadence(ケーデンス)を試してみました。(音楽用語のカデンツのことですね)
https://docs.onflow.org/cadence/tutorial/01-first-steps/
CadenceにはPlaygroundが用意されており、これを使ってFlowの特徴であるアカウントごとのストレージについてチュートリアルを実行して理解を深めました。
まずは、単純な文字列を表示するだけのプログラムです。上記コントラクトをデプロイします。左に表示されているのはアカウントで、0x01からアドレスがふられています。これは0x01にプログラムとしてデプロイしたのでコントラクト名Helloがアドレスの下に表示されます。(言語はSwiftに似ている)
保存されたリソースが実行できることを確認します。loadしたリソースは戻すか破棄する必要があるようです。次に他のアカウントからアクセスできる方法を考えます。
0x02アカウントのストレージにあるリソースをloadするのではなく、linkを取得します。ためしに0x03アカウントでトランザクションを送信しますがエラーになりまだアクセスできません。
0x02アカウントで送信するともちらん成功しました。
他のアカウントからアクセスするためには、少しトランザクションを変更したものを用意し送信してみます。今度は成功しました。
このような感じで、Playgroundではアカウントの切り替えなど直感的で、Flowのしくみを学ぶことができます。NFTが得意とされているようですので、また次の機会に試してみたいと思います。
参考動画