質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.02%
Solidity

Solidityは、仮想通貨イーサリアム上で実行できるプログラミング言語。スマートコントラクトやDAppsなどの開発・実装に用いられます。コントラクト指向・高水準な言語のため、イーサリアム上で動作するEVM Codeに翻訳することが可能です。

Q&A

受付中

Solidityにおけるlibraryの使い方について

ts21
ts21

総合スコア32

Solidity

Solidityは、仮想通貨イーサリアム上で実行できるプログラミング言語。スマートコントラクトやDAppsなどの開発・実装に用いられます。コントラクト指向・高水準な言語のため、イーサリアム上で動作するEVM Codeに翻訳することが可能です。

0回答

0グッド

0クリップ

605閲覧

投稿2021/10/07 07:57

前提・実現したいこと

こちらのレポジトリを実験しています。
solcのv0.5.12を推奨されていますが、最新のv0.8.9で開発をしているため、多少コードを書き換えています。

発生している問題・エラーメッセージ

npm run compileSolの部分でエラーとなり、困っています。

% npm run compileSol > semaphore-contracts@0.0.1 compileSol /Users/username/semaphore-card/semaphore/contracts > ./scripts/compileSol.sh Building contracts Compiling ./sol/IncrementalMerkleTree.sol... 中略 Compiling ./sol/verifier.sol... { Error: TypeError: Library functions must be implemented if declared. --> /Users/username/semaphore-card/semaphore/contracts/sol/MiMC.sol:28:5: | 28 | function MiMCSponge(uint256 in_xL, uint256 in_xR) | ^ (Relevant source part starts here and spans across multiple lines). ,TypeError: Library functions must be implemented if declared. --> sol/MiMC.sol:28:5: | 28 | function MiMCSponge(uint256 in_xL, uint256 in_xR) | ^ (Relevant source part starts here and spans across multiple lines). at new ExtendableError (/Users/username/semaphore-card/semaphore/contracts/node_modules/etherlime/cli-commands/compiler/etherlime-error/index.js:7:19) at new CompileError (/Users/username/semaphore-card/semaphore/contracts/node_modules/etherlime/cli-commands/compiler/etherlime-compile/compile-error.js:11:5) at Promise (/Users/username/semaphore-card/semaphore/contracts/node_modules/etherlime/cli-commands/compiler/etherlime-compile/index.js:81:18) at process.runNextTicks [as _tickCallback] (internal/process/task_queues.js:52:5) at Function.Module.runMain (internal/modules/cjs/loader.js:880:11) at findNodeScript.then.existing (/usr/local/lib/node_modules/npm/node_modules/libnpx/index.js:268:14) message: 'TypeError: Library functions must be implemented if declared.\n --> /Users/username/semaphore-card/semaphore/contracts/sol/MiMC.sol:28:5:\n |\n28 | function MiMCSponge(uint256 in_xL, uint256 in_xR)\n | ^ (Relevant source part starts here and spans across multiple lines).\n\n,TypeError: Library functions must be implemented if declared.\n --> sol/MiMC.sol:28:5:\n |\n28 | function MiMCSponge(uint256 in_xL, uint256 in_xR)\n | ^ (Relevant source part starts here and spans across multiple lines).\n\u001b[31mCompilation failed. See above.\u001b[39m', stack: 'Error: TypeError: Library functions must be implemented if declared.\n --> /Users/username/semaphore-card/semaphore/contracts/sol/MiMC.sol:28:5:\n |\n28 | function MiMCSponge(uint256 in_xL, uint256 in_xR)\n | ^ (Relevant source part starts here and spans across multiple lines).\n\n,TypeError: Library functions must be implemented if declared.\n --> sol/MiMC.sol:28:5:\n |\n28 | function MiMCSponge(uint256 in_xL, uint256 in_xR)\n | ^ (Relevant source part starts here and spans across multiple lines).\n at new ExtendableError (/Users/username/semaphore-card/semaphore/contracts/node_modules/etherlime/cli-commands/compiler/etherlime-error/index.js:7:19)\n at new CompileError (/Users/username/semaphore-card/semaphore/contracts/node_modules/etherlime/cli-commands/compiler/etherlime-compile/compile-error.js:11:5)\n at Promise (/Users/username/semaphore-card/semaphore/contracts/node_modules/etherlime/cli-commands/compiler/etherlime-compile/index.js:81:18)\n at process.runNextTicks [as _tickCallback] (internal/process/task_queues.js:52:5)\n at Function.Module.runMain (internal/modules/cjs/loader.js:880:11)\n at findNodeScript.then.existing (/usr/local/lib/node_modules/npm/node_modules/libnpx/index.js:268:14)', name: 'CompileError' } internal/modules/cjs/loader.js:670 throw err; ^ Error: Cannot find module '/Users/username/semaphore-card/semaphore/contracts/build/buildMiMC.js' at Function.Module._resolveFilename (internal/modules/cjs/loader.js:668:15) at Function.Module._load (internal/modules/cjs/loader.js:591:27) at Function.Module.runMain (internal/modules/cjs/loader.js:877:12) at internal/main/run_main_module.js:21:11 npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! semaphore-contracts@0.0.1 compileSol: `./scripts/compileSol.sh` npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the semaphore-contracts@0.0.1 compileSol script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! /Users/username/.npm/_logs/2021-10-07T06_58_24_211Z-debug.log

「MiMC.solで定義してあるlibraryの中のfunctionが使用されていない」とあるのですが、実際にはIncrementalMerkleTree.solというファイルにおいて呼び出されています。

該当のソースコード

MiMC.solはこちらになります。

solidity

1 2//SPDX-License-Identifier: Unlicense 3 4pragma solidity ^0.8.0; 5 6library MiMC { 7 function MiMCSponge(uint256 in_xL, uint256 in_xR) 8 public 9 pure 10 returns (uint256 xL, uint256 xR); 11} 12

呼び出し元のファイルはこちら
IncrementalMerkleTree.sol

solidity

1 2 3//SPDX-License-Identifier: Unlicense 4 5pragma solidity ^0.8.0; 6 7import {SnarkConstants} from "./SnarkConstants.sol"; 8import {MiMC} from "./MiMC.sol"; 9 10contract IncrementalMerkleTree is SnarkConstants { 11 uint8 internal constant MAX_DEPTH = 32; 12 13 uint8 internal treeLevels; 14 15 uint256 internal nextLeafIndex = 0; 16 17 uint256 public root; 18 19 uint256[MAX_DEPTH] internal zeros; 20 21 uint256[MAX_DEPTH] internal filledSubtrees; 22 23 mapping(uint256 => bool) public rootHistory; 24 25 event LeafInsertion(uint256 indexed leaf, uint256 indexed leafIndex); 26 27 constructor(uint8 _treeLevels, uint256 _zeroValue) { 28 require( 29 _treeLevels > 0 && _treeLevels <= MAX_DEPTH, 30 "IncrementalMerkleTree: _treeLevels must be between 0 and 33" 31 ); 32 33 34 treeLevels = _treeLevels; 35 36 zeros[0] = _zeroValue; 37 38 uint256 currentZero = _zeroValue; 39 for (uint8 i = 1; i < _treeLevels; i++) { 40 uint256 hashed = hashLeftRight(currentZero, currentZero); 41 zeros[i] = hashed; 42 filledSubtrees[i] = hashed; 43 currentZero = hashed; 44 } 45 46 root = hashLeftRight(currentZero, currentZero); 47 } 48 49 50 function insertLeaf(uint256 _leaf) internal returns (uint256) { 51 require( 52 _leaf < SNARK_SCALAR_FIELD, 53 "IncrementalMerkleTree: insertLeaf argument must be < SNARK_SCALAR_FIELD" 54 ); 55 56 uint256 currentIndex = nextLeafIndex; 57 58 uint256 depth = uint256(treeLevels); 59 require( 60 currentIndex < uint256(2)**depth, 61 "IncrementalMerkleTree: tree is full" 62 ); 63 64 uint256 currentLevelHash = _leaf; 65 uint256 left; 66 uint256 right; 67 68 for (uint8 i = 0; i < treeLevels; i++) { 69 if (currentIndex % 2 == 0) { 70 left = currentLevelHash; 71 right = zeros[i]; 72 73 filledSubtrees[i] = currentLevelHash; 74 } else { 75 left = filledSubtrees[i]; 76 right = currentLevelHash; 77 } 78 79 currentLevelHash = hashLeftRight(left, right); 80 81 currentIndex >>= 1; 82 } 83 84 root = currentLevelHash; 85 rootHistory[root] = true; 86 87 uint256 n = nextLeafIndex; 88 nextLeafIndex += 1; 89 90 emit LeafInsertion(_leaf, n); 91 92 return currentIndex; 93 } 94 95 function hashLeftRight(uint256 _left, uint256 _right) 96 internal 97 pure 98 returns (uint256) 99 { 100 101 uint256 R = _left; 102 uint256 C = 0; 103 104 (R, C) = MiMC.MiMCSponge(R, 0); 105 106 R = addmod(R, _right, SNARK_SCALAR_FIELD); 107 (R, C) = MiMC.MiMCSponge(R, C); 108 109 return R; 110 } 111} 112

試したこと

MiMCSpongeにおいて、returnsがあるにも関わらず、return文が記述されていないのは何故でしょうか?
つまり、次のような書き方になると思います。

library MiMC { function MiMCSponge(uint256 in_xL, uint256 in_xR) public pure returns (uint256, uint256) { return (in_xL, in_xR); } }

実際に実行してみると、別のエラーとなります。

% npm run compileSol > semaphore-contracts@0.0.1 compileSol /Users/usernaeme/semaphore-card/semaphore/contracts > ./scripts/compileSol.sh Building contracts Compiling ./sol/IncrementalMerkleTree.sol... 中略 Compiling ./sol/verifier.sol... Thu, 07 Oct 2021 07:19:49 GMT unhandledRejection: Cannot read property 'children' of undefined TypeError: Cannot read property 'children' of undefined at orderABI (/Users/usernaeme/semaphore-card/semaphore/contracts/node_modules/etherlime/cli-commands/compiler/etherlime-compile/index.js:155:41) at Object.keys.forEach (/Users/usernaeme/semaphore-card/semaphore/contracts/node_modules/etherlime/cli-commands/compiler/etherlime-compile/index.js:115:31) at Array.forEach (<anonymous>) at Object.keys.forEach (/Users/usernaeme/semaphore-card/semaphore/contracts/node_modules/etherlime/cli-commands/compiler/etherlime-compile/index.js:94:33) at Array.forEach (<anonymous>) at Promise (/Users/usernaeme/semaphore-card/semaphore/contracts/node_modules/etherlime/cli-commands/compiler/etherlime-compile/index.js:92:26) at process.runNextTicks [as _tickCallback] (internal/process/task_queues.js:52:5) at Function.Module.runMain (internal/modules/cjs/loader.js:880:11) at findNodeScript.then.existing (/usr/local/lib/node_modules/npm/node_modules/libnpx/index.js:268:14)

バージョンの違いが原因で書き方が変わったのかと思い調べてみましたが、参考になるようなことはありませんでした。

https://docs.soliditylang.org/en/v0.8.9/contracts.html#libraries

他に見落としてることがあれば、ご享受いただけると幸いです

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.02%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Solidity

Solidityは、仮想通貨イーサリアム上で実行できるプログラミング言語。スマートコントラクトやDAppsなどの開発・実装に用いられます。コントラクト指向・高水準な言語のため、イーサリアム上で動作するEVM Codeに翻訳することが可能です。