Substrateのink!調査メモ

# 以前lockdropをsubstrateで実装しようとしたのですが
- 基本的な仕組みが分かっていなかったので、まずEthereumで実装しました。[ここ](https://qiita.com/realtakahashi/items/b9e46af9b03582c2d448)
- で、いざsubstrateでやってみようと思ったのですが、その当時のバージョンではデプロイが上手くいかず断念していました。
- 最近のバージョンを試したら、動くので再開

# substrateでpayableとか、balanceとか取り方知らない・・・
- いざやろうと思ったのですが、前提知識が全然足りてなくて焦る・・・

# 調査メモ
- ※初心者なので間違っているかもしれません。
- rust初心者かつsubstrate初心者の私にはここまで調べるのに随分と苦労しました。
- なので調査メモです。

# バージョン情報
```
$ cargo -V
cargo 1.44.0 (05d080faa 2020-05-06)

$ cargo contract -V
cargo-contract 0.6.1

$ substrate -V
substrate 2.0.0-rc3-44978b9b1-x86_64-linux-gnu

$ rustc -V
rustc 1.44.0 (49cae5576 2020-06-01)
```

# 送信者のAccountId
```
self.env().caller()
```

# Transaction送信時に送った金額（？）の取得
```
self.env().transferred_balance()
```

# Contract Addressの残高の確認
```
self.env().balance()
```

# Contract残高からトランザクションの送信者に送金する
```
self.env().transfer(self.env().caller(), _value);
```

# Contract全体のソースも載せておきます。
- ※flipperのソースからやったので余分なものが含まれています。

```
#![cfg_attr(not(feature = "std"), no_std)]

use ink_lang as ink;

#[ink::contract(version = "0.1.0")]
mod my_transfer {
    use ink_core::storage;

    /// Defines the storage of your contract.
    /// Add new fields to the below struct in order
    /// to add new static storage fields to your contract.
    #[ink(storage)]
    struct MyTransfer {
        /// Stores a single `bool` value on the storage.
        value: storage::Value<bool>,
    }

    impl MyTransfer {
        /// Constructor that initializes the `bool` value to the given `init_value`.
        #[ink(constructor)]
        fn new(&mut self, init_value: bool) {
            self.value.set(init_value);
        }

        /// Constructor that initializes the `bool` value to `false`.
        ///
        /// Constructors can delegate to other constructors.
        #[ink(constructor)]
        fn default(&mut self) {
            self.new(false)
        }

        /// A message that can be called on instantiated contracts.
        /// This one flips the value of the stored `bool` from `true`
        /// to `false` and vice versa.
        #[ink(message)]
        fn flip(&mut self) {
            *self.value = !self.get();
        }

        /// Simply returns the current value of our `bool`.
        #[ink(message)]
        fn get(&self) -> bool {
            *self.value
        }

        /// test env().transferred_balance
        #[ink(message)]
        fn check_transfer(&mut self) {
            if self.env().transferred_balance() < 10 {
                *self.value = false;
            } else {
                *self.value = true;
            }
        }

        /// return balance from contract to caller
        #[ink(message)]
        fn return_balance(&self, _value: Balance) {
            self.env().transfer(self.env().caller(), _value);
        }

        /// get contract balance
        #[ink(message)]
        fn get_contract_balance(&self) -> Balance {
            self.env().balance()
        }
    }

    /// Unit tests in Rust are normally defined within such a `#[cfg(test)]`
    /// module and test functions are marked with a `#[test]` attribute.
    /// The below code is technically just normal Rust code.
    #[cfg(test)]
    mod tests {
        /// Imports all the definitions from the outer scope so we can use them here.
        use super::*;

        /// We test if the default constructor does its job.
        #[test]
        fn default_works() {
            // Note that even though we defined our `#[ink(constructor)]`
            // above as `&mut self` functions that return nothing we can call
            // them in test code as if they were normal Rust constructors
            // that take no `self` argument but return `Self`.
            let my_transfer = MyTransfer::default();
            assert_eq!(my_transfer.get(), false);
        }

        /// We test a simple use case of our contract.
        #[test]
        fn it_works() {
            let mut my_transfer = MyTransfer::new(false);
            assert_eq!(my_transfer.get(), false);
            my_transfer.flip();
            assert_eq!(my_transfer.get(), true);
        }
    }
}

```
# （2020/06/28追記）
## substrateではStringがサポートされていない？？
- 正確には調査していないですが、実装出来なくて調べていたら、[そのように書いている方](https://qiita.com/YuasaJunki/items/21295a8992bc4688a21a)がいました。
- 製品としてWEB UIまで付けたいというわけではないので、一旦使わないで済まそうと思います。