Soulbound Token
イーサリアムの提唱者ビタリック・ブリテンの論文
https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4105763
で話題となった”Soulbound Token(SBT)”。
簡単に言うと譲渡できないNFTというもののようですが、ブロックチェーンのまた新しい可能性を感じます。
ここでは、実際にそのトークンの実装を説明した動画をみて理解を深めたいと思います。(IDE(Remix)の使い方は以下と同様)
http://bitlife.me/bc/2022/04/29/
http://bitlife.me/bc/2022/01/09/
https://github.com/Dervoo/Soulbound-Token/blob/master/contracts/SoulboundToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
/**
* An experiment in Soul Bound Tokens (SBT's) following Vitalik's
* co-authored whitepaper at:
* https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4105763
*
* I propose for a rename to Non-Transferable Tokens NTT's
*/
contract SoulboundToken {
struct Soul {
uint256 patientIdentityNumber;
string identity; // name / surname
string town;
string street;
uint8 streetNumber;
string postCode;
string sicknessIdentity;
string lastTestRecord;
string findings;
string treatment;
string treatmentIndications;
string annotations;
string plannedVisits;
}
mapping (address => Soul) private souls; // Souls created by operator
mapping (address => mapping (address => Soul)) soulProfiles; // Anybody can create 1 profile for soul owners
mapping (address => address[]) private profiles; // Addresses of people who created profiles for a soul
string public name;
string public ticker; // operation identity
address public operator;
bytes32 private zeroHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
event Mint(address _soul);
event Burn(address _soul);
event Update(address _soul);
event SetProfile(address _profiler, address _soul);
event RemoveProfile(address _profiler, address _soul);
constructor(string memory _name, string memory _ticker) {
name = _name;
ticker = _ticker;
operator = msg.sender;
}
function mint(address _soul, Soul memory _soulData) external {
require(keccak256(bytes(souls[_soul].identity)) == zeroHash, "Soul already exists");
require(msg.sender == operator, "Only operator can mint new souls");
souls[_soul] = _soulData;
emit Mint(_soul);
}
function burn(address _soul) external {
require(msg.sender == _soul || msg.sender == operator, "Only users and issuers have rights to delete their data");
delete souls[_soul];
for (uint i=0; i<profiles[_soul].length; i++) {
address profiler = profiles[_soul][i];
delete soulProfiles[profiler][_soul];
}
emit Burn(_soul);
}
function update(address _soul, Soul memory _soulData) external {
require(msg.sender == operator, "Only operator can update soul data");
require(keccak256(bytes(souls[_soul].identity)) != zeroHash, "Soul does not exist");
souls[_soul] = _soulData;
emit Update(_soul);
}
function hasSoul(address _soul) external view returns (bool) {
if (keccak256(bytes(souls[_soul].identity)) == zeroHash) {
return false;
} else {
return true;
}
}
function getSoul(address _soul) external view returns (Soul memory) {
return souls[_soul];
}
/**
* Profiles are used by 3rd parties and individual users to store data.
* Data is stored in a nested mapping relative to msg.sender
* By default they can only store data on addresses that have been minted
*/
function setProfile(address _soul, Soul memory _soulData) external {
require(keccak256(bytes(souls[_soul].identity)) != zeroHash, "Cannot create a profile for a soul that has not been minted");
soulProfiles[msg.sender][_soul] = _soulData;
profiles[_soul].push(msg.sender);
emit SetProfile(msg.sender, _soul);
}
function getProfile(address _profiler, address _soul) external view returns (Soul memory) {
return soulProfiles[_profiler][_soul];
}
function listProfiles(address _soul) external view returns (address[] memory) {
return profiles[_soul];
}
function hasProfile(address _profiler, address _soul) external view returns (bool) {
if (keccak256(bytes(soulProfiles[_profiler][_soul].identity)) == zeroHash) {
return false;
} else {
return true;
}
}
function removeProfile(address _profiler, address _soul) external {
require(msg.sender == _soul, "Only users have rights to delete their profile data");
delete soulProfiles[_profiler][msg.sender];
emit RemoveProfile(_profiler, _soul);
}
}
Code language: JavaScript (javascript)
コードを見てみるとその内容がよく理解できます。
mapping (address => Soul) private souls; // Souls created by operator
mapping (address => mapping (address => Soul)) soulProfiles; // Anybody can create 1 profile for soul owners
この二行が特徴をよく説明しています。オリジナルのコードにはないですが、動画にあるコメントがわかりやすいので追記しました。
Soulという構造体のデータを発行できる人、焼却できる人、登録できる人、更新できる人、参照できる人、それぞれルールが決められています。
所有者が移動できないので構造はシンプルです。
コードの中でeventやzeroHashについても調べてみました。
eventについて
https://qiita.com/hakumai-iida/items/3da0252415ec24fe177b
詳しく説明されいます。サンプルDAppsについてとても興味深いです。
https://www.tutorialspoint.com/solidity/solidity_events.htm
コントラクトからフロントエンドへの通知の実装について書かれています。使い方がよくわかります。(スクショとりました)
zeroHashについて
bytes32 private zeroHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
..
require(keccak256(bytes(souls[_soul].identity)) == zeroHash, “Soul already exists”);
インスタンスがない状態、Nullのような状態を表すために使われているようです。
ためしにゼロのハッシュ値をとってみました。(Ethereum標準ハッシュ関数keccak256 ケチャック)
参考) https://qiita.com/kaito1994/items/62974800419f0e51c6cb
from Crypto.Hash import keccak
import binascii
keccak256 = keccak.new(data=0, digest_bits=256).digest()
print("Keccak256:", binascii.hexlify(keccak256))
#Keccak256: b'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'
Code language: PHP (php)
下記サイトでは、SBTついて詳しく書かれています。
https://www.xross-dx.com/article/aboutSBT-byGG-vol1.html
アドレスの所有者に固有の情報を与えことによって、信用調査等に利用できるといったところでしょうか。
情報を改竄できないブロックチェーンならではの使い方と言えます。
Move / Aptos
今週、注目のレイヤー1プロジェクトのAptos(アプトス:APT)が大手取引所に一斉に上場されました。
注目されている理由は、大手投資機関から多額の出資を受けているのもありますが、もともとFacebook(今はMeta)のプロジェクトで途中で断念した、仮想通貨Diem(ディエム 旧リブラ)の元開発者が創設したこともあり、話題もとても豊富なことがあります。
(Facebookのようなプラットホーマが仮想通貨を持つことが国家のような組織から見たら、かなり脅威だったのでしょう、つぶされた感が否めません。)
開発者としては、開発に使われる環境やプログラミング言語Moveにとても興味があります。
https://aptos.dev/cli-tools/aptos-cli-tool/install-aptos-cli
開発には、上記Aptos CLIで行うようです。
また下記動画にAptosについて、またMove言語について詳しい説明がありましたので参考にさせていただきました。
https://www.youtube.com/watch?v=I5dehispk-E
Aptos CLIの使い方や、MoveとSolidityとの違いについて、動画の中でとてもわかりやすく説明されていましたので、その部分のスクリーンショットを使わせていただきます。
Move言語がRust言語ベースでブロックチェーンプログラムに特化(アカウントチェックをやってくれることからコーディング量が減少)していることと、Solanaチェーンにも使われる可能性があるということはとても興味深い内容でした。
「Solana in Rust & TypeScript」
http://bitlife.me/bc/2022/02/11/
Rustは値の所有権という概念があり、デジタル資産の管理と親和性があります。ブロックチェーンプログラムでよく使われるのも理にかなっています。もしかして”Move”というのは、Rustの所有権の移動(Move)という考え方からとっているかもしれませんね。
今回はAptos CLIでなく、便利なPlaygroundがあるということから動画を参考に使ってみました。
https://playground.pontem.network/
起動するとexample-projectが現れます。これらを使ってアドレス0x01から0x02へののコインの送金をしてみました。mint関数は、Coins.moveのものと名前がぶつかるのでmy_mintとしました。実行はscriptの関数をRunの入力項目に引数とともに記述します。
次は新規にファイルを作成して、HelloモジュールをScriptから呼び出します。
ここまでですが、とても使いやすいと感じました。
example-projectのコードも見やすく、何をやっているのか理解がしやすかったです。
もう少し学習をすすめようと思います。
Bitlife Coin / iOS
最近iOS開発を再々開することになり、iOSアプリでも暗号通貨を扱ってみたいという思いから、調べたことを久しぶりに投稿いたします。
iPhoneが発売されてから、iOSアプリ(当時はiPhoneアプリ)開発をはじめ、Swiftきっかけで再開し、そして今回Appleシリコン、MLきっかけで三度始めることになりました。
https://github.com/horizontalsystems/ethereum-kit-ios
http://bitlife.me/bc/2022/01/23/ (前回ブログ)
目標は、上記EthereumKitを以前作ってマイコイン”Bitlife Coin”の残高を表示させることです。
iOSのプログラムにいく前に、Bitlife Coinの復習と、Ropstenテストネットが終了するという情報もあることから前回ブログを参考に、Goerliテストネットへのデプロイをしました。
前回のDocker環境の仕方を忘れてしまい(Docker imageがどっかにいってしまった・・)、いろいろと手間取りました。(メモっておかないとだですね)
Windows Docker Desktop -> Containers -> competent_para スタート
WSL -> docker exec -it competent_pare bash
(こんなやり方だった? WSLが起動しなくなる現象はこれが原因? PC再起動でなんとか復旧)
truffleの実行でエラーがでたため、nvmアップデート
nvm install 12.22.12
nvm use 12.22.12
truffle console –network goerli
その前に、truffle-config.jsの編集(前回このあたりの説明がなかった・・)
ropsten: {
provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/${infura_key}`, 0, numAccounts),
network_id: 3,
gas: 5500000, // Ropsten has a lower block limit than mainnet
confirmations: 2, // # of confs to wait between deployments. (default: 0)
timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
skipDryRun: true, // Skip dry run before migrations? (default: false for public nets )
from: account,
gasPrice: 10000000000, // in wei (default: 100 gwei)
websockets: true // Enable EventEmitter interface for web3 (default: false)
},
goerli: {
provider: () => new HDWalletProvider(mnemonic, `https://goerli.infura.io/v3/${infura_key}`, 0, numAccounts),
network_id: 5,
gas: 5500000, // Ropsten has a lower block limit than mainnet
confirmations: 2, // # of confs to wait between deployments. (default: 0)
timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
skipDryRun: true, // Skip dry run before migrations? (default: false for public nets )
from: account,
gasPrice: 10000000000, // in wei (default: 100 gwei)
websockets: true // Enable EventEmitter interface for web3 (default: false)
},
Code language: JavaScript (javascript)
infura.ioのアカウントはまだ使用可能で、上記goerliのendpointを確認。
前回同様にデプロイしてミント。
truffle(goerli)> migrate
truffle(goerli)> token.mint(accounts[0], web3.utils.toWei(“5000”, “ether”))
https://qiita.com/guntamania/items/d1605961f0af008e8e8d
せっかくなので、こちらを参考に前回やらなかった送金をしました。
その前にこちらでEtherを取得
このメタマスクのウォレットのニーモニックをtruffle実行フォルダにある.secretに保存します。
truffle(goerli)> tc = await MyCoin.at(MyCoin.address).then(=>)
truffle(goerli)> tc.totalSupply().then(ts=>ts.toString())
‘5000000000000000000000’
truffle(goerli)> dest = “0x…..” <- 送金先 truffle(goerli)> tc.transfer(dest, 100000000000000)
さていよいよiOS側ですが、githubから取得したプロジェクトをXcodeに読み込ませビルドします。(github参考に、pod installも。.xcworkspaceを使用)
私テスト用デバイスiPhone6がiOS13.0に対応していないのでiPhoneシミュレータを使いました。
ここでgoerliテストネットワーク用に修正をします。
Configuration.swift
・chain.id 5(goerli)でErc20Token追加
3(ropsten)でも一応確認。
・BLCトークンアドレスの設定(前回ブログ確認)
・RpcResourceの設定。goerli用の関数を使用
・infuraCredentialsの設定。登録したアカウントのProjectIDとSecretコード。
・defaultWordsの設定。MetaMaskのニーモニックコードを使用。(このユーザの残高を確認。ログイン時の指定できるが面倒なのでデフォルトに)
・RcpResourceの設定。goerli用の関数に変更。引数にinfuraCredentialsを指定。
・TransactionResourceの設定。goerli用の関数に変更。etherScanのアカウントを作成しAPIキーを指定。
Chain.swift
・goerliのcointypeを1から60に変更(ropstenでも同様)
ニーモニックから出力するアドレスが一致しないため、いろいろと調べたところ、HDWallet.swiftのprivateKey:pathが違ったため。
ganache-cli -m “….”
….
Mnemonic: ….
Base HD Path: m/44’/60’/0’/0/{account_index}
ganacheでも確認可
実行結果
まだ送金ができていませんが、アプリに組み込むのに何が必要なのか理解できた気がします。
<おまけ>
コードを修正しながら動作確認していく上でなかなかうまくできなかったので、上記APIも実行して確認しました。
https://api-goerli.etherscan.io/api?module=account&action=tokenbalance&contractaddress=”mycoin contract address”&address=”wallet address”&tag=latest&apikey=”APIKEY”
Response: {“status”:”1″,”message”:”OK”,”result”:”4999998999499499499500″}
Terra LUNA Shock
ちょっと遅くなりましたがTerra Luna ショックについてまとめるのと、これをきっかけにここまでの総括をしようと思います。
http://bitlife.me/bc/2022/03/12/ 参考) 先進的なFinance機能を持つTerra LUNA
ステーブルコインUSTが暴落し、それとともにLUNAも暴落、これまで資産価値上位にあったコインの価値がなくなりました。
クリプト業界にとって大きなできごとであり、自分にとってもこれらの関与についてひと段落するきっかけだったことから長文ですが備忘録としてまとめてみました。
Blockchain技術の興味からこのブログもはじめ、クリプトへの理解を深めるためトレードも始めました。
(ブログでも述べましたが、あれだけクリプトが過熱していた時期に興味をもたなかったのにNFTがきっかけで興味をもつようになりました。)株取引の経験はストックオプションの売買を少ししたくらいでほとんどありません。FXはそれ自体よりもトレードアプリMT4に興味があり学習はしましたが、実際のトレードはやりませんでした。
まず手始めに国内取引所に口座をつくり10万円ほど入金しました。入金するとすぐにメジャーどころのBitcoin、Ethereum、そしてPolkadotなど購入しました。(今考えたらタイミングを考えずに買うなどありえないですね。買わなきゃ始まらないみたいなノリで・・しかもこの時期下落前)Ehereumはスマートコントラクトやネームサービスでドメインを購入したりといろいろと遊べるため積極的に買いました。(ガス代、転送手数料など考えていない時期)メタマスクのウォレットの使い方も覚えました。また取引所では他のコインも売買楽しみました。(板が使えない、使えたとしてはも少額ではできない、スプレッドが高い)ここまでかなりロスをすることは明らかですね。
注目のBlockchainのコインはどれも国内で購入できないことや、やはり板取引でないとかなり不利であることから、情報も多い海外取引所をByBitを使うことにしました。最低10ドルで取引ができ手数料もやすいことから私のような少額で遊ぶ人にはとても向いています。注目のコインもたくさんありいろいろ買いすぎました。
最初は現物ばかりでしたが、デリバティブ取引での空売りも覚え、これまで国内取引所でやっていたことがいかに不利であるか実感しました。(円で取引するので為替変動が影響するのもやっかいです)
ByBitといえどもほしいコインがないことがあり、他の海外取引所も調べました。日本発ということからASTRを購入したかっためGateIOを利用することにしました。ちなみにByBit、GateIOには国内取引所から送金しました。(今は??) ASTR、ADA、SOLなどのまたメタマス以外のウォレット(Polkatot.js、Yoroi、Phantom)も使ってみて、それぞれ特徴を知りました。(Blogでも利用)
入金の手数料が気になり、いろいろと調べてみるとJPYCのプリペイドを利用すると安くできることがわかり、メタマスクでPolygonチェーンのQuickSwap, SushiSwapを使ってUSDCに(Maticも少し必要)、そしてGateIOに数万円分新規に転送しました。GateioからByBitにはTRXチェーンを使うと手数料がなく転送できました。(その前にUSDC->USDT。最低金額は5000円くらい) このとき「取引所はなくても取引できるんだ」と知りました。(これもあって日本発のコスプレトークンをDeXで買ってみました)ステーキングも興味がありましたが、動かせなくなる資金があるほど余裕もなかったためしくみだけ学習してやりませんでした。
ひととおりクリプトの使い方やしくみがわかったところで、トレードに集中するようになり、外部要因による影響とか(FOMCがどうのナスダックがどうだとか)、テクニカル指標の使い方とか(ボリンジャーバンドがどうだとか)、意識するようになりました。
しかしいきなり10%近い急上昇、下落があるクリプトの相場は非常に難しいです。これが面白い特徴的でもあるのですが、ここで自問自答したのは、何を目的にトレードするかでした。(何を得たいのか?長期、短期? )目的はあくまで勉強なので(このような少額で儲かってもしれている)、ショートタームで難しい局面でも積極的に試行錯誤してチャレンジしました。
クリプトのトレードは、株ほど広範囲(興味のない分野)の情報が必要でもなく、FXほどテクニカルでもなく、適度なストーリー(興味があるBlockchain界隈にニュース)が影響するので、自分にとって面白く感じました。しかしずっとチャートにへばりついているわけにもいかず、どういう時間帯でどのくらいの時間やるのか、ということが重要だと思いました。リアルタイムで見ていれば、急落、急上昇(ボラティリティが高いというのですよね)でポジションを変更することもできますが、見ていないときがほとんどなので、こういうことに対処するにはやはり自動トレードをプログラミングする必要性も感じました。
こういうアルゴリズムを考えるのにも、ボラティリティが高い動きを見る経験が必要になるので、クリプトは向いているのかもしれません。あといろんな感情を経験するものだと思いました。人間味がでるというか応援したいプロジェクトかどうかで判断がかわります。(本来そういうものなのかも。。ちなみに4月中からのダウントレンドでASTRを安値買いをつづけて空売りできませんでした。)
そしてLUNAの暴落がありました。暴落の途中なんども持ち直す動きがあったのでコントロールされていると思い部分的にしか空売りをしませんでした。(実績があったコインだけに、まさかこれ以上は下がらないよね・・と思い続けていました。) あれだけ下がっていても空売りって継続できないものですね。また底と思って買った現物のLUNAが消えてしまいました。(今はLUNA Classic: LUNC ルナシー?) このときもチャートをウォッチできておらず、やはり自動トレードは必要だと感じました。
4月中からのダウントレンドでBitcoinに引っ張られる形でアルトコインも下落しましたが、いろいろと種類をもっていたためメンテができず気づいたら$10下回り取引ができなくなるということにもなりました。ここでも自動トレードは必要性を感じました。(それ以前に初心者なのに手を広げすぎか・・あとインバース無期限で下落して結構減らした(SOL))
こういつたこともあり、年の初めからここまでで(5月中)、トレードについてひと段落しようと思いました。
クリプト冬の時代といわれる中、利上げによる株安、そしてなによりロシアによるウクライナ侵攻と、かなり厳しい外部要因がある中のトレードでした。結果資金は半分くらいになり、上昇トレンドの浮ついた気持ちを味わうことはありませんでしたが、いっぱい失敗して勉強になりました。
今後、さらなるBitcoinの暴落があるという予測がありますが、もし下がった場合、単に価格が下がるだけでなくもっと深刻な影響がありそうな気がします。LUNAが下がっているとき、USTだけでなくUSDTも下がった瞬間がありました。多くのコインの取引がUSDTとペアになっているので、売られるとUSDTが増大し担保が不安です。(もともと問題をはらんでいる)もしBitcoinが大量に売られれば、この問題が大きくなり、そもそも基準にしているUSDTが下落したら正しい価値がわからず取引することになるのではという心配があります。またLUNA暴落時、USDCをUSDTで買おうとしたときByBitで初めてタイムアウトで取引が成立しない経験しました。あとロウソク足表示が追い付かず、取引判断のタイミングが遅れたのも初めてでした。ByBitはとても処理が速いサーバでもともと優秀なシステムですが、このときは異常なほどトラフィックがあったのでしょう。
クリプトは国境を越えた送金が簡単にでき、メタマスクでそれを経験したときは、本当にその便利さを実感しました。このようはパワフルなツールが、中央集権的な支配をしたい人たちの敵対的な存在になるのかどうかによっても、今後の先行きに影響を与える気がします。非中央集権的な自由を守りたいという気持ちもありつつ、なんでも自由なのがよいのか、ということを最近感じ始め、なにが良いのかよくわからなくなってきています。
またDeXの例を挙げましたが、DeFiが進む取引が自動化され、従来のしくみが不要になります。またBlockchainにはDAO(自立分散組織)というプロジェクトもあり、これが進むと組織も効率化できます。
これらはAI以上に人の仕事を奪いかねません。(システムの自動化・無人化) こういった方向性に夢をもちつつも、何かわからない懸念みたいなものも同時に感じています。(民主的で自由だと思っていたシステムが実はそうでなかったとか・・お金を持っている人が影響力をもつのも民主的?)
とても奥が深いです。
大変長くなりましたが、経験したことを後で思い出すことができるように書きました。(損失しましたが、それが少しでも役に立ったという思いになれます。)
まだまだいろいろと勉強していきたいと思っています。
Ethereum Remix & Github
Ethereum の開発環境RemixでSolidity を使った開発を、下記記事で以前試しましたが、
http://bitlife.me/bc/2022/01/09/
今回は、RemixとGithubアカウントを連携してより環境を充実させることと、より具体的に開発を進めるためにサンプルコードBallot.solを掘り下げてみました。
これは投票する項目をデプロイ時に登録して、投票権を与えたアカウントの投票させ、その結果一番多い投票があった項目を表示するものです。
最初登録する項目proposalNamesの与え方がよくわかりませんでしたが、動画(最下部)を参考にしました。
このように配列で与えるのですが、それも適当なデータではなく、きちんとした文字列である必要があり、下記コードで生成しました。
const ethers = require('ethers');
async function createBytes(args){
const name = args[0];
const bytes = ethers.utils.formatBytes32String(name);
console.log("Bytes: ", bytes);
}
Code language: JavaScript (javascript)
$ node createBytes.js name01
Bytes: 0x6e616d6530310000000000000000000000000000000000000000000000000000
$ node createBytes.js name02
Bytes: 0x6e616d6530320000000000000000000000000000000000000000000000000000
デプロイ時いちいちコピペするのが面倒なので、コードの中で与えるように変更しました。
https://github.com/systemsblue/Solidity-work01/blob/main/contracts/3_Ballot.sol
このような変更も今回 Remixのプラグイン、DGITを使ってできました。
Githubアカウント側の準備としては、Settings -> Developer settings -> Personal access tokes -> Generate new token でトークンを発行してこれを DGIT の Github Settings に貼り付けます。
あとはgitコマンドを使うようにメニューから実行していきます。
最初にもどってBallotの操作手順を追っていきます。
コンパイルするとコンストラクタの引数をなくしたので、ビルドすると上のように入力エリアがなくなります。これでDeployボタンをクリックします。(二つの名前が暗黙的に登録されます)
操作はACCOUNT(上の画像)を切り替えながら、ときにはアドレスをコピペして下記に貼り付け、ボタンをクリックしていきます。
操作は結構面倒です。
まずchairpersonで、投票の権限を与えるアカウントを確認して、このアカウントが選択されているときにgiveRightToVoteが使えます。ここに投票するアカウントのアドレスをコピペするのですが、ACCOUNTを切り替えてコピーし、chairpersonにまたもどしてgiveRightToVoteをクリックします。
投票できるアカウントが登録できたら、それぞれのACCOUNTに切り替えて投票します(Voteをクリック)。このときの値は2項目であれば、インデックスとして0と1になります。
winnerNameをクリックすると投票数が多い方の名前(といっても数値)が表示されます。
このサンプルはいろんなエッセンスを学ぶことができとても参考になります。IDEをWebアプリで使うことを考えると、Githubの連携も欠かせないと思いました。
CosmosとかPolkadotなどでもGithubアカウントが必要だったのですが、認証の意味とファイルの保存目的のような感じを受けました。Gitコマンドのように使えるこのプラグインはとても便利です。
参考動画
Astar Network
以前取り上げたPolkadotのバラチェーンであるAstar Networkについて、いろいろ試してみました。
http://bitlife.me/bc/2022/02/26/
基本的な使い方はこの「Substrate / Polkadot」で取り上げたとおりですが、「Solidity to WASM Compiler」というドキュメントからWASMについて調べたいと思ったのがきっかけです。
https://docs.astar.network/build/smart-contracts/wasm/solidity
WASMは一つのバイナリをいろいろな場所で動かすことができるため、最近とても興味を持って調べています。
まず結果からですが、SBYトークンが取得できず(枯れているみたい)うまくいきませんでした。(先週も今も) しかしそこに至る経緯をメモしておきたいので、このまま進めたいと思います。(やりたいことは最後の動画を参考にしました)
その前に、Astar Networkについて整理しますが、Stake Technologiesという会社で創業者が日本人ということもあり個人的にもとても応援しているプロジェクトです。dApp開発者が報酬を得られるdApp Stakingというものに興味を持っています。
あと名前がややこしいのですが、Polkadot/Kusama (メインネット/実験ネット)に相当するのが、Astar/Shiden で、Shibuyaはテストネットになります。実験ネットとテストネットは違い実験ネットのコインは購入する必要があります。(少額はFaucetで取得できるみたい(しかし今はできない?)) Plasm Networkという名前もさまざまなドキュメントで残っていますが、これはAster Networkの以前の名前のようです。
AstarにはWASMがアップロードするためのコントラクトの項目がなかったので、Shibuyaで作業することにしました。
ShibuyaのFaucetは、Discord で取得できという案内がありましたができず、Astarのポータルからもできませんでした。
下記コミュニティFaucetからはできましたが、SS58(ネイティブ)ではなくH160(EVM)でした。
下記でコンバートしてEVMデポジットに入金が確認できたのですが、ポータルでSS58に変換することができず、WASMをデプロイするためのガス代として使用できませんでした。(EVMから引き出しでエラー。少額だから?)
では、前置きが長くなりましたが下記サイトを参考に環境構築(solidityコンパイラ)からやってみます。
https://docs.astar.network/build/smart-contracts/wasm/solidity
sudo apt install llvm openssl libxml2-dev
sudo apt-get install liblld-10-dev
いつものように、Ubuntu20.04にインストールましたが、llvmのバージョンがあわずバイナリーを使うことにしました。(13が必要でUbuntuでは10,11,12までしかなし)
wget https://github.com/hyperledger-labs/solang/releases/download/v0.1.10/solang-linux-x86-64
wget https://raw.githubusercontent.com/hyperledger-labs/solang/master/examples/flipper.sol
テストプログラムも取得しました。(やっている内容はビット反転ですね)
contract flipper {
bool private value;
/// Constructor that initializes the `bool` value to the given `init_value`.
constructor(bool initvalue) {
value = initvalue;
}
/// A message that can be called on instantiated contracts.
/// This one flips the value of the stored `bool` from `true`
/// to `false` and vice versa.
function flip() public {
value = !value;
}
/// Simply returns the current value of our `bool`.
function get() public view returns (bool) {
return value;
}
}
Code language: PHP (php)
コンパイルしてできた、flipper.contract ファイル をアップロードします。
スクリーンショットとは違いますが、実際のアカウントは、shibuya01を使用。
あと、警告も解消させています。
Walletからinjectしただけでは、EVMデポジットに送ることができず、JSONファイルであらためてインポートしました。
結局できたのは、SBYが取得できなかったため(H160(EVM)でなくSS58(ネイティブ)でないと上記に表示できない?)、Deployする直前までで、実行についてサイトにあるものをご参考ください。
へんな形になりましたが、開発がどんどんすすんでいる最中のお試しとしては、できなかったとして何もしないよりもできたとこだけ記録しておくということ大切だと思っています。
ポータルの使い方としては、Polkadotと同じなので、このあたり統一されていてとてもわかりやすいと思いました。
Avalanche Postman-collection
Exchange Chain (X-Chain), Platform Chain (P-Chain), Contract Chain (C-Chain) の3つのビルドインブロックチェーンをもつ、独特なしくみで高いパフォーマンスとEthereumとの互換性をもつAvalanche Platform。
Web APIで操作できるしくみは他のプラットフォームでも珍しくないのですが、Postmanの設定ファイルが用意されていることを動画(最下部)で知り便利だと思い試してみました。
しかしながら結果からいうと、Avalancheのテストノードが使える状態に同期するまでの時間がかかりすぎて(30時間以上かかるようで見積残り処理時間もなかなか減らずいつ終わるかわからない・・)、やろうとしていた動画のようなWallet間の送金はできませんでした。そのためいろいろとトライしたことの記録となります。
https://docs.avax.network/build/tutorials/nodes-and-staking/run-avalanche-node
上記を参考に、nodeの起動とcurlコマンドで送る手順が動画と同じことを確認できます。
./avalanchego –network-id=fuji –http-host 127.0.0.1
テストネットはFUJIというらしく(ここでも日本語が・・) このようにオプションを指定して起動します。(何もつけなければメインネット) ここではWSLでバイナリモジュールを使って起動。
次はPostmanをインストールして、下記から二つの設定ファイル(environment,collction)を読み込んで実行します。
https://github.com/ava-labs/avalanche-postman-collection
“Create a Keystore User”まではできますが、”Create an Address”は、上記ブートストラップがtrueにならないとできません。(これが30時間以上かかる?)
これとは別にWalletの準備をしました。
アドレスにC-ChainとX-Chainがあります。Xはネイティブ用で、CはEVM用でMetaMaskアドレスに送ることができます。
X-Chainに2 Avax、C-Chainに1 Avax送った結果です。上記Walletを作ると、X,C,P 3つのアドレスが作成されます。動画によるとPはステーキング用のようです。(アドレスはXとP部分以外は同じ文字列)
Postmanの前にもともとWallet-SDKを使って送金しようとたのですが、これもうまくいきませんでした。(うーん)
https://docs.avax.network/build/tools/avalanche-wallet-sdk/
下記メモです。
import { NetworkConstants, Network} from '@avalabs/avalanche-wallet-sdk';
これがうまくExportされないためExportされないためないため
const net = require('./avalanche-wallet-sdk/dist/index.js');
テストネット切り替えなど部分的にはうまくいったものもあるが
(node-fetchをクローバルにする方法などいろいろ試したりする方法などいろいろ試したり.jsの内容もいろいろ変えたり、 ts-nodeでバージョンを変えたりts-node-esmもためしたが同じ
import {MnemonicWallet, BN} from '@avalabs/avalanche-wallet-sdk'
これはうまくいくので(X,C,Pとも
メインネットンネット(x-avax..., x-fuji...)
XとPはこの文字以外は基本的に同じ字以外は基本的に同じ
Code language: JavaScript (javascript)
アドレス生成コード
import {MnemonicWallet, BN} from './avalanche-wallet-sdk/dist'
const net = require('./avalanche-wallet-sdk/dist/index.js');
const mnemonic = `wedding ...... orient bicycle`;
net.setNetwork(net.TestnetConfig);
//net.setNetwork(net.MainnetConfig);
let myWallet = new MnemonicWallet(mnemonic)
console.log(myWallet.getAddressX());
console.log(myWallet.getAddressP());
console.log(myWallet.getAddressC());
Code language: JavaScript (javascript)
また以下のようにPaper Walletというのを出力できます。
気になったのが、ここのアドレスとWebに表示されているアドレスがXだけ違っていました.
うまくいかないことが多かったのですが、いろいろと理解は深まりました。また機会があれば続きをやりたいと思います。
参考動画
Enjin Platform
ERC1155というコントラクトを考案した、Enjin社。NFTの分野で進んでいる印象があります。
今回、NFTの登録、Enjin Walletの接続、GraphQLを使った情報の取得を試してみました。
また下記NFTについて、他のBlockchainとの比較が興味深い記事です。
Enjin SDKのページから、上部にあるリンクからKovanテストネットワークを選びます。
https://docs.enjin.io/sdks/getting-started
https://kovan.cloud.enjin.io/platform
アカウントの登録をして、プロジェクトを作成します。
このときiPhoneにも、Enjin Walletアプリをインストールします。
Settingsで表示されるQRコードをアプリで読み取ると、Walletがリンクされます。
Walletへの入金は、KETHは下記から、
https://gitter.im/kovan-testnet/faucet
KENJはユーザサポートにメールで問い合わせ、Walletアドレスを知らせて入金してもらいました。(KETH, KENJは、ETH,ENJのKovanテストネットワーク用コイン)
ユーザサポートに聞きながらトライ&エラーをしたのでない画面があったり、前後している部分がありますが、FT,NFTの登録、トランザクションでのエラーを起こすときはKETHが足りないのも原因になるようです。
Webでの操作ごとにWallet側で承認の作成をしなくてはならないところは面倒に感じました。少なくともプロジェクトの作成、アセットの作成、アセットの発行(MINT)の3回必要。実は最初のMINTは成功したのですが、Tibit ProjのMINTは失敗しています。MINTに成功するとスマホにも表示されますが、表示できているのは最初のもの。(登録エラーのときもそうですが、エラーの原因がわかりづらい)
あとメモとしては、Walletを開発バージョンにしないと、KETH,KENJを表示しないため、設定画面のバージョン表示部分を10回タップする必要があります。
今回は、Enjin Platformのほんの一部ですが、Enjinを少しでも理解したかったので触ってみました。下記動画にはEnjin社のNFTに対する取り組みが詳しく説明されています。ポルカドットパラチェーン対応のEfinityについてはまた調べたいです。
NEAR Protocol
Nightshadeという独自シャーディングモデルによってスケーラビリティを向上させ高い性能を誇るNEAR Protocolの開発環境を試したみました。
参考:
NEAR Wallet Integrationを選びました。”Open in Gitpod” クリック(要Githubアカウント)
VS CodeライクなWebアプリが立ち上がり、開発環境一式が自動的にビルドされます。
“Open Browser”ボタンをクリックすると、フロントエンドのWebアプリが新しいWinodowで立ち上がります。(このときブラウザに許可をする)
Sign in すると、Walletとの接続を求められます。(必要になるアカウントの設定は済んでいるとする)
接続が終了すると、画面が変化。
“Say hi!”ボタンをクリックして、スマートコントラクトの呼び出し。
リンクをクリックしてスマートコントラクトが呼び出された様子を見てみる。
コードを見てみる。
上記3つのコードでやっていることは、なんとなく理解できそうです。
NEARというブロックチェーンから開発環境も含めて、実用性が高いという印象を受けました。(既存のWeb開発っぽい・・ブロックチェーンならではという部分のハードルが低そう・・) クロスチェーンに関する部分もまだ開発中ということで、まだまだ先が楽しみです。
参考動画
Terra LUNA
テラは、Cosmos のブロックチェーン開発エンジンTendermintによって開発されています。LUNAというネイティブトークン以外に、USTという担保なしのアルゴリズムによって法定通貨とペッグする、ステーブルコインも発行しており、下記www.terra.moneyにも”Programmable Money”とあるようにファイナンス関して先進的な印象をもちました。最近勢いがあります。
https://github.com/terra-money/LocalTerra
今回は、LocalTerraというローカルブロックチェーンを使ってテストしてみました。(ここにもterra-moneyとありますが、”money” 目立ちます)
環境) Docker, WSL / Ubuntu 20.04 / Windows 11
git clone –depth 1 https://www.github.com/terra-money/LocalTerra
cd LocalTerra
(私の環境では、docker-composeをアップデート /usr/local/bin)
sudo wget https://github.com/docker/compose/releases/download/v2.3.2/docker-compose-linux-x86_64
docker-compose up
これで一気にブロックチェーンの起動までいきます。新しいコンソールを開き、
docker-compose stop
で停止します。
LocalTerraの起動状況
起動したときのコンテナの状態
terrad statusなどのコマンドは、CLIから実行可能。
アカウントがあらかじめ用意されているので、LocalTerraに接続して、Terra Station Wallet (Chrome機能拡張)を作成する。
Chrome機能拡張
Rustの設定
https://docs.terra.money/docs/develop/dapp/quick-start/initial-setup.html
rustup default stable
rustup target add wasm32-unknown-unknown
cargo install cargo-generate –features vendored-openssl
cargo install cargo-run-script
Terrain インストール
sudo npm install -g @iboss/terrain
DApp イントール
terrain new my-terra-dapp
cd my-terra-dapp
npm install
デプロイ
terrain deploy counter –signer validator
コンソールを使ってデプロイしたコントラクトにアクセス
フロントエンドアプリを使ってコントラクトにアクセス(http://localhost:3000/)
terrain sync-refs
cd frontend
npm install
npm start
Walletに接続して、カウンターをインクリメント(コンソールのつづきなので9)
“+”を押すと、Walletがひらく
インクリメント完了
increment, getCountのコード確認
Blockchain開発にRustという言語はとても重要な位置をしめていますね。USTのようなステーブルコインのしくみはここでは関与しませんでしたが、とても興味深いです。
これまで、USDT,USDCのように実物のドルの担保があるのが普通でしたが、アルゴリズムだけで実現したものを皆が信用するということは、すごいことだなと、単純に思います。いろんな金融商品を組み合わせてリスクヘッジしたりすることは投資の世界でよくあるようですが、こういうのもアルゴリズムがあるのでしょう。最近Blockchainを研究するとともに、ちょっとファイナンス関連にも興味をもつようになってきたような・・