Web3 〜 平成脳で学ぶスマートコントラクト入門 〜
昭和脳は言い過ぎやった。
従来のWeb技術(JavaScriptやAPI)とWeb3(ブロックチェーン、スマートコントラクト)はかなり似てる部分があるということが徐々にわかってきたので、昭和脳のお前らに、違いを比較しながら、NFTとか決済とかを"わかりやすく"解説していきマスオさん。
1. JavaScriptのクラスとスマートコントラクトの類似点
めちゃ簡単にいうと、ブロックチェーン上の取引って、ブロックチェーン上に保存されたオブジェクト(デプロイ時にクラスから生成されたインスタンス)にアクセスして、お金(暗号通貨)を払うことでそのメソッドを実行してるに過ぎない。
共通点:
-
contract
はJavaScriptのClass
みたいなもん -
function
はメソッド -
state variable
はプロパティ -
constructor
で初期化は同じ
JavaScript(クラス)
class Shop {
constructor(owner) {
this.owner = owner;
}
buy(productId) {
console.log(`${this.owner} bought ${productId}`);
}
}
Solidity(スマートコントラクト)
contract Shop {
address public owner;
constructor() {
owner = msg.sender;
}
function buy(string memory productId) public {
// 購入ロジック
}
}
2. ブロックチェーンとデータベースの違い(保存と検索)
結局は、取引の履歴が不特定多数の匿名なノードに保存されてるか、管理者のいるデータベースに保存されているかの違い。
あと、ブロックチェーンにアクセスしてデータを書き換えたり関数を実行するとガス(コスト)がかかるけど、コントラクに保存されているデータを見るのは基本的に無料。
旧来のデータベースの場合はユーザーアカウントを作ってブログとかのアップデートとかしても基本的にはお金はかからないよね。サービスの運営側は、サーバーとかに払ってるけども、ブロックチェーンの場合は、そもそも運営者がいないという点がポイントなので、各自コストを負担しないといけない。
比較対象 | ブロックチェーン | 従来のDB(MySQLとか) |
---|---|---|
データ保存先 | 世界中のノード | 特定のサーバ |
読み書き方法 | 関数で操作 | SQLクエリ |
改ざん耐性 | 不可(書いたら消されへん) | 管理者がいじれる、覗ける |
読み込み |
view 関数でガス無し |
SELECT文 |
書き込み | トランザクション(ガス必要) | INSERT/UPDATE文 |
🌱 Solidity
mapping(address => uint256) public balances;
function getBalance(address user) public view returns (uint256) {
return balances[user];
}
🗄️ JS(DB)
const user = db.find(userId);
return user.balance;
3. 関数呼び出しとHTTPリクエストの類似
Solidity関数 | HTTPリクエスト | 内容 |
---|---|---|
view 関数 |
GET |
データ取得 |
通常関数 |
POST / PUT
|
状態を変更 |
ストレージ削除 | DELETE |
削除系処理 |
⛓ Solidity
function getProduct(string memory id) public view returns (string memory) {
return products[id];
}
🌐 Express API
app.get("/product/:id", (req, res) => {
res.json(db[req.params.id]);
});
4 🌳 木のメタファで理解するスマートコントラクトとNFT
ブロックチェーン上のスマートコントラクトを「木」に例えると、構造と動きがめっちゃわかりやすくなるんやで。
📚 木の構造にたとえると...
要素 | ブロックチェーンでの意味 |
---|---|
幹(Trunk) | スマートコントラクト本体(ロジックの塊) |
枝(Branch) | 各NFT(tokenIdごと)やユーザーの記録 |
葉(Leaf) | それぞれのトランザクション(購入や譲渡の履歴) |
根(Root) | ブロックチェーンネットワークやノードの基盤 |
年輪(Ring) | 各ブロック(block)、つまり歴史の記録 |
🎨 イメージで言うとこうや
🌳 スマートコントラクト(幹)
│
├── 🌿 NFT #0(枝)
│ └─ 🍂 tx1:ミント
│ └─ 🍂 tx2:転送
│
├── 🌿 NFT #1(枝)
│ └─ 🍂 tx3:ミント
│
└── 🌿 NFT #2(枝)
└─ 🍂 tx4:ミント
└─ 🍂 tx5:転送
✅ つまりこういうこと:
- コントラクト(幹)は、NFTを生み出す中心。
- ミントされるたびに新しい枝(NFT)が生まれ、固有の
tokenId
を持つ。 - 各枝に付く葉っぱ(トランザクション)が、NFTの活動記録。
- 全部の枝と葉は、1本の幹にぶら下がってるから、1つのコントラクトで一元管理されてる。
✍️ まとめ
スマートコントラクトは「幹」、NFTは「枝」、トランザクションは「葉っぱ」。
新しいNFTをミントするたびに、新しい枝が生えて葉がつく。
5. ブロックチェーンアドレスとIPアドレスの違い
項目 | ブロックチェーンアドレス | IPアドレス |
---|---|---|
形式 | 0x123... |
192.168.0.1 |
用途 | ウォレットやコントラクト識別 | デバイスとかPC |
永続性 | 変わらへん(固定) | DHCPで変わることある |
目的 | 資産のやりとり | 通信のやりとり |
6. TxとTxHash、Webhookとの違い
例えば、何かを売ったり買ったりのトランザクションが発生した時、それが無事に完了した時に、従来のショッピングサイトだとWebhookとかを使うよね。ブロックチェーンだとtxHashっという似た感じの仕組みがある。
🔁 ブロックチェーンのトランザクション
const tx = await contract.buy("abc123", {
value: ethers.utils.parseEther("0.01")
});
console.log(tx.hash); // トランザクションID
await tx.wait(); // ブロックに確定するの待つ
各取引が終わると、txHashといういわばプロミスが返って来る。
-
txHash
は「レシート番号」 -
tx.wait()
でブロックに書き込まれるまで待つ
🔗 Web2 Webhookとの違い
特徴 | Webhook | ブロックチェーン |
---|---|---|
トリガー | APIイベント | トランザクション発生 |
検証方法 | HMACなど | txHash & EVM検証 |
完全性 | ネット依存 | 完全確定(Immutable) |
7. Solidityのmsg
とJSのevent
の似てるとこ
Solidityでコントラクトのコードを書いてると、msgオブジェクトっていうのをよく使うんだけど、非常にJSのeventオブジェクトに似ている。
比較 | Solidity msg
|
JS event
|
---|---|---|
誰がその関数をコールしたか | msg.sender |
event.target |
送金額 | msg.value |
なし(独自定義) |
生データ | msg.data |
event.detail |
セキュリティ | 署名あり | クライアント側で操作可能 |
function buy() public payable {
require(msg.value == 0.01 ether);
emit Purchase(msg.sender, "item123");
}
8. 従来API決済からブロックチェーン決済に置き換えるワークフロー
例えば、決済が完了してから、データのダウンロードリンクやQRなんかを返す場合。
💳 Web2(API決済):
[カード入力] → [Stripe API] → [サーバで検証] → [ユーザーにURL返す]
⛓ Web3(スマートコントラクト):
[ウォレット接続] → [contract.buy() 実行] → [txHash取得] → [確認完了後、リンク解放]
Solidity
function buyContent(string memory id) public payable {
require(msg.value == 0.01 ether);
access[id][msg.sender] = true;
}
🛒 従来のショッピングサイト vs NFT型ショップ
【Web2ショッピング】
ユーザー → カード決済 → データベース記録 → アクセスURL発行
【Web3/NFTショップ】
ユーザー → ウォレット決済 → NFTミント → ブロックチェーンにオーナー記録 → IPFSまたはダウンロード用URL表示
ミントっていうのは、最初のオーナーとしてNFTをブロックチェーンに記録するイベント。
コンテンツの制作者と最初のオーナーは同じでも別々でもかまへん。でも、ミントするときにコストがかかるんや。だから、制作者はコストを払ってくれるバイヤーにミントさせて最初の所有者になってもらったりする。
NFTショップでは 「所有者=ウォレットアドレス」 やさかい、コンテンツの証明や譲渡もスマートにいけるんや!
ちょっと分かりにくいのは、例えばOpenSeaならOpenSeaで、取引のやり方とかを記述したスマートコントラクトは一つで、NFTがミントされる度に、そのNTFトークン番号がそのコントラクト上に加えられるんや。で、そのトークンのやり取りが発生する度に、その情報がブロック状になって、伸びていくっていうイメージや。NFTが作られるたびに新しいコントラクトも作られるわけやないんやで。
まとめ
- SolidityはJavaScriptみたいにクラスベースやし、関数はAPIっぽい動きをする
- トランザクションがレコードになって、txHashがレシート代わり
- 完全に匿名でお金のやり取りをできるっていうブロックチェーンのコンセプトは非常にヤバい。銀行にも、国にも、どのサービスプロバイダーにも捕捉されない。分かるよね?