このガイドでは、コンピュータ上で動作するローカルInjectiveネットワークにcw20スマートコントラクトをデプロイする方法を説明します。
CosmWasmの仕様とコントラクトのコレクションからcw20-baseコントラクトを使用します。cw20-baseはcw20互換コントラクトの基本実装で、カスタムコントラクトにインポートして構築できます。cw20仕様とすべてのExtensionの完全な実装が含まれています。cw20-baseはそのままデプロイするか、他のコントラクトからインポートして使用できます。
前提条件
以下の手順に従ってGo、Rust、その他のCosmWasm依存関係をインストールしてください:
- Go
- Rust
開始前に、rustupと最新バージョンのrustcおよびcargoがインストールされていることを確認してください。現在、Rust v1.58.1以降でテストしています。
また、wasm32-unknown-unknownターゲットとcargo-generate Rustクレートもインストールする必要があります。
以下のコマンドでバージョンを確認できます:
rustc --version
cargo --version
rustup target list --installed
# wasm32が上記に表示されない場合、以下を実行
rustup target add wasm32-unknown-unknown
# cargo-generateをインストールするには、以下を実行
cargo install cargo-generate
injectived
injectivedがローカルにインストールされていることを確認してください。injectivedのインストールガイドに従ってinjectivedとその他の前提条件をローカルで実行できるようにしてください。
injectivedをインストールしたら、ローカルチェーンインスタンスを起動してください。
CosmWasmコントラクトのコンパイル
このステップでは、すべてのCW本番テンプレートコントラクトを取得し、CosmWasm Rust OptimizerのDockerイメージ(複数コントラクト用のworkspace-optimizer)を使用してコンパイルします。最新バージョンはこちら(x86)またはこちら(ARM)を確認してください。このプロセスには時間とCPUリソースが必要です。
git clone https://github.com/CosmWasm/cw-plus
cd cw-plus
ARM以外(非Apple Silicon)のデバイス:
docker run --rm -v "$(pwd)":/code \
--mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
cosmwasm/workspace-optimizer:0.12.12
Apple Siliconデバイス(M1、M2など)の場合:
docker run --rm -v "$(pwd)":/code \
--mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
cosmwasm/workspace-optimizer-arm64:0.12.12
Dockerスクリプトはリポジトリ内のすべてのCWコントラクトをビルドおよび最適化し、コンパイル済みコントラクトはartifactsディレクトリに配置されます。これでcw20_base.wasmコントラクト(ARMデバイスでコンパイルした場合はcw20_base-aarch64.wasm)をデプロイできます。
CosmWasmコントラクトのチェーンへのアップロード
# CosmWasm/cw-plusリポジトリ内で
yes 12345678 | injectived tx wasm store artifacts/cw20_base.wasm --from=genesis --chain-id="injective-1" --yes --gas-prices=500000000inj --gas=20000000
出力:
code: 0
codespace: ""
data: ""
events: []
gas_used: "0"
gas_wanted: "0"
height: "0"
info: ""
logs: []
raw_log: '[]'
timestamp: ""
tx: null
txhash: 4CFB63A47570C4CFBE8E669273B26BEF6EAFF922C07480CA42180C52219CE784
次にtxhashでトランザクションをクエリして、コントラクトが正常にデプロイされたことを確認します。
injectived query tx 4CFB63A47570C4CFBE8E669273B26BEF6EAFF922C07480CA42180C52219CE784
出力:
code: 0
codespace: ""
data: 0A460A1E2F636F736D7761736D2E7761736D2E76312E4D736753746F7265436F64651224080112205F8201CF5E2D7E6C15DB11ADF03D62DDDDC92B8D4FAE98C4F3C1C37F378E15D9
...
出力を詳しく見ると、コントラクトのcode_idが1であることがわかります。
コントラクトコードはアップロードしましたが、まだインスタンス化する必要があります。
コントラクトのインスタンス化
コントラクトをインスタンス化する前に、CW-20コントラクトのinstantiate関数シグネチャを確認しましょう。
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
mut deps: DepsMut,
_env: Env,
_info: MessageInfo,
msg: InstantiateMsg,
) -> Result<Response, ContractError> {
特に、トークン名、シンボル、デシマル、その他の詳細を含むInstantiateMsgパラメータに注目してください。
#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)]
pub struct InstantiateMsg {
pub name: String,
pub symbol: String,
pub decimals: u8,
pub initial_balances: Vec<Cw20Coin>,
pub mint: Option<MinterResponse>,
pub marketing: Option<InstantiateMarketingInfo>,
}
コントラクトのインスタンス化の最初のステップは、初期CW20トークン割り当てを受け取るアドレスを選択することです。この場合、キーがすでにセットアップされているgenesisアドレスを使用できますが、新しいアドレスとキーを生成しても構いません。
選択したアドレスのプライベートキーを持っていることを確認してください。そうでないと、そのアドレスからのトークン転送をテストできません。また、選択したアドレスはチェーン上の有効なアドレス(過去に資金を受け取ったことがある)である必要があり、コントラクト実行時のガス支払い用の残高が必要です。
genesisアドレスを確認するには:
yes 12345678 | injectived keys show genesis
出力:
- name: genesis
type: local
address: inj10cfy5e6qt2zy55q2w2ux2vuq862zcyf4fmfpj3
pubkey: '{"@type":"/injective.crypto.v1beta1.ethsecp256k1.PubKey","key":"ArtVkg9feLXjD4p6XRtWxVpvJUDhrcqk/5XYLsQI4slb"}'
mnemonic: ""
code_id 1とJSONエンコードされた初期化引数(選択したアドレス付き)およびlabelを指定してCLIコマンドを実行し、コントラクトをインスタンス化します:
CODE_ID=1
INIT='{"name":"Albcoin","symbol":"ALB","decimals":6,"initial_balances":[{"address":"inj10cfy5e6qt2zy55q2w2ux2vuq862zcyf4fmfpj3","amount":"69420"}],"mint":{"minter":"inj10cfy5e6qt2zy55q2w2ux2vuq862zcyf4fmfpj3"},"marketing":{}}'
yes 12345678 | injectived tx wasm instantiate $CODE_ID $INIT --label="Albcoin Token" --from=genesis --chain-id="injective-1" --yes --gas-prices=500000000inj --gas=20000000 --no-admin
インスタンス化されたコントラクトのアドレスはhttp://localhost:10337/swagger/#/Query/ContractsByCodeで取得できます。
コントラクト情報のメタデータはhttp://localhost:10337/swagger/#/Query/ContractInfoまたはCLIクエリで取得できます。
CONTRACT=$(injectived query wasm list-contract-by-code $CODE_ID --output json | jq -r '.contracts[-1]')
injectived query wasm contract $CONTRACT
出力:
injectived query wasm contract $CONTRACT
address: inj14hj2tavq8fpesdwxxcu44rty3hh90vhujaxlnz
contract_info:
admin: ""
code_id: "1"
created:
block_height: "95"
tx_index: "0"
creator: inj10rdsxdgr8l8s0gvu8rynhu22nnxkfytg58cwm8
extension: null
ibc_port_id: ""
label: Albcoin Token
コントラクトのクエリ
コントラクトの全状態は以下でクエリできます:
injectived query wasm contract-state all $CONTRACT
出力:
models:
- key: 000762616C616E6365696E6A31306366793565367174327A793535713277327578327675713836327A63796634666D66706A33
value: IjY5NDIwIg==
- key: 636F6E74726163745F696E666F
value: eyJjb250cmFjdCI6ImNyYXRlcy5pbzpjdzIwLWJhc2UiLCJ2ZXJzaW9uIjoiMS4wLjEifQ==
- key: 6D61726B6574696E675F696E666F
value: eyJwcm9qZWN0IjpudWxsLCJkZXNjcmlwdGlvbiI6bnVsbCwibG9nbyI6bnVsbCwibWFya2V0aW5nIjpudWxsfQ==
- key: 746F6B656E5F696E666F
value: eyJuYW1lIjoiQWxiY29pbiIsInN5bWJvbCI6IkFMQiIsImRlY2ltYWxzIjo2LCJ0b3RhbF9zdXBwbHkiOiI2OTQyMCIsIm1pbnQiOnsibWludGVyIjoiaW5qMTBjZnk1ZTZxdDJ6eTU1cTJ3MnV4MnZ1cTg2MnpjeWY0Zm1mcGozIiwiY2FwIjpudWxsfX0=
pagination:
next_key: null
total: "0"
個々のユーザーのトークン残高は以下でクエリできます:
BALANCE_QUERY='{"balance": {"address": "inj10cfy5e6qt2zy55q2w2ux2vuq862zcyf4fmfpj3"}}'
injectived query wasm contract-state smart $CONTRACT "$BALANCE_QUERY" --output json
出力:
{"data":{"balance":"69420"}}
トークンの転送
TRANSFER='{"transfer":{"recipient":"inj1dzqd00lfd4y4qy2pxa0dsdwzfnmsu27hgttswz","amount":"420"}}'
yes 12345678 | injectived tx wasm execute $CONTRACT "$TRANSFER" --from genesis --chain-id="injective-1" --yes --gas-prices=500000000inj --gas=20000000
残高転送が成功したことを確認します:
# 最初のアドレスの残高クエリ
BALANCE_QUERY='{"balance": {"address": "inj10cfy5e6qt2zy55q2w2ux2vuq862zcyf4fmfpj3"}}'
injectived query wasm contract-state smart $CONTRACT "$BALANCE_QUERY" --output json
出力:
{"data":{"balance":"69000"}}
受信者が資金を受け取ったことを確認します:
# 受信者アドレスの残高クエリ
BALANCE_QUERY='{"balance": {"address": "inj1dzqd00lfd4y4qy2pxa0dsdwzfnmsu27hgttswz"}}'
injectived query wasm contract-state smart $CONTRACT "$BALANCE_QUERY" --output json
出力:
{"data":{"balance":"420"}}
テストネット開発
localとtestnetの開発/デプロイの主な違いは以下の通りです:
injectivedの使用方法とtestnetに対するクエリ/トランザクション送信については、injectivedの使用ガイドを参照してください。