はじめに
CryptoKittiesの開発チームにより、ゼロから設計、開発された基盤技術で、NBATopShotに用いられていることで注目されたFlowの情報をまとめています。
特徴
Ethereumが中央台長で所有権を管理していたことに対して、Flowではアカウントのストレージにリソースオブジェクトを配置することで、スケールできるモデルを構築していることが特徴となっています。
node自体も、トランザクション収集、コンセンサス(PoS)、計算、検証それぞれのnodeに分断されており、このことが高速化につながっているわけですが、それぞれの領域に対して適切にコードを記述していくことが重要です。FlowにはEthereumのEOAとContractアドレスの区別はなく、スマートコントラクトは存在するアカウントにデプロイされ、そのアカウントのストレージを利用します。ストレージ容量はアカウントの保有FLOW数に応じて割り当てます。
(アーキテクチャの説明な)
https://medium.com/dapperlabs/enter-the-octagon-ufc-on-flow-brings-mma-to-crypto-480618408510)
FlowCLIのインストール
brew install flow-cli
sh -ci "$(curl -fsSL https://storage.googleapis.com/flow-cli/install.sh)"
flow cadence install-vscode-extension
EmulatorでFlowCLIを使ったコントラクトのdeployまで
一連の流れを試すために、FlowPlaygroundを実行する方法と、cliでPC上のシミュレーターで試す方法の2通りがあります。
ここではCLIを通じたデモを実行する方法を残しておきます。
How to Create NFTs Like NBA Top Shot With Flow and IPFS
で書かれているpinata-partyの事例が非常にわかりやすいので、こちらの手順を参考にしています。
1.プロジェクト作成
$ mkdir pinata-party
$ cd pinata-party
$ flow project init
$ flow accounts create
$ flow accounts get 0x01cf0e2f2f715450
2.ディレクトリとファイルを下記のように作成
contract...実行したアカウントのストレージにdeployされる
transaction...実行したアカウントで、デプロイ済のコントラクトを操作する
script...ストレージの状態をReadする
cadence
|-contracts
|-PinataPartyContract.cdc
flow.json
scripts
|-CheckTokenMetadata.cdc
transactions
|-MintPinataParty.cdc
3.flow.jsonを整形
"contracts": {
"PinataPartyContract": "./cadence/contracts/PinataPartyContract.cdc"
}
"deployments": {
"emulator": {
"emulator-account": ["PinataPartyContract"]
}
}
4.PinataPartyContract.cdcを作成。下記をcopy
https://gist.github.com/polluterofminds/17e961796b795a4c001c2e644bda6a41
5.Contractのdeployを行う
$flow project start-emulator
$flow project deploy --network=emulator
6.MintPinataParty.cdcを作成
https://gist.github.com/polluterofminds/35f6b46abe8ad59237e491b280d30665
7.keyの生成
$flow keys generate
8.mint - transactionの実行
flow transactions send --code ./transactions/MintPinataParty.cdc --signer emulator-account
9.CheckTokenMetadata.cdcの作成
import PinataPartyContract from 0xf8d6e0586b0a20c7
pub fun main() : {String : String} {
let nftOwner = getAccount(0xf8d6e0586b0a20c7)
// log("NFT Owner")
let capability = nftOwner.getCapability<&{PinataPartyContract.NFTReceiver}>(/public/NFTReceiver)
let receiverRef = capability.borrow()
?? panic("Could not borrow the receiver reference")
return receiverRef.getMetadata(id: 1)
}
10.実行
flow scripts execute ./scripts/CheckTokenMetadata.cdc
11.成功!
Result: {"name": "The Big Swing", "swing_velocity": "29", "swing_angle": "45", "rating": "5", "uri": "ipfs://QmRZdc3mAMXpv6Akz9Ekp1y4vDSjazTx2dCQRkxVy1yUj6"}
Testnetで、FlowCLIを使ったコントラクトのdeployまで
次に、Testnetを利用して、これらのコントラクトをdeployします。コードは、emulatorで使ったものをそのまま利用しますので割愛。
1. keyを作成する
$flow keys generate
2. publickeyをfaucetに登録して、addressを登録する
https://testnet-faucet-v2.onflow.org/
3. cliを通じて、アカウントに1000flowがあることを確認する
$flow accounts get 0x5262a052b4e278ae --network=testnet
4. flow.jsonに取得したaddressとkey(pk)を記述する
"accounts": {
"emulator-account": {
"address": "",
"keys": "",
"chain": "flow-emulator"
},
"testnet-account": {
"address": "",
"keys": "",
"chain": "flow-testnet"
}
},
5.flow.jsonのdeploymentにtestnetの項目をたす
"deployments": {
"emulator": {
"emulator-account": ["PinataPartyContract"]
},
"testnet": {
"testnet-account": ["PinataPartyContract"]
}
}
6. deployする
flow project deploy --network=testnet
(balanceが減る)
Balance 1000.00100000
->
Balance 1000.00099000
7. mintする
$ flow transactions send ./transactions/MintPinataParty.cdc --network=testnet --signer testnet-account
8. チェックする
$ flow scripts execute ./scripts/CheckTokenMetadata.cdc --network=testnet
Testnetでscriptを用いて、Webアプリなどから読み込む
// npm install onflow/fcl --save
const fcl = require('@onflow/fcl');
(async () => {
fcl.config()
.put("accessNode.api", 'https://access-testnet.onflow.org');
const resp = await fcl.send([
fcl.script(`
import DemoContract from xxxxxxxxxx
pub fun main(): {String: String}? {
let nftOwner = getAccount(xxxxxxxxxx)
let capability = nftOwner.getCapability<&{DemoContract.NFTReceiver}>(/public/NFTReceiver)
let receiverRef = capability.borrow()
?? panic("Could not borrow the receiver reference")
return receiverRef.getMetadata(id: 1)
}
`)
]);
const result = await fcl.decode(resp);
console.log(result);
})();
NFTの雛形
Ethereumではopenzippelinなどの雛形を利用して、NFTを作るようなケースがありました。
Flowの場合も、同様にして、いくつかの雛形が用意されているため、これらを読み込みながら、最低限の実装を行うことが可能です。
https://docs.onflow.org/core-contracts/non-fungible-token/
https://www.npmjs.com/package/@onflow/six-topshot-transfer-moment
const mainnetContracts = {
FungibleToken: '0xf233dcee88fe0abe',
FlowToken: '0x1654653399040a61',
FlowFee: '0xf919ee77447b7497',
StakingTable: '0x8624b52f9ddcd04a',
LockedTokens: '0x8d0e87b65159ae63',
NonFungibleToken: '0x1d7e57aa55817448',
StakingProxy: '0x62430cf28c26d095',
Topshot: '0x0b2a3299cc857e29'
}
const testnetContracts = {
FungibleToken: '0x9a0766d93b6608b7',
FlowToken: '0x7e60df042a9c0868',
FlowFee: '0x912d5440f7e3769e',
StakingTable: '0x9eca2b38b18b5dfe',
LockedTokens: '0x95e019a17d0e23d7',
NonFungibleToken: '0x631e88ae7f1d7c20',
StakingProxy: '0x7aad92e5a0715d21',
Topshot: '0x877931736ee77cff'
}
Flow開発に必要な様々なツールやデモ
node
Flow 公式
(main)https://access-mainnet-beta.onflow.org
(test)https://access-testnet.onflow.org
Blocto ウォレット公式
(main)https://flow-access-mainnet.portto.io
(test)https://access-testnet.onflow.org
Tools
Faucet
flowcliで生成したpublic keyを用いてfaucetを利用することが可能です。
https://testnet-faucet-v2.onflow.org/
Exploler
Wallet
Blocto、Ledgerなど利用可能。Flowのライブラリで提供されるウォレットディスカバリーでもこの2つにくわて、DapperWalletというものが提供されている。
https://fcl-discovery.onflow.org/testnet/authn
https://blocto.portto.io/en/
https://port.onflow.org
dAppsとの連携(EthereumのWeb3.js的な位置付け)
Flow Client LibraryがWalletとの接続やコントラクトの実行などを
行なっている。EthereumのWeb3.js的なイメージ。
https://github.com/portto/fcl-demo
この辺りがサンプルで、FCL wallet interactionsなどを試すとイメージが湧く。
https://fcl-demo.portto.io/
GasFee
Ethereumと同様にして、トランザクションの送信者がトランザクションに署名してGasを支払うことでブロックに取り込まれるのは同じだが、トランザクション送信に必要なロールが3つにに分かれている。
Proposer
トランザクションを発行するアカウント。
Payer
トランザクション手数料を払うアカウント。
Authorizers
トランザクションを承認するアカウント。複数アカウントを指定することが可能。(一般的なケースでは、Proposer=Authorizer)
GasFeeもFLOWというネイティブトークンが必要だが、
Transaction Fee: 0.000001 FLOWと現時点では結構安い。
https://docs.onflow.org/flow-token/concepts#fees
ResouceObject
Flowのスマートコントラクトではトークン数量のようなアセットとなるものをリソースとして定義する。リソースは中央のコントラクトで管理されるのではなく、個々のアカウントのストレージに保有分のリソースが保持。
また、リソースはその時に唯一の場所に存在し、コピーや消失が起こるようなプログラムが書けないように保護されている。例えば、一般的なトークンでは下記のような情報・機能をもつリソースを、初期化するときに自分のアカウントに設置することが必要となる、
残高情報
引き出し機能
預け入れ機能
Flowの理解を助けるためのDemo
Market Demo
http://kitty-items-flow-testnet.herokuapp.com
https://github.com/onflow/kitty-items
このdemoでは、kibbleというサービストークンを用いて、ItemをmintしたりSellしたりする操作を試すことができます。
Contractはこの辺りを参照。
https://github.com/onflow/kitty-items/blob/master/cadence/transactions/kittyItemsMarket/sell_market_item.cdc
https://medium.com/flow-japan/cadence-tutorial2-3a7958ba00fb
non-fungeble Token
https://docs.onflow.org/cadence/tutorial/04-non-fungible-tokens/
https://medium.com/pinata/how-to-create-nfts-like-nba-top-shot-with-flow-and-ipfs-701296944bf
Dappsを作る
https://medium.com/flow-japan/flow-dapps-dev-3f042ba3b8d2
https://medium.com/pinata/how-to-display-your-nft-collection-like-nba-top-shot-with-flow-and-ipfs-6ba75048bf8a
リンク集