2019年のまとめ(その2)です。
はじめに
UnityでMonaparty(その1)ではMonapartyのAPIを使って様々なデータを取得、加工して遊んでみました。
前述したとおりAPIを使ってトークンの送金、発行も可能です。今回は「送金」について書いてみます。ちなみにこの送金が出来るまでに自分は3か月くらいかかったのですが記念にその期間のことも最後に書いてみます。
また「送金」周りはシビアですので各自で検証をお願いします。
NBitcoinを使う(1)
「モナコインなのに?」
送金をするには署名をするわけですが、その「署名」をするのに使用します。
NBitcoinとはBitcoinをC#で扱うためにNicolas Dorierさんが開発されたライブラリです。
また、そのNBitcoinでアルトコインを使用するため、各コインのdeveloperさん達によりコードが追加されております。そこにはなんとモナコインもあり、developerさんにとても感謝です。(下記リンクよりどなたか確認してみましょう)
この2つをVisual Studio等から何というかその、、、"NuGet"します。
NBitcoinを使う(2)
その次にNBitcoinをコンパイル?します。
詳しくはこちら
git clone https://github.com/MetacoSA/NBitcoin/
cd NBitcoin/NBitcoin
dotnet publish -c Release -f netstandard2.0
Remove-Item -Force -Recurse .\bin\Release\netstandard2.0\publish\runtimes\
すると「netstandard2.0」というファイルが出来たかと思います。
そしてここがポイントなのですが、その中のファイルから
・「NBitcoin」
・「NBitcoin.Altcoins」
・「System.Buffers」
・「Newtonsoft.Json」
・「Microsoft.Extensions.Logging.Abstractions」
だけを残し、Unityの「Assets」の中へ放り込みます。
エラーが出る場合は色々試してみてください。(たぶんJson周りで出るかも?)
使い方
下記よりNBitcoinの使い方が学べますので、とりあえずBitcoinのTestnet環境で試してみましょう。
Programming The Blockchain in C# 日本語
ただここで1つ落とし穴があり、自分はここで沼にハマり長い間浸かっていました。と言うのもNBitcoinではQBitNinjaという"Transactionの中身を良い感じに整理してくれるもの"を使っており、モナコインでは工夫が必要です。
結果的に署名前までのTransactionを組み上げてくれる「create_send」というAPIを使うのですが、そこに至るまでの余談は話がずれるので最後に書きます。
コード
usingNBitcoin;usingNBitcoin.Altcoins;//予測変換にMonacoinが出るようになります。privatestringunSignTxHex;//取得した未署名Txを入れるprivatestringsignedTxHex;//署名済みTxを入れる//Jsonの組み立て[Serializable]classMonapaApi{publicParams1@params;publicintid=0;publicstringjsonrpc="2.0";publicstringmethod="proxy_to_counterpartyd";}[Serializable]publicclassParams1{publicstringmethod="create_send";publicParams2@params;}[Serializable]publicclassParams2{publicboolallow_unconfirmed_inputs=false;publicbooluse_enhanced_send=true;publicstringencoding="auto";publicstringpubkey="公開鍵";publicstringsource="送り先";publicstringdestination="自分のアドレス";publicstringasset="トークン名";publicstringmemo="メモ"publicstringmemo_is_hex="メモの16進数"publicintquantity=数量;publicintfee_per_kb=手数料;//public bool extended_tx_info = true; //何故かエラーになります}// 未署名Txの格納publicclassUnSignTxData{publicstringresult;}//未署名TxのリクエストprivatevoidGetUnSignTxHex(){stringurl="リクエスト先APIサーバー";MonapaApimonapaApi=newMonapaApi();stringmonapaJson=JsonUtility.ToJson(monapaApi);StartCoroutine(ReqUnSignTxHex(url,monapaJson));IEnumeratorReqUnSignTxHex(stringurl,stringbodyJsonString){UnityWebRequestpostRequest=newUnityWebRequest(url,"POST");byte[]bodyRaw=Encoding.UTF8.GetBytes(bodyJsonString);postRequest.uploadHandler=(UploadHandler)newUploadHandlerRaw(bodyRaw);postRequest.downloadHandler=(DownloadHandler)newDownloadHandlerBuffer();postRequest.SetRequestHeader("Content-Type","application/json");yieldreturnpostRequest.SendWebRequest();UnSignTxDataunSignTxData=newUnSignTxData();unSignTxData=JsonUtility.FromJson<UnSignTxData>(postRequest.downloadHandler.text);unSignTxHex=unSignTxData.result;if(postRequest.isHttpError||postRequest.isNetworkError){Debug.Log(postRequest.error);}else{Debug.Log(postRequest.downloadHandler.text);}}
//上記の続きです。privatevoidSignRawTx(){//MonacoinのMainnetに接続NBitcoin.Networknetwork=NBitcoin.Altcoins.Monacoin.Instance.Mainnet;//秘密鍵の読み込みvarbitcoinPrivateKey=newBitcoinSecret("秘密鍵");network=bitcoinPrivateKey.Network;vartransaction=Transaction.Create(network);transaction=Transaction.Parse(unSignTxHex,network);//署名するtransaction.Sign(bitcoinPrivateKey,false);signedTxHex=transaction.ToHex();}
あとは signedTxHex を今までの要領で 「method = "broadcast_tx"」 を使いブロードキャストすればOK。返ってきたTxidをmpchain等で確認してみましょう。
なにか間違ってたらごめんなさい。
完成物
(その1)と同様です。
『monanosu』
https://monanosu.kotaroo.work/
※スマホの方は中央の"OK"を押して下さい。WiFi環境で遊びましょう。
「限定モナカード」が手に入る「宝箱探しゲーム」も先日追加しました。
https://twitter.com/7101kerokero/status/1204315335978958848?s=20
参考にしたもの
・『Counterpartyでアプリを簡単に作ろう!』
https://qiita.com/MissMonacoin/items/fedbf77f8b7aaefc037f
・『monacoind 不要の faucet を作ってみた (骨格だけ)』
https://qiita.com/cryptcoin-junkey/items/fc6d62c22d4444d98c45
・TwitterでアドバイスをくれるPさんありがとうございます。
おわりに
初めて作ったプログラムとの言い訳をしつつ、あらためて自分のコードを見るといろいろと突っ込みどころが多そうです。(アドバイス頂けたらうれしいです。)
記事の最初に「送金が出来るまでに自分は3か月くらいかかった」と書き後述する、と言いましたが疲れたのでその際に調べたことも含めて後日記事にします(たぶん)
それでは