SolanaでEthereumのOpenZeppelinやTruffleっぽく利用できる Anchor - A Minimal Example のハマリポイント。
原因究明まではやっていないため、以下すべて仮説。今回は対応策で解決はできたものの、状況によって異なる可能性あり。
Agenda
found no record of a prior creditエラー
現象
「ANCHOR_WALLET=
# ANCHOR_WALLET=/root/.config/solana/id.json node client.js
Running client.
Transaction simulation failed: Attempt to debit an account but found no record of a prior credit.
Translating error SendTransactionError: failed to send transaction: Transaction simulation failed: Attempt to debit an account but found no record of a prior credit.
at Connection.sendEncodedTransaction (/usr/src/app/anchor-master/examples/tutorial/node_modules/@solana/web3.js/lib/index.cjs.js:6591:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Connection.sendRawTransaction (/usr/src/app/anchor-master/examples/tutorial/node_modules/@solana/web3.js/lib/index.cjs.js:6550:20)
at async sendAndConfirmRawTransaction (/usr/src/app/anchor-master/examples/tutorial/node_modules/@solana/web3.js/lib/index.cjs.js:8513:21)
at async Provider.send (/usr/src/app/anchor-master/examples/tutorial/node_modules/@project-serum/anchor/dist/cjs/provider.js:85:22)
at async Object.rpc [as initialize] (/usr/src/app/anchor-master/examples/tutorial/node_modules/@project-serum/anchor/dist/cjs/program/namespace/rpc.js:11:31)
at async main (/usr/src/app/anchor-master/examples/tutorial/basic-0/client.js:22:3) {
logs: []
}
node:internal/process/promises:246
triggerUncaughtException(err, true /* fromPromise */);
^
SendTransactionError: failed to send transaction: Transaction simulation failed: Attempt to debit an account but found no record of a prior credit.
at Connection.sendEncodedTransaction (/usr/src/app/anchor-master/examples/tutorial/node_modules/@solana/web3.js/lib/index.cjs.js:6591:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Connection.sendRawTransaction (/usr/src/app/anchor-master/examples/tutorial/node_modules/@solana/web3.js/lib/index.cjs.js:6550:20)
at async sendAndConfirmRawTransaction (/usr/src/app/anchor-master/examples/tutorial/node_modules/@solana/web3.js/lib/index.cjs.js:8513:21)
at async Provider.send (/usr/src/app/anchor-master/examples/tutorial/node_modules/@project-serum/anchor/dist/cjs/provider.js:85:22)
at async Object.rpc [as initialize] (/usr/src/app/anchor-master/examples/tutorial/node_modules/@project-serum/anchor/dist/cjs/program/namespace/rpc.js:11:31)
at async main (/usr/src/app/anchor-master/examples/tutorial/basic-0/client.js:22:3) {
logs: []
}
原因
取引履歴が存在していない。つまり、チュートリアルのプログラムのdeployがちゃんとできていない。
対応
1.Solanaノードを起動しておく。
# solana-test-validator
--faucet-sol argument ignored, ledger already exists
Ledger location: test-ledger
Log: test-ledger/validator.log
Identity: 96aeBVR8ZopwXx3ttLiQWxjaVuWFfBhsmhocP1nj6ttK
Genesis Hash: 3rrq1z2jgqA74vVKJLseFiQvmhG7aF2zdP1iWayYsXiZ
Version: 1.8.0
Shred Version: 48177
Gossip Address: 127.0.0.1:1024
TPU Address: 127.0.0.1:1027
JSON RPC URL: http://127.0.0.1:8899
2.Solanaの設定をlocalhostにする
# solana config get
Config File: /root/.config/solana/cli/config.yml
RPC URL: https://api.mainnet-beta.solana.com
WebSocket URL: wss://api.mainnet-beta.solana.com/ (computed)
Keypair Path: /root/.config/solana/id.json
Commitment: confirmed
# solana config set --url localhost
Config File: /root/.config/solana/cli/config.yml
RPC URL: http://localhost:8899
WebSocket URL: ws://localhost:8900/ (computed)
Keypair Path: /root/.config/solana/id.json
Commitment: confirmed
3.10 SOL airdropする
localhost, devnet, testnet, mainnetと、いろんなサーバーがあるが、トランザクションがなにかしら走る場合は、SOLの手数料が必要。
# solana airdrop 10
Requesting airdrop of 10 SOL
Signature: 53QEKUxsrjueDUP1XUmGxuK6ULDX9vNdNxRNRteiMw1ZyhqipLHvYN2rsn6BUHQkj1RyBTahp4WXiNJBH6mFLZJF
10 SOL
4.プログラムをデプロイする
# anchor deploy
Deploying workspace: http://localhost:8899
Upgrade authority: /root/.config/solana/id.json
Deploying program "basic-0"...
Program path: /usr/src/app/anchor-master/examples/tutorial/basic-0/target/deploy/basic_0.so...
Program Id: 8Cj6ZYCXk6F15TgJqPr9pSjtMFaY4wmhxVcQPghcGeDs
Deploy success
5.client.jsを起動する
Successになったら成功。
# ANCHOR_WALLET=/root/.config/solana/id.json node client.js
Running client.
Success
insufficient fundsエラー
現象
# anchor deploy
Deploying workspace: http://localhost:8899
Upgrade authority: /root/.config/solana/id.json
Deploying program "basic-0"...
Program path: /usr/src/app/anchor-master/examples/tutorial/basic-0/target/deploy/basic_0.so...
=================================================================================
Recover the intermediate account's ephemeral keypair file with
`solana-keygen recover` and the following 12-word seed phrase:
=================================================================================
scatter music supreme arm someone swap indicate strong stairs good appear because
=================================================================================
To resume a deploy, pass the recovered keypair as
the [PROGRAM_ADDRESS_SIGNER] argument to `solana deploy` or
as the [BUFFER_SIGNER] to `solana program deploy` or `solana write-buffer'.
Or to recover the account's lamports, pass it as the
[BUFFER_ACCOUNT_ADDRESS] argument to `solana program close`.
=================================================================================
Error: Account 3H3yDb6ph9fAT6iowbwizvR2CXCHJPoLBa9xsQtrGk5V has insufficient funds for spend (1.05455832 SOL) + fee (0.00077 SOL)
There was a problem deploying: Output { status: ExitStatus(ExitStatus(256)), stdout: "", stderr: "" }.
原因
手数料が足りない場合に発生するエラー。
対応
残高を増やす必要がある。
足りないと言われたアドレスは、上記の場合は「3H3yDb6ph9fAT6iowbwizvR2CXCHJPoLBa9xsQtrGk5V」になるため、まずクラスターのURLと残高を確認する。
% solana config get
Config File: /Users/user/.config/solana/cli/config.yml
RPC URL: https://api.devnet.solana.com
WebSocket URL: wss://api.devnet.solana.com/ (computed)
Keypair Path: /Users/user/.config/solana/id.json
Commitment: confirmed
% solana balance 3H3yDb6ph9fAT6iowbwizvR2CXCHJPoLBa9xsQtrGk5V
0 SOL
次にairdropで増やす。
% sol airdrop 1 3H3yDb6ph9fAT6iowbwizvR2CXCHJPoLBa9xsQtrGk5V
Requesting airdrop of 1 SOL
Signature: 4qGSUG25iDkxcW1c6kGLfHnvbLfWgyQX9bGqp4vJYDv5pbXmm9Qp85wV7FzAi6JAmUfemUDZc3DMKeN31q534PX7
1 SOL
クラスターURLによってairdrop上限が決まっているため(localnetは無限?、devnetだと2 SOLなど)、要注意。
補足
- Webサイト上でairdrop提供しているツールもあり、「solana testnet faucet」で検索するとHITする。そこで自分のアドレスを入れるとairdropできる。
- 「Balance unchanged」が表示された場合は、airdrop失敗。localnetの場合は「% solana logs」でログ確認を、devnetなどの場合は Solana Explorer でログ確認を。
Solana Explorerだと以下のように表示される。以下の例ではairdrop量が多い(リクエスト5 SOLに対して、airdrop上限2 SOL)と言われている。
> Program log: Memo (len 39): "request too large; req: ◎5, cap: ◎2"
FetchError: request to http://localhost:8899/エラー
現象
# ANCHOR_WALLET=/root/.config/solana/id.json node client.js
Running client.
Translating error Error: failed to get recent blockhash: FetchError: request to http://localhost:8899/ failed, reason: connect ECONNREFUSED 127.0.0.1:8899
at Connection.getRecentBlockhash (/usr/src/app/anchor-master/examples/tutorial/node_modules/@solana/web3.js/lib/index.cjs.js:5965:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Provider.send (/usr/src/app/anchor-master/examples/tutorial/node_modules/@project-serum/anchor/dist/cjs/provider.js:77:31)
at async Object.rpc [as initialize] (/usr/src/app/anchor-master/examples/tutorial/node_modules/@project-serum/anchor/dist/cjs/program/namespace/rpc.js:11:31)
at async main (/usr/src/app/anchor-master/examples/tutorial/basic-0/client.js:22:3)
node:internal/process/promises:246
triggerUncaughtException(err, true /* fromPromise */);
^
Error: failed to get recent blockhash: FetchError: request to http://localhost:8899/ failed, reason: connect ECONNREFUSED 127.0.0.1:8899
at Connection.getRecentBlockhash (/usr/src/app/anchor-master/examples/tutorial/node_modules/@solana/web3.js/lib/index.cjs.js:5965:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Provider.send (/usr/src/app/anchor-master/examples/tutorial/node_modules/@project-serum/anchor/dist/cjs/provider.js:77:31)
at async Object.rpc [as initialize] (/usr/src/app/anchor-master/examples/tutorial/node_modules/@project-serum/anchor/dist/cjs/program/namespace/rpc.js:11:31)
at async main (/usr/src/app/anchor-master/examples/tutorial/basic-0/client.js:22:3)
Node.js v17.1.0
原因
localhostのSolanaノード(solana-test-validator)が起動していない。
対応
localhostのSolanaノードを起動する。
# solana-test-validator
node: --dns-result-order= is not allowedエラー
現象
【テスト結果が出ない状態(AsIs)】
一見、成功しているように見えるが、テストが走っていない。passingやdescribeが出力されておらず、テスト結果がfailになるように修正してもfailにならない(反映されない)。
$ anchor test
BPF SDK: /Users/user/.local/share/solana/install/releases/1.8.0/solana-release/bin/sdk/bpf
Running: rustup toolchain list -v
Running: cargo +bpf build --target bpfel-unknown-unknown --release
Finished release [optimized] target(s) in 0.48s
Running: /Users/user/.local/share/solana/install/releases/1.8.0/solana-release/bin/sdk/bpf/dependencies/bpf-tools/llvm/bin/llvm-readelf --dyn-symbols /Users/user/Desktop/blockchain/anchor-master/examples/tutorial/basic-0/target/deploy/basic_0.so
To deploy this program:
$ solana program deploy /Users/user/Desktop/blockchain/anchor-master/examples/tutorial/basic-0/target/deploy/basic_0.so
The program address will default to this keypair (override with --program-id):
/Users/user/Desktop/blockchain/anchor-master/examples/tutorial/basic-0/target/deploy/basic_0-keypair.json
node: --dns-result-order= is not allowed in NODE_OPTIONS
【テスト結果が出る状態(本来期待する結果ToBe)】
# anchor test
BPF SDK: /root/.local/share/solana/install/releases/1.8.0/solana-release/bin/sdk/bpf
Running: rustup toolchain list -v
Running: cargo +bpf build --target bpfel-unknown-unknown --release
Finished release [optimized] target(s) in 1.69s
Running: /root/.local/share/solana/install/releases/1.8.0/solana-release/bin/sdk/bpf/dependencies/bpf-tools/llvm/bin/llvm-readelf --dyn-symbols /usr/src/app/anchor-master/examples/tutorial/basic-0/target/deploy/basic_0.so
To deploy this program:
$ solana program deploy /usr/src/app/anchor-master/examples/tutorial/basic-0/target/deploy/basic_0.so
The program address will default to this keypair (override with --program-id):
/usr/src/app/anchor-master/examples/tutorial/basic-0/target/deploy/basic_0-keypair.json
yarn run v1.22.17
$ /usr/src/app/anchor-master/examples/tutorial/node_modules/.bin/mocha -t 1000000 tests/
basic-0
✔ Uses the workspace to invoke the initialize instruction (2758ms)
1 passing (3s)
Done in 8.28s.
原因
anchorのバグ。Issues w/ anchor test #945
1.0.18.2で修正済み。
対応
Anchor CLIを最新にする。
インストールされているバージョンを調べる。自分の場合は0.18.0だった。
$ anchor --version
anchor-cli 0.18.0
Anchor公式サイトの Build from source for other operating systems に沿ってインストールする。
$ cargo install --git https://github.com/project-serum/anchor --tag v0.18.2 anchor-cli --locked
・・・
$ anchor --version
anchor-cli 0.18.2
ReferenceError: z is not definedエラー
現象
$ anchor test
BPF SDK: /Users/user/.local/share/solana/install/releases/1.8.0/solana-release/bin/sdk/bpf
Running: rustup toolchain list -v
Running: cargo +bpf build --target bpfel-unknown-unknown --release
Finished release [optimized] target(s) in 0.47s
Running: /Users/user/.local/share/solana/install/releases/1.8.0/solana-release/bin/sdk/bpf/dependencies/bpf-tools/llvm/bin/llvm-readelf --dyn-symbols /Users/user/Desktop/blockchain/anchor-master/examples/tutorial/basic-0/target/deploy/basic_0.so
To deploy this program:
$ solana program deploy /Users/user/Desktop/blockchain/anchor-master/examples/tutorial/basic-0/target/deploy/basic_0.so
The program address will default to this keypair (override with --program-id):
/Users/user/Desktop/blockchain/anchor-master/examples/tutorial/basic-0/target/deploy/basic_0-keypair.json
yarn run v1.22.17
$ /Users/user/Desktop/blockchain/anchor-master/examples/tutorial/node_modules/.bin/mocha -t 1000000 tests/
ReferenceError: z is not defined
at Object.<anonymous> (/Users/user/Desktop/blockchain/anchor-master/examples/tutorial/basic-0/tests/basic-0.js:17:1)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at ModuleWrap.<anonymous> (internal/modules/esm/translators.js:195:29)
at ModuleJob.run (internal/modules/esm/module_job.js:145:37)
at async Loader.import (internal/modules/esm/loader.js:182:24)
at async formattedImport (/Users/user/Desktop/blockchain/anchor-master/examples/tutorial/node_modules/mocha/lib/nodejs/esm-utils.js:7:14)
at async Object.exports.requireOrImport (/Users/user/Desktop/blockchain/anchor-master/examples/tutorial/node_modules/mocha/lib/nodejs/esm-utils.js:48:32)
at async Object.exports.loadFilesAsync (/Users/user/Desktop/blockchain/anchor-master/examples/tutorial/node_modules/mocha/lib/nodejs/esm-utils.js:88:20)
at async singleRun (/Users/user/Desktop/blockchain/anchor-master/examples/tutorial/node_modules/mocha/lib/cli/run-helpers.js:125:3)
at async Object.exports.handler (/Users/user/Desktop/blockchain/anchor-master/examples/tutorial/node_modules/mocha/lib/cli/run.js:374:5)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
原因
原因はわからなかったが、いじりまくっているうちにおかしくなってしまったと思われる。
対応
きれいな状態で1からやり直す。自分の場合は以下2点で直った。
- 以下をもとに環境を最新版にする。Yarnも最新版にする。
Installing Dependencies - Anchorの最新版をGitHubから改めてDLしてから、再度チュートリアルを実行する。
GitHub - project-serum/anchor
ログがどこにあるかわからない
deployログは .anchor > program-logs にアドレス毎に出力される。
anchor version is not correctエラー
現象
anchorを バージョンアップ してから実行すると、バージョンが違うと言われる。
% cargo install --git https://github.com/project-serum/anchor --tag v0.19.0 anchor-cli --locked
% anchor --version
Only x86_64 / Linux distributed in NPM package right now.
Trying globally installed anchor.
Globally installed anchor version is not correct. Expected “anchor-cli 0.17.0”, found “anchor-cli 0.19.0".
原因
npmとcargoで重複インストールされていて、npmの古いバージョンが呼ばれてしまっていた。
対応
npmのanchorを削除する。
% npm list -g
/Users/sxdev/.nodebrew/node/v16.11.1/lib
├── @project-serum/anchor-cli@0.17.0
├── corepack@0.9.0
├── ganache-cli@6.12.2
├── mocha@9.1.2
├── npm@8.0.0
├── truffle@5.4.19
└── yarn@1.22.15
% npm uninstall -g @project-serum/anchor-cli
% anchor --version
anchor-cli 0.19.0
Attempt to load a program that does not existエラー
現象
anchor testするとプログラムが存在しないと言われて、ローカルバリデータにデプロイできない。
(このケースでは、solana-test-validatorでローカルバリデータを起動しつつ、anchor testを実施した)
% anchor test --skip-local-validator
Deploy success
yarn run v1.22.10
$ /Users/user/Documents/Programming/Blockchain/solana-anchor-react-minimal-example/anchor/tutorial/basic-3/node_modules/.bin/mocha -t 1000000 tests/
basic-3
Transaction simulation failed: Attempt to load a program that does not exist
1) Performs CPI from puppet master to puppet
0 passing (76ms)
1 failing
1) basic-3
Performs CPI from puppet master to puppet:
Error: failed to send transaction: Transaction simulation failed: Attempt to load a program that does not exist
at Connection.sendEncodedTransaction (node_modules/@solana/web3.js/lib/index.cjs.js:6591:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Connection.sendRawTransaction (node_modules/@solana/web3.js/lib/index.cjs.js:6550:20)
at async sendAndConfirmRawTransaction (node_modules/@solana/web3.js/lib/index.cjs.js:8513:21)
at async Provider.send (node_modules/@project-serum/anchor/dist/cjs/provider.js:90:22)
at async Object.rpc [as initialize] (node_modules/@project-serum/anchor/dist/cjs/program/namespace/rpc.js:31:31)
at async Context.<anonymous> (tests/basic-3.js:17:16)
error Command failed with exit code 1.
なお、「anchor test」だと通る。
原因
declare_idが間違っているため、プログラムが発見できない状態になっている。
idlの各ファイルにdeclare_idが書き込まれ、その情報をもとに、programs(lib.rs)を探す仕組みになっている。
対応
以下コマンドでPublic Keyを取得して、Anchor.tomlとlib.rsに、正しいdeclare_idに書き換える。
% solana address -k target/deploy/[対象のKeypair]
念のため最後にdeployしておく。
% anchor deploy
「custom program error: 0x1004」エラー
現象
以下のように「custom program error: 0x1004」エラーが表示される。
% anchor test
〜〜〜省略〜〜〜
Error: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: custom program error: 0x1004
〜〜〜省略〜〜〜
原因
Anchorのdeclare_idが誤っているため。