はじめに
- 本記事では Smart Contract を書き始める
- いきなりお薬手帳完全版を作るのは厳しいのでまずはざっと思いつく変数を書いてみる
- いったんコンパイルが通るか確認してみる
solidity 関連で気になる用語や困ったことがあったら以下のサイトを読むとよい
https://docs.soliditylang.org/en/v0.8.16/
Smart Contract を書いてみる
ソースコードの License について
世界中の人が自分の書いたコードを使用できるよう、基本的には以下の文言をファイル先頭に記載する。
商用利用禁止のコードは別の文言がファイル先頭に記載されているはず?なので、注意するべし。
// SPDX-Licence-Identifier: MIT
Contract の記述開始!!
まず、どの solidity version で動作するかを記載する必要がある。
// SPDX-Licence-Identifier: MIT
pragma solidity ^0.8.16;
これはこのコードが solidity version 0.8.16 未満でコンパイルできないことを意味している。
また、version情報の前に ^
がついているので solidity version 0.9.0 以上でも動かせないことを意味している。
次に contract を記述する部分を作成する。
// SPDX-Licence-Identifier: MIT
pragma solidity ^0.8.16;
contract medicineNotebook {
}
contract コントラクト名 {}
で {}
の中にコントラクトを記述することができる。
ここで、処方された薬をどのように記録するか検討する。
まず、薬の標準コードについて調べてみたところ、以下のサイトを発見。
GIN-13という薬品コード規格というものがあるらしい。文字列ではなく数値で表されるらしい。今回はこれを使ってみる。
https://www.data-index.co.jp/knowledge/146/
病気や病院についても何かしらコードがあるはず...なので、
とりあえず数値で表されると考える。
※Solidity は文字列の記録に多めのガス代がかかる場合があるらしい?が
私もまだ理解しきれていないため、いったん先へ進む。(どこかでしっかり調べようと思う)
- ガス代とは?
取引を実行する際にかかる手数料のこと。
Ethereum は世界中に分散したマイナー達がトランザクションを監視、記録することで
不正なく取引を実行できる仕組みを提供している。
このマイナー達もボランティアでそのようなことをしているのではなく、
記録の際にある条件を満たすと報酬+手数料(ガス代)が得られる仕組みになっている。
マイナー達に報酬+手数料(ガス代)を得られるというインセンティブを与え、
電気代やハードウェア代を投入してでも Ethereum のトランザクションを記録しようとするモチベーションが生まれている。
また Ethereum ネットワークに高負荷をかけるような攻撃への抑止力としても機能している。
ガス代が存在することでトランザクションの実行回数に上限ができ、
保有資金以上のガス代を必要とするような大量のトランザクションを実行することができない。
攻撃が失敗したときに自分の資産が無くなるので、そんな攻撃する人いないよね?ということである。
とりあえず処方された薬の他に、一緒に記録したほうが良いと思われる情報を
記録するための変数や構造体を書いてみた。
/ SPDX-Licence-Identifier: MIT
pragma solidity ^0.8.16;
contract medicineNotebook {
// globaly recorded items on this contract
// - medicine code(GTIN-13)
// - disease code
// - hospital code
// - population
uint256[] public medicineCodesList;
uint64[] public diseaseCodesList;
uint256[] public hospitalcodesList;
uint256 public population;
// struct for record list
struct RecordItem {
uint256 recordTime; // Unit: second, epoch unix time
uint8 age; // Unit: years oldnode --v
uint8 weight; // Unit: kg
uint8 height; // Unit: cm
uint8 sex; // 0: men, 1: women
uint256[] medicineCurrentTaking; // medicine currently taking
mapping(uint256 => uint8) medicineToTakingQuantity; // medicine quantity when you take at once
uint64[] diseaseCodes; // disease code you have
uint256[] hospitalCodes; // hospital code you go to
}
// struct for each person
struct Person {
uint256 humanId; // ID number for each person
uint8 lifeAndDeath; // life and death
RecordItem[] records; // recorded items
}
}
-
//
:コメント行
//
と書いてそのあとに文章が書かれているが、これはコメント行である。自分や他人がこのコードを見たときに役立つ情報を記載するものである。記載ルールもあるようなので、私の書き方を信用しないよう注意。 -
uint
:unsigned integer type
0 と整数のみを表すことのできる型。ほかにもint
型やbytes
型などがある。 -
struct
:構造体
複数の変数をひとまとまりにすることのできるカスタマブルな型である。今回、RecordItem という構造体に診察時の情報をまとめることができ、さらにその情報をPerson という構造体にまとめることができるようにしている。
compile してみる
compileは簡単。ターミナルに以下のコマンドを打てばコンパイルできる。
brownie compile
実施したところ、以下のエラーが出た...。簡単じゃないやん...
PS C:\Users\taken\Documents\demos\medicineNotebook> brownie compile ineNotebook\build\contracts
情報: 与えられたパターンのファイルが見つかりませんでした。
Brownie v1.19.1 - Python development framework for Ethereum
File "C:\Users\taken\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\brownie\_cli\__main__.py", line 64, in main
importlib.import_module(f"brownie._cli.{cmd}").main()
File "C:\Users\taken\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\brownie\_cli\compile.py", line 50, in main
proj = project.load()
File "C:\Users\taken\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\brownie\project\main.py", line 780, in load
return Project(name, project_path)
File "C:\Users\taken\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\brownie\project\main.py", line 188, in __init__
self.load()
File "C:\Users\taken\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\brownie\project\main.py", line 198, in load
contract_sources = _load_sources(self._path, self._structure["contracts"], False)
File "C:\Users\taken\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\brownie\project\main.py", line 1029, in _load_sources
source = fp.read()
UnicodeDecodeError: 'cp932' codec can't decode byte 0xef in position 160: illegal multibyte sequence
最後の一文にcp932
というコーデック(暗号化したり複合したりするソフト)で何かを複合できないと書いてあるようだ。
調べるとcp932
はShift_JIS規格でありWindowsのデフォルトの標準出力がこの規格になっているのに対し、pythonはutf-8
というものを使用している模様。
ここでファイルの文字コードと読み込む際に指定された文字コードが異なることでエラーが発生しているようだ。(まだ理解しきれていない)
ひとまずsource = fp.read()
という部分が問題なようなのでそこを見てみる。この記載は1行上のC:\Users\taken\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\brownie\project\main.py
にあるようだ。
for path in project_path.glob(f"{subfolder}/**/*"):
if path.suffix not in suffixes:
continue
if next((i for i in path.relative_to(project_path).parts if i.startswith("_")), False):
continue
with path.open() as fp:
source = fp.read()
source = fp.read()
を検索すると上記の記載があった。
この下から2行目のwith path.open() as fp:
のカッコ内にencoding="utf-8"
というオプションを追記してみる。
for path in project_path.glob(f"{subfolder}/**/*"):
if path.suffix not in suffixes:
continue
if next((i for i in path.relative_to(project_path).parts if i.startswith("_")), False):
continue
with path.open(encoding="utf-8") as fp:
source = fp.read()
修正後に main.py を上書き保存し、再度brownie compile
を実行してみる。
PS C:\Users\taken\Documents\demos\medicineNotebook> brownie compile
情報: 与えられたパターンのファイルが見つかりませんでした。
Brownie v1.19.1 - Python development framework for Ethereum
Project has been compiled. Build artifacts saved at C:\Users\taken\Documents\demos\medicineNotebook\build\contracts
エラー解消し、無事compileできた模様!
ざっと思いつく変数を記録し、コンパイルすることができた。
今回はここまでとする。