Solidity備忘録⑥(2021年5月22日)

今日は5月19日に後回しにしたエラーの解析を行っていこうと思います。

今回扱うエラーはこちらです。

TypeError: Data location must be "memory" or "calldata" for return parameter in function, but none was given. --> 

どうやら型が異なるようです。

上の記事を参考にしていきます。

contract MyContract {
   string value;
   function get() public view returns (string) {
       return value;
   }
   function set(string _value) public {
       value = _value;
   }
   constructor() public {
       value = "myValue";
   }
}

コードはこちらを使います。

回答はこちらです。

You should add memory keyword for string parameter, which was introduced in solidity version 0.5.0

「memory」というキーワードがStringに対し、必要になったのですね。
 そして、これはバージョン0.5.0で導入されたようです。

Explicit data location for all variables of struct, array or mapping types is now mandatory. This is also applied to function parameters and return variables.

Struct, 配列、マッピングタイプの全ての変数に対する明確なデータ位置(データを保存する場所?)が強制になった。
これは、functionのパラメータや返り値の変数にも適用される。

 For example, change uint[] x = m_x to uint[] storage x = m_x, and function f(uint[][] x) to function f(uint[][] memory x) where memory is the data location and might be replaced by storage or calldata accordingly. Note that external functions require parameters with a data location of calldata.

例えば
変更前 uint[]  x = m_x  
変更後 uint[] storage x = m_x

変更前 f(uint [] [] x) 
変更後 f(uint [] [] memory x)

「memory」はデータの保管場所を示しており、「storage」や「calldata」になることもある。

外部functionは「calldata」が必要となる。

これをもとにした正しいコードは↓

contract MyContract {
   string value;
   function get() public view returns (string memory) {
       return value;
   }
   function set(string memory _value) public {
       value = _value;
   }
   constructor() public {
       value = "myValue";
   }
}こ

このようにstringの後に「memory」が入っていますね。

これでコンパイルをしたところ、上手く実行ができました!

でも、まだ警告が出ているようです。

Warning: Visibility for constructor is ignored. If you want the contract to be non-deployable, making it "abstract" is sufficient. -->

警告:constructor の可視性(外から見えるか)は無視される。もしコントラクトをデプロイが出来ないようにしたいのならば、「abstract」をつければ十分である。

この「abstract」がキーワードのようですね。

この記事を見ていきます。

スクリーンショット (130)

Abstract Contracts
Contracts need to be marked as abstract when at least one of their functions is not implemented. Contracts may be marked as abstract even though all functions are implemented.

⇒少なくとも一つ、実装されていないfunctionがあれば「abstract」をつけなければならない。

This can be done by using the abstract keyword as shown in the following example. Note that this contract needs to be defined as abstract, because the function utterance() was defined, but no implementation was provided (no implementation body { } was given).:

⇒下のように「abstract」キーワードをつける。
これは「utterance」というfunctionが定義されているものの、これに対する実装が提供されていないから。

pragma solidity >=0.4.0 <0.7.0;
abstract contract Feline {
   function utterance() public virtual returns (bytes32);
}

確かにこのfunctionの中身が書いていないですね!

Such abstract contracts can not be instantiated directly. This is also true, if an abstract contract itself does implement all defined functions. The usage of an abstract contract as a base class is shown in the following example:

そんな「abstract contract」は直接インスタンス化することは出来ない。
もし定義されたfunctionを全て実装すればできるが。
「abstract contract」の「base class」としての使用法を下に示す。

pragma solidity ^0.6.0;
abstract contract Feline {
   function utterance() public virtual returns (bytes32);
}
contract Cat is Feline {
   function utterance() public override returns (bytes32) { return "miaow"; }
}
If a contract inherits from an abstract contract and does not implement all non-implemented functions by overriding, it needs to be marked as abstract as well.

contractがabstract contractをinherit(継承した)した場合も、実装をしなければ、abstractはつける必要がある。

Note that a function without implementation is different from a Function Type even though their syntax looks very similar.

注意しなければいけないこととして、実装していないfunctionは例え構文が似ていてもfunction Typeは異なる。

Example of function without implementation (a function declaration):

下は実装していないfunctionの例
(確かにこれだと何をしているかわからない。)

function foo(address) external returns (address);
Example of a declaration of a variable whose type is a function type:

下は変数の型=functionの型の宣言の例
(fooは変数?)

function(address) external returns (address) foo;
Abstract contracts decouple the definition of a contract from its implementation providing better extensibility and self-documentation and facilitating patterns like the Template method and removing code duplication.

「abstract contract」はコントラクトの定義と実装を分離する。
これにより、よりよい拡張性、自身による説明、「テンプレートメソッド」のようなパターンを促進し、コードの複製を防ぐ
⇒確かに定義とコードを分離するメリットは多そう。

 Abstract contracts are useful in the same way that defining methods in an interface is useful. It is a way for the designer of the abstract contract to say “any child of mine must implement this method”.

「abstract contract」は使いやすい。それは「Interface」内でmethodを定義するのと同じように。「abstract contract」の設計者は言う「どんな子もこのmethodを実装しなければならない。」

⇒最後がよくわからない。。

ただ、どんなときに「abstract」をつければ良いのかはわかったので、今日はここまで。

サポートをしていただけたらすごく嬉しいです😄 いただけたサポートを励みに、これからもコツコツ頑張っていきます😊