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

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

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

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

Q&A

0回答

976閲覧

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

ts21

総合スコア32

Solidity

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

0グッド

0クリップ

投稿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

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問