<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Blsqui Tech Blog]]></title><description><![CDATA[Blsqui Tech Blog]]></description><link>https://tech-blog.blsqui.net</link><image><url>https://cdn.hashnode.com/uploads/logos/6a54b7c15c0c654db32e149a/1d8b10a7-aaf9-4c65-b3ee-de9f1db02b03.jpg</url><title>Blsqui Tech Blog</title><link>https://tech-blog.blsqui.net</link></image><generator>RSS for Node</generator><lastBuildDate>Sun, 11 Oct 2026 08:49:37 GMT</lastBuildDate><atom:link href="https://tech-blog.blsqui.net/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[ちょっと高度な Hello World !]]></title><description><![CDATA[Hello World! スマートコントラクトのデプロイ方法
バックエンドで実行するためにはウォレットが作成したアドレスでは上手くいきません。ウォレットが作成した秘密鍵はウォレットにアクセスすることでしか取得できないからです。これはバックエンドでトランザクションを行いたい時に.exeなどの実行ファイルだけでは実行できないことを意味します。
そこで、自分たちで秘密鍵とブロックチェーンアドレスを作成し]]></description><link>https://tech-blog.blsqui.net/hello-world</link><guid isPermaLink="true">https://tech-blog.blsqui.net/hello-world</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Tue, 22 Sep 2026 06:24:14 GMT</pubDate><content:encoded><![CDATA[<h3>Hello World! スマートコントラクトのデプロイ方法</h3>
<p>バックエンドで実行するためにはウォレットが作成したアドレスでは上手くいきません。ウォレットが作成した秘密鍵はウォレットにアクセスすることでしか取得できないからです。これはバックエンドでトランザクションを行いたい時に.exeなどの実行ファイルだけでは実行できないことを意味します。</p>
<p>そこで、自分たちで秘密鍵とブロックチェーンアドレスを作成します。そしてそれらを使ってバックエンドからトランザクションを実行します。</p>
<hr />
<p>まず、その前にFlow CLIというツールで <code>flow init</code> を実行したら何ができているのかを紹介します。</p>
<pre><code class="language-json">{
	"contracts": {
	},
	"dependencies": {
		"Burner": {
			"source": "mainnet://f233dcee88fe0abe.Burner",
			"hash": "71af18e227984cd434a3ad00bb2f3618b76482842bae920ee55662c37c8bf331",
			"block_height": 149816757,
			"aliases": {
				"emulator": "f8d6e0586b0a20c7",
				"mainnet": "f233dcee88fe0abe",
				"testnet": "9a0766d93b6608b7"
			}
		},
		"FlowToken": {
			"source": "mainnet://1654653399040a61.FlowToken",
			"hash": "f82389e2412624ffa439836b00b42e6605b0c00802a4e485bc95b8930a7eac38",
			"block_height": 149816757,
			"aliases": {
				"emulator": "0ae53cb6e3f42a79",
				"mainnet": "1654653399040a61",
				"testnet": "7e60df042a9c0868"
			}
		},
		"FungibleToken": {
			"source": "mainnet://f233dcee88fe0abe.FungibleToken",
			"hash": "3b04b3191e0c5d4d9ee3ce9c671b11985d29bf2732a5721b526cc8523c536f8f",
			"block_height": 149816757,
			"aliases": {
				"emulator": "ee82856bf20e2aa6",
				"mainnet": "f233dcee88fe0abe",
				"testnet": "9a0766d93b6608b7"
			}
		},
		"FungibleTokenMetadataViews": {
			"source": "mainnet://f233dcee88fe0abe.FungibleTokenMetadataViews",
			"hash": "70477f80fd7678466c224507e9689f68f72a9e697128d5ea54d19961ec856b3c",
			"block_height": 149816757,
			"aliases": {
				"emulator": "ee82856bf20e2aa6",
				"mainnet": "f233dcee88fe0abe",
				"testnet": "9a0766d93b6608b7"
			}
		},
		"MetadataViews": {
			"source": "mainnet://1d7e57aa55817448.MetadataViews",
			"hash": "b290b7906d901882b4b62e596225fb2f10defb5eaaab4a09368f3aee0e9c18b1",
			"block_height": 149816757,
			"aliases": {
				"emulator": "f8d6e0586b0a20c7",
				"mainnet": "1d7e57aa55817448",
				"testnet": "631e88ae7f1d7c20"
			}
		},
		"NonFungibleToken": {
			"source": "mainnet://1d7e57aa55817448.NonFungibleToken",
			"hash": "a258de1abddcdb50afc929e74aca87161d0083588f6abf2b369672e64cf4a403",
			"block_height": 149816757,
			"aliases": {
				"emulator": "f8d6e0586b0a20c7",
				"mainnet": "1d7e57aa55817448",
				"testnet": "631e88ae7f1d7c20"
			}
		},
		"ViewResolver": {
			"source": "mainnet://1d7e57aa55817448.ViewResolver",
			"hash": "374a1994046bac9f6228b4843cb32393ef40554df9bd9907a702d098a2987bde",
			"block_height": 149816757,
			"aliases": {
				"emulator": "f8d6e0586b0a20c7",
				"mainnet": "1d7e57aa55817448",
				"testnet": "631e88ae7f1d7c20"
			}
		}
	},
	"networks": {
		"emulator": "127.0.0.1:3569",
		"mainnet": "access.mainnet.nodes.onflow.org:9000",
		"testnet": "access.devnet.nodes.onflow.org:9000"
	},
	"accounts": {
		"emulator-account": {
			"address": "f8d6e0586b0a20c7",
			"key": {
				"type": "file",
				"location": "emulator-account.pkey"
			}
		}
	},
	"deployments": {
		"mainnet": {
		},
		"testnet": {
		}
	}
}
</code></pre>
<p>こういう感じのJSONが<code>flow.json</code>ファイルに作成されています。このflow.jsonがスマートコントラクトをデプロイする時の全ての参照先になります。</p>
<p>最初は"accounts"に"emulator-account"だけあって、"testnet-account"や"mainnet-account"がありません。また、"deployments"が最初は<code>flow init</code>実行した直後は無いですが、ここは今後必要になってきます。</p>
<hr />
<h2>アカウントを作成する</h2>
<p>これは<code>Flow CLI</code>を使って作成します。</p>
<pre><code class="language-shell">flow accounts create
</code></pre>
<p>実行すると、以下のような出力がされます。</p>
<pre><code class="language-shell">Address	 0x348175517cb1c79e
Balance	 0.00200000
Keys		 1

Key 0	Public Key		 e21fd469bf39be5718fbd16f6444c1c0cef51ec40db865df8a9dc90c443b68946aa7a63d6083666109864511b6c8d589a4cc7202b3257c34c3d1a7885c3de880
		Weight			 1000
		Signature Algorithm	 ECDSA_P256
		Hash Algorithm		 SHA3_256
		Revoked 		 false
		Sequence Number 	 0
		Index 			 0

Contracts Deployed: 0
</code></pre>
<p>ECDSA_P256アルゴリズムでPrivate KeyとPublic Key、ブロックチェーンアドレス が一度に作成されます。</p>
<hr />
<p>flow.jsonを見てみます。</p>
<pre><code class="language-json">	"accounts": {
		"emulator-account": {
			"address": "f8d6e0586b0a20c7",
			"key": {
				"type": "file",
				"location": "emulator-account.pkey"
			}
		},
		"testnet-account": {
			"address": "348175517cb1c79e",
			"key": {
				"type": "file",
				"location": "testnet-account.pkey"
			}
		}
	},
</code></pre>
<p>このように作成されたブロックチェーンアドレス(<strong>348175517cb1c79e</strong>)がすでにセットされています。<code>Public Key</code>は見当たりませんが、実はアドレスを生成したときにそこに引数として渡されています。Scanサイト(FlowScan)でこのアドレスを検索するとそこで<code>Public Key</code>を見つけることができます。</p>
<p><code>testnet-account.pkey</code>というファイルが<code>flow.json</code>と同じ階層に作成されているので、それを開いてみると<code>Private Key</code>が見つかります。</p>
<p>同様にメインネットのアカウントも作成します。</p>
<pre><code class="language-shell">flow accounts create
</code></pre>
<p>対象のネットワークに<code>mainnet</code>を選択すると<code>flow.json</code>は以下のようになります。</p>
<pre><code class="language-json">	"accounts": {
		"emulator-account": {
			"address": "f8d6e0586b0a20c7",
			"key": {
				"type": "file",
				"location": "emulator-account.pkey"
			}
		},
		"mainnet-account": {
			"address": "deef3052ad5a0289",
			"key": {
				"type": "file",
				"location": "mainnet-account.pkey"
			}
		},
		"testnet-account": {
			"address": "348175517cb1c79e",
			"key": {
				"type": "file",
				"location": "testnet-account.pkey"
			}
		}
	}
</code></pre>
<hr />
<h2>スマートコントラクトをデプロイする</h2>
<p>この生成したアカウントにスマートコントラクトをデプロイすることで、好きな時にコントラクトメソッドをトランザクションで実行することができます。<code>Private Key</code>がウォレットにではなく、<code>testnet-account.pkey</code>や<code>mainnet-account.pkey</code>にあるのでこれを<code>.env</code>ファイルに貼り付けることで、どこからでもトランザクションを実行することができます。</p>
<p><code>flow.json</code>ファイルと同じ階層に<code>cadence/contracts</code>フォルダがすでにあります。そこに<code>HelloWorld.cdc</code>ファイルを作成します。そこに以下を貼り付けて保存します。</p>
<pre><code class="language-swift">access(all) contract HelloWorld {
  // Declare a public field of type String.
  //
  // All fields must be initialized in the init() function.
  access(all) var greeting: String

  // Public function that sets our friendly greeting!
  // In your own applications you may want to tighten up this access control.
  access(all) fun changeGreeting(newGreeting: String) {
    self.greeting = newGreeting
  }

  // Public function that returns our friendly greeting!
  access(all) fun hello(): String {
      return self.greeting
  }

  // The init() function is required if the contract contains any fields.
  init() {
    self.greeting = "Hello, World!"
  }
}
</code></pre>
<p>ではデプロイしましょう。</p>
<p><code>flow.json</code>を開きます。</p>
<pre><code class="language-json">	"contracts": {
		"HelloWorld": {
			"source": "./cadence/contracts/HelloWorld.cdc",
			"aliases": {
				"emulator": "f8d6e0586b0a20c7",
				"mainnet": "deef3052ad5a0289",
				"testnet": "348175517cb1c79e"
			}
		}
	},
</code></pre>
<p><code>"emulator"</code>のアドレスは常に<code>"f8d6e0586b0a20c7"</code>です。これは変わりません。</p>
<p><code>"HelloWorld"</code>の部分はコントラクト名と合わせます。<code>"testnet"</code>と<code>"mainnet"</code>はこれからデプロイするアドレスです。先ほど作成ずみのアドレスを指定します。</p>
<p>次に以下を記入します。</p>
<pre><code class="language-json">	"deployments": {
		"mainnet": {
			"mainnet-account": [
				"HelloWorld"
			]
		},
		"testnet": {
			"testnet-account": [
				"HelloWorld"
			]
		}
	}
</code></pre>
<p><code>"mainnet-account"</code>と<code>"testnet-account"</code>の部分は<code>flow accounts create</code>コマンドを実行したときに指定した名前です。そのため、人によっては<code>"mainnet-acc"</code>だったり、<code>"testnet-acc"</code>だったりします。入力したアカウント名を入れます。その下に配列を作り、"HelloWorld"をセットします。（一度に複数のコントラクトをデプロイできます）</p>
<p>そして以下を実行します。</p>
<pre><code class="language-shell">flow project deploy --network testnet
</code></pre>
<hr />
<p>おそらく失敗します。Σ＼(￣д￣;)ﾅﾝﾃﾞﾔﾈﾝ</p>
<p>出力結果はこう出ます。</p>
<pre><code class="language-shell">❌ Failed to deploy contract HelloWorld: failed to deploy contract HelloWorld: [Error Code: 1103] error caused by: 1 error occurred:
	* storage limit check failed: [Error Code: 1103] The account with address (348175517cb1c79e) uses 1930 bytes of storage which is over its capacity (0 bytes). Capacity can be increased by adding FLOW tokens to the account.
</code></pre>
<p>この<code>storage limit check failed: [Error Code: 1103]</code>というのは開発していると必ず１回は見ることになります。これはトークンを持っていないよ、ということなので、トークンを補充します。そうすればそこからトランザクションフィーが支払われて実行が成功します。</p>
<p><a href="https://faucet.flow.com/fund-account">https://faucet.flow.com/fund-account</a></p>
<p>にアクセスしてブロックチェーンアドレスを入力するとテストネット用のトークンを<strong>100,000</strong>もらえます。</p>
<p>再度実行するとこのように表示されるはずです。</p>
<pre><code class="language-shell">Deploying 1 contracts for accounts: testnet-account

HelloWorld -&gt; 0x348175517cb1c79e (a811542caa8f4ce5e897669d887b7b7c12c741e2c798e0f920b5440ab6e2f83e) 

🎉 All contracts deployed successfully
</code></pre>
<p>更新する時は以下のコマンドを実行します。</p>
<pre><code class="language-shell">flow project deploy --network testnet --update
</code></pre>
<p>スマートコントラクトのフィールドを変更していない限り更新に成功します。（フィールド: <code>init</code>の中で初期化が必要なプロパティ）</p>
<hr />
<h2>Hello, World!の実行</h2>
<h3>トランザクションの実行</h3>
<p><code>/cadence/transactions</code>の下に<code>ChangeGreeting.cdc</code>ファイルを生成します。</p>
<p>そして以下を貼り付けて保存します。</p>
<pre><code class="language-swift">import "HelloWorld"

transaction(greeting: String) {

  prepare(acct: &amp;Account) {
    log(acct.address)
  }

  execute {
    HelloWorld.changeGreeting(newGreeting: greeting)
  }
}
</code></pre>
<p>以下のコマンドを実行します。</p>
<pre><code class="language-shell">flow transactions send ./cadence/transactions/ChangeGreeting.cdc "Hello" --network testnet --signer testnet-account
</code></pre>
<p>以下のように結果が返されます。</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a54b7c15c0c654db32e149a/b3309428-fe17-434d-93ed-08cc3cedb00a.png" alt="" style="display:block;margin:0 auto" />

<p>Go言語でもNode.jsでもできます。もちろんOS実行をするのであればFlow CLIはLinuxでもインストールできますので、Pythonでも呼び出して実行することができます。</p>
<h3>スクリプトの実行</h3>
<p><code>/cadence/scripts</code>の下にGetGreeting.cdcというファイルを作成し、以下を貼り付けて保存します。</p>
<pre><code class="language-swift">import "HelloWorld"

access(all) fun main(): String {
  return HelloWorld.hello()
}
</code></pre>
<p>以下を実行します。</p>
<pre><code class="language-shell">flow scripts execute ./cadence/scripts/GetGreeting.cdc --network testnet
</code></pre>
<p>以下が返されます。</p>
<pre><code class="language-shell">Result: "Hello"
</code></pre>
<hr />
<p><code>Go</code>言語、<code>Node.js</code>で実行する時はGeminiなどの生成AIに聞きながら行うと自分で調べるより早く実装できたりします。</p>
<p>秘密鍵は<code>.env</code>ファイル等に入れて決してGithubにアップロードしないでください。<code>Private Key</code>さえあれば以下を実行されてあっという間に全額抜き取られます。</p>
<pre><code class="language-javascript">const fcl = require("@onflow/fcl");
const { SHA3 } = require("sha3");
var EC = require("elliptic").ec;
var ec = new EC("p256");
require("dotenv").config();

fcl
  .config()
  .put("flow.network", "mainnet")
  .put("accessNode.api", "https://rest-mainnet.onflow.org");

// CHANGE THESE THINGS FOR YOU
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const ADDRESS = process.env.ADDRESS;
const KEY_ID = parseInt(process.env.KEY_ID);

const hash = (message) =&gt; {
  const sha = new SHA3(256);
  sha.update(Buffer.from(message, "hex"));
  return sha.digest();
};

const sign = (message) =&gt; {
  const key = ec.keyFromPrivate(Buffer.from(PRIVATE_KEY, "hex"));
  const sig = key.sign(hash(message)); // hashMsgHex -&gt; hash
  const n = 32;
  const r = sig.r.toArrayLike(Buffer, "be", n);
  const s = sig.s.toArrayLike(Buffer, "be", n);
  return Buffer.concat([r, s]).toString("hex");
};

async function authorizationFunction(account) {
  return {
    ...account,
    tempId: `${ADDRESS}-${KEY_ID}`,
    addr: fcl.sansPrefix(ADDRESS),
    keyId: Number(KEY_ID),
    signingFunction: async (signable) =&gt; {
      return {
        addr: fcl.withPrefix(ADDRESS),
        keyId: Number(KEY_ID),
        signature: sign(signable.message),
      };
    },
  };
}

async function sendTx() {
  const addr = process.env.RECIPIENT_ADDRESS;
  const transactionId = await fcl.mutate({
    cadence: `
      import FungibleToken from 0xf233dcee88fe0abe
      import FlowToken from 0x1654653399040a61

      transaction(amount: UFix64, to: Address) {
        let vault: @FlowToken.Vault

        prepare(signer: auth(BorrowValue) &amp;Account) {
          self.vault &lt;- signer.storage
            .borrow&lt;auth(FungibleToken.Withdraw) &amp;{FungibleToken.Provider}&gt;(from: /storage/flowTokenVault)!
            .withdraw(amount: amount) as! @FlowToken.Vault
        }
        execute {
          getAccount(to)
            .capabilities
            .get&lt;&amp;{FungibleToken.Receiver}&gt;(/public/flowTokenReceiver)
            .borrow()!
            .deposit(from: &lt;-self.vault)
        }
      }
    `,
    args: (arg, t) =&gt; [arg(100.0, t.UFix64), arg(addr, t.Address)],
    payer: authorizationFunction,
    proposer: authorizationFunction,
    authorizations: [authorizationFunction],
    limit: 999,
  });

  console.log({ transactionId });
  fcl.tx(transactionId).subscribe((res) =&gt; {
    console.log(res);
  });
}

sendTx();
</code></pre>
<p>これはNode.jsのコードですが、Goでは少し違う形になります。</p>
<p>ここで書いている内容は<a href="https://qiita.com/flowcadence/items/82c4e2d91df09051b1de#signing-function">ここ</a>や<a href="https://github.com/onflow/fcl-js/blob/master/packages/fcl-core/src/wallet-provider-spec/authorization-function.md">ここ</a>を参考にしてください。鍵のアルゴリズム、PRIVATE_KEY、KEY_IDの部分以外は同じ書き方になります。あくまで同じようなことが書いてあるな、と理解するだけで大丈夫です。大事なのは<code>Private Key</code>を決して公開しない事です。</p>
<p>上記のコードをsendFlow.jsのようなファイルに保存して<code>node ./sendFlow.js</code>を実行すれば、Flowトークンを好きな時に他のアカウントに送ることができます。よく使用します。</p>
]]></content:encoded></item><item><title><![CDATA[Variables & Constants & Collection Overview]]></title><description><![CDATA[Variables and Constants
How to declare
let represents a constant, and var represents a variable.
pub fun main {
   var a: Int = 2 // Regular types cannot contain nil (null).
   var a: Int? = nil // To]]></description><link>https://tech-blog.blsqui.net/variables-constants-collection-overview</link><guid isPermaLink="true">https://tech-blog.blsqui.net/variables-constants-collection-overview</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Thu, 20 Aug 2026 00:42:46 GMT</pubDate><content:encoded><![CDATA[<h2>Variables and Constants</h2>
<h3>How to declare</h3>
<p><code>let</code> represents a constant, and <code>var</code> represents a variable.</p>
<pre><code class="language-swift">pub fun main {
   var a: Int = 2 // Regular types cannot contain nil (null).
   var a: Int? = nil // To allow variables to hold nil, use an Optional Type.
   var b Int = a!  // To convert an Optional type to a regular variable, use !. (In this case, it's nil, so it will result in an error.)
}
</code></pre>
<p>In Cadence, it is common to convert an optional type to a regular type. Using optional binding (the <code>if let</code> statement) simplifies this process, as the variable within the <code>if let</code> block is no longer optional.</p>
<hr />
<h2>Types</h2>
<h3><strong>Boolean type</strong></h3>
<pre><code class="language-swift">let boolVar: Bool = true
</code></pre>
<hr />
<h3><strong>Int type</strong></h3>
<pre><code class="language-typescript">let int8: Int8 = 127 // -128~127
let int16: Int16 = 32767 // -32768~32767
let int32: Int32 = 2147483647 // -2147483648~2147483647
let int64: Int64 = 9223372036854775807 // -9223372036854775808~9223372036854775807
let int128: Int128 = 9223372036854775808 // -2^127~2^127 − 1
let int256: Int256 = 9223372036854775808 // -2^255~2^255 − 1
</code></pre>
<hr />
<h3><strong>UInt type</strong></h3>
<pre><code class="language-typescript">let uint8: UInt8 = 255 // 0~255
let uint16: UInt16 = 65535 // 0~65535
let uint32: UInt32 = 4294967295 // 0~4294967295
let uint64: UInt64 = 18446744073709551615 // 0~18446744073709551615
let uint128: UInt128 = 18446744073709551616 // 0~2^128 − 1
let uint256: UInt256 = 18446744073709551616 // 0~2^256 − 1
</code></pre>
<hr />
<h3>Arbitrary-precision type (<code>Int</code>/<code>UInt</code>)</h3>
<pre><code class="language-swift">let integer: Int = 1 // Arbitrary-precision (unbounded)
let uinteger: UInt = 1 // Arbitrary-precision (unbounded)
</code></pre>
<hr />
<h3><strong>Word</strong> type</h3>
<p>Unsigned integer types that do not perform overflow or underflow checks, i.e., those that wrap around, have the prefix “Word” and can represent values within the following range.</p>
<pre><code class="language-typescript">let nilWord: Word8? = Word8.fromString("1024") // nil, out of bounds, 0~255
let word16: Word16? = Word16.fromString("255") // 0~65535
let word32: Word32? = Word32.fromString("255") // 0~4294967295
let word64: Word64? = Word64.fromString("255") // 0~18446744073709551615
</code></pre>
<hr />
<h3><strong>Fix / UFix</strong> type</h3>
<pre><code class="language-typescript">let fix64: Fix64? = Fix64.fromString("-0.1") // ok, -92233720368.54775808~92233720368.54775807
let ufix64: UFix64? = UFix64.fromString("-0.1") // nil, 0.0~184467440737.09551615
</code></pre>
<hr />
<h3><strong>Address</strong> type</h3>
<pre><code class="language-typescript">let some: Address = 0x436164656E636521 // UInt64 length. (Max:18446744073709551615)
</code></pre>
<hr />
<h3><strong>AnyStruct / AnyResource</strong> type</h3>
<p>All types are classified as either <code>AnyStruct</code> or <code>AnyResource</code>. The <code>AnyStruct</code> type can represent all types except for <code>Resource</code> types.</p>
<pre><code class="language-typescript">var someStruct: AnyStruct = 1 // Can represent all types except Resource type
var someResource: @AnyResource &lt;- create TestResource()
</code></pre>
<p>Always prefix the resource type with the <code>@</code> directive. Use the <code>&lt;-</code> operator for moves.</p>
<hr />
<h3><strong>Never</strong> type</h3>
<pre><code class="language-typescript"> let x: Never = nil
</code></pre>
<p><strong>Return type of the panic function</strong></p>
<hr />
<h3><strong>Character / String</strong> type</h3>
<pre><code class="language-typescript">let char: Character = "\u{FC}"
let someString: String = "Hello, world!"
</code></pre>
<hr />
<h2>Functions for each type</h2>
<h3><strong>Int / Address type functions</strong></h3>
<pre><code class="language-typescript">/* Convert a number to a string */
let int8Number: Int8 = 127
let int8str String = int8Number.toString()


/* Returns a byte array in big-endian order */
let largeNumber: Int32 = 1234567890
let arr: [UInt8] = largeNumber.toBigEndianBytes() //[73, 150, 2, 210]


/* Convert a string to a number */
let int8str: String = "42"
let int8number: Int64? = Int64.fromString(int8str)


/* Return the maximum value of a number */
let max = UInt8.max // 255


/* Return the minimum value of a number */
let min = UInt8.min // 0


/* Convert a FixedPointNumber to a string */
let fix64number: Fix64 = 1.23
let fix64str String = fix64number.toString()


/* Convert an Address to a string */
let shortAddress: Address = 0x1
let str: String = shortAddress.toString()  // "0x0000000000000001"


/* Convert an Address to a UInt8 array */
let someAddress: Address = 0x436164656E636521
someAddress.toBytes()  // is [67, 97, 100, 101, 110, 99, 101, 33]
</code></pre>
<hr />
<h3><strong>String type functions</strong></h3>
<pre><code class="language-typescript">/* Get the length of a string */
let example: String = "hello"
let length: Int = example.length // 5


/* Convert a string to a byte array using UTF8 encoding */
let str: String = "hello"
let utf8: [UInt8] = str.utf8()


/* Concatenate strings */
let str1 = "hello"
let str2 = "world"
let helloWorld = str1.concat(str2) // "helloworld"


/* Get a part of a string */
let example = "helloworld"
let slice = example.slice(from: 3, upTo: 6) // "low"


/* Convert a string to a byte array represented as a hexadecimal string */
let example = "436164656e636521"
example.decodeHex() // is [67, 97, 100, 101, 110, 99, 101, 33]


/* Convert a string to lowercase */
let example = "Flowers"
example.toLower() // `flowers`


/* Convert a byte array to a hexadecimal string */
let data = [1 as UInt8, 2, 3, 0xCA, 0xDE]
String.encodeHex(data) // is "010203cade"


/* Get one character from a string */
let str = "abc"
let c: Character = str[0] // is the Character "a"
</code></pre>
<hr />
<h3><strong>Character type functions</strong></h3>
<pre><code class="language-typescript">/* Convert a character to a string */
let c: Character = "x"
c.toString()  // is "x"


/* Convert an array of characters to a string */
let rawUwU: [Character] = ["U", "w", "U"]
let uwu: String = String.fromCharacters(rawUwU) // "UwU" 
</code></pre>
<hr />
<h1>Collection Types</h1>
<h2>Array type</h2>
<h3>How to declare</h3>
<p>They can be declared within <code>contract</code>, <code>struct</code>, or <code>resource</code> types, as well as within transaction code. When defined within a smart contract, initialization via <code>init</code> is required.</p>
<pre><code class="language-typescript">access(all) contract SampleContract {
    access(contract) var allNames: [String]
    init() {
      self.allNames = []
    }
 }
</code></pre>
<p>A <code>Contract</code> is also a type, but in this case, the address where it is deployed is included as part of the type definition. Consequently, <code>Struct</code> and <code>Resource</code> types are never confused with types defined within other Contracts.</p>
<hr />
<h3><strong>Array type functions</strong></h3>
<pre><code class="language-typescript">/* Retrieve the length of an array */
self.allNames.length


/* Concatenate arrays */
self.allNames.concat(allNames2)


/* Check if an array contains a value */
self.allNames.contains("Kitty")


/* Add a value to array */
self.allNames.append("Jane") // This function mutates the array.


/* Add multiple values to an array */
self.allNames.appendAll("Jane", "Daisy") // This function mutates the array.


/* Get the index of a value in an array */
self.allNames.firstIndex(of: "Daisy")


/* Get a portion of an array */
self.allNames.slice(from: 1, upTo: 3)


/* Insert a value at any position in an array */
self.allNames.insert(at: 2, "Daisy") // This function mutates the array.


/* Remove a value from an array */
self.allNames.remove(at: 1) // This function mutates the array.


/* Remove the first value from an array */
self.allNames.removeFirst() // This function mutates the array.


/* Remove the last value from an array */
self.allNames.removeLast() // This function mutates the array.
</code></pre>
<hr />
<h2>Dictionary type</h2>
<h3>How to declare</h3>
<p>They can be declared within <code>contract</code>, <code>struct</code>, or <code>resource</code> types, as well as within transaction code. When defined within a smart contract, initialization via <code>init</code> is required.</p>
<pre><code class="language-typescript">access(all) var luckeyNumbers: {String: Int}
init() {
  self.luckeyNumbers = {}
}
</code></pre>
<p>When <code>self</code> is referenced within a <code>struct</code> type, it represents the <code>struct</code> type; within a <code>resource</code> type, it represents the <code>resource</code> type; and within a <code>contract</code>, it represents the <code>contract</code> type.</p>
<hr />
<h3><strong>Dictionary type functions</strong></h3>
<pre><code class="language-swift">/* Insert a value */
self.luckeyNumbers["Daisy"] = 7


/* ・If you want to raise an error when "Daisy" is not present in `luckeyNumbers`, you can achieve this by using a `pre` block. */
pre {
    self.luckeyNumbers.contains("Daisy"): "Not in luckeyNumbers"
}


/* Get all keys from a Dictionary */
self.luckeyNumbers.keys


/* Get all values from a Dictionary */
self.luckeyNumbers.values // This method cannot be used with a Dictionary containing resources (resources cannot be moved without the &lt;- operator).


/* Insert a value at any position in a Dictionary */
self.luckeyNumbers.insert(key: "Jessica", 42) // If a value already exists, it is returned as an Optional type.


/* Retrieve a value from a Dictionary */
self.luckeyNumbers.remove(key: "Joe") // If a value is present, it returns that value as an Optional type; otherwise, it returns nil.


/* Check if a Dictionary contains a value */
self.luckeyNumbers.containsKey("Kitty")


/* Iterates over all keys in the Dictionary */
self.luckeyNumbers.forEachKey(fun (key: String): Bool {
    // The returned boolean value signals whether to continue
    // true = `continue`
    // false = `break`
    return true
})
</code></pre>
<hr />
<h3>pre and post blocks</h3>
<p>The <code>pre{}</code> block contains validation logic to be checked before the transaction is executed,</p>
<p>while the <code>post{}</code> block contains validation logic to verify the transaction's validity immediately before it is included in the blockchain.</p>
<p>As the name implies, the <code>pre</code> block is used to verify the validity of values ​​at the beginning of a method. If a value is invalid, a panic (transaction failure) occurs, and the string following the colon (<code>:</code>) is displayed in the transaction result output.</p>
<p>Similarly, the <code>post</code> block is used to verify the validity of values ​​at the end of a method. If a value is invalid, a panic (transaction failure) occurs, and the string following the colon (<code>:</code>) is displayed in the transaction result output.</p>
<p><code>pre</code> and <code>post</code> blocks can also be used in transaction code; transaction processing proceeds in the order: <code>prepare</code> block -&gt; <code>pre</code> block -&gt; <code>execute</code> block -&gt; <code>post</code> block. (In principle, anything that can be written in a smart contract—except for event declarations—can also be written in transaction code.)</p>
<hr />
<h3><strong>event</strong></h3>
<p>You can declare it within the smart contract and invoke it during transaction execution; it can be called from either a smart contract or transaction code. When invoking it, you can pass arguments of the types specified in the event declaration, and by monitoring these in Go or JavaScript, you can track what is happening. Retrieving events is slightly more complex than retrieving blockchain information based on a transaction ID.</p>
<hr />
]]></content:encoded></item><item><title><![CDATA[Why Cadence Stands Out]]></title><description><![CDATA[Cadence is the smart contract language written in Go. There are only four concepts to learn: variables, collection types (arrays and dictionaries), structs, and resources. Yet, once a smart contract i]]></description><link>https://tech-blog.blsqui.net/why-cadence-stands-out</link><guid isPermaLink="true">https://tech-blog.blsqui.net/why-cadence-stands-out</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Wed, 19 Aug 2026 07:44:45 GMT</pubDate><content:encoded><![CDATA[<hr />
<p>Cadence is the smart contract language written in Go. There are only four concepts to learn: variables, collection types (arrays and dictionaries), structs, and resources. Yet, once a smart contract is deployed, it enables not only financial management but also the creation of systems—such as unmanned vegetable stands or financial platforms for ride-sharing—in just a few dozen lines of code by updating and referencing data. You can even build features like game ranking systems in a similar amount of code.</p>
<hr />
<p>The Cadence language is often referred to as a resource-oriented language. A party holding a resource can execute its internal methods, and the owner stores that resource in the blockchain's internal storage.</p>
<hr />
<p>Non-resource types (variables, arrays/dictionaries, and structs) do not physically move, so they are not stored in any specific account's storage; instead, they are accessible to everyone. Resources, on the other hand, play a central role in smart contracts because, fundamentally, only their owner can invoke their internal methods; consequently, they are stored in the owner's storage.</p>
<hr />
<p>When looking at smart contracts, one often sees a structure like the following.</p>
<pre><code class="language-swift">contract A {

  access(all) resource  B {
    access(all) fun setRankingAndDeliverPrize() {
    }
  }

  init {
    self.account.storage.save(&lt;- new B(), to: /storage/B)
  }
}
</code></pre>
<p>The smart contract deployer is represented as <code>self.account</code> within the smart contract. Since the <code>init</code> function executes only once—at the time of deployment—this type of code is used when the goal is to create a single, system-critical resource. In the example above, this means that only the smart contract deployer owns Resource B, and only that account can execute the contract's <code>setRankingAndDeliverPrize</code> method. Because this blockchain (Flow) supports scheduled execution, it enables fair, automated operations—such as recalculating rankings and distributing prize money to the top three teams every week.</p>
<hr />
<h3>Regarding the deep technical relationship between the Flow team (Dapper Labs) and the original Diem/Libra team at Meta:</h3>
<h3>Move &amp; Cadence Shared Roots</h3>
<p>While Flow and Libra/Diem were developed in parallel, the Dapper Labs team and Meta's crypto research team collaborated extensively through technical working groups in the 2018–2020 era.</p>
<p>Both teams shared the same fundamental thesis: <strong>existing blockchains (like Ethereum's EVM) were structurally unsafe and poorly suited for mainstream consumer applications and NFTs.</strong></p>
<ol>
<li><p><strong>Resource-Oriented Architecture:</strong> Meta created the <strong>Move</strong> language for Libra, while Dapper Labs created <strong>Cadence</strong> for Flow. Both languages adopted the "Resource-Oriented Programming" paradigm—a concept originally inspired by Rust's linear type system where digital assets are treated as physical objects in memory that cannot be duplicated, implicit-dropped, or re-entered.</p>
</li>
<li><p><strong>Technical Exchange:</strong> Engineers from Dapper Labs and Meta regularly cross-pollinated ideas regarding resource safety, access control capabilities, and account abstractions during the initial design phases of both languages.</p>
</li>
</ol>
<h3>Why Instagram Supported Flow at NFT Feature Launch</h3>
<p>When Meta launched its native NFT and digital collectibles feature on Instagram in May 2022, <strong>Flow was chosen as one of the primary launch blockchains</strong> alongside Ethereum and Polygon.</p>
<p>This choice was directly tied to those technical roots and operational history:</p>
<ul>
<li><p><strong>Mass-Consumer Scaling:</strong> Flow was designed specifically for high-throughput consumer apps (like <em>NBA Top Shot</em>), making it a natural fit for Instagram's massive user base without exposing users to high gas fees or network congestion.</p>
</li>
<li><p><strong>Shared Developer Philosophy:</strong> Because Meta's internal crypto teams were already intimately familiar with Cadence's resource model and Flow's account architecture through their earlier Libra-era working groups, integrating Flow into Instagram's backend infrastructure was smooth and architecturally aligned with Meta's standards.</p>
<hr />
<p>The Flow team frequently held working group sessions with Meta’s Libra (later renamed Diem) foundation, driven by a shared awareness of issues facing existing blockchains. However, it was the Flow team—not Meta’s development team—that ignited the NFT boom. The Cadence smart contract language, written in Go (a language ergonomically superior to Rust), is characterized by being easy to write and learn, making the process of programming enjoyable.</p>
<hr />
<h3>Demystifying Cadence: Why Resource-Oriented Programming Prevents Exploits at Compile Time</h3>
<p>In conventional smart contract environments like Ethereum’s EVM, digital assets (like ERC-20 tokens or ERC-721 NFTs) are represented as entries in a central database dictionary. To transfer a token, a contract modifies integer balances mapped to user addresses (<code>balances[from] -= amount; balances[to] += amount</code>).</p>
<p>This pattern is prone to catastrophic vulnerabilities—such as <strong>reentrancy attacks, integer overflows, and unauthorized balance manipulation</strong>—because assets do not exist as real objects.</p>
<p>Flow's <strong>Cadence</strong> solves this by introducing <strong>Resource-Oriented Programming</strong>.</p>
</li>
</ul>
<h3>Three Technical Pillars of Cadence</h3>
<ol>
<li><p>Linear Types &amp; Assets as "Physical Objects"</p>
<p>In Cadence, resources represent real-value assets. They are governed by linear typing rules derived from Rust:</p>
<ul>
<li><p><strong>Cannot be Copied:</strong> A resource cannot be duplicated (<code>let clone = resource</code> throws a compile-time error).</p>
</li>
<li><p><strong>Cannot be Implicitly Dropped:</strong> If a resource is moved into a function scope, it must be explicitly moved into account storage or destroyed using the <code>destroy</code> keyword.</p>
</li>
<li><p><strong>Must occupy exactly one location at any time.</strong></p>
</li>
</ul>
</li>
</ol>
<pre><code class="language-swift">// Defining a Resource NFT
access(all) resource NFT {
    access(all) let id: UInt64
    init(id: UInt64) {
        self.id = id
    }
}

// Creating and transferring a resource
access(all) fun mintAndStore(account: &amp;Account) {
    // Uses the move operator '&lt;-' instead of equality '='
    let newNFT &lt;- create NFT(id: 1001)
    
    // The asset MUST be moved to storage, otherwise the compiler throws an error
    account.storage.save(&lt;-newNFT, to: /storage/MyNFT)
}
</code></pre>
<h4>2. The Move Operator (<code>&lt;-</code>)</h4>
<p>To enforce that resources cannot be accidentally overwritten, Cadence uses the explicit move operator <code>&lt;-</code> rather than the standard assignment operator <code>=</code>. This visually and syntactically alerts developers that ownership of an asset is being transferred.</p>
<h4>3. Capability-Based Access Control</h4>
<p>Instead of checking <code>msg.sender == owner</code> at runtime (a common source of authorization bugs in Solidity), Cadence uses <strong>Capabilities</strong>. Accounts issue unforgeable references to their private storage paths, delegating precise permissions (e.g., "read-only" vs. "deposit-only") without exposing the underlying asset.</p>
<hr />
<p>The language itself is similar to Swift. Since the creator of CryptoKitties is a former Apple engineer who worked on Keynote around 2010, the language is highly compatible with Apple's development ecosystem.</p>
<p>You can write everything—including financial calculations, game data management (such as rankings), and asset distribution—within a single piece of code. Furthermore, simply by registering a resource to <code>self</code>, you can freely execute these processes from the backend.</p>
]]></content:encoded></item><item><title><![CDATA[アカウント能力 (Capability) の委任]]></title><description><![CDATA[Capabilityを委任する
通常のCapabilityはsigner.capabilitiesに対して公開しますが、Capabilityの委任時はsigner.inboxに対して公開します。
通常のCapabilityの公開
/* Create a Thief resource */
signer.storage
    .save(<- MMORPG.createThiefResource(]]></description><link>https://tech-blog.blsqui.net/capability</link><guid isPermaLink="true">https://tech-blog.blsqui.net/capability</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Sat, 15 Aug 2026 06:33:57 GMT</pubDate><content:encoded><![CDATA[<h3>Capabilityを委任する</h3>
<p>通常のCapabilityは<code>signer.capabilities</code>に対して公開しますが、Capabilityの委任時は<code>signer.inbox</code>に対して公開します。</p>
<p><strong>通常のCapabilityの公開</strong></p>
<pre><code class="language-swift">/* Create a Thief resource */
signer.storage
    .save(&lt;- MMORPG.createThiefResource(payment: &lt;- payment),
            to: /storage/MMORPGThiefResource)

/* リソースのaccess(all)のフィールドをCapabilityで公開する */
let cap = signer.capabilities
    .storage
    .issue&lt;&amp;MMORPG.Thief&gt;(/storage/MMORPGThiefResource)

signer.capabilities
    .publish(cap, at: /public/MMORPGThiefResource)
                    }
</code></pre>
<p><strong>委任時のCapabilityの公開</strong></p>
<pre><code class="language-swift">/* Issue a resource capability for ThiefAbility1 entitlement */
let capability = signer.capabilities
    .storage
    .issue&lt;auth(MMORPG.ThiefAbility1) &amp;MMORPG.Thief&gt;
                                (/storage/MMORPGThiefResource)

/* Publish the capability for the specified recipient */
signer.inbox
    .publish(
        capability,
        name: "PoisonMakingSkill",
        recipient: recipient
    )
</code></pre>
<p>recipientは委任する相手のアドレスです。</p>
<hr />
<h3>委任された能力(Capability)を使用する</h3>
<pre><code class="language-swift">/* Claim the capability published by buddy */
let capability = signer.inbox
    .claim&lt;auth(MMORPG.ThiefAbility1) &amp;MMORPG.Thief&gt;(
        "PoisonMakingSkill",
        provider: providerAddress
    )
capability!.borrow()!.PoisonMaking(battleId: battleId)
</code></pre>
<p>providerAddressは委任したアカウントのアドレス</p>
<hr />
<h3>委任された Capability の一覧表示と UI 設計</h3>
<p>Flow の Inbox 仕様上、委任データは受取側へのストレージスパムを防ぐため、受取人（Recipient）のアカウントではなく<strong>発行者（Provider）のストレージ</strong>に保持されます。</p>
<p>そのため、実務の Web3 ゲーム開発では「発行者が公開中の委任一覧スクリプト」<strong>や</strong>「オンチェーンイベントをオフチェーン DB でインデックスしたデータ」を活用して、受取可能な能力を UI にリアルタイム表示します。</p>
<h4><strong>発行中（委任中）の Capability を一覧取得するスクリプト</strong></h4>
<p>発行者（Provider）が「誰にどの能力を委任したまま未受取になっているか」を確認、あるいはフロントエンドで利用可能な能力を特定するためのスクリプトです。</p>
<pre><code class="language-cadence">import MMORPG from 0xMMORPGAddress

// UI表示用のデータ構造体
access(all) struct InboxItemData {
    access(all) let inboxName: String
    access(all) let ability: String

    init(inboxName: String, ability: String) {
        self.inboxName = inboxName
        self.ability = ability
    }
}

/* クエリー処理 */
access(all) fun main(providerAddress: Address): [InboxItemData] {
    let account = getAccount(providerAddress)
    let inboxItems: [InboxItemData] = []

    // 発行者のアカウントで現在公開・委任中の Inbox 名一覧を取得
    let inboxStorageNames = account.inbox.getNames()

    for name in inboxStorageNames {
        // 具象型 &amp;MMORPG.Thief として中身を安全に参照 (peek)
        if let cap = account.inbox.peek&lt;&amp;MMORPG.Thief&gt;(name: name) {
            if let thief = cap.borrow() {
                inboxItems.append(InboxItemData(
                    inboxName: name,
                    ability: thief.getAbilityDetail()
                ))
            }
        }
    }

    return inboxItems
}
</code></pre>
<h3>オフチェーン連携と UI 表示の流れ</h3>
<ol>
<li><p><strong>イベント検知と DB 保存:</strong> 発行者が <code>signer.inbox.publish(...)</code> を実行すると、Flow のシステムイベント（<code>flow.AccountInboxPublished</code>）が発火します。ゲームのバックエンド（インデクサー）でこれを検知し、<code>providerAddress</code>、<code>recipientAddress</code>、<code>inboxName</code> をデータベースへ保存します。</p>
</li>
<li><p><strong>利用可能スキルの UI レンダリング:</strong> 受取人（Recipient）がログインした際、DB から「自分宛てに届いている委任一覧」を取得して UI 上に「仲間から借りられるスキル」として表示します。</p>
</li>
<li><p><strong>安全な Claim と実行:</strong> UI から対象のスキルを選択すると、保存されている <code>providerAddress</code> と <code>name</code> を渡して <code>signer.inbox.claim</code> トランザクションを実行し、即座にゲーム内で能力を発動できます。</p>
</li>
</ol>
<h3>ゲーム・UI 設計におけるメリット</h3>
<ul>
<li><p><strong>ブラインド Claim の防止:</strong> プレイヤーは事前に DB やスクリプト経由で「どの仲間から、どんなスキルが委任されているか」を確認してから Claim できます。</p>
</li>
<li><p><strong>リアルタイム通知・バフ表示:</strong> 仲間からスキルが委任された瞬間に「パーティメンバーから支援スキルが届きました！」という通知バッジを表示可能です。</p>
</li>
<li><p><strong>ガス代ゼロでの事前確認:</strong> スクリプト（Read-only）やオフチェーンキャッシュを利用するため、不要なガス代をかけることなく UI を更新できます。</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[その他の文法 (Castなど)]]></title><description><![CDATA[乱数生成
access(all) fun rollDice(): UInt64 {
    // modulo: 6 returns 0, 1, 2, 3, 4, or 5
    let rawRoll: UInt64 = revertibleRandom(modulo: 6)
    return rawRoll + 1
}


現在時刻の取得
self.execTime = getCurre]]></description><link>https://tech-blog.blsqui.net/cast</link><guid isPermaLink="true">https://tech-blog.blsqui.net/cast</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Sat, 15 Aug 2026 05:17:27 GMT</pubDate><content:encoded><![CDATA[<h3>乱数生成</h3>
<pre><code class="language-swift">access(all) fun rollDice(): UInt64 {
    // modulo: 6 returns 0, 1, 2, 3, 4, or 5
    let rawRoll: UInt64 = revertibleRandom(modulo: 6)
    return rawRoll + 1
}
</code></pre>
<hr />
<h3>現在時刻の取得</h3>
<pre><code class="language-swift">self.execTime = getCurrentBlock().timestamp // 秒単位まで
</code></pre>
<p>乱数生成と現在時刻取得はグローバルメソッドでありimportは何も必要ありません。</p>
<hr />
<h2>型変換</h2>
<h3><strong>Cast</strong></h3>
<pre><code class="language-swift">let integer: Int = 1
// This is an upcast.
let number = integer as Number // number = 1 and has type Number.  (as はDowncastには使えません)
</code></pre>
<h3><strong>Conditional Downcast</strong></h3>
<pre><code class="language-swift">let something: AnyStruct = 1
let number: Int? = something as? Int    // 1
let boolean: Bool? = something as? Bool // nil (as?はDowncastに使えます。subtypeでなくCast出来ない場合はnilを返す)
</code></pre>
<h3><strong>Forced Downcast</strong></h3>
<pre><code class="language-swift">let something: AnyStruct = 1
let number: Int? = something as! Int  // 1 (as! はDowncastに使えます。 subtypeでない場合はnilを返す)
</code></pre>
<h3><strong>Forced Unwrap (</strong><code>!</code><strong>)</strong></h3>
<pre><code class="language-swift">let c: Int? = 3
let d: Int = c!
</code></pre>
<hr />
<h2>Resource Interface</h2>
<p>インターフェイスは、実装しなければならない動作（関数やフィールド）の規約を定義するものです。</p>
<pre><code class="language-swift">access(all) resource interface IGreeting {
    access(all) let greeting: String
}

access(all) resource Greeting: IGreeting {
    access(all) let greeting: String
    init() {
        self.greeting = "Hello, World!"
    }
}

access(all) fun createRestrictedGreeting(): @{IGreeting} {
    return &lt;- create Greeting()
}
</code></pre>
<ul>
<li><p>インターフェイス型として扱う場合は、<code>@{IGreeting}</code> のように指定します。</p>
</li>
<li><p>メソッドやフィールドへの詳細なアクセス制限を行いたい場合は、Entitlement を使用して制御します。</p>
</li>
</ul>
<p>(若干、Cadence v1.0以前とCadence v1.0では変更が発生しています。 <code>@Greeting{IGreeting}</code> 構文は廃止され、<code>@{IGreeting}</code> のように指定するなど。)</p>
<hr />
<h2>Operator</h2>
<p><code>=</code></p>
<pre><code class="language-swift">var a = 4
</code></pre>
<p><code>&lt;-</code></p>
<pre><code class="language-swift">// リソースを空の変数またはコンテナに移動します。
// 空でないと判断できる場合コンパイルエラーとなります。代わりに&lt;-!を使用してください
return &lt;- create Arms(attack: attack)
</code></pre>
<p><code>&lt;-!</code></p>
<pre><code class="language-swift">// リソースを Optional (@T?) に代入します。その際、現在の値が nil であることを前提とします（nil でない場合はパニックします）。
self.equippedWeapon &lt;-! newWeapon
</code></pre>
<p><code>&lt;-&gt;</code></p>
<pre><code class="language-swift">// どちらもdestroyすることなく、2つのリソースをアトミックに入れ替えます。
var mainHand: @Arms &lt;- create Arms(name: "Excalibur")
var storage: @Arms? &lt;- nil
mainHand &lt;-&gt; storage
</code></pre>
<p>arithmetic(<code>+, -, *, /, %</code>)</p>
<pre><code class="language-swift">let a = 1 + 2 // is 3
</code></pre>
<p>super-types (Upcast &amp; Downcast)</p>
<pre><code class="language-swift">// 抽象型 Integer へのアップキャストと、演算実行のための具象型 Int8 へのダウンキャスト（as!）
let x: Integer = 3 as Int8
let y: Integer = 4 as Int8 
let z: Integer = (x as! Int8) + (y as! Int8)
// 1. Storing an Int8 in an Integer variable is an upcast.
// 2. Similarly, 4 is created as Int8 and upcast to Integer.
// 3. Integer is an abstract super-type / interface which does not allow direct arithmetic. Therefore, x and y must be explicitly downcast back to their concrete type using as!.
</code></pre>
<p>Ternary Conditional</p>
<pre><code class="language-swift">let x: Int = 1 &gt; 2 ? 3 : 4     // 4
let y: Int? = 1 &gt; 2 ? nil : 3  // 3
</code></pre>
<p>Nil-Coalescing (<code>??</code>)</p>
<pre><code class="language-swift">let a: Int? = nil
let b: Int = a ?? 42 // Optional型がnilでなければその値を返し、nilであれば代替の値を返す。)
</code></pre>
<p><code>!</code></p>
<pre><code class="language-swift">let a = true
let b = !a // false
</code></pre>
<p><code>&amp;&amp;</code></p>
<pre><code class="language-swift">true &amp;&amp; true    // true
true &amp;&amp; false   // false
</code></pre>
<p><code>||</code></p>
<pre><code class="language-swift">false || true   // true
false || false  // false
</code></pre>
<p><code>==</code></p>
<pre><code class="language-swift">let x: Int? = 1
x == nil  // false

// Comparisons of different levels of optionals are possible.
let x: Int? = 2
let y: Int?? = 2
x == y    // true

let a: Int? = nil            // nil
let b: Int?? = nil           // nil (outer level is nil)
let c: Int?? = (nil as Int?) // Some(nil) (inner level is nil)

a == b // true
b == c // false (b is nil, but c contains an optional holding nil!)
</code></pre>
<p><code>!=</code></p>
<pre><code class="language-swift">let x: Int? = 1
x != nil  // true

// Comparisons of different levels of optionals are possible.
let x: Int? = 2
let y: Int?? = 2
x != y    // false
</code></pre>
<p><code>&lt;</code></p>
<pre><code class="language-swift"> 1 &lt; 2  // true
 2 &lt; 1  // false
</code></pre>
<p><code>&lt;=</code></p>
<pre><code class="language-swift"> 1 &lt;= 1  // true
 2 &lt;= 1  // false
</code></pre>
<p><code>&gt;</code></p>
<pre><code class="language-swift"> 1 &gt; 1  // false
 2 &gt; 1  // true
</code></pre>
<p><code>&gt;=</code></p>
<pre><code class="language-swift"> 1 &gt;= 1  // true
 1 &gt;= 2  // false
</code></pre>
<hr />
<h3><strong>Bitwise operator</strong></h3>
<p>Bitwise AND (<code>&amp;</code>)</p>
<pre><code class="language-swift">let firstFiveBits = 0b11111000
let lastFiveBits  = 0b00011111
let middleTwoBits = firstFiveBits &amp; lastFiveBits  // 0b00011000
</code></pre>
<p>Bitwise OR (<code>|</code>)</p>
<pre><code class="language-swift">let someBits = 0b10110010
let moreBits = 0b01011110
let combinedbits = someBits | moreBits  // 0b11111110
</code></pre>
<p>Bitwise XOR (<code>^</code>)</p>
<pre><code class="language-swift">let firstBits = 0b00010100
let otherBits = 0b00000101
let outputBits = firstBits ^ otherBits  // 0b00010001
</code></pre>
<p>Bitwise LEFT SHIFT (<code>&lt;&lt;</code>)</p>
<pre><code class="language-swift">let someBits = 4  // 0b00000100
let shiftedBits = someBits &lt;&lt; 2   // 0b00010000
</code></pre>
<p>Bitwise RIGHT SHIFT (<code>&gt;&gt;</code>)</p>
<pre><code class="language-swift">let someBits = 8  // 0b00001000
let shiftedBits = someBits &gt;&gt; 2   // 0b00000010
</code></pre>
<hr />
]]></content:encoded></item><item><title><![CDATA[Struct（構造体）と Resource（リソース）の全体像]]></title><description><![CDATA[Struct の宣言方法
  access(all) struct Info {

    access(contract) var orderQueue: [Order]

    /* setter */
    access(contract) fun setOrder(execTime: UFix64) {
      var order = Order(execTime: execTim]]></description><link>https://tech-blog.blsqui.net/struct-resource</link><guid isPermaLink="true">https://tech-blog.blsqui.net/struct-resource</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Sat, 15 Aug 2026 02:23:40 GMT</pubDate><content:encoded><![CDATA[<h2>Struct の宣言方法</h2>
<pre><code class="language-swift">  access(all) struct Info {

    access(contract) var orderQueue: [Order]

    /* setter */
    access(contract) fun setOrder(execTime: UFix64) {
      var order = Order(execTime: execTime)
      self.orderQueue.append(order)
    }

    init() {
      self.orderQueue = []
    }
  }
</code></pre>
<hr />
<h2>Struct の初期化方法</h2>
<pre><code class="language-swift">access(all) contract RideShare {
    access(self) let info: Info

    access(all) fun getInfo(): Info {
        return self.info
    }

    init() {
        self.info = Info()
    }
}
</code></pre>
<p>ここでは<code>Contract</code>型の<code>init</code>内で初期化していますが、一つ上のコードで書いたように<code>Struct</code>型のメソッド内で初期化することもできます。</p>
<p><code>Struct</code>型の中で別の<code>Struct</code>型を持つことができます。</p>
<hr />
<h2>Resourceの宣言方法</h2>
<pre><code class="language-swift">  access(all) resource Admin {

    access(all) var name: String

    init(name: String) {
      self.data = name
    }
  }
</code></pre>
<hr />
<h2>Resourceの初期化方法</h2>
<p>リソースはStructと違って必ずアカウントのストレージに保存しなければならないので、もしスマートコントラクトのデプロイ時に初期化を行いたい場合は以下のようにします。</p>
<pre><code class="language-swift">access(all) contract RideShare {

       :

    init() {
        self.account.storage.save( &lt;- create Admin("Admin"), to: /storage/RideShareAdmin)
    }
}
</code></pre>
<p>create キーワードを使用します。</p>
<p>createキーワードは必ずスマートコントラクト内に書く必要があります。（<strong>createキーワードはトランザクションコード内で使用出来ない</strong>）</p>
<p><strong>例</strong></p>
<pre><code class="language-swift">    access(all) fun createWarriorResource(payment: @FlowToken.Vault): @MMORPG.Warrior {
        pre {
            payment.balance == 5.0: "Payment must be 5.0 FLOW."
        }

        let warrior &lt;- create Warrior()
        MMORPG.FlowTokenVault.borrow()!.deposit(from: &lt;- payment) 

        return &lt;- warrior
    }
</code></pre>
<p>支払いに応じてリソースを作成しています。このメソッドをトランザクション内から実行します。</p>
<pre><code class="language-swift">: @MMORPG.Warrior 
</code></pre>
<p>となっている通り、リソースをトランザクションコードに返す場合、返却する型の前には <code>@</code> をつけます。</p>
<hr />
<h3>トランザクション内でストレージにリソースを保存</h3>
<pre><code class="language-swift">/* Create a Warrior resource */
signer.storage
    .save(&lt;- MMORPG.createWarriorResource(payment: &lt;- payment),
            to: /storage/MMORPGWarriorResource)
</code></pre>
<p>トランザクション内から<code>createWarriorResource</code>メソッドを呼んでいます。</p>
<p>リソースは<code>Contract</code>内でしか生成できないので、管理しやすく、管理番号をつけることが容易になります。</p>
<hr />
<h3>コントラクト内で管理番号やCapabilityを持てる</h3>
<pre><code class="language-swift">access(all) contract RideShare {

    access(self) var totalDrivers: UInt // Driver ID
    access(self) let FlowTokenVault: Capability&lt;&amp;{FungibleToken.Receiver}&gt;

    init() {
        self.totalDrivers = 0
        self.FlowTokenVault = self.account.capabilities.get&lt;&amp;{FungibleToken.Receiver}&gt;(/public/flowTokenReceiver)
    }
}
</code></pre>
<p>このように<code>Contract</code>や<code>Struct</code>、<code>Resource</code>の中に持てる変数or定数はフィールド(Field)と呼ばれ、必ず<code>init</code>内で初期化します。フィールドが一つもなければ<code>init</code>は不要です。</p>
<p><code>Resource</code>と<code>Struct</code>は初期化時に引数を渡せます。<code>Contract</code>の初期化時に引数を渡すにはトランザクションコードの<code>signer.contracts.add</code>に引数を渡します。</p>
<hr />
<h3>スマートコントラクトのデプロイ時に引数を渡す</h3>
<pre><code class="language-swift">transaction(contractName: String, code: String, title: String) {
    prepare(signer: auth(AddContract) &amp;Account) {
        
        signer.contracts.add(
            name: contractName,
            code: code.utf8,
            gameTitle: title // 引数1
        )
    }
}
</code></pre>
<pre><code class="language-swift">access(all) contract MyGameItem {
    access(all) var gameTitle: String

    init(gameTitle: String) {
        self.gameTitle = gameTitle
    }
}
</code></pre>
<hr />
<h2>まとめ</h2>
<h3><strong>- 特徴 -</strong></h3>
<p><strong>構造体:</strong></p>
<ul>
<li><p>静的変数のように使える。但し、厳格に型を定める必要がある。</p>
</li>
<li><p>宣言時は必ず<code>access(all)</code>であり、構造体の型は公開される。</p>
</li>
<li><p><code>init</code>以外での構造体の値書き換えには<code>access(contract)</code>より小さいアクセス修飾子がついたSetter関数が必要</p>
</li>
</ul>
<p><strong>リソース:</strong></p>
<ul>
<li><p>クラスオブジェクトに近い</p>
</li>
<li><p>ポインタの概念を持つ (<code>borrow</code>で拝借することでストレージから移動せずともフィールドにアクセスできる)</p>
</li>
<li><p>宣言時は必ず<code>access(all)</code>でありクラスの型は公開される</p>
</li>
<li><p>create演算子でオブジェクトを生成し、オブジェクトはストレージに保存される</p>
</li>
<li><p>cpu消費を避ける為、基本的にはポインタを通じて<code>resource</code>のフィールド/メソッドにアクセスする（移動はトランザクションコストが余計にかかる為）</p>
</li>
<li><p>ストレージ間を移動できる。所有できる。</p>
</li>
</ul>
<p><strong>両者に共通:</strong></p>
<ul>
<li><p>インタフェース(抽象型)を継承できる</p>
</li>
<li><p>任意の数のインタフェースを継承することができる</p>
</li>
<li><p>Swift言語に近いがJava言語にも文法的に似ている(インタフェースを型にするインターセクション<code>&lt;&amp;{FungibleToken.Receiver}&gt;</code> はJava言語と同じ書き方で、このように<code>&lt;&amp;{}&gt;</code>で囲む。そのためJavaエンジニアにとっても親しみやすい文法となっている)</p>
</li>
</ul>
<hr />
<h3><strong>- アクセス方法/保存場所 -</strong></h3>
<p><strong>構造体:</strong></p>
<ul>
<li><p>スマートコントラクトのaccess(all)メソッドが入り口となって値を読み書きできる</p>
</li>
<li><p>スマートコントラクトがデプロイされたアカウントのストレージ内に保存される</p>
</li>
</ul>
<p><strong>リソース:</strong></p>
<ul>
<li><p>スマートコントラクトのaccess(all)メソッドを介してリソースを生成でき、アカウントのストレージ内に保存される</p>
</li>
<li><p>リソースのメソッドを通じてスマートコントラクトの構造体の値も読み書きできる（逆は構造的に不可能）</p>
</li>
<li><p>リソースが他のリソースを保持する事も可能である</p>
</li>
</ul>
<hr />
<h3>スマートコントラクトの一例</h3>
<pre><code class="language-swift">import "FlowToken"
import "FungibleToken"

access(all) contract MMORPG8 {

  access(self) let FlowTokenVault: Capability&lt;&amp;{FungibleToken.Receiver}&gt;
  access(self) let info: Info
  access(self) var totalGamePlayers: UInt // Player ID

  access(all) entitlement ThiefAbility1
  access(all) entitlement ThiefAbility2
  access(all) entitlement WarriorAbility1
  access(all) entitlement WarriorAbility2

  access(all) event ESportsGamerInitiated(battleId: Int, player1Address: Address, player2Address: Address)

  /* 構造体 */
  access(all) struct Info {

    /* fields */
    access(contract) var battleQueue: [GameBattle]
    access(contract) var basicAbility: {String: String}     // リソース別の基本アビリティ
    access(contract) var basicAttackInfo: {String: [UInt8]} // システム側から通常攻撃トランザクションを行うための情報

    /* setter  &lt;Return: Battle ID&gt; */
    access(contract) fun newGameBattle(
      player1Address: Address,
      player2Address: Address,
      lifeOfPlayer1: UInt8,
      lifeOfPlayer2: UInt8,
      reward: UFix64
    ): Int {
      var battle = GameBattle(
        player1Address: player1Address,
        player2Address: player2Address,
        lifeOfPlayer1: lifeOfPlayer1,
        lifeOfPlayer2: lifeOfPlayer2,
        reward: reward
      )
      self.battleQueue.append(battle)
      return self.battleQueue.length - 1
    }

    /* setter */
    access(contract) fun updateGameBattle(
      battleId: Int,
      target: String?,
      lifeChange: UInt8,
      isDamage: Bool
    ) {
      if (target != nil) {
        self.battleQueue[battleId]!.setPlayerLife(target: target!, lifeChange: lifeChange, isDamage: isDamage)
      } else {
        self.battleQueue[battleId]!.setEnemyLife(damage: lifeChange) // 敵への攻撃は全体攻撃しかない..
      }
    }

    /* init */
    init() {
      self.battleQueue = []
      self.basicAbility = {
       "Warrior-BasicAttack": "Rage Attack",
       "Warrior-ShareableAbility": "LargeRecoveryShield",
       "Thief-BasicAttack": "Whip Attack",
       "Thief-ShareableAbility": "PoisonMaking",
       "Enemy-BasicAttack": "A Crushing Blow"
      }
      self.basicAttackInfo = {
        "Warrior": [1, 3], // [GroupAttack?, damageVolume] (Rage Attack)
        "Thief": [1, 1], // [GroupAttack?, damageVolume] (Whip Attack
        "Enemy": [0, 4] // [GroupAttack?, damageVolume] (A Crushing Blow)
      }
    }
  }

  /* Info内の構造体 */
  access(all) struct GameBattle {

    /* fields */
    access(all) let execTime: UFix64
    access(all) let player1Address: Address
    access(all) let player2Address: Address
    access(all) var lifeOfPlayer1: UInt8
    access(all) var lifeOfPlayer2: UInt8
    access(all) var enemy1Life: UInt8
    access(all) var enemy2Life: UInt8
    access(all) let reward: UFix64

    /* setter(ダメージまたは回復) */
    access(contract) fun setPlayerLife(target: String, lifeChange: UInt8, isDamage: Bool) {
      if (target == "TeamPlayer1") {
        if (isDamage) {
          self.lifeOfPlayer1 = self.lifeOfPlayer1 &lt; lifeChange ? 0 : self.lifeOfPlayer1 - lifeChange
        } else {
          self.lifeOfPlayer1 = self.lifeOfPlayer1 + lifeChange
        }
      } else if (target == "TeamPlayer2") {
        if (isDamage) {
          self.lifeOfPlayer2 = self.lifeOfPlayer2 &lt; lifeChange ? 0 : self.lifeOfPlayer2 - lifeChange
        } else {
          self.lifeOfPlayer2 = self.lifeOfPlayer2 + lifeChange
        }
      }
    }
    /* setter(敵への全体攻撃) */
    access(contract) fun setEnemyLife(damage: UInt8) {
      self.enemy1Life = self.enemy1Life &lt; damage ? 0 : self.enemy1Life - damage
      self.enemy2Life = self.enemy2Life &lt; damage ? 0 : self.enemy2Life - damage
    }

    /* init */
    init(player1Address: Address, player2Address: Address, lifeOfPlayer1: UInt8, lifeOfPlayer2: UInt8, reward: UFix64) {
      let modulo: UInt8 = 3
      self.execTime = getCurrentBlock().timestamp
      self.player1Address = player1Address
      self.player2Address = player2Address
      self.lifeOfPlayer1 = lifeOfPlayer1
      self.lifeOfPlayer2 = lifeOfPlayer2

      // 両方戦士タイプなら悪魔を登場させる
      if (lifeOfPlayer1 &gt; 5 &amp;&amp; lifeOfPlayer2 &gt; 5) {
        self.enemy2Life = 9 + revertibleRandom(modulo: modulo) // 9 ~ 11の整数
      } else {
        self.enemy2Life = 5 + revertibleRandom(modulo: modulo) // 5 ~ 7の整数
      }
      self.enemy1Life = 8 + revertibleRandom(modulo: modulo) // 8 ~ 10の整数
      self.reward = reward
    }
  }

  // GET
  access(all) fun getInfo(): Info {
    return self.info
  }

  // PUT
  access(all) fun newGameBattle(
    payment: @FlowToken.Vault,
    player1Address: Address,
    player2Address: Address,
    lifeOfPlayer1: UInt8,
    lifeOfPlayer2: UInt8
  ) {
    let battleId = self.info.newGameBattle(
      player1Address: player1Address,
      player2Address: player2Address,
      lifeOfPlayer1: lifeOfPlayer1,
      lifeOfPlayer2: lifeOfPlayer2,
      reward: payment.balance * 2.0)

    emit ESportsGamerInitiated(battleId: battleId, player1Address: player1Address, player2Address: player2Address)

    // Game Feeをシステムアカウントに保存
    self.FlowTokenVault.borrow()!.deposit(from: &lt;- payment)
  }

  access(all) resource Thief {
    access(all) let id: UInt
    access(all) let maxLife: UInt8

    access(ThiefAbility1) fun PoisonMaking(battleId: Int) {
      MMORPG8.info.updateGameBattle(battleId: battleId, target: nil, lifeChange: 6, isDamage: true)
    }
    access(ThiefAbility2) fun WhipAttack(battleId: Int) {
      MMORPG8.info.updateGameBattle(battleId: battleId, target: nil, lifeChange: 1, isDamage: true)
    }
    
    init() {
      MMORPG8.totalGamePlayers = MMORPG8.totalGamePlayers + 1
      self.id = MMORPG8.totalGamePlayers
      self.maxLife = 5
    }
  }

  access(all) resource Warrior {
    access(all) let id: UInt
    access(all) let maxLife: UInt8

    access(WarriorAbility1) fun LargeRecoveryShield(battleId: Int, target: String) {
      MMORPG8.info.updateGameBattle(battleId: battleId, target: target, lifeChange: 4, isDamage: false)
    }
    access(WarriorAbility2) fun RageAttack(battleId: Int) {
      MMORPG8.info.updateGameBattle(battleId: battleId, target: nil, lifeChange: 3, isDamage: true)
    }

    init() {
      MMORPG8.totalGamePlayers = MMORPG8.totalGamePlayers + 1
      self.id = MMORPG8.totalGamePlayers
      self.maxLife = 8
    }
  }

  access(all) resource Admin {
    access(all) fun payRewards(recipient1: Address, recipient2: Address, reward: UFix64) {
      // Pay the reward.
      let reward1 &lt;- MMORPG8.account
        .storage
        .borrow&lt;auth(FungibleToken.Withdraw) &amp;{FungibleToken.Provider}&gt;(from: /storage/flowTokenVault)!
        .withdraw(amount: reward) as! @FlowToken.Vault

      getAccount(recipient1)
        .capabilities
        .get&lt;&amp;{FungibleToken.Receiver}&gt;(/public/flowTokenReceiver)
        .borrow()!.deposit(from: &lt;- reward1)

      let reward2 &lt;- MMORPG8.account
        .storage
        .borrow&lt;auth(FungibleToken.Withdraw) &amp;{FungibleToken.Provider}&gt;(from: /storage/flowTokenVault)!
        .withdraw(amount: reward) as! @FlowToken.Vault

      getAccount(recipient2)
        .capabilities
        .get&lt;&amp;{FungibleToken.Receiver}&gt;(/public/flowTokenReceiver)
        .borrow()!.deposit(from: &lt;- reward2)
    }

    access(all) fun basicAttack(battleId: Int, target: String?, resourceName: String) {
      MMORPG8.info.updateGameBattle(battleId: battleId, target: target, lifeChange: MMORPG8.info.basicAttackInfo[resourceName]![1], isDamage: true)
    }
  }

  access(all) fun createWarriorResource(payment: @FlowToken.Vault): @MMORPG8.Warrior {
    pre {
      payment.balance == 5.0: "Cost of resource must be 5.0FLOW coin."
    }
    let _resource &lt;- create Warrior() // resourceは予約語なので_をつけてます

    MMORPG8.FlowTokenVault.borrow()!.deposit(from: &lt;- payment) // 代金徴収
    return &lt;- _resource
  }

  access(all) fun createThiefResource(payment: @FlowToken.Vault): @MMORPG8.Thief {
    pre {
      payment.balance == 5.0: "Cost of resource must be 5.0FLOW coin."
    }
    let _resource &lt;- create Thief()

    MMORPG8.FlowTokenVault.borrow()!.deposit(from: &lt;- payment) // 代金徴収
    return &lt;- _resource
  }

  init() {
    self.info = Info()
    self.FlowTokenVault = self.account.capabilities.get&lt;&amp;{FungibleToken.Receiver}&gt;(/public/flowTokenReceiver)
    self.totalGamePlayers = 0
    self.account.storage.save( &lt;- create Admin(), to: /storage/MMORPG8Admin)
  }
}
</code></pre>
<p>スマートコントラクトは内部のフィールドに変更があると更新ができません。</p>
<p>その為、フィールドを追加したい場合、コントラクト名を変更するか、デプロイするアカウントを変更する必要があります。コントラクトは削除できないため、"*削除&amp;再デプロイ"*はできません。</p>
]]></content:encoded></item><item><title><![CDATA[トランザクション(Transaction)の概要]]></title><description><![CDATA[トランザクションの概要
トランザクションコード
transactionから始まるCadence言語で書かれた実行メソッドです。スマートコントラクトをimportしそのスマートコントラクトのメソッドを実行することができます。スマートコントラクトのメソッドはaccess(all)メソッドであれば誰でも呼び出せます。
例
  const txId = await fcl.mutate({
      c]]></description><link>https://tech-blog.blsqui.net/transaction</link><guid isPermaLink="true">https://tech-blog.blsqui.net/transaction</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Fri, 14 Aug 2026 04:35:18 GMT</pubDate><content:encoded><![CDATA[<h2><strong>トランザクションの概要</strong></h2>
<h3>トランザクションコード</h3>
<p><code>transaction</code>から始まるCadence言語で書かれた実行メソッドです。スマートコントラクトをimportしそのスマートコントラクトのメソッドを実行することができます。スマートコントラクトのメソッドは<code>access(all)</code>メソッドであれば誰でも呼び出せます。</p>
<p><strong>例</strong></p>
<pre><code class="language-typescript">  const txId = await fcl.mutate({
      cadence: `
          import CookStocker from 0xb576a3926d239682

          transaction(id: String, add: [String], remove: [String]) {
              prepare(signer: &amp;Account) {
                  CookStocker.setCookStockerInfo(id: id, add: add, remove: remove)
              }
              execute {
                  log("success")
              }
          }
      `,
      args: (arg, t) =&gt; [
          arg(id.toString(), t.String),
          arg(add, t.Array(t.String)),
          arg(remove, t.Array(t.String)),
      ],
</code></pre>
<p>トランザクションは値を返すことができません。トランザクションはトランザクションIDを返します。このトランザクションIDを使用してトランザクション結果を確認します。</p>
<p><strong>例</strong></p>
<pre><code class="language-typescript">fcl.tx(txId).subscribe((res: any) =&gt; {
  if (res.status === 4 &amp;&amp; !res.errorMessage) {
    isProcessing = false; // ローディングを停止
    syncBalance(); // 残高を更新
    changeScene(); // 次の処理へ
  } else if (res.errorMessage) {
    isProcessing = false;
    alert(res.errorMessage); // トランザクションがpanicで出力した内容もしくは残高不足などのエラーメッセージが含まれます。
  }
});
</code></pre>
<hr />
<h3><code>prepare</code>ブロック</h3>
<pre><code class="language-typescript">prepare(signer: &amp;Account) {
</code></pre>
<p><code>prepare</code>ブロックの引数にはトランザクションに署名したアカウントの数だけそのアカウントの情報が渡されます。</p>
<hr />
<h3><code>Entitlement</code></h3>
<p>エンタイトルメントと呼びます。「権利」という意味になり、スマートコントラクトの中で宣言することでトランザクションコードでも使用可能になります。</p>
<p><strong>例</strong></p>
<pre><code class="language-typescript">import "FlowToken"
import "FungibleToken"

transaction(to: Address) {
    let sentVault: @{FungibleToken.Vault}

    prepare(signer: auth(BorrowValue) &amp;Account) {
        // Hardcoded amount: 5.0
        let vaultRef = signer.storage.borrow&lt;auth(FungibleToken.Withdraw) &amp;FlowToken.Vault&gt;(
            from: /storage/flowTokenVault
        ) ?? panic("Could not borrow reference to the owner's Vault!")

        self.sentVault &lt;- vaultRef.withdraw(amount: 5.0)
    }

    execute {
        let receiverRef = getAccount(to)
            .capabilities.get&lt;&amp;{FungibleToken.Receiver}&gt;(/public/flowTokenReceiver)
            .borrow()
            ?? panic("Could not borrow receiver reference to the recipient's Vault!")

        receiverRef.deposit(from: &lt;-self.sentVault)
    }
}
</code></pre>
<p>これは署名したアカウントから<code>5.0</code>FLOWを引き出して<code>transaction</code>ブロックの引数の<code>to</code>アドレスに対して振り込んでいます。</p>
<p>ごく一般的な送金処理です。</p>
<p><code>FungibleToken</code>コントラクトの中などで宣言された<code>Entitlement</code>はトランザクションコード内で<code>auth()</code>で囲んで使用します。<code>FungibleToken.Withdraw</code>がEntitlementです。<code>BorrowValue</code>はストレージに対するEntitlementです。</p>
<p>どうしても慣れる方が早いので「習うより慣れろ」、という学習スタイルになります。</p>
<p>上記のコードはもっと短くできます。</p>
<pre><code class="language-typescript">import "FlowToken"
import "FungibleToken"

transaction(to: Address) {
    prepare(signer: auth(BorrowValue) &amp;Account) {
        // Hardcoded amount: 5.0
        let vaultRef = signer.storage.borrow&lt;auth(FungibleToken.Withdraw) &amp;FlowToken.Vault&gt;(
            from: /storage/flowTokenVault)
            ?? panic("Could not borrow reference to the owner's Vault")
        let sentVault &lt;- vaultRef.withdraw(amount: 5.0)

        let receiverRef = getAccount(to)
            .capabilities.get&lt;&amp;{FungibleToken.Receiver}&gt;(/public/flowTokenReceiver)
            .borrow()
            ?? panic("Could not borrow receiver reference to the recipient's Vault")
        receiverRef.deposit(from: &lt;-sentVault)
    }
}
</code></pre>
<p><code>execute</code>ブロックは署名したアカウントの情報が引数に渡されません。そのため、<code>prepare</code>ブロックに必要な情報が全て揃っているため、ここに必要なロジックを書くだけでトランザクションは成立します。<code>transaction</code>ブロックの外側にも変数を宣言することができ、その変数を使用して<code>execute</code>ブロックに値を渡してメイン処理を行う、というのがマナーの良い書き方になります。（しかし、コードが短い方が視認性が良いと考える人は<code>prepare</code>ブロックだけを使用します。実際一つ前のコードと見比べてください。明らかにexecuteブロック無しの方が分かりやすいです。手続き型言語のCOBOLのように利用したい場合は、transactionブロックの中で使用できるprepare ブロック、preブロック、execute ブロック、postブロック全てを使用するのもありだと思います。）</p>
<hr />
<h3>クエリー(<code>query</code>)</h3>
<p>トランザクションは値を返さずトランザクションIDを返しますが、クエリーは値を指定した型で返します。</p>
<pre><code class="language-typescript">export const getInfo = async function (id) {
  const result = await fcl.query({
    cadence: `
    import CookStocker from 0x1234abcd5678efgh

    access(all) fun main(id: String): CookStocker.VegeData? {
        return CookStocker.getCookStockerInfo(id: id)
    }
    `,
    args: (arg, t) =&gt; [arg(id, t.String)],
  });
  return result;
};
</code></pre>
<p><code>access(all) fun main</code>ブロックに対し、<code>:</code>をつけて取得する値の型を指定します。CookStocker.VegeData?というOptional型を返します。Resouce型であれば先頭に<code>@</code>がつくので自動的にVegeDataはCookStockerコントラクトのStruct(構造体)であることが分かります。</p>
<p>スマートコントラクトで独自の型を持つのは一般的に<code>Contract</code>型と<code>Struct</code>型と<code>Resource</code>型だけです。(<code>Event</code>や<code>Entitlement</code>も型と呼ぶ場合はそれも含みます)</p>
<p>ブロックチェーンにアクセスするのは主にこの２つ、トランザクションとクエリーですが、もう一つブロックチェーンにアクセスする方法があります。Eventsです。</p>
<hr />
<h3><code>Events</code></h3>
<p><strong>例</strong></p>
<pre><code class="language-typescript">import * as fcl from "@onflow/fcl";

// Subscribe / Query events by event name and block range
const events = await fcl.events("A.0xContractAddress.ContractName.EventName")
  .fromBlockHeight(10000000)
  .toBlockHeight(10000100)
  .subscribe((event) =&gt; {
    console.log("Event received:", event);
  });
</code></pre>
<hr />
<h3><code>tx</code></h3>
<p>トランザクション結果をすぐに取得したい場合はEventsではなく<code>tx</code>メソッドを使用します。</p>
<pre><code class="language-typescript">fcl.tx(txId).subscribe((res: any) =&gt; {
  if (res.status === 4 &amp;&amp; !res.errorMessage) {
    isProcessing = false; // ローディングを停止
    syncBalance(); // 残高を更新 (中ではfcl.queryを行っています)
    changeScene(); // 次の処理へ
  } else if (res.errorMessage) {
    isProcessing = false;
    alert(res.errorMessage); // トランザクションがpanicで出力した内容もしくは残高不足などのエラーメッセージが含まれます。
  }
});
</code></pre>
<hr />
<h3>クエリーとトランザクションの違い</h3>
<p>クエリーは値を変更しようとすると<code>panic</code>が起こります。(トランザクションフィーを渡していないのでそもそも変更ができない)</p>
<p>１分間に複数回クエリーを発行することを実現する為にはノードを契約するという手法があります。</p>
<p>無料のノードを使用したい場合は以下のようにAccess Nodeを指定します。</p>
<pre><code class="language-typescript">  let isTestnet = true;
  if (isTestnet) {
    fcl.config({
      "discovery.wallet": "https://lab.blsqui.net/authn",
      "accessNode.api": "https://rest-testnet.onflow.org",// &lt;-無料
      "flow.network": "testnet",
      "app.detail.title": "Your IP Title here",
      "app.detail.icon": "Your IP Icon URL here",
    });
  } else {
    fcl.config({
      "discovery.wallet": "https://wallet.blsqui.net/authn",
      "accessNode.api": "https://rest-mainnet.onflow.org",// &lt;-無料
      "flow.network": "mainnet",
      "app.detail.title": "Your IP Title here",
      "app.detail.icon": "Your IP Icon URL here",
    });
  }
</code></pre>
<p>無料の公開ノードは通常１秒間にリクエスト回数を１回までに押さえておけばエラーになりません。レートリミットを超えても１秒間に１回は正しく値を返してくれることがあります。</p>
<p>リソースのメソッドは<code>access(all)</code>であっても決して所有者以外は呼び出すことはできません。(リソースはアカウントストレージ内に保存されるため所有者以外はアクセスできないからです) しかし、<code>viewResolver</code> または <code>Capability</code>を使用すると呼び出すことが可能になります。</p>
<hr />
<h3><code>viewResolver</code>と<code>Capability</code></h3>
<p>あるユーザーがそのリソースに対する「ケイパビリティ（<strong>Capability</strong>）」を公開していない限り、スクリプトは別のユーザーのプライベートな <code>/storage/</code> からリソースを任意に読み込んだり借用したりすることはできません。そのため、リソースのデータはメソッドが<code>access(all)</code>であっても<strong>Capability</strong>無しでは決して所有者以外は呼び出すことはできません。</p>
<p>調査するには、主に2つの方法があります。</p>
<p><strong>例1:</strong> <code>ViewResolver</code> <strong>&amp;</strong> <code>MetadataViews</code></p>
<p>こちらは<code>View</code>を使用する方法でコントラクト内で設定する様式が細かい為、難易度は高めです。以下は一例。</p>
<pre><code class="language-typescript">import MetadataViews from 0x631edd8282631f7b

access(all) fun main(address: Address, id: UInt64): AnyStruct? {
    // Get public account reference
    let account = getAccount(address)

    // Borrow public capability/collection reference
    let collectionRef = account.capabilities.borrow&lt;&amp;{MetadataViews.ResolverCollection}&gt;(
        /public/MyNFTCollection
    ) ?? panic("Could not borrow public collection reference")

    // Resolve the view data safely
    let view = collectionRef.borrowViewResolver(id: id)
    return view.resolveView(Type&lt;MetadataViews.Display&gt;())
}
</code></pre>
<p><strong>例2:</strong> <code>Capability</code><strong>の基本的な使い方を利用する</strong></p>
<p>こちらの方が独自性のあるコードを書けます。</p>
<pre><code class="language-swift">/* スマートコントラクト */
access(all) contract GameItem {
    // Declare Entitlement for write/privileged actions
    access(all) entitlement ManageItem

    access(all) resource Arms {
        access(all) var level: UInt64

        init() { self.level = 10 }

        // PUBLIC: Anyone holding an un-entitled capability can call this
        access(all) fun getLevel(): UInt64 {
            return self.level
        }

        // PROTECTED: Only callers holding auth(ManageItem) capability can call this
        access(ManageItem) fun levelUp() {
            self.level = self.level + 1
        }
    }
}

/* ここからトランザクション: リソースを署名者のストレージに格納 */
import GameItem from 0xCONTRACT_ADDRESS

transaction {
    prepare(signer: &amp;Account) {
        // Save resource
        signer.storage.save(&lt;-GameItem.createArms(), to: /storage/MyArms)

        /* Issue un-entitled capability(auth(ManageItem)がついていないので持ち主以外はlevelUpメソッドを呼び出せません) */
        let cap = signer.capabilities.storage.issue&lt;&amp;GameItem.Arms&gt;(/storage/MyArms)

        /* Publish to /public/ ストレージ */
        signer.capabilities.publish(cap, at: /public/MyArms)
    }
}

/* クエリー処理 */
import GameItem from 0xCONTRACT_ADDRESS

access(all) fun main(player: Address): UInt64 {
    let ref = getAccount(player)
        .capabilities
        .borrow&lt;&amp;GameItem.Arms&gt;(/public/MyArms)
        ?? panic("Could not borrow public capability")

    // Can call access(all) method directly.
    return ref.getLevel()
}
</code></pre>
<p>リソースの作成と保存は、「Struct（構造体）と Resource（リソース）の全体像」でも述べます。</p>
<hr />
<h3><code>Capability</code></h3>
<p><code>Capability</code>は人が保持している（ストレージに保存されている）リソースのメソッドを呼び出すことができます。リソースをストレージに保存する時、ユーザーはストレージに対する保存を許可する署名を行います。その時同時に、どれぐらいまでそのリソースに対するアクセスを人(システム)に許可するかを<code>Entitlement</code>と一緒に<code>Capability</code> で設定します。<code>Entitlement</code> を付けなかった<code>Capability</code>は<code>access(all)</code>メソッドだけが他人でもアクセスできます。<code>Capability</code>を公開しなければ、<code>access(all)</code>も呼び出すことは不可能ですが、署名者はトランザクション時に自由にアクセスできますので特段不都合がある訳ではありません。ゲームであれば必要な情報は構造体(<code>Struct</code>)にまとめておく方が圧倒的に便利であり、<code>Capability</code>が必要になるのは(能力&lt;<code>Capability</code>&gt;を委任したい場合など)複雑なシステムだけということが往々にしてあります。</p>
<ol>
<li><p>Capabilityを発行する（<code>auth()</code>がついてないので<code>access(all)</code>のメソッドのみ呼べます）</p>
<pre><code class="language-typescript">let cap = signer.capabilities.storage.issue&lt;&amp;GameItem.Arms&gt;(/storage/MyArms)
</code></pre>
</li>
<li><p>Capabilityを公開する</p>
<pre><code class="language-typescript">signer.capabilities.publish(cap, at: /public/MyArms)
</code></pre>
</li>
<li><p>Capabilityを拝借する</p>
</li>
</ol>
<pre><code class="language-typescript">    let ref = getAccount(player)
        .capabilities
        .borrow&lt;&amp;GameItem.Arms&gt;(/public/MyArms)
        ?? panic("Could not borrow public capability")
</code></pre>
<p>４. Capabilityを通じて呼び出す。</p>
<pre><code class="language-typescript">return ref.getLevel()
</code></pre>
<p><code>Entitlement</code>をつけて<code>Capability</code>を発行する時は以下のようにします。（1.と違って<code>auth(GameItem.ManageItem)</code>がついています）</p>
<pre><code class="language-typescript">let entitledCap = signer.capabilities.storage.issue&lt;
            auth(GameItem.ManageItem) &amp;GameItem.Arms
        &gt;(/storage/MyArms)
</code></pre>
<p><code>Capability</code>は必要に迫られるまでは作成しないので最初は気にする必要はありません。</p>
<hr />
<h3>アクセス修飾子</h3>
<pre><code class="language-typescript">access(all)         権限なくアクセス可能
access(contract)    コントラクト内からであればアクセス可能
access(self)        リソースまたはStruct内からのみアクセス可能
access(Entitlement) 宣言したEntitlementの権限を持っていればアクセス可能

例:
access(ManageItem) fun levelUp() {
  self.level = self.level + 1
}
</code></pre>
<hr />
<h3>ウォレットアカウントの情報を取得する</h3>
<pre><code class="language-typescript">fcl.currentUser().subscribe((newVal: any) =&gt; {
    user = newVal;
    syncBalance();
});
</code></pre>
<hr />
<h3>Flowネイティブ通貨の残高を取得する</h3>
<pre><code class="language-typescript">  // Get Player's balance
  async function syncBalance() {
    if (!user?.addr) {
      esportsBalance = '-';
      return;
    };
    const account = await fcl.account(user.addr);
    esportsBalance = String(account.balance);

    if (!esportsBalance.includes('.')) {
      const num = parseFloat(esportsBalance) / 100000000;
      esportsBalance = num.toLocaleString('en-US', {
        minimumFractionDigits: 2,
        maximumFractionDigits: 8
      });
    }
  }
</code></pre>
<hr />
<p>ブロックチェーンシステムを作るに当たり、最初に覚えておかなければならないことはこれぐらいです。これだけ覚えておけば誰でも決済システム・eスポーツを作れます。</p>
]]></content:encoded></item><item><title><![CDATA[変数・定数・Collection の全体像]]></title><description><![CDATA[変数・定数
宣言方法
letは定数を、varは変数を表します。
pub fun main {
   var a: Int = 2 // 通常の型はnil(ヌル)を含むことができません。
   var a: Int? = nil // 変数にnilを入れられるようにするには、Optional Typeを使用します。
   var b: Int = a!  // Optional Typeをから通常の]]></description><link>https://tech-blog.blsqui.net/collection</link><guid isPermaLink="true">https://tech-blog.blsqui.net/collection</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Fri, 14 Aug 2026 02:48:28 GMT</pubDate><content:encoded><![CDATA[<h2><strong>変数</strong>・定数</h2>
<h3><strong>宣言方法</strong></h3>
<p>letは定数を、varは変数を表します。</p>
<pre><code class="language-swift">pub fun main {
   var a: Int = 2 // 通常の型はnil(ヌル)を含むことができません。
   var a: Int? = nil // 変数にnilを入れられるようにするには、Optional Typeを使用します。
   var b: Int = a!  // Optional Typeをから通常の変数に変換するには ! を使用します。(この場合はnilなのでエラーになります)
}
</code></pre>
<p>Cadenceでは、Optional Typeから通常のTypeに変換することがよくあります。そのような場合、Optional Binding ( =if let文 )を使って実装すると、実装が簡単になります。(if letの中に入る変数はOptionalではなくなります)</p>
<hr />
<h2>型の種類</h2>
<h3><strong>Boolean型</strong></h3>
<pre><code class="language-typescript">let boolVar: Bool = true
</code></pre>
<hr />
<h3><strong>Int型</strong></h3>
<pre><code class="language-typescript">let int8: Int8 = 127 // -128~127
let int16: Int16 = 32767 // -32768~32767
let int32: Int32 = 2147483647 // -2147483648~2147483647
let int64: Int64 = 9223372036854775807 // -9223372036854775808~9223372036854775807
let int128: Int128 = 9223372036854775808 // -2^127~2^127 − 1
let int256: Int256 = 9223372036854775808 // -2^255~2^255 − 1
</code></pre>
<hr />
<h3><strong>UInt型</strong></h3>
<pre><code class="language-typescript">let uint8: UInt8 = 255 // 0~255
let uint16: UInt16 = 65535 // 0~65535
let uint32: UInt32 = 4294967295 // 0~4294967295
let uint64: UInt64 = 18446744073709551615 // 0~18446744073709551615
let uint128: UInt128 = 18446744073709551616 // 0~2^128 − 1
let uint256: UInt256 = 18446744073709551616 // 0~2^256 − 1
</code></pre>
<hr />
<h3>任意精度型 (<code>Int</code>/<code>UInt</code>)</h3>
<pre><code class="language-swift">let integer: Int = 1 // 任意精度（理論上無制限 / メモリ依存） / Arbitrary-precision (unbounded)
let uinteger: UInt = 1 // 任意精度（理論上無制限 / メモリ依存） / Arbitrary-precision (unbounded)
</code></pre>
<hr />
<h3><strong>Word型</strong></h3>
<p>オーバーフロー，アンダーフローのチェックを行わない，すなわちラップアラウンドする符号なし整数型は，Wordの接頭辞を持ち，以下の範囲の値を表現することができます。</p>
<pre><code class="language-typescript">let nilWord: Word8? = Word8.fromString("1024") // nil, out of bounds, 0~255
let word16: Word16? = Word16.fromString("255") // 0~65535
let word32: Word32? = Word32.fromString("255") // 0~4294967295
let word64: Word64? = Word64.fromString("255") // 0~18446744073709551615
</code></pre>
<hr />
<h3><strong>Fix / UFix型</strong></h3>
<pre><code class="language-typescript">let fix64: Fix64? = Fix64.fromString("-0.1") // ok, -92233720368.54775808~92233720368.54775807
let ufix64: UFix64? = UFix64.fromString("-0.1") // nil, 0.0~184467440737.09551615
</code></pre>
<hr />
<h3><strong>Address型</strong></h3>
<pre><code class="language-typescript">let some: Address = 0x436164656E636521 // UInt64 length. (Max:18446744073709551615)
</code></pre>
<hr />
<h3><strong>AnyStruct / AnyResource型</strong></h3>
<p><strong>全ての型は AnyStruct 型か AnyResource 型に分類されます。Resource型以外の全ての型をAnyStruct</strong> 型は表現できます。</p>
<pre><code class="language-typescript">var someStruct: AnyStruct = 1 // Resource型以外の全ての型を表現できる
var someResource: @AnyResource &lt;- create TestResource()
</code></pre>
<p>Resourceの型の前には必ず<code>@</code>指示子をつけます。移動には <code>&lt;-</code> 演算子を使います。</p>
<hr />
<h3><strong>Never型</strong></h3>
<pre><code class="language-typescript"> let x: Never = nil
</code></pre>
<p>panic関数の戻り値の型です。</p>
<hr />
<h3><strong>Character / String型</strong></h3>
<pre><code class="language-typescript">let char: Character = "\u{FC}"
let someString: String = "Hello, world!"
</code></pre>
<hr />
<h2>各型の関数</h2>
<h3><strong>数値型・Address型 の関数</strong></h3>
<pre><code class="language-typescript">・数値を文字列に変換する
let int8Number: Int8 = 127
let int8str String = int8Number.toString()


・big-endian の順でバイト配列を返す
let largeNumber: Int32 = 1234567890
let arr: [UInt8] = largeNumber.toBigEndianBytes() //[73, 150, 2, 210]


・文字列を数値に変換する
let int8str: String = "42"
let int8number: Int64? = Int64.fromString(int8str)


・数値の最大値を返す
let max = UInt8.max // 255


・数値の最小値を返す
let min = UInt8.min // 0


・FixedPointNumberを文字列に変換する
let fix64number: Fix64 = 1.23
let fix64str String = fix64number.toString()


・Addressを文字列に変換する
let shortAddress: Address = 0x1
let str: String = shortAddress.toString()  // "0x0000000000000001"


・AddressをUInt8配列に変換する
let someAddress: Address = 0x436164656E636521
someAddress.toBytes()  // is [67, 97, 100, 101, 110, 99, 101, 33]
</code></pre>
<hr />
<h3><strong>String型の関数</strong></h3>
<pre><code class="language-typescript">・文字列の長さを取得する
let example: String = "hello"
let length: Int = example.length // 5


・文字列をUTF8エンコードによるバイト配列に変換する
let str: String = "hello"
let utf8: [UInt8] = str.utf8()


・文字列を結合する
let str1 = "hello"
let str2 = "world"
let helloWorld = str1.concat(str2) // "helloworld"


・文字列の一部を取得する
let example = "helloworld"
let slice = example.slice(from: 3, upTo: 6) // "low"


・文字列を16進文字列で表されるバイト配列に変換する
let example = "436164656e636521"
example.decodeHex() // is [67, 97, 100, 101, 110, 99, 101, 33]


・文字列を小文字に変換する
let example = "Flowers"
example.toLower() // `flowers`


・バイト配列を16進文字列に変換する
let data = [1 as UInt8, 2, 3, 0xCA, 0xDE]
String.encodeHex(data) // is "010203cade"


・文字列から１文字取得する
let str = "abc"
let c: Character = str[0] // is the Character "a"
</code></pre>
<hr />
<h3><strong>Character型の関数</strong></h3>
<pre><code class="language-typescript">・Characterを文字列に変換する
let c: Character = "x"
c.toString()  // is "x"


・Characterの配列を文字列に変換する
let rawUwU: [Character] = ["U", "w", "U"]
let uwu: String = String.fromCharacters(rawUwU) // "UwU" 
</code></pre>
<hr />
<h1>Collection</h1>
<h2>Array型</h2>
<h3>宣言方法</h3>
<p>Contract型の中、Struct型の中、Resource型の中で宣言できます。また、トランザクションコードの中でも宣言できます。スマートコントラクトの中で記載する場合は <code>init</code> による初期化が必要です。</p>
<pre><code class="language-typescript">access(all) contract SampleContract {
    access(contract) var allNames: [String]
    init() {
      self.allNames = []
    }
 }
</code></pre>
<p>Contractも型ですが、この場合デプロイが行われているアドレスも含めて型とみなされます。そのためStructとResourceの型は他のContractの内部の型と混同されることはありません。</p>
<hr />
<h3><strong>Array型の関数</strong></h3>
<pre><code class="language-typescript">・ 配列の長さを取得する
self.allNames.length


・配列を結合する
self.allNames.concat(allNames2)


・配列が値を含むかを判定する
self.allNames.contains("Kitty")


・配列に値を追加する
self.allNames.append("Jane") // This function mutates the array.


・配列に複数の値を追加する
self.allNames.appendAll("Jane", "Daisy") // This function mutates the array.


・配列に値を含む場所のインデックスを取得する
self.allNames.firstIndex(of: "Daisy")


・配列の一部を取得する
self.allNames.slice(from: 1, upTo: 3)


・配列の任意の場所に値を挿入する
self.allNames.insert(at: 2, "Daisy") // This function mutates the array.


・配列から値を取り除く
self.allNames.remove(at: 1) // This function mutates the array.


・配列から最初の値を取り除く
self.allNames.removeFirst() // This function mutates the array.


・配列から最後の値を取り除く
self.allNames.removeLast() // This function mutates the array.
</code></pre>
<hr />
<h2>Dictionary型</h2>
<h3>Dictionaryの宣言方法</h3>
<p>Contract型の中、Struct型の中、Resource型の中で宣言できます。また、トランザクションコードの中でも宣言できます。スマートコントラクトの中で記載する場合は <code>init</code> による初期化が必要です。</p>
<pre><code class="language-typescript">access(all) var luckeyNumbers: {String: Int}
init() {
  self.luckeyNumbers = {}
}
</code></pre>
<p>Struct型の中でselfを参照するとStructの型を、Resource型の中でselfを参照するとResourceの型を、Contractの中でselfを参照するとContractの型をそれぞれselfは表します。</p>
<hr />
<h3><strong>Dictionaryの関数</strong></h3>
<pre><code class="language-typescript">・値を挿入する
self.luckeyNumbers["Daisy"] = 7


・luckeyNumbers に "Daisy" が存在しない場合にエラーを発生させたい場合は、`pre`ブロックを使用することで実現できます
pre {
    self.luckeyNumbers.contains("Daisy"): "Not in luckeyNumbers"
}


・Dictionaryのすべてのキーを取得する
self.luckeyNumbers.keys


・Dictionaryのすべての値を取得する
self.luckeyNumbers.values // このメソッドはリソースを含むDictionaryでは使用できない（リソースは &lt;- オペレーターなしで移動することはできない）


・Dictionaryの任意の場所に値を挿入する
self.luckeyNumbers.insert(key: "Jessica", 42) // 既に値が入っている場合はOptional型でその値を返します。そうでない場合はnilを返します。


・Dictionaryから値を取り出す
self.luckeyNumbers.remove(key: "Joe") // 値が入っている場合はOptional型でその値を返します。そうでない場合はnilを返します。


・Dictionaryが値を含むかを判定する
self.luckeyNumbers.containsKey("Kitty")


・Dictionaryのすべてのキーを繰り返し処理する
self.luckeyNumbers.forEachKey(fun (key: String): Bool {
    // The returned boolean value signals whether to continue
    // true = `continue`
    // false = `break`
    return true
})
</code></pre>
<hr />
<h3><code>pre</code>ブロックと<code>post</code>ブロック</h3>
<p><code>pre{}</code>ブロックはtransactionが実行される前に確認したい検証ロジック、</p>
<p><code>post{}</code>ブロックはブロックチェーンに含まれる直前に取引の有効性を確認したい検証ロジックです。</p>
<p><code>pre</code>ブロックはその名の通り、メソッドの最初で値の有効性を確認するときに使用します。値が有効でない場合パニック(トランザクション失敗)となり、 <code>:</code> 以降の文字列がトランザクション結果出力時に出力されます。</p>
<p><code>post</code>ブロックはその名の通り、メソッドの最後で値の有効性を確認するときに使用します。値が有効でない場合パニック(トランザクション失敗)となり、 <code>:</code> 以降の文字列がトランザクション結果出力時に出力されます。</p>
<p>pre, postはトランザクションコードでも使用でき、トランザクションの処理は<code>prepare</code>ブロック -&gt; <code>pre</code>ブロック -&gt; <code>execute</code>ブロック -&gt; <code>post</code>ブロックの順番に進行します。（基本的に<code>event</code>の宣言以外、スマートコントラクトに書けるものはトランザクションコードでも書けます。）</p>
<hr />
<h3>event</h3>
<p>スマートコントラクトの中に宣言し、トランザクション実行時に呼び出します。スマートコントラクトからでもトランザクションコードからでも呼び出せます。呼び出し時、Event宣言時に指定した型の引数を渡すことができ、それをGo言語やJavascriptで監視することで何が起きているかを知ることができます。Event取得処理はトランザクションIDを元にブロックチェーン情報を取得する処理より少し難易度が高いです。</p>
<hr />
]]></content:encoded></item><item><title><![CDATA[Cadence言語とは]]></title><description><![CDATA[Go言語で書かれたスマートコントラクト用言語です。この言語では変数、Collection型(配列・ディクショナリ)、Struct(構造体)、リソースの4種類しか覚える事はありません。しかし、スマートコントラクトをデプロイしておけば、お金の管理が出来るだけでなく、その情報を更新したり参照することで、無人野菜販売所やライドシェアの金融取引システム等が数十行で書けます。また、ゲーム向けのランキングシステ]]></description><link>https://tech-blog.blsqui.net/cadence</link><guid isPermaLink="true">https://tech-blog.blsqui.net/cadence</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Mon, 10 Aug 2026 04:02:03 GMT</pubDate><content:encoded><![CDATA[<hr />
<p>Go言語で書かれたスマートコントラクト用言語です。この言語では変数、Collection型(配列・ディクショナリ)、Struct(構造体)、リソースの4種類しか覚える事はありません。しかし、スマートコントラクトをデプロイしておけば、お金の管理が出来るだけでなく、その情報を更新したり参照することで、無人野菜販売所やライドシェアの金融取引システム等が数十行で書けます。また、ゲーム向けのランキングシステムなんかも数十行で書けます。</p>
<hr />
<p>Cadence言語はよくResource Oriented (リソース指向)言語と呼ばれます。リソースを持っている人はそのリソースの内部メソッドを実行することができ、リソースの持ち主はそのリソースをブロックチェーン内部のストレージに保存します。</p>
<hr />
<p>リソース以外 (変数 / 配列・ディクショナリ / 構造体) は物理的に移動しないので特定のアカウントストレージに保存することはしません。そして誰でも共通にアクセスすることができます。リソースは基本的にその所有者しか内部メソッドを呼び出せないことからスマートコントラクトの中心的役割を担うことになり、所有者のストレージに保管されます。</p>
<hr />
<p>スマートコントラクトを見るとよく以下のような形が見られます。</p>
<pre><code class="language-swift">contract A {

  access(all) resource  B {
    access(all) fun setRankingAndDeliverPrize() {
    }
  }

  init {
    self.account.storage.save(&lt;- new B(), to: /storage/B)
  }
}
</code></pre>
<p>スマートコントラクトのデプロイ者はスマートコントラクトの中では<code>self.account</code>と表現されます。そして<code>init</code>はスマートコントラクトのデプロイ時の一回しか実行されないため、システム上重要なリソースをひとつしか生成したくない場合にこのようなコードが書かれます。上記だとBリソースはスマートコントラクトのデプロイ者だけが所有できることになります。そしてそのアカウントだけがスマートコントラクトのsetRankingAndDeliverPrize メソッドを実行できます。このブロックチェーン(Flow)では予約実行が可能なので、一週間おきにランキングを再計算し、上位3チームに賞金を配布する、といった公正な自動運用が可能となります。</p>
<hr />
<h3>Regarding the deep technical relationship between the Flow team (Dapper Labs) and the original Diem/Libra team at Meta:</h3>
<h3>Move &amp; Cadence Shared Roots</h3>
<p>While Flow and Libra/Diem were developed in parallel, the Dapper Labs team and Meta's crypto research team collaborated extensively through technical working groups in the 2018–2020 era.</p>
<p>Both teams shared the same fundamental thesis: <strong>existing blockchains (like Ethereum's EVM) were structurally unsafe and poorly suited for mainstream consumer applications and NFTs.</strong></p>
<ol>
<li><p><strong>Resource-Oriented Architecture:</strong> Meta created the <strong>Move</strong> language for Libra, while Dapper Labs created <strong>Cadence</strong> for Flow. Both languages adopted the "Resource-Oriented Programming" paradigm—a concept originally inspired by Rust's linear type system where digital assets are treated as physical objects in memory that cannot be duplicated, implicit-dropped, or re-entered.</p>
</li>
<li><p><strong>Technical Exchange:</strong> Engineers from Dapper Labs and Meta regularly cross-pollinated ideas regarding resource safety, access control capabilities, and account abstractions during the initial design phases of both languages.</p>
</li>
</ol>
<h3>Why Instagram Supported Flow at NFT Feature Launch</h3>
<p>When Meta launched its native NFT and digital collectibles feature on Instagram in May 2022, <strong>Flow was chosen as one of the primary launch blockchains</strong> alongside Ethereum and Polygon.</p>
<p>This choice was directly tied to those technical roots and operational history:</p>
<ul>
<li><p><strong>Mass-Consumer Scaling:</strong> Flow was designed specifically for high-throughput consumer apps (like <em>NBA Top Shot</em>), making it a natural fit for Instagram's massive user base without exposing users to high gas fees or network congestion.</p>
</li>
<li><p><strong>Shared Developer Philosophy:</strong> Because Meta's internal crypto teams were already intimately familiar with Cadence's resource model and Flow's account architecture through their earlier Libra-era working groups, integrating Flow into Instagram's backend infrastructure was smooth and architecturally aligned with Meta's standards.</p>
</li>
</ul>
<hr />
<p>Flow TeamはMeta（メタ）のLibra (後年、Diemと改称) 財団とワーキンググループを頻繁に開催していました。それは共通の既存ブロックチェーンに対する問題意識があったからでした。ただ、NFTブームを引き起こしたのはMetaの開発チームではなくFlowチームの方でした。人間工学的にRustより優れたGo言語で書かれていたCadenceスマートコントラクト言語は書くのが簡単で覚えやすく、プログラムを書くのが楽しい、という特徴があります。</p>
<hr />
<h3>Why Resource-Oriented Programming Prevents Exploits at Compile Time</h3>
<p>Ethereum（EVM）などの従来のスマートコントラクトでは、トークンを送金する際は、コントラクト内の残高テーブルを更新する処理（<code>balances[from] -= amount; balances[to] += amount</code>）を行います。しかし、この構造はリエントラント攻撃（再入攻撃）や不正な書き換え、権限チェック漏れなど、バグや資産紛失を引き起こす最大の要因となっていました。Flowの<strong>Cadence</strong>は、これを「リソース指向プログラミング (Resource-Oriented Programming)」によって根本から解決しました。</p>
<h3>Cadenceにおける3つの技術的柱</h3>
<h4><strong>1. 線形型システムと「実体」としてのデジタル資産</strong></h4>
<p>Cadenceにおける「リソース」は、Rustの線形型システムに着想を得た実体オブジェクトです。</p>
<ul>
<li><p>複製（コピー）の不可: コピー処理はコンパイルエラーになります。</p>
</li>
<li><p>暗黙の破棄の不可: 生成されたリソースは、アカウントのストレージに保存されるか、<code>destroy</code> キーワードで明示的に破棄されない限りコンパイルが通りません。</p>
</li>
<li><p>常に空間上に1つしか存在しない: ダブルスペンディングが物理的に不可能な設計</p>
</li>
</ul>
<pre><code class="language-swift">// リソース（SomeResource）の定義
access(all) resource SomeResource {
    access(all) let id: UInt64
    init(id: UInt64) {
        self.id = id
    }
}

// リソースの生成とアカウントへの移動
access(all) fun mintAndStore(account: &amp;Account) {
    // 代入 '=' ではなく、移動演算子 '&lt;-' を使用
    let newNFT &lt;- create SomeResource(id: 1001)
    
    // リソースをストレージに移動させないとコンパイルエラーが発生する
    account.storage.save(&lt;-newNFT, to: /storage/SomeResource)
}
</code></pre>
<h4><strong>2. 移動演算子 (</strong><code>&lt;-</code><strong>) による明確な視覚化</strong></h4>
<p>資産の上書き事故を防ぐため、通常の代入演算子 <code>=</code> ではなく、専用の移動演算子 <code>&lt;-</code> を使用します。これにより、コード上で「資産の所有権がどこからどこへ移動したか」が一目で判別できます。</p>
<h4>3. ケーパビリティ（Capability）ベースのアクセス制御</h4>
<p>Solidityのように実行時に <code>msg.sender == owner</code> などの権限チェック（ヒューマンエラーの温床）を行うのではなく、CadenceではCapability（操作権限への参照）を発行します。「閲覧のみ」「受領のみ」といった最小限のアクセス権限を第三者に安全に委任できます。</p>
<hr />
<p>言語としてはSwiftに似ています。Crypto Kitties作者が元AppleでKeynoteを2010年ごろ開発していたエンジニアであったため、Appleの開発した情報と親和性が非常にあります。</p>
<p>１枚のプログラミングコードにお金の計算、ランキングなどゲーム情報の管理、資産の分配などを全て書くことができます。それも<strong>Resourceをselfに対して登録しておくだけ</strong>でバックエンドから自由にこれらの処理を行うことができます。</p>
]]></content:encoded></item><item><title><![CDATA[Q. なぜあなたはスマートコントラクトを書く必要があるのか]]></title><description><![CDATA[これは日本らしさとメタバースについての考察です。
日本らしさには、えっこんな方法があったの？というちょっと裏ワザっぽいけど丁寧に作り込まれた奥の深さと、誰も見放さない万人に優しく接する設計が伺えます。
前者には才能が必要ですが、何故か日本の作品はこれができるものが多いですね。
というのが日本らしさの特徴ですが、メタバースのゲームには没入感を売りにしたものであっても(金銭面の臭いがする独特の雰囲気も]]></description><link>https://tech-blog.blsqui.net/q</link><guid isPermaLink="true">https://tech-blog.blsqui.net/q</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Sat, 08 Aug 2026 04:51:53 GMT</pubDate><content:encoded><![CDATA[<p>これは<strong>日本らしさ</strong>と<strong>メタバース</strong>についての考察です。</p>
<p><strong>日本らしさ</strong>には、えっこんな方法があったの？というちょっと裏ワザっぽいけど丁寧に作り込まれた奥の深さと、誰も見放さない万人に優しく接する設計が伺えます。</p>
<p>前者には才能が必要ですが、何故か日本の作品はこれができるものが多いですね。</p>
<p>というのが日本らしさの特徴ですが、メタバースのゲームには没入感を売りにしたものであっても(金銭面の臭いがする独特の雰囲気もあります)、なかなか日本人で新規でやろうとする人は少ないように感じます。</p>
<hr />
<p>メタバースという言葉自体海外から来たものだし、RPGが日本では伝統的に強く、メタバースの面白さがいまいち伝わって来ません。でも伝わってこないだけで、海外では<strong>マインクラフト</strong>が大人気なように、没入感があるゲームが大好きです。</p>
<p>日本人はRPG以外を食わず嫌いしているだけです。メタバースゲームでRPGをやってみるのも面白いかも知れませんが、ここは海外で流行っているなら日本らしさを組み合わせたらウケるかもしれない、と考える方がしっくり来ます。</p>
<p>ここでもう一度、日本らしさの定義を。「えっこんな方法があったの？というちょっと裏ワザっぽいけど丁寧に作り込まれた奥の深さ」です。これはアニメのフリーレンとか見ていると同感していただけると思います。</p>
<p>実はこれ、没入感そのものですよね？ポケモンの絶妙な難易度設定、例えばタケシ戦のイワークとか洞窟の攻略とかすごい没入感があります。</p>
<hr />
<h3>考察</h3>
<p>でもフリーレンを見ていたら人気の秘訣は「万人受け」も重要な要素だな、と感じます。子供が気に入らないものは作らない、という徹底した万人受けを日本発の作品は狙っています。</p>
<p><strong>メタバース</strong>と言えば<strong>大人</strong>ばっかりが注目しますが、大人向けだとそれはもう日本らしさではなくなってしまうんですよね。</p>
<p>日本人は<strong>メタバース</strong>という言葉に惑わされている気がします。日本らしさを素で出せればそこには没入感が出来ます。</p>
<p>やはりここは日本の考えと海外の大人気ぶりを融合させるべきだと思います。</p>
<hr />
<h3>Q. そこでBlsquiは何をできるのか？</h3>
<p>**A. まず第一に言いたいのは、真正さを出せる事です。**例えばランキングです。スマートコントラクトではチート行為が出来ません。ブロックチェーンのスマートコントラクトは世界で同じものが使われます。チートのないランキングを誰でも作れますし、イカサマや海賊版は一気にその地位を失います。</p>
<p>Blsquiなら<strong>eスポーツウォレット</strong>だからゲームのブリーフィング機能があり、没入感を出せます。スマートコントラクトもMPCでワンクリックでデプロイできます。これは心強いはずです。</p>
<h3>Q. Blsquiで没入感を出せる機能は？</h3>
<p>**A. 日本人が作った、Flow初の MPC&amp;FLIX ウォレットです。**ドキドキを与える機能と誰でも使える操作性が特徴です。万人受け=安全さを最優先にした信じられないくらいの量の、安全設計を組み合わせています。他にはハンヅオン(**Plug-And-Play)**でプレイヤー同士でアイテムを交換したり、アイテムを売ってポイントや現金を獲得したりすることができます。</p>
<p><strong>でも一番大事なのはスマートコントラクトを書くのが楽しい</strong>、ということです。今AIのおかげで全てのプログラムはAIが作れます。ですが、<strong>メタバースのスマートコントラクト</strong>は今あなたが書けばきっとAIが驚嘆します。AIが知らないことを作っていることになるのですから。</p>
<p>実際、Blsquiを作ってる時は楽しかったですよ。AIが知らないことを作っていく感じがずっとしてて。最近では<strong>Unreal Engineのゲーム</strong>にLocal Loopbackで<strong>ブロックチェーンの機能</strong>を組み込むっていうのが今のAIでは考えつかないものらしいです。ブロックチェーンはまだまだ固定観念が強力です。そこをスマートコントラクトを書いて世界を驚かすのはアリだと思います。</p>
<p>スマートコントラクトを書くのはいかに楽しいか、それは自分オリジナルのメタバース作品を生み出せる新規性にあります。あなたもスマートコントラクトを書いてみませんか？</p>
<p><a href="https://blsqui.net/technical-docs/creators-four-pillars#smart-contract">https://blsqui.net/technical-docs/creators-four-pillars#smart-contract</a></p>
]]></content:encoded></item><item><title><![CDATA[Q. FLIXとは何か？]]></title><description><![CDATA[A. FLIXとはBlsquiウォレットがコア機能として採用したシステムです。トランザクションコードとメタ情報がセットとして組み合わせられます。本格採用したのはBlsquiが最初です。
この情報をnpmでインストールしたFCL(Flow Client)に渡すと、トランザクションが実行できます。非常に簡単です。
トランザクションはスマートコントラクトのデータ書き換えや、ウォレット間で"もの"を移動さ]]></description><link>https://tech-blog.blsqui.net/q-flix</link><guid isPermaLink="true">https://tech-blog.blsqui.net/q-flix</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Fri, 07 Aug 2026 06:35:22 GMT</pubDate><content:encoded><![CDATA[<p>A. FLIXとはBlsquiウォレットがコア機能として採用したシステムです。トランザクションコードとメタ情報がセットとして組み合わせられます。本格採用したのはBlsquiが最初です。</p>
<p>この情報をnpmでインストールしたFCL(Flow Client)に渡すと、トランザクションが実行できます。非常に簡単です。</p>
<p>トランザクションはスマートコントラクトのデータ書き換えや、ウォレット間で"もの"を移動させるといったことができます。</p>
<p>FCLに渡したFLIX情報はウォレットが受け取ります。ウォレットはそのFLIXが正規のものか徹底的に検証した後、ウォレットが持つ署名用の鍵で署名します。（俗にいう秘密鍵。当社は多層構造です）署名済みの封筒をFCLに返してトランザクション実行となります。</p>
<p>とまぁ、Web3とだけ聞くと軽く聞こえますが、内部は非常に最新技術です。</p>
<p>トランザクションは色々なことができます。お金を引き出したり、考え次第で無限に色々なことができます。ですが一つのスマートコントラクトで採用しているトランザクションはせいぜい3〜５つぐらいまでです。ゲームであればそれが常に実行されるわけです。引数はまた別で、本体となるコードはほぼ固定されます。</p>
<p>BlsquiはこのコードをID管理し、そのIDを他のトランザクションコードに埋め込むことも可能です。スマートコントラクトがBlsquiTerminalというコントラクトをインポートしていれば、ウォレット間の移動はBlsqui TerminalがそのFLIX IDを実行することで代わりに行えます。</p>
<p>ウォレットに保存させた”もの”の中にFLIXという名のトランザクションコードが埋め込まれている感じです。その”もの”はBlsqui Terminalの中でカード形式で表示されます。</p>
<p>これで何ができるのか。</p>
<p>まず、スマートコントラクトを１クリックでデプロイできます。（デプロイもスマートコントラクトが引数で、コードは定型のコードだからです）</p>
<p>今、カブトムシがブームですよね？例えば「ムシバトル」というゲームを例にします。</p>
<p>カブトムシやクワガタを戦わせるゲームをUnreal Engineで作ります。そこでBlsqui SDKにFLIX IDを渡してLocal Loopbackで勝者に署名を実行してもらいます。</p>
<p>Blsquiターミナルでは勝利して獲得したクワガタカードが表示されます。それはBlsqui Terminal上で知り合い（仲間）にあげる（Transfer）ことができます。ゲームはその処理をする必要がありません。Blsquiが代わりにFLIXを実行します。</p>
<p>これがBlsqui eスポーツウォレットのコア機能、FLIXです。</p>
<p>ですが、最初書いた通り、FCLを使用します。BlsquiはFLIXを本格採用した初のウォレットですので、スポンサーを募集しています。私どもだけでFlow財団と渡り歩くのはちょっと心細いためです。スポンサーを急募しています。LinkedInのメッセージからでも構いません、お待ちしています。</p>
<p>また、賞品の贈与にも使えます。BlsquiTerminalコントラクトには売り戻し用のFLIX IDも埋め込むことができます。プレイヤーは好きな時にそれをポイントステーブルコインにBlsqui Terminal上で換金することができます。</p>
<p>最後はちょっとパチンコみたいな3点方式みたいになりましたが、eスポーツというのは勝利＝当事者の実力なので、法律で定められている賭け事の定義には当てはまりません。（当事者がその実力を持って獲得した場合賭け事とみなさない、と明文化されています。）本来は購入したアイテムを売ることを目的にしたRPGゲーム用に考えたFLIXですから何割で売れるかはスマートコントラクトを開発する側で設定します。当社は実行の代行だけです。</p>
]]></content:encoded></item><item><title><![CDATA[RideShare Smart Contract の作り方]]></title><description><![CDATA[ドライバーの受注管理と、乗客の発注機能をスマートコントラクトに組み込みます。


スマートコントラクトはこちら
import "FlowToken"
import "FungibleToken"

access(all) contract RideShare {

  access(self) let FlowTokenVault: Capability<&{FungibleToken.Recei]]></description><link>https://tech-blog.blsqui.net/rideshare-smart-contract</link><guid isPermaLink="true">https://tech-blog.blsqui.net/rideshare-smart-contract</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Thu, 06 Aug 2026 02:06:02 GMT</pubDate><content:encoded><![CDATA[<p>ドライバーの受注管理と、乗客の発注機能をスマートコントラクトに組み込みます。</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a54b7c15c0c654db32e149a/c3cef27e-cf3c-49a0-bff6-ea0557b63153.png" alt="" style="display:block;margin:0 auto" />

<p>スマートコントラクトはこちら</p>
<pre><code class="language-swift">import "FlowToken"
import "FungibleToken"

access(all) contract RideShare {

  access(self) let FlowTokenVault: Capability&lt;&amp;{FungibleToken.Receiver}&gt;
  access(self) let DriverFlowTokenVault: {UInt: Capability&lt;&amp;{FungibleToken.Receiver}&gt;}
  access(self) let info: Info
  access(self) var totalDrivers: UInt // Driver ID

  /* 構造体 */
  access(all) struct Info {

    access(contract) var driverData: {UInt: DriverData}
    access(contract) var orderQueue: [Order]

    /* setter */
    access(contract) fun setDriver(id: UInt, keys: [String], values: [String]): UInt {
      if let saved = self.driverData[id] {
        for index, key in keys {
          saved.set(key: key, value: values[index])
        }
        self.driverData[id] = saved // 更新
        return id
      } else {
        // 新規登録
        RideShare.totalDrivers = RideShare.totalDrivers + 1
        var data = DriverData()
        for index, key in keys {
          data.set(key: key, value: values[index])
        }
        self.driverData[RideShare.totalDrivers] = data
        return RideShare.totalDrivers
      }
    }

    access(contract) fun setOrder(execTime: UFix64, driverId: UInt, start: String, goal: String, wage: UFix64) {
      var order = Order(execTime: execTime, driverId: driverId, start: start, goal: goal, wage: wage)
      self.orderQueue.append(order)
      
    }

    init() {
      self.driverData = {}
      self.orderQueue = []
    }
  }


  /* Info内の構造体 */
  access(all) struct DriverData {

    access(contract) var data: {String: String}

    /* setter */
    access(contract) fun set(key: String, value: String) {
      self.data[key] = value
    }

    init() {
      self.data = {}
    }
  }

  /* Info内の構造体 */
  access(all) struct Order {

    access(all) let execTime: UFix64
    access(all) let driverId: UInt
    access(all) let start: String
    access(all) let goal: String
    access(all) let wage: UFix64

    init(execTime: UFix64, driverId: UInt, start: String, goal: String, wage: UFix64) {
      self.execTime = execTime
      self.driverId = driverId
      self.start = start
      self.goal = goal
      self.wage = wage
    }
  }

  // GET
  access(all) fun getInfo(): Info {
    return self.info
  }
  // PUT
  access(all) fun setDriverInfo(driverId: UInt, keys: [String], values: [String], flow_vault_receiver: Capability&lt;&amp;{FungibleToken.Receiver}&gt;?) {
    let _driverId = RideShare.info.setDriver(id: driverId, keys: keys, values: values)
    if (flow_vault_receiver != nil) {
      RideShare.DriverFlowTokenVault[_driverId] = flow_vault_receiver
    }
  }

  // PUT
  access(all) fun newOrder(payment: @FlowToken.Vault, execTime: UFix64, driverId: UInt, start: String, goal: String) {
    self.info.setOrder(execTime: execTime, driverId: driverId, start: start, goal: goal, wage: payment.balance * 0.97)
    self.FlowTokenVault.borrow()!.deposit(from: &lt;- payment)
  }

  access(all) resource Admin {
    // ORDER COMPLETE
    access(all) fun payWage(driverId: UInt, wage: UFix64) {
      pre {
        RideShare.DriverFlowTokenVault[driverId] != nil: "Deposit destination is nil, so we can't send wage."
      }
      // Pay the wage.
      let wage &lt;- RideShare.account.storage.borrow&lt;auth(FungibleToken.Withdraw) &amp;{FungibleToken.Provider}&gt;(from: /storage/flowTokenVault)!.withdraw(amount: wage) as! @FlowToken.Vault
      RideShare.DriverFlowTokenVault[driverId]!.borrow()!.deposit(from: &lt;- wage)
    }
  }

  init() {
    self.info = Info()
    self.FlowTokenVault = self.account.capabilities.get&lt;&amp;{FungibleToken.Receiver}&gt;(/public/flowTokenReceiver)
    self.DriverFlowTokenVault = {}
    self.totalDrivers = 0
    self.account.storage.save( &lt;- create Admin(), to: /storage/RideShareAdmin)
  }
}
</code></pre>
<p>ここでリソース(resource)が初登場します。<code>access(all) resource Admin {</code></p>
<p>専売的にスマートコントラクトが持っているメソッドでトランザクションを実行する為には、リソースが不可欠だからです。誰でもシステム運営者の所持金を送金できたら、資金が盗難されて困るからです。</p>
<p>スマートコントラクトをデプロイする時（<code>init</code>）にデプロイアカウントに対してAdminというResourceを持たせています。<code>self.account.storage.save( &lt;- create Admin(), to: /storage/RideShareAdmin)</code></p>
<p>スマートコントラクトのリソースに定義されたメソッドはそのリソースの持ち主にしか呼び出せません。このリソースがドライバーに対して賃金を支払う役割を果たします。（バックエンドで秘密鍵を保持していればバックエンドサーバーが自動でこれを行えます。つまりリソースの保持者かどうかは<strong>秘密鍵があっているかどうか</strong>で判定します。SSHログインと同じですね。そのため、秘密鍵が１箇所に集約されていないBlsquiはゲームユーザーの権利を守る上で強固なんですね。）</p>
<p>さぁ、あとはスマートコントラクト内部のメソッドを呼ぶ実装をするだけです。</p>
<hr />
<h3>structとresourceの違い</h3>
<p><strong>struct:</strong></p>
<ul>
<li><p>静的変数のNoSQL、但し厳格に型を定める</p>
</li>
<li><p>宣言時はaccess(all)であり、構造体の型は公開される</p>
</li>
<li><p>init以外での値の書き換えにはsetterが必要</p>
</li>
</ul>
<p><strong>resource:</strong></p>
<ul>
<li><p>クラスオブジェクトに近い</p>
</li>
<li><p>ポインタの概念を持つ</p>
</li>
<li><p>宣言時はaccess(all)でありクラスの型は公開される</p>
</li>
<li><p>create演算子でオブジェクトを生成し、オブジェクトはストレージに保存される</p>
</li>
<li><p>cpu消費を避ける為、基本的にポインタを通じてresourceのメソッドを呼ぶ</p>
</li>
<li><p>動くことができ、ストレージ間を移動する(=所有できる)</p>
</li>
</ul>
<hr />
<h3><strong>注文読み取り</strong></h3>
<ul>
<li>スマートコントラクトの構造体の情報を取得します。</li>
</ul>
<pre><code class="language-javascript">import { query } from "@onflow/fcl";

export const getRideShareInfo = async function () {
  const result = await query({
    cadence: `
        import "RideShare"

        access(all) fun main(): RideShare.Info? {
            return RideShare.getInfo()
        }
    `,
    args: (arg, t) =&gt; [],
  });
  return result;
};
</code></pre>
<hr />
<ul>
<li>複数のアカウントの所持金を取得する</li>
</ul>
<pre><code class="language-javascript">export const getBalances = async function (address) {
    let driverAddress;
    if (import.meta.env &amp;&amp; import.meta.env.VITE_DRIVER_ADDRESS) {
        driverAddress = import.meta.env.VITE_DRIVER_ADDRESS;
   }
    const systemAddress = "0xb576a3926d239682";
    const result = await query({
        cadence: `
            import "FlowToken"
            import "FungibleToken"
            access(all) fun main(
                address: Address,
                driverAddress: Address,
                systemAddress: Address
            ): [UFix64] {

                let vaultRef = getAccount(address)
                    .capabilities
                    .borrow&lt;&amp;FlowToken.Vault&gt;(/public/flowTokenBalance)
                    ?? panic("Something wrong happened.")
                let driverVaultRef = getAccount(driverAddress)
                    .capabilities
                    .borrow&lt;&amp;FlowToken.Vault&gt;(/public/flowTokenBalance)
                    ?? panic("Something wrong happened.")
                let systemVaultRef = getAccount(systemAddress)
                    .capabilities
                    .borrow&lt;&amp;FlowToken.Vault&gt;(/public/flowTokenBalance)
                    ?? panic("Something wrong happened.")

                var addresses: [UFix64] = []
                addresses.append(vaultRef.balance)
                addresses.append(driverVaultRef.balance)
                addresses.append(systemVaultRef.balance)
                return addresses
            }
        `,
        args: (arg, t) =&gt; [
            arg(address, t.Address),
            arg(driverAddress, t.Address),
            arg(systemAddress, t.Address),
        ],
    });
    return result;
};
</code></pre>
<p>RideShareスマートコントラクト内に登録ドライバー全員のアドレスを保存しておくことで、クエリー時にドライバー全員のアドレスを取得することで、ドライバー全員の所持金を一度に取得することも可能です。</p>
<hr />
<h3><strong>トランザクションの送信</strong></h3>
<ul>
<li>クリプトによる支払い（リソースのストレージ移動はアプリ利用者による署名が必要な処理です）</li>
</ul>
<pre><code class="language-javascript">import { mutate, authz } from "@onflow/fcl";

const formatUFix64 = (num) =&gt; Number(num).toFixed(8);

export const newOrder = async function (
    execDateTime,
    driverId,
    start,
    goal,
    price
) {
    const txId = await mutate({
        cadence: `
            import "RideShare"
            import "FlowToken"
            import "FungibleToken"

            transaction(
                execTime: UFix64,
                driverId: UInt,
                start: String,
                goal: String,
                price: UFix64
            ) {
                prepare(signer: auth(BorrowValue) &amp;Account) {
                    let payment &lt;- signer
                        .storage
                        .borrow&lt;auth(FungibleToken.Withdraw) &amp;FlowToken.Vault&gt;(from: /storage/flowTokenVault)!
                        .withdraw(amount: price) as! @FlowToken.Vault

                    RideShare.newOrder(
                        payment: &lt;- payment, // リソースを移動する時は &lt;- (Linear Types記号)を使用
                        execTime: execTime,
                        driverId: driverId,
                        start: start,
                        goal: goal
                    )
                }
                execute {
               }
            }
        `,
    args: (arg, t) =&gt; [
            arg(formatUFix64(new Date(execDateTime).getTime() / 1000), t.UFix64),
            arg(driverId, t.UInt),
            arg(start, t.String),
            arg(goal, t.String),
            arg(formatUFix64(price), t.UFix64),
        ],

        proposer: authz,
        payer: authz,
        authorizations: [authz],
        limit: 999,
    });
    console.log(txId);
    return txId;
};
</code></pre>
<p>このjavascriptメソッドを呼び出すことでRideShareサービスに注文を発行し、同時に支払われたクリプトは一時的にシステムアカウントが受け取ります。注文が実行された時,ドライバーにその内の97%を支払います。3%は支払いマージンとして利益とします。</p>
<p>トランザクションのprepareメソッドはexecuteメソッドと違い、引数にsigner(署名者アカウントのオブジェクト)が入ります。そのためsignerが必要な処理はprepareメソッド内に書きます。</p>
<p>transactionメソッドにはprepare, execute以外にもpreとpostが存在し、トランザクションの処理はprepare -&gt; pre -&gt; execute -&gt; postの順番に進行します。</p>
<hr />
<ul>
<li>ドライバーを登録する処理 (秘密鍵をバックエンドで保持していればバックエンドで実行可能)</li>
</ul>
<pre><code class="language-swift">import RideShare from 0xb576a3926d239682
import FlowToken from 0x1654653399040a61
import FungibleToken from 0xf233dcee88fe0abe

transaction(driverId: UInt, driverAddress: Address, keys: [String], values: [String]) {
    prepare() {
        let FlowTokenReceiver = getAccount(driverAddress)
            .capabilities
            .get&lt;&amp;{FungibleToken.Receiver}&gt;(/public/flowTokenReceiver)

        RideShare.setDriverInfo(driverId: driverId, keys: keys, values: values, 
            flow_vault_receiver: FlowTokenReceiver)
    }
    execute {
        log("success")
    }
}
</code></pre>
<hr />
<ul>
<li>ドライバーに報酬を支払う処理</li>
</ul>
<pre><code class="language-javascript">const transaction = `

    import RideShare from 0xb576a3926d239682

    transaction(driverId: UInt, wage: UFix64) {
        prepare(signer: auth(BorrowValue) &amp;Account) {
            let RideShareAdmin = signer
                .storage
                .borrow&lt;&amp;RideShare.Admin&gt;(from: /storage/RideShareAdmin)
                ?? panic("Could not borrow reference to the Administrator Resource.")

            RideShareAdmin.payWage(driverId: driverId, wage: wage)
        }
        execute {
        }
    }
`;
</code></pre>
<p>ドライバーに報酬を支払う事はシステムによる特権なので、Adminリソースがその役割を果たします。</p>
<p>こういったシステムはバックエンドで秘密鍵を保持しておくのが通常なので、以下のようなコードで承認関数(<code>authFunction</code>と<code>authFunctionForProposer</code>)を自作して自動実行します。</p>
<pre><code class="language-javascript">import { config, sansPrefix, withPrefix, mutate, tx } from "@onflow/fcl";


txId = await mutate({
      cadence: transaction,
      args: (arg, t) =&gt; [
          arg(message.driverId, t.UInt),
          arg(message.wage, t.UFix64),
      ],
      proposer: authFunctionForProposer,
      payer: authFunction,
      authorizations: [authFunction],
      limit: 999,
});
console.log(`txId: ${txId}`);

tx(txId).subscribe((res) =&gt; {
    console.log(res);
});
</code></pre>
<p>これはNode.jsによる実行ですが、Go言語でもできます。(FlowとCadenceはGoで書かれているので親和性も高いです)</p>
<p>トランザクション承認を担う関数は少し長いですがこのようになります。</p>
<pre><code class="language-javascript">try {

    var IT_KEY_ID = 0;
    if (fs.existsSync('/tmp/sequence.txt')) {
        IT_KEY_ID = parseInt(fs.readFileSync('/tmp/sequence.txt', { encoding: 'utf8' }));
    } else {
        IT_KEY_ID = 10;
    }
    IT_KEY_ID = !IT_KEY_ID || IT_KEY_ID &gt;= 10 ? 0 : IT_KEY_ID + 1;
    fs.writeFileSync('/tmp/sequence.txt', IT_KEY_ID.toString());

    console.log('IT_KEY_ID', IT_KEY_ID);

    // CHANGE THESE THINGS FOR YOU
    const PRIVATE_KEY = fs.readFileSync('testnet-account.pkey', { encoding: 'utf8' });
    const ADDRESS = '0x975b04756864e9ea';
    const KEY_ID = 0;

    const hash = (message) =&gt; {
        const sha = new SHA3(256);
        sha.update(Buffer.from(message, 'hex'));
        return sha.digest();
    };

    const sign = (message) =&gt; {
        const key = ec.keyFromPrivate(Buffer.from(PRIVATE_KEY, 'hex'));
        const sig = key.sign(hash(message)); // hashMsgHex -&gt; hash
        const n = 32;
        const r = sig.r.toArrayLike(Buffer, 'be', n);
        const s = sig.s.toArrayLike(Buffer, 'be', n);
        return Buffer.concat([r, s]).toString('hex');
    };

    async function authFunction(account) {
        return {
            ...account,
            tempId: `${ADDRESS}-${KEY_ID}`,
            addr: sansPrefix(ADDRESS),
            keyId: Number(KEY_ID),
            signingFunction: async (signable) =&gt; {
                return {
                    addr: withPrefix(ADDRESS),
                    keyId: Number(KEY_ID),
                    signature: sign(signable.message)
                };
            }
        };
    }
    async function authFunctionForProposer(account) {
        return {
            ...account,
            tempId: `${ADDRESS}-${IT_KEY_ID}`,
            addr: sansPrefix(ADDRESS),
            keyId: Number(IT_KEY_ID),
            signingFunction: async (signable) =&gt; {
                return {
                    addr: withPrefix(ADDRESS),
                    keyId: Number(IT_KEY_ID),
                    signature: sign(signable.message)
                };
            }
        };
    }
</code></pre>
<p><code>IT_KEY_ID = !IT_KEY_ID || IT_KEY_ID &gt;= 10 ? 0 : IT_KEY_ID + 1;</code>は何をしているかというと、バックエンドでは連続でトランザクションを実行することになると思いますが、ブロックチェーン側は連続処理に対し、KEY_IDの変更を求めてきます。（リプレイアタックの防止）</p>
<pre><code class="language-javascript">txId = await mutate({
   cadence: transaction,
   args: (arg, t) =&gt; [arg(gamerId, t.UInt), arg(outcome, t.Bool)],
   proposer: authFunctionForProposer, // キーをサイクルする承認関数
   payer: authFunction,               // キーをサイクルしない承認関数
   authorizations: [authFunction],    // キーをサイクルしない承認関数
   limit: 999,
});
</code></pre>
<p>(サンプルコードは<a href="https://github.com/temt-ceo/oraga-esports/blob/main/aws_lambda/mainnet/src/index.mjs#L174">こちら</a>にあります。)</p>
<p>これで<strong>ドライバーが売り上げの97%を取得できるアプリ</strong>が明日からでも運用できます。</p>
]]></content:encoded></item><item><title><![CDATA[VegeSeller Smart Contract の作り方]]></title><description><![CDATA[Cadence言語は思いついた事をなんでも実現できると断言できます。システムに平等さを組み込むことができます。
ブロックチェーンの情報はjavascript があれば取得できます。今、どんな組み込みソフトウェアでもWebKitは使えるはずですので、つまり、全ての機器はブロックチェーンから情報を取得することができます。


今から、この画像にあるような無人野菜販売所のアプリを作ります。
(無人野菜販]]></description><link>https://tech-blog.blsqui.net/vegeseller-smart-contract</link><guid isPermaLink="true">https://tech-blog.blsqui.net/vegeseller-smart-contract</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Wed, 05 Aug 2026 06:13:06 GMT</pubDate><content:encoded><![CDATA[<p>Cadence言語は思いついた事をなんでも実現できると断言できます。システムに平等さを組み込むことができます。</p>
<p>ブロックチェーンの情報はjavascript があれば取得できます。今、どんな組み込みソフトウェアでもWebKitは使えるはずですので、つまり、全ての機器はブロックチェーンから情報を取得することができます。</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a54b7c15c0c654db32e149a/cd7f3d09-3e0e-4aaa-a28c-a0769e1a929b.png" alt="" style="display:block;margin:0 auto" />

<p>今から、この画像にあるような無人野菜販売所のアプリを作ります。</p>
<p>(無人野菜販売所に立てかけたQRコードで支払ってもらう購入手数料が0のシステムです)</p>
<hr />
<p>ではスマートコントラクトから見ていきましょう。ベースはCookStockerスマートコントラクトで、違うところは在庫の概念を追加したこととお金を徴収できるようにしたところです。差分は以下です。</p>
<pre><code class="language-swift">import "FlowToken"
import "FungibleToken"

access(all) contract VegeSeller {

   access(self) let FlowTokenVault: Capability&lt;&amp;{FungibleToken.Receiver}&gt;
</code></pre>
<p>まず、お金を徴収できるコントラクト（FlowTokenとFungibleToken）をインポートします。</p>
<p>本当は入金先を生産者別に用意すべきですが、ここではとりあえずこのコントラクトをデプロイしているアカウントに全ての代金を入金させます。</p>
<hr />
<pre><code class="language-swift">/* setter */
access(contract) fun set(id: String, add: [String], addAmount: [UInt8], remove: [String]) {
    if let saved = self.data[id] {
        for index, name in add {
            saved.set(category: name, amount: addAmount[index])
        }
        for name in remove {
            saved.unset(category: name)
        }
        // Save
        self.data[id] = saved
</code></pre>
<p>差分の１つ目です。forループにindexがありますので、これを使用してsetメソッドを生産者による在庫調整のメソッドに変えていきます。但し、forループをあまり大量に実行するとトランザクション費用が比例して上がることになります。</p>
<p>2行目のIf let で取得したオブジェクトの要素(saved となっている変数)は変更しても、再度オブジェクト(<a href="http://self.data">self.data</a>)にセットしないとスマートコントラクト内で変更は反映されません。(1番下の行)</p>
<hr />
<pre><code class="language-swift">access(contract) fun buy(id: String, buy: [String]) {
    if let saved = self.data[id] {
        for name in buy {
            if (saved.data[name] == nil) {
                panic("The stock is empty.")
            }
            saved.set(category: name, amount: saved.data[name]! - 1)
        }
        // Save
        self.data[id] = saved
     } else {
        panic("No data.")
     }
}
</code></pre>
<p>購入処理（在庫の野菜数を減少させる処理）のスマートコントラクトのコードです。</p>
<hr />
<pre><code class="language-swift">/* setter */
access(contract) fun set(category: String, amount: UInt8) {
    self.data[category] = amount
}
</code></pre>
<p>在庫処理のコードです。前回のスマートコントラクトで日時を入れていたところを数値に置き換えただけです。</p>
<hr />
<pre><code class="language-swift">// BUY
access(all) fun buyVege(id: String, amount: @FlowToken.Vault, buy: [String]) {
    self.info.buy(id: id, buy: buy)
    self.FlowTokenVault.borrow()!.deposit(from: &lt;- amount)
}
</code></pre>
<p>購入処理のメソッドの始まりのコードです。このメソッドに対して外部のjavascriptからfclを使ってトランザクション送信することで購入処理を実行することができます。3行目ではこのスマートコントラクトをデプロイしているアカウントに対して代金を入金しています。</p>
<hr />
<pre><code class="language-swift">    init() {
        self.info = Info()
        self.FlowTokenVault =  self.account
            .capabilities.get&lt;&amp;{FungibleToken.Receiver}&gt;(/public/flowTokenReceiver)
    }
}
</code></pre>
<p>最後に、このスマートコントラクトをデプロしているアドレスを入金先にして完成です。</p>
<hr />
<p>全体のスマートコントラクトは以下です。</p>
<pre><code class="language-swift">import "FlowToken"
import "FungibleToken"

access(all) contract VegeSeller {

    access(self) let FlowTokenVault: Capability&lt;&amp;{FungibleToken.Receiver}&gt;
    access(self) let info: Info

    /* 構造体 */
    access(all) struct Info {

       access(contract) var data: {String: VegeData}

        /* setter */
       access(contract) fun set(id: String, add: [String], addAmount: [UInt8], remove: [String]) {
           if let saved = self.data[id] {
               for index, name in add {
                   saved.set(category: name, amount: addAmount[index])
               }
               for name in remove {
                   saved.unset(category: name)
               }
               // Save
               self.data[id] = saved
           } else {
               var data = VegeData()
               for index, name in add {
                   data.set(category: name, amount: addAmount[index])
               }
               for name in remove {
                   data.unset(category: name)
               }
               self.data[id] = data
           }
       }
       access(contract) fun buy(id: String, buy: [String]) {
          if let saved = self.data[id] {
              for name in buy {
                  if (saved.data[name] == nil) {
                      panic("The stock is empty.")
                  }
                  saved.set(category: name, amount: saved.data[name]! - 1)
              }
              // Save
              self.data[id] = saved
          } else {
              panic("No data.")
          }
       }

       init() {
          self.data = {}
       }
    }

    /* Info内の構造体 */
    access(all) struct VegeData {

       access(contract) var data: {String: UInt8}

       /* setter */
       access(contract) fun set(category: String, amount: UInt8) {
          self.data[category] = amount
       }

       access(contract) fun unset(category: String) {
          self.data[category] = nil
       }

       init() {
          self.data = {}
       }
    }

    // GET
    access(all) fun getVegeSellerInfo(id: String): VegeData? {
       return self.info.data[id]
    }
    // PUT
    access(all) fun setVegeSellerInfo(id: String, add: [String], addAmount: [UInt8], remove: [String]) {
       self.info.set(id: id, add: add, addAmount: addAmount, remove: remove)
    }
    // BUY
    access(all) fun buyVege(id: String, amount: @FlowToken.Vault, buy: [String]) {
       self.info.buy(id: id, buy: buy)
       self.FlowTokenVault.borrow()!.deposit(from: &lt;- amount)
    }

    init() {
        self.info = Info()
        self.FlowTokenVault = self.account
            .capabilities.get&lt;&amp;{FungibleToken.Receiver}&gt;(/public/flowTokenReceiver)
    }
}
</code></pre>
<p>このスマートコントラクトを <a href="https://blsqui.net/developer-guide/resource-oriented-design"><strong>blsqui.net</strong></a> のウェブサイトの左上にあるデプロイボタンでデプロイします。</p>
<p>buyVegeメソッドのamount引数が@FlowToken.Vaultという特別な型を持ってます(灰色の部分)。これはリソースの型を表します。Cadence言語においてResourceの型は特別な型なので@をつける仕様になっています。</p>
<p>&amp;{FungibleToken.Receiver}となっている部分はこれはインタフェースを型にする時に使用します。&amp;{}でインタフェースを型にする（インターセクションと呼ばれます）のはJava言語にもあるようで結構普遍的な書き方です。Entitlementというインタフェースの簡易版がでていますので現在はあまり使われなくなりましたが、以前はCapabilityを公開する時に、Capabilityのインタフェースを型にするため、この&amp;{}を使用していました。</p>
<h3>野菜購入のトランザクション</h3>
<p>flow_blockchainフォルダにtransactions.jsファイルを新規作成します。</p>
<pre><code class="language-swift">import { mutate, authz } from “@onflow/fcl";

export const buyVege = async function (id, buy, price) {
    const txId = await mutate({
        cadence: `
            import "VegeSeller"
            import "FlowToken"
            import "FungibleToken"

            transaction(id: String, buy: [String], price: UFix64) {
                prepare(signer: auth(BorrowValue) &amp;Account) {
                    let payment &lt;- signer
                        .storage
                        .borrow&lt;auth(FungibleToken.Withdraw) &amp;FlowToken.Vault&gt;(from: /storage/flowTokenVault)!
                        .withdraw(amount: price) as! @FlowToken.Vault
                    VegeSeller.buyVege(id: id, amount: &lt;- payment, buy: buy)
                }
                execute {
                    log("success")
                }
            }
        `,
        args: (arg, t) =&gt; [
            arg(id.toString(), t.String),
            arg(buy, t.Array(t.String)),
           arg(price, t.UFix64),
        ],
        proposer: authz,
        payer: authz,
        authorizations: [authz],
        limit: 999,
    });
    console.log(txId);
    return txId;
};
</code></pre>
<p>（コードは<a href="https://github.com/temt-ceo/oraga-esports/blob/main/flow_blockchain/mainnet/transactions.js#L180">こちら</a>にあります。）</p>
<p>これを実行すると野菜を購入するためにお金を支払うことを承認するように求めるポップアップがログインしているユーザが見ている画面に表示されます。</p>
<p>(このポップアップはiFrameによるものですが、それはウォレットプロバイダーが自由に設定することができます。ブラウザの別タブに承認画面を出させることも出来ます。)</p>
<p>fclが提供しているmutateメソッドはトランザクションIDを返します。これをFlowscanのホームページ (<a href="https://www.flowscan.io/">https://www.flowscan.io/</a>) に貼り付けるとトランザクションが成功したかどうかをすぐに分かりますので、大体の場合はどこかにログとして残しておきます。</p>
<p><a href="https://github.com/temt-ceo/oraga-esports/blob/main/src/lib/VegeSeller.svelte#L126">txメソッドのsubscribe</a>で得られるステータスを確認し、ステータスがSEALEDになったら購入者に解錠ボタンを押してもらい、無人野菜販売所の野菜ストッカーは内蔵されるWebKitがブロックチェーンと通信し野菜が購入がされたかを確認し、アンロックする機能だけがあればシステムとして完成です。</p>
]]></content:encoded></item><item><title><![CDATA[CookStocker Smart Contract の作り方]]></title><description><![CDATA[Cadence言語はSwift言語に非常によく似ています (Cadenceは元Appleエンジニアによって開発されています)。Swift言語といっても、慣れたらJavascript と同じようにスラスラ書けますし、クセがありませんので開発方法を忘れることもありません。


今から、この画像にあるような冷蔵庫にある野菜保存室の管理アプリを作ります。(野菜を購入した日付をブロックチェーンで管理するアプ]]></description><link>https://tech-blog.blsqui.net/cookstocker-smart-contract</link><guid isPermaLink="true">https://tech-blog.blsqui.net/cookstocker-smart-contract</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Wed, 05 Aug 2026 04:17:15 GMT</pubDate><content:encoded><![CDATA[<p>Cadence言語はSwift言語に非常によく似ています (Cadenceは元Appleエンジニアによって開発されています)。Swift言語といっても、慣れたらJavascript と同じようにスラスラ書けますし、クセがありませんので開発方法を忘れることもありません。</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a54b7c15c0c654db32e149a/febc15bc-1b1c-4276-8cc0-18688760cad6.png" alt="" style="display:block;margin:0 auto" />

<p>今から、この画像にあるような冷蔵庫にある野菜保存室の管理アプリを作ります。(野菜を購入した日付をブロックチェーンで管理するアプリです)</p>
<p>では作りましょう。まずはスマートコントラクトからです。CookStocker.cdcというファイルをflow_blockchain/cadence/contractsフォルダの中に作ります。以下を入力しましょう。</p>
<pre><code class="language-swift">access(all) contract CookStocker {

  access(self) let info: Info

  /* 構造体 */
  access(all) struct Info {

    access(contract) var data: {String: VegeData}

    /* setter */
    access(contract) fun set(id: String, add: [String], remove: [String]) {
      if let saved = self.data[id] {
        for name in add {
          saved.set(category: name, bought_at: getCurrentBlock().timestamp)
        }
        for name in remove {
          saved.unset(category: name)
        }
        // Save
        self.data[id] = saved
      } else {
        var data = VegeData()
        for name in add {
          data.set(category: name, bought_at: getCurrentBlock().timestamp)
        }
        for name in remove {
          data.unset(category: name)
        }
        self.data[id] = data
      }
    }

    access(contract) fun delete(id: String) {
      self.data[id] = nil
    }

    init() {
      self.data = {}
    }
  }

  /* Info内の構造体 */
  access(all) struct VegeData {

    access(contract) var data: {String: UFix64?}

    /* setter */
    access(contract) fun set(category: String, bought_at: UFix64) {
      self.data[category] = bought_at
    }

    access(contract) fun unset(category: String) {
      self.data[category] = nil
    }

    init() {
      self.data = {}
    }
  }

  // GET
  access(all) fun getCookStockerInfo(id: String): VegeData? {
    return self.info.data[id]
  }
  // PUT
  access(all) fun setCookStockerInfo(id: String, add: [String], remove: [String]) {
    self.info.set(id: id, add: add, remove: remove);
  }
  // DELETE
  access(all) fun deleteCookStockerInfo(id: String) {
    self.info.delete(id: id)
  }

  init() {
    self.info = Info()
  }
}
</code></pre>
<p><strong>黄色と黄緑色</strong>で表示されているのは型です。addとremove引数が[<strong>String</strong>]となっていることからこれらは文字列の配列ということになります。<strong>紫色で表示されている</strong> nilとはnullのことです。(Cadenceではnullをnilと表現します。)</p>
<p>Swiftと文法がよく似ており、特に if let 文はSwift言語の特徴ですので、わからない所に出会ったら"Swift"と一緒に検索して調べるといいと思います。セミコロンはあってもなくてもいいです。</p>
<p>getCurrentBlock().timestamp は秒単位でブロックが生成される時間をエポック秒で取得します。(秒単位ですので、date関数に渡す時には後ろに’000’をつける必要があります)</p>
<p>このスマートコントラクトを <a href="https://blsqui.net/developer-guide/resource-oriented-design">blsqui.net</a> のウェブサイトの左上にあるデプロイボタンでデプロイします。</p>
<h3><strong>スマートコントラクトに保存された情報を取得</strong></h3>
<p>まず、fcl (Flow Client Library)を用意する必要がありますので、インストールします。</p>
<pre><code class="language-shell">npm install @onflow/fcl
</code></pre>
<p>このコマンドをTerminalで実行するとfclがJavaScriptで使えるようになります。Svelteだとフレームワーク設定が必要ないので簡単に開発に着手できます。</p>
<p>次に、以下のようなメソッドを用意します。(言語はJavascriptです) flow_blockchainフォルダにscripts.jsというファイルを新規作成して以下を入力します。</p>
<pre><code class="language-javascript">import { query } from "@onflow/fcl";

export const getInfo = async function (id) {
  const result = await query({
    cadence: `
    import CookStocker from 0x1234abcd5678efgh

    access(all) fun main(id: String): CookStocker.VegeData? {
        return CookStocker.getCookStockerInfo(id: id)
    }
    `,
    args: (arg, t) =&gt; [arg(id, t.String)],
  });
  return result;
};
</code></pre>
<p>（コードは<a href="https://github.com/temt-ceo/oraga-esports/blob/main/flow_blockchain/mainnet/scripts.js#L48">こちら</a>にあります。）</p>
<p>このJavascriptファイルは大体、flow_blockchainフォルダの下ぐらいに置きますがどこに配置しても構いません。</p>
<p>このメソッドはCookStockerスマートコントラクトに保存されている情報を取得するgetCookStockerInfoというメソッドを実行してその情報を返します。</p>
<p>あとはこのscripts.jsファイル内でexportされているgetInfoメソッドを呼び出すだけです。</p>
<pre><code class="language-javascript">import { config } from "@onflow/fcl";
import { getInfo } from '../../flow_blockchain/scripts';

config({
    'flow.network': 'testnet',
    'accessNode.api': 'https://rest-testnet.onflow.org',
});

const id = localStorage.getItem('ID') || Math.random().toString();
localStorage.setItem('ID', id);

setInterval(async () =&gt; {
    info = await getInfo(id);
    console.log(info); &lt;- ここでブラウザのConsoleにログを出しています
}, 1500); (1秒おき以上だと無料で呼び出せます)

 {#each Object.keys(list) as name}
     &lt;VegeCard name={name} pastDate={
         info ? new Date(parseInt(info.data[name]) * 1000).getTime() : null
     } /&gt;
 {/each}
</code></pre>
<p>最初はまだ情報がコントラクトに登録されていないのでnullがConsoleに出力されます。</p>
<img src="https://cdn.hashnode.com/uploads/covers/6a54b7c15c0c654db32e149a/fee1cd45-e4eb-4159-890f-17fbd6675508.png" alt="" style="display:block;margin:0 auto" />

<h3><strong>スマートコントラクトに情報を保存する</strong></h3>
<p>スマートコントラクトのコード内に、ブロックチェーンに保存するメソッドと、保存データを削除するメソッドが書かれています。</p>
<p>スマートコントラクトにデータの保存を行うトランザクションは以下のように記述します。</p>
<pre><code class="language-javascript">import { mutate } from "@onflow/fcl";

  const txId = await mutate({
      cadence: `
          import CookStocker from 0xb576a3926d239682

          transaction(id: String, add: [String], remove: [String]) {
              prepare(signer: &amp;Account) {
                  CookStocker.setCookStockerInfo(id: id, add: add, remove: remove)
              }
              execute {
                  log("success")
              }
          }
      `,
      args: (arg, t) =&gt; [
          arg(id.toString(), t.String),
          arg(add, t.Array(t.String)),
          arg(remove, t.Array(t.String)),
      ],
</code></pre>
<p>この下に承認関数が来るのですが、とりあえず省きます。</p>
<p>スマートコントラクトのsetCookStockerInfoメソッドを呼び出して引数に保存したい情報を渡しています。</p>
<h3>全削除ボタンを押した時のトランザクションのメソッド</h3>
<pre><code class="language-javascript">const txId = await mutate({
    cadence: `
        import CookStocker from 0xb576a3926d239682

        transaction(id: String) {
            prepare(signer: &amp;Account) {
                CookStocker.deleteCookStockerInfo(id: id)
            }
            execute {
                log("success")
            }
        }
    `,
    args: (arg, t) =&gt; [arg(id.toString(), t.String)],
</code></pre>
<p>こちらのコードも承認関数を省いています。引数にはブロックチェーンに渡す値をセットしています。id.toString()となっている部分ですね。</p>
<p>idとはユーザー別に保存を管理するための識別子です。</p>
<p>スマートコントラクトの全削除を行うところのコードを見てみましょう。</p>
<pre><code class="language-swift">    access(contract) fun delete(id: String) {
      self.data[id] = nil
    }
</code></pre>
<p>削除していますね。</p>
<p>もう一回スマートコントラクトの構造体のところを見てみましょう。</p>
<pre><code class="language-swift">  access(self) let info: Info

  /* 構造体 */
  access(all) struct Info {

    access(contract) var data: {String: VegeData}

    /* setter */
    access(contract) fun set(id: String, add: [String], remove: [String]) {
      if let saved = self.data[id] {
        for name in add {
          saved.set(category: name, bought_at: getCurrentBlock().timestamp)
        }
        for name in remove {
          saved.unset(category: name)
        }
        // Save
        self.data[id] = saved
      } else {
        var data = VegeData()
        for name in add {
          data.set(category: name, bought_at: getCurrentBlock().timestamp)
        }
        for name in remove {
          data.unset(category: name)
        }
        self.data[id] = data
      }
    }

    access(contract) fun delete(id: String) {
      self.data[id] = nil
    }

    init() {
      self.data = {}
    }
  }

  /* Info内の構造体 */
  access(all) struct VegeData {

    access(contract) var data: {String: UFix64?}

    /* setter */
    access(contract) fun set(category: String, bought_at: UFix64) {
      self.data[category] = bought_at
    }

    access(contract) fun unset(category: String) {
      self.data[category] = nil
    }

    init() {
      self.data = {}
    }
  }
</code></pre>
<p>スマートコントラクトの構造体は複雑な構造のデータを保存することができます。（だから構造体。）</p>
<p>一番上に <code>access(self) let info: Info</code> というのが見えますね。これはスマートコントラクトに<code>info</code>というフィールドがあり、それは<code>Info</code>型であることを示しています。</p>
<p>だからスマートコントラクトの中では</p>
<pre><code class="language-swift">  access(all) fun getCookStockerInfo(id: String): VegeData? {
    return self.info.data[id]
  }
</code></pre>
<p>このようにして スマートコントラクトのinfoフィールドのデータにアクセスすることができます。</p>
<p>このコードの１行目の後ろをよくみると<code>VegeData?</code>というのが見えますね。これはinfo.data が 以下のように定義されているためです。</p>
<pre><code class="language-swift">  access(all) struct Info {

    access(contract) var data: {String: VegeData}
</code></pre>
<p>あとは簡単<code>VegeData</code>という構造体を新しく作るだけです。</p>
<p>基本的に変数や配列以上に複雑な構造を作ろうとすると、それは全て構造体になります。構造体のフィールドがやはり変数や配列より複雑であればそれも構造体です。</p>
<p>慣れれば簡単、基本的な文法はSwiftというモダン言語と同じです。</p>
<p>今回は基本部分だけ。</p>
<hr />
<p>この構造体の情報はスマートコントラクトを保存しているアカウント（つまりデプロイしているアカウント）に保存されます。</p>
<p>何に役立つかというと、消えない、世界で共通の情報として使うことができます。</p>
<p>構造体はスマートコントラクトをデプロイした人であれば、その情報を変えることは簡単なので、あくまでスマートコントラクトのロジックで必要な情報の格納先として使うのが正しい使い方だと思います。</p>
<p>だから、賞品やトロフィー🏆などは構造体内では扱いません。</p>
]]></content:encoded></item><item><title><![CDATA[Blsqui eスポーツウォレット、ネットショッピングなどのポイントでPCゲーム(Unreal Engine 対応)の代金をステーブルコイン決済できるBlsqui SDKを発表]]></title><description><![CDATA[Unreal Engine(c++)やUnity等に対応 — 導入コストがゼロかつゲーム内でわずか1行の実装でポイント決済を実現
主な機能
ゲーム開発者は Blsqui SDK を導入することで、Point-to-Pointステーブルコインや独自ブランドのトークン、暗号資産をゲーム内決済へと手軽に組み込むことが可能です。さらに、ステーブルコイン等のスマートコントラクトをワンクリックで安全にデプロイ]]></description><link>https://tech-blog.blsqui.net/blsqui-e-pc-unreal-engine-blsqui-sdk</link><guid isPermaLink="true">https://tech-blog.blsqui.net/blsqui-e-pc-unreal-engine-blsqui-sdk</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Mon, 03 Aug 2026 05:11:13 GMT</pubDate><content:encoded><![CDATA[<h3><em><strong>Unreal Engine(c++)やUnity等に対応 — 導入コストがゼロかつゲーム内でわずか1行の実装でポイント決済を実現</strong></em></h3>
<h3>主な機能</h3>
<p>ゲーム開発者は Blsqui SDK を導入することで、Point-to-Pointステーブルコインや独自ブランドのトークン、暗号資産をゲーム内決済へと手軽に組み込むことが可能です。さらに、ステーブルコイン等のスマートコントラクトをワンクリックで安全にデプロイできる、堅牢なブロックチェーンインフラも標準提供します。</p>
<p><strong>独自のポイントベースのステーブルコインをゲーム内通貨として利用可能</strong></p>
<hr />
<h3>弊社の最先端インフラを使用したサービスを利用するメリット</h3>
<ol>
<li><p>すべての開発者およびユーザーが、決済手数料無料で決済画面機能を利用できます。 </p>
</li>
<li><p>Unreal EngineやUnity、Godotの<strong>マルチゲームエンジン</strong>に対応した、ガス代が不要なステーブルコイン決済を実現します。 </p>
</li>
<li><p>MPC-CMP（マルチパーティ計算）閾値署名技術を搭載。高速な処理速度を維持したまま、堅牢な多層鍵管理セキュリティを提供いたします。 </p>
</li>
<li><p>事前設定不要のネイティブウォレット層を同時提供。従来なら数週間を要した決済機能の組み込みをわずか1~2時間へと短縮できます。</p>
</li>
<li><p>ユーザーが自信をもって決済できるスマートコントラクトコードのレジストリシステムを搭載。（FLIXシステム）これにより決済画面に多言語に対応した決済の説明表示が可能です。</p>
</li>
</ol>
<hr />
<h3>弊社の決済インフラはエンタープライズグレードのネットワークを使用しており、最先端のインフラ環境となっています</h3>
<ol>
<li><p>DNSから弊社サーバーのIPアドレス追跡を隠蔽するIP Maskingを実施しています。 </p>
</li>
<li><p>トランザクション履歴の追跡にCDN Functions を利用し、低遅延を実現、また、ブロックチェーンAPI情報の完全抽象化を実現しています。 </p>
</li>
<li><p>AI活用のAnti-DDoS機能により分散型大規模DoS攻撃に対応しています。 </p>
</li>
<li><p>Threat Filteringにより、APIに対するあらゆる怪しい攻撃を遮断しています。</p>
</li>
</ol>
<hr />
<h3>ブロックチェーンAPI情報の完全抽象化を実現</h3>
<p>Blsqui SDK が外部から取得する情報はブロックチェーンAPIによる影響がゲーム内に及ばない設計になっています。APIのバージョンアップ等でレスポンス形式が変わったとしてもゲーム内SDKがアップデートを強いられることは、決してありません。</p>
<p>世界300都市で最新のCDN Functionによる抽象化ロジックが同時に展開され、ゲーム内SDKには最適化されたレスポンスのみが提供されます(下図)。これにより、JSONの解析に必要となるメモリ使用量も最小限に抑えることができます。</p>
<pre><code class="language-json">{
  "status": "SEALED",
  "txId": "fb1272c57c...",
  "nonce": "fb1272c57c...",
  "errorMessage": null,
  "payer": "fb1272c57c...",
  "amount": "10.00",
  "currency": "USDC",
  "timestamp": 1722052603
}
</code></pre>
<hr />
<h3>私達のビジョン</h3>
<p>10年以上にわたり、ゲーム開発者はクレジットカードの決済手数料として2〜3%を支払うことに加え、従来のプラットフォーム運営会社に対して総収益の30%を差し出すことを余儀なくされてきました。</p>
<p>Blsquiはこうした障壁を解消するため、「ポイント・ツー・ポイント（共通ポイントをブロックチェーンのステーブルコインとして決済する仕組み）」のチェックアウトフローを採​​用することにしました。また、Blsqui SDKにおいてRFC 8252に着想を得たローカルHTTPループバックによるゲーム中にスムーズに決済スクリーンを表示する機能を実現してきました。トランザクションID（txId）を、Unreal EngineやUnity、Godotといったネイティブゲームエンジン内で生成された決済参照番号へと安全に受け渡します。</p>
<p><strong>ゲームパブリッシャー向け Blsqui SDKの主な特徴</strong></p>
<ul>
<li><p>パブリッシャーは収益の100%を受け取ることができます。</p>
</li>
<li><p>支払いはプレイヤーのウォレットからパブリッシャーの受取用ウォレットへ直接送金されます。銀行など仲介が介在しないことから、支払いの保留や取り消しのリスクがありません。</p>
</li>
<li><p>eスポーツのプレイヤーは生体認証（Face ID / Touch ID / パスキー）を含むパスキーを使用して決済取引を承認します。</p>
</li>
<li><p><strong>Unreal Engine</strong>および<strong>Unity</strong>、<strong>Godot</strong>用SDKにより、ゲーム開発者はわずか1行のコード（ <em>BlsquiSDK.RequestTransaction()</em> ）で決済フローを実装できます。</p>
</li>
</ul>
<hr />
<h3>よくある質問（FAQ）</h3>
<p><strong>Q. Blsqui はどのようにして「手数料ゼロの決済画面」を実現しているのですか？</strong></p>
<p><strong>A.</strong> Blsqui は、従来のクレジットカードネットワークや中間決済業者を介さない中間マージンが不要となるようなアーキテクチャを採用しています。</p>
<p><strong>Q. Blsqui Payment SDK が対応しているゲームエンジンは何ですか？</strong></p>
<p><strong>A.</strong> Unreal Engine、Unity、Godot Engine 向けの軽量なパブリック SDK に加え、ネイティブ Web アプリケーション向けの Web API を提供しています。</p>
<p><strong>Q. サポートされているステーブルコインは何ですか？</strong></p>
<p><strong>A.</strong> 現在 Blsqui は、ポイントベースの一般的なステーブルコインとブロックチェーンのネイティブ通貨であるFLOWに対応しています。また近いうちに、USDC や PYUSD などの主要な米ドル連動型トークンにも対応予定です。</p>
<p><strong>Q. ワンクリックでの安全なスマートコントラクトデプロイはどうして可能ですか？</strong></p>
<p><strong>A.</strong> Blsquiは、誰でもスマートコントラクトを即座にデプロイできる多層鍵管理セキュリティ搭載ウォレットシステムを構築しており、コントラクト追加処理である signerAccount.contracts.add(...) を組み込んだ専用のUI画面がFLIXを介して提供されるため、高度なブロックチェーン知識や手動の環境設定を行うことなく、安全なワンクリックデプロイを実現しています。</p>
<hr />
<h3>Get Started Today</h3>
<p>以下は Unreal Engine 5 の格闘ゲームにポイントステーブルコインおよび仮想通貨決済の機能を実装した様子です。(Chrome Extension やシードフレーズ等は一切不用。) </p>
<p><strong>Blsqui eスポーツウォレット は即座にスマートコントラクトをデプロイできることからゲーム開発者は様々な賞金、景品、アイテム配布ロジックをシームレスにゲームに組み込むことができます。ソースコードをFLIXレジストリで管理しておき、 FLIX IDをBlsqui SDKに渡すだけでキャプションやアイコンなどバラエティに富んだ署名画面のeSportsブロックチェーンゲームを自社のリソースを消費することなく開発することができます。</strong></p>
<p><a class="embed-card" href="https://www.youtube.com/watch?v=dzjDuH_fbTY">https://www.youtube.com/watch?v=dzjDuH_fbTY</a></p>

<p>TEM Technologies Co. LLC / Blsqui Wallet Division</p>
<p>URL: <a href="https://blsqui.net/contact">https://blsqui.net/contact</a></p>
]]></content:encoded></item><item><title><![CDATA[Blsqui eSports Wallet Announces "Blsqui SDK"—Enabling PC Game Stablecoin Payments (Unreal Engine Supported) Using E-Commerce Reward Points]]></title><description><![CDATA[Supports Unreal Engine (C++), Unity, and more — Achieve seamless point-based payments with zero integration costs and just 1 line of in-game code.
Major Features
By integrating the Blsqui SDK, game de]]></description><link>https://tech-blog.blsqui.net/blsqui-esports-wallet-announces-blsqui-sdk-enabling-pc-game-stablecoin-payments-unreal-engine-supported-using-e-commerce-reward-points</link><guid isPermaLink="true">https://tech-blog.blsqui.net/blsqui-esports-wallet-announces-blsqui-sdk-enabling-pc-game-stablecoin-payments-unreal-engine-supported-using-e-commerce-reward-points</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Mon, 03 Aug 2026 04:58:12 GMT</pubDate><content:encoded><![CDATA[<h3><em>Supports Unreal Engine (C++), Unity, and more — Achieve seamless point-based payments with zero integration costs and just 1 line of in-game code.</em></h3>
<h3>Major Features</h3>
<p>By integrating the Blsqui SDK, game developers can effortlessly incorporate Point-to-Point stablecoins, custom-branded tokens, and cryptocurrencies into their in-game payment systems. Furthermore, it comes standard with a robust blockchain infrastructure that enables secure, one-click deployment of smart contracts, including stablecoins.</p>
<p><strong>Utilize your own point-based stablecoins as in-game currency</strong></p>
<hr />
<h3>Benefits of Our State-of-the-Art Infrastructure</h3>
<ol>
<li><p>All developers and users can utilize the checkout screen functionality with absolutely zero transaction fees.</p>
</li>
<li><p>Delivers gasless stablecoin payments with <strong>multi-engine</strong> support for Unreal Engine, Unity, and Godot.</p>
</li>
<li><p>Powered by MPC-CMP (Multi-Party Computation) threshold signature technology, providing robust, multi-layered key management security without compromising processing speed.</p>
</li>
<li><p>Includes a pre-configured native wallet layer out of the box. This reduces the payment integration timeline from several weeks to just 1–2 hours.</p>
</li>
<li><p>Features a smart contract code registry system (the FLIX system) that empowers users to transact with confidence. This enables multi-lingual payment descriptions to be displayed directly on the checkout screen.</p>
</li>
</ol>
<hr />
<h3>Complete Abstraction of Blockchain API Data</h3>
<p>The Blsqui SDK is designed so that external data retrieval completely isolates the game client from any blockchain API changes. Even if an API version update alters the response format, game developers will never be forced to update the in-game SDK.</p>
<p>State-of-the-art CDN Functions deploy abstraction logic simultaneously across 300 cities worldwide, delivering only optimized responses to the in-game SDK (see below). Consequently, this minimizes the memory footprint required for JSON parsing on the game engine side.</p>
<pre><code class="language-json">{
  "status": "SEALED",
  "txId": "fb1272c57c...",
  "nonce": "fb1272c57c...",
  "errorMessage": null,
  "payer": "fb1272c57c...",
  "amount": "10.00",
  "currency": "USDC",
  "timestamp": 1722052603
}
</code></pre>
<hr />
<h3>Our Vision</h3>
<p>For over a decade, game developers have been forced to surrender 30% of their gross revenue to traditional platform operators, in addition to paying 2–3% in credit card transaction fees.</p>
<p>To dismantle these barriers, Blsqui has adopted a "Point-to-Point" checkout flow (a system that processes common reward points as blockchain-based stablecoins). Furthermore, inspired by RFC 8252, the Blsqui SDK utilizes local HTTP loopbacks to smoothly display the checkout screen during gameplay. It securely passes the transaction ID (txId) to payment reference numbers generated directly within native game engines like Unreal Engine, Unity, and Godot.</p>
<p><strong>Key Benefits of the Blsqui SDK for Game Publishers:</strong></p>
<ul>
<li><p>Publishers retain 100% of their revenue.</p>
</li>
<li><p>Payments are routed directly from the player's wallet to the publisher's receiving wallet. With no banks or intermediaries involved, there are zero risks of payment holds or chargebacks.</p>
</li>
<li><p>eSports players authorize payment transactions using Passkeys, including biometric authentication (Face ID / Touch ID).</p>
</li>
<li><p>With the SDKs for <strong>Unreal Engine</strong>, <strong>Unity</strong>, and <strong>Godot</strong>, game developers can implement the entire payment flow with just a single line of code (<em>BlsquiSDK.RequestTransaction()</em>).</p>
</li>
</ul>
<hr />
<h3>Frequently Asked Questions (FAQ)</h3>
<p><strong>Q. How does Blsqui achieve a "zero-fee checkout screen"?</strong></p>
<p><strong>A.</strong> Blsqui utilizes an architecture that bypasses traditional credit card networks and payment intermediaries, eliminating the need for intermediary margins and fees.</p>
<p><strong>Q. Which game engines does the Blsqui Payment SDK support?</strong></p>
<p><strong>A.</strong> We provide lightweight public SDKs for Unreal Engine, Unity, and Godot Engine, alongside a Web API for native web applications.</p>
<p><strong>Q. Which stablecoins are supported?</strong></p>
<p><strong>A.</strong> Currently, Blsqui supports popular point-based stablecoins and FLOW, a native blockchain currency. In the near future, we will also support major USD-pegged tokens such as USDC and PYUSD.</p>
<p><strong>Q. How is secure, one-click smart contract deployment possible?</strong></p>
<p><strong>A.</strong> Blsqui features a wallet system equipped with multi-layered key management security that allows anyone to deploy smart contracts instantly out-of-the-box. Because a dedicated UI screen executing the contract addition logic signerAccount.contracts.add(...) is provided via the FLIX system, it enables secure, one-click deployments without requiring advanced blockchain knowledge or manual environment configurations.</p>
<hr />
<h3>Get Started Today</h3>
<p>Below is a demonstration of point-based stablecoin and cryptocurrency payments implemented in an Unreal Engine fighting game. (No Chrome Extensions or seed phrases required.)</p>
<p><strong>Because the Blsqui eSports Wallet can instantly deploy smart contracts, game developers can seamlessly integrate diverse prize pools, rewards, and item distribution logic directly into their games. By managing the source code in the FLIX registry and simply passing the FLIX ID to the Blsqui SDK, developers can create rich Blockchain eSports experiences—complete with customized captions and icons on authorization screen—without consuming their own server resources.</strong></p>
<p><a class="embed-card" href="https://www.youtube.com/watch?v=dzjDuH_fbTY">https://www.youtube.com/watch?v=dzjDuH_fbTY</a></p>

<p>TEM Technologies Co. LLC / Blsqui Wallet Division</p>
<p>URL: <a href="https://blsqui.net/contact">https://blsqui.net/contact</a></p>
]]></content:encoded></item><item><title><![CDATA[eスポーツの未来を切り拓く Point-to-Point 思想と、ポイント×ステーブルコイン経済圏の最前線]]></title><description><![CDATA[1. なぜ、BlsquiはPoint-to-Point for eSports を追い求めるのか？
答えは至極シンプルです。熱狂的なeスポーツを、今すぐこの手で実現したいからです。これ以上に理由はありません。
eスポーツ業界において、ポイント to ポイント（Point-to-Point） はキラーワードだと言えます。
この構造を組み込むだけで、法的なハードルを下げながら、グローバルかつリアルタイ]]></description><link>https://tech-blog.blsqui.net/e-point-to-point</link><guid isPermaLink="true">https://tech-blog.blsqui.net/e-point-to-point</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Mon, 27 Jul 2026 20:07:35 GMT</pubDate><content:encoded><![CDATA[<h3>1. なぜ、BlsquiはPoint-to-Point for eSports を追い求めるのか？</h3>
<p>答えは至極シンプルです。<strong>熱狂的なeスポーツを、今すぐこの手で実現したいから</strong>です。これ以上に理由はありません。</p>
<p>eスポーツ業界において、<strong>ポイント to ポイント（Point-to-Point）</strong> はキラーワードだと言えます。</p>
<p>この構造を組み込むだけで、法的なハードルを下げながら、グローバルかつリアルタイムな決済、または報酬配布を行えるインフラストラクチャーを備えたゲーム大会が成立します。</p>
<p>「ポイント to ポイント」のスマートコントラクト実装は、実は非常にシンプルです。 私は過去に、大手企業向けに<strong>金（Gold）価格に連動するステーブルコイン</strong>の仕組みを実装から納品まで請け負ったことがあります。外部のAPIから金価格を取得し、オラクルを経由してリアルタイムにスマートコントラクトへ反映させる設計でした。</p>
<p>「ポイント to ポイント」は実はとても簡単です。</p>
<ul>
<li><p>1対1の固定レートのため、金価格のような変動オラクルによる調整がありません。</p>
</li>
<li><p>日本円との直接交換を回避し、法定通貨への直接換金を挟まず、ポイント同士の等価交換に特化することで短期間でのリリースを実現できます。 仕様さえ決まれば1日でも実装可能であり、これによってeスポーツの実現速度は飛躍的に加速することでしょう。</p>
</li>
</ul>
<h3>2. 日本国内におけるポイント×ステーブルコインのトレンド</h3>
<p>現在、日本のポイント経済圏とステーブルコインの融合は、歴史的な転換期を迎えています。</p>
<p>2026年6月、JPYC社はHashPortおよび三井住友トラストクラブと提携し、クレジットカード（Diners Club）の特典ポイントを直接JPYCへ交換できる日本初のサービスを発表しました。</p>
<p>この動きが意味することは明白です。</p>
<p><strong>ポイントをステーブルコイン化し、エコシステム内で循環させるという思想において、私たちBlsquiの目線は、すでにメガキャリアや大手金融機関と完全に同じ高さにある</strong>ということです。(<code>注: 株式会社HashPortは au Financial 、Coincheckと合弁会社を設立(名称: au Coincheck Digital Assets)しており、au Pontaポイントをすでにステーブルコインとしてリリースしています</code>)</p>
<h3>共通のゴール</h3>
<p>彼ら大手事業者がポータルサイトや巨大アライアンスを通じた日本市場の変革を目指す一方で、私たちBlsquiも<strong>ブロックチェーンゲーム／eスポーツ</strong>という現場から日本を進化させたいという、アプローチの出発点こそ異なりますが到達すべき共通のゴールを持っています。</p>
<h2>3. Blsquiの強み</h2>
<p>私たちBlsquiチームは、暫定企業価値5億円規模の精鋭スタートアップです。だからこそ大手には真似できない決定的なアドバンテージを有しています。</p>
<h3><strong>① エンジニア主導</strong></h3>
<p>Blsquiの代表自身がプロダクトのコードを書き、アーキテクチャを設計する技術者集団ですので、ユーザーやゲーム事業者が目にするUI/UX、SDKの挙動を、現場のニーズに合わせて即日かつ自由にアップデートできる機動力があります。</p>
<h3>② 次世代ブロックチェーン「Flow」とGoogle Cloud基盤</h3>
<p>先行する競合他社が1世代前のブロックチェーンのインフラを活用しているのに対し、Blsquiは創業時よりGoogle Cloudがバックアップする「Flowブロックチェーン」を採用しています。</p>
<ul>
<li><p>GCPインフラのおかげで超低遅延かつ高スループットであり、5G時代の高速ネットワークに最適化できます。</p>
</li>
<li><p>PayPalやCircle（USDC）などの<strong>グローバルスタンダード</strong> の巨人がエコシステムに参画する信頼性の高いブロックチェーンです。</p>
</li>
</ul>
<h2>4. Blsqui SDKの主な機能</h2>
<h3>独自のステーブルコインやポイントトークンをゲーム内通貨として利用可能です。</h3>
<p>ゲーム開発者は、Blsqui SDKを使用することで、カスタマイズされたPoint-to-Point ステーブルコインや独自ブランドのエコシステム・トークン、仮想通貨をゲーム内決済に統合できます。ステーブルコインなどのスマートコントラクトはワンクリックで安全にデプロイできるブロックチェーンインフラも備えています。</p>
<h3>弊社の最先端インフラを使用したサービスを利用するメリット</h3>
<ol>
<li><p>すべての開発者とユーザーが、決済手数料無料で決済画面の機能を利用できます。</p>
</li>
<li><p>Unreal EngineやUnity、Godotなどの高性能ゲームエンジンに対応した、ガス代不要（Gasless）のステーブルコイン決済機能を提供しています。</p>
</li>
<li><p>**MPC-CMP（マルチパーティ計算）**による閾値署名技術を備えており、トランザクション速度を損なうことなく、多層的な鍵管理セキュリティを実現できます。</p>
</li>
<li><p>ブロックチェーンロジックの複雑さを「FLIX ID」として抽象化し、設定不要なネイティブウォレット層を同時に提供しているため、<strong>Blsqui SDKは、従来なら数週間を要した決済機能の導入作業を、わずか1〜2時間のセットアップ期間へと短縮できます</strong>。</p>
</li>
</ol>
<h3>弊社の決済インフラはエンタープライズグレードのネットワークを使用しており、最先端のインフラ環境となっています</h3>
<ol>
<li><p>DNSから弊社サーバーのIPアドレス追跡を隠蔽するIP Maskingを実施しています。</p>
</li>
<li><p>トランザクション履歴の追跡にCDN Functions を利用し、低遅延を実現、また、ブロックチェーンAPI情報の完全抽象化を実現しています。</p>
</li>
<li><p>AI活用のAnti-DDoS機能により分散型大規模DoS攻撃に対応しています。</p>
</li>
<li><p>Threat Filteringにより、APIに対するあらゆる怪しい攻撃を遮断しています。</p>
</li>
</ol>
<h3>ブロックチェーンAPI情報の完全抽象化を実現</h3>
<p>Blsqui SDK が外部から取得する情報はブロックチェーンAPIによる影響がゲーム内に及ばない設計になっています。APIのバージョンアップ等でレスポンス形式が変わったとしてもゲーム内SDKがアップデートを強いられることは、決してありません。 世界300都市で最新のCDN Functionによる抽象化ロジックが同時にデプロイされ、ゲーム内SDKは抽象化データのみが提供されます (下図)。また、JSONの解析に必要となるメモリ消費もこれにより最低限に抑えることができます。</p>
<pre><code class="language-json">{
  "status": "SEALED",
  "txId": "fb1272c57c...",
  "nonce": "fb1272c57c...",
  "errorMessage": null,
  "payer": "fb1272c57c...",
  "amount": "10.00",
  "currency": "USDC",
  "timestamp": 1722052603
}
</code></pre>
<h3><strong>【本件に関するお問い合わせ・アライアンスのご相談】</strong></h3>
<p>TEM Technologies Co. LLC / Blsqui Wallet Division</p>
<p>URL: <a href="https://blsqui.net/contact">https://blsqui.net/contact</a></p>
]]></content:encoded></item><item><title><![CDATA[Bypassing the Chrome Extension: Why Blsqui is Reviving the Seamless Blocto UX Pattern for AI-Agent Games.]]></title><description><![CDATA[English text is followed by the Japanese version below. (Scroll down or click here to jump to the Japanese text.)
The current clunky state of AI payment setups versus the seamless UX reviving with the]]></description><link>https://tech-blog.blsqui.net/bypassing-the-chrome-extension-why-blsqui-is-reviving-the-seamless-blocto-ux-pattern-for-ai-agent-games</link><guid isPermaLink="true">https://tech-blog.blsqui.net/bypassing-the-chrome-extension-why-blsqui-is-reviving-the-seamless-blocto-ux-pattern-for-ai-agent-games</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Sun, 26 Jul 2026 20:15:20 GMT</pubDate><content:encoded><![CDATA[<p>English text is followed by the Japanese version below. (Scroll down or <a href="#japanese-version">click here</a> to jump to the Japanese text.)</p>
<h2>The current clunky state of AI payment setups versus the seamless UX reviving with the Blsqui architecture.</h2>
<p>Why your AI Assistant is Giving You Terrifying Code for Payment Logic</p>
<p>If you have ever asked an AI assistant to generate payment logic for your application, you’ve probably stared at the output in absolute horror.</p>
<p>AI is incredibly superior at optimizing game loops, generating assets, and structuring databases. But the moment you type the word "payment," the AI returns a monstrous wall of terrifying code. You are suddenly looking at dense server configurations, complex webhooks, third-party payment gateway middlewares, state management handlers, and data tracking endpoints just to move a single dollar.</p>
<p>Why does this happen? Because AI only knows the traditional tech stack. It assumes you need to build a heavy, centralized billing fortress.</p>
<p>People use AI every single day because it makes creation frictionless. Yet, the moment monetization enters the equation, the friction returns tenfold. Developers are struggling to cope with payment logic not because they lack skill, but because the traditional architecture is fundamentally broken for modern independent applications.</p>
<p>There has to be a cleaner way to handle settlement without writing code that looks like a cybersecurity nightmare.</p>
<h2>japanese-version</h2>
<p>AIアシスタントが提示する決済ロジックのコードが「恐ろしく複雑」になってしまう理由</p>
<p>アプリケーションの決済ロジックをAIに生成させたことがある人なら、その出力結果を見て思わずゾッとした経験があるはずです。</p>
<p>AIは、ゲームループの最適化やアセット生成、データベースの構造化においては圧倒的に優秀です。しかし、あなたが「決済」という単語を入力した瞬間、AIは恐ろしく難解で長大なコードの壁を返し始めます。たった1ドルを移動させるためだけに、高密度なサーバー設定、複雑なウェブフック、サードパーティの決済ゲートウェイ、状態管理ハンドラー、データトラッキングのエンドポイントが画面を埋め尽くすのです。</p>
<p>なぜこれが起きるのでしょうか？それは、AIが「従来のレガシーなテックスタック」しか知らないからです。AIは、あなたが巨大で中央集権的な課金要塞をゼロから構築しなければならないと前提しているのです。</p>
<p>人々は開発をスムーズにするために毎日AIを使っています。しかし、マネタイズが絡んだ瞬間に、その摩擦（フリクション）は10倍になって戻ってきます。開発者が決済ロジックに苦労しているのは、技術が足りないからではありません。従来のアーキテクチャ自体が、現代のインディー開発やAIアプリケーションにとって根本的に壊れているからです。</p>
<p>サイバーセキュリティの悪夢のようなコードを書くことなく、よりクリーンに決済を処理する方法が他にあるはずです。</p>
<hr />
]]></content:encoded></item><item><title><![CDATA[Moving From Prompt to Paycheck: Resolving the Monetization Bottleneck in AI-Agent Game Development]]></title><description><![CDATA[English text is followed by the Japanese version below. (Scroll down or click here to jump to the Japanese text.)
We can solve problems that AI cannot.
Across X, YouTube, and Discord, we are watching ]]></description><link>https://tech-blog.blsqui.net/moving-from-prompt-to-paycheck-resolving-the-monetization-bottleneck-in-ai-agent-game-development</link><guid isPermaLink="true">https://tech-blog.blsqui.net/moving-from-prompt-to-paycheck-resolving-the-monetization-bottleneck-in-ai-agent-game-development</guid><dc:creator><![CDATA[Takashi Tahara]]></dc:creator><pubDate>Mon, 13 Jul 2026 11:19:36 GMT</pubDate><content:encoded><![CDATA[<p>English text is followed by the Japanese version below. (Scroll down or <a href="#japanese-version">click here</a> to jump to the Japanese text.)</p>
<p>We can solve problems that AI cannot.</p>
<p>Across X, YouTube, and Discord, we are watching a profound cultural shift: parents and children are sitting down together, co-prompting AI agents, and spinning up fully playable 3D games in a single afternoon.</p>
<h3>What Normal People and Families Are Actually Trying</h3>
<p>Based on data across developer communities, families and "normal" people are building <strong>Casual Simulations, Sandbox Upgraders, and Casual Tycoons</strong>.</p>
<ul>
<li><p>They are prompting things like: <em>"Make a game where a character cuts down a tree, carries wood to a shop, gets 10 coins, and upgrades their axe."</em></p>
</li>
<li><p>The core mechanic is a <strong>simple sequence</strong>: <strong>Perform Task ➔ Gain Resource ➔ Purchase Upgrade</strong>.</p>
</li>
</ul>
<h3>Technical Bottleneck</h3>
<p>These creators want their games to make money so they can show their kids real validation (or, for solo indie creators, pay their bills).</p>
<p>But right now, <strong>Google, Claude, and ChatGPT agents fail them at the checkout gate</strong>. If you ask an AI agent: <em>"Add a secure checkout system"</em> the AI spits out hundreds of lines of complex Node.js/Go server logic, database configuration schemas, and security headers.</p>
<p>The normal creator looks at that infrastructure mountain and completely gives up.</p>
<p><strong>At Blsqui, our engineering philosophy is built around a single phrase: Democratizing Revenue for Independent Game Creators.</strong></p>
<p>The Blsqui esports wallet enables creators to implement payment verification and blockchain security layers without requiring backend expertise—all through a no-code solution.</p>
<p>Payment implementation, which previously took weeks, <strong>has been streamlined to the execution of just a single line of script in Unity or Godot.</strong> Once the necessary conditions are met, a sleek wallet interface appears—no Chrome extension required.</p>
<p>Game creators no longer need to write code to handle in-game payments.</p>
<p>Blsqui ensures that everyone can rightfully earn 100% of their revenue, and the entire setup process takes less than a minute.</p>
<p>As shown <a href="https://blsqui.net/products/deploy-in-1-min">here</a>, simply running <code>npm create blsqui</code> launches a game screen featuring a sample game and an integrated Blsqui wallet. You simply need to set the wallet address to the one generated via Blsqui. Once you swap in your own game design and run the <code>npm run build</code> command, your wallet setup is complete. Additionally, since the system accepts cryptocurrency exchange addresses, you can immediately convert your earnings into cash.</p>
<ol>
<li><p><strong>Native Cross-Platform Execution:</strong> Whether the game is exported to Windows, iOS, or Android via Unity or Godot, a single script natively calls the device's default web browser.</p>
</li>
<li><p><strong>Income from Tomorrow:</strong> The creator inputs their wallet address and asset strings. When a player buys the "Golden Axe" in-game, the transaction is cryptographically processed on the ledger, verified by our cloud, and cleared safely.</p>
</li>
</ol>
<h2>japanese-version</h2>
<p>プロンプトから「収益」へ：AIゲーム開発における最大のボトルネック「決済インフラ」を解消する</p>
<p>私たちは、AIには解決できないことを解決できます。</p>
<p>今、XやYouTube、Discordを見渡すと、テクノロジーの歴史における大きな転換点を目にすることができます。それは、親と子どもが机を並べ、AIエージェントにプロンプトを打ち込みながら、わずか数時間で実際に遊べるゲームを作り上げている光景です。</p>
<h3>一般の人々や家族が実際に試みていること</h3>
<p>開発者コミュニティのデータを分析すると、家族や「一般の」人々は、<strong>カジュアル・シミュレーション、サンドボックス型アップグレード・ゲーム、カジュアルなタイクーン（経営）ゲーム</strong>を制作しようとしています。</p>
<ul>
<li><p>彼らは次のようなプロンプトを入力しています。「キャラクターが木を切り倒し、木材を店に運んで10コインを獲得し、斧をアップグレードするゲームを作って」</p>
</li>
<li><p>その核となるメカニズムは、<strong>「タスク実行 ➔ リソース獲得 ➔ アップグレード購入」というシンプルなもの</strong>です。</p>
</li>
</ul>
<h3><strong>技術面でのボトルネック</strong></h3>
<p>こうしたクリエイターは、子供たちに「実際に成果が出た」ことを見せるため（あるいは、個人開発者なら生活費を稼ぐため）に、ゲームで収益を上げたいと考えています。</p>
<p>しかし現状では、<strong>Google、Claude、ChatGPTといったAIエージェントが、決済（チェックアウト）の実装段階でつまずいてしまいます</strong>。AIエージェントに安全な決済システムを追加してと頼むと、AIは数百行にも及ぶ複雑なNode.jsやGoのサーバーロジック、データベース設定スキーマ、セキュリティヘッダーなどを出力してくるのです。</p>
<p>一般のクリエイターは、その膨大なインフラ構築の山を目の当たりにして、完全にやる気を失ってしまいます。</p>
<p><strong>Blsquiが掲げるミッションはただ一つです。</strong> <strong>「独立したゲームクリエイターの収益を、完全に民主化する（Democratizing Revenue for Independent Game Creators）」</strong></p>
<p>Blsqui eスポーツウォレットはクリエイターにバックエンドの知識を強いず、決済の検証とブロックチェーンのセキュリティ層を、ノーコードで提供することことができます。</p>
<p>これまで数週間かかっていた決済の実装は、<strong>UnityやGodotにおける「わずか1行のスクリプト実行」へと簡潔化されました</strong>。そしてその条件が満たされた時、Chromeエクステンションを必要としない、美しいウォレット画面を表示します。</p>
<p>もうゲームクリエイターはゲームの決済にコードを書く必要はなくなりました。</p>
<p>Blsqui は誰もが正当に１００％の収益を得られることができ、その手順は１分もあれば終わります。</p>
<p><a href="https://blsqui.net/products/deploy-in-1-min">ここ</a>にあるように</p>
<pre><code class="language-shell">npm create blsqui
</code></pre>
<p>を実行するだけでサンプルゲームとBlsquiウォレットが実装されたゲーム画面が立ち上がります。あなたはそのウォレットアドレスにBlsquiで作成したアドレスをセットするだけです。ゲームデザインをあなたの作ったものに切り替えて、</p>
<pre><code class="language-shell">npm run build
</code></pre>
<p>のコマンドを実行すればもうウォレットの準備は万全です。また、ウオレットアドレスは暗号通貨取引所のアドレスでも機能しますので、即座に売上を換金することができます。</p>
<ol>
<li><p><strong>ネイティブなクロスプラットフォーム対応:</strong> ゲームがWindows、Mac、iOS、Androidのどれに書き出されても、ゲームエンジンから標準ブラウザを安全に呼び出し、シームレスな決済画面を展開します。</p>
</li>
<li><p><strong>明日から始まるゲームビジネス:</strong> クリエイターは自分のウォレットアドレスとアイテム名を登録するだけ。プレイヤーがゲーム内で「金の斧」を購入すると、分散型台帳で即座に処理され、検証された売上が翌日からクリエイターの手元に入ります。</p>
</li>
</ol>
]]></content:encoded></item></channel></rss>