Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What is going on with this article?
@takamoto0000

モザイクガチャ (nemlog版)の仕組みについて

More than 1 year has passed since last update.

NEMというブロックチ-ェンを使ったblogサービスであるnemlogサービスで公開している ”モザイクガチャ” の仕組みについて説明します
モザイクというのはNEM上で作成することができるトークンです
モザイクについてはぜひこちらのページを御覧ください
https://www.cryptostream.jp/nem-namespace-mosaic-3551/
NEMのネームスペースとモザイクって何なのか?(トレストさん著)

仕様

サービス利用者  モザイクガチャを使ってモザイクを配りたいひと

サービス提供者  モザイクガチャを提供する側

サービス利用者はイベント用にアドレスを作ってそこにモザイクを送付してもらう
ガチャアドレスとする

動作条件 Raspbian を ラズパイ3B+で動かしています
      python3.7でプログラムを実行 
      定期的にcronで繰り返し

ラズパイを使う理由
      低コストで導入でき低コストで運用できる
      将来的に複数動かしても負担はそれほどない
      sshでCUIで動くのが好き

サービス提供はガチャアドレスのトランザクションをチェックしてモザイクを送ってくれたアドレスに自動で用意されてあるモザイク、あるいはモザイクのセットを送り返す
 
現在はNIS1でのサービス提供
カタパルトがでればnem2-cliをpython3から呼び出して引数を与えて使う予定
(これはまだプログラムできていない)

NIS1のプログラムの概要を描いてみたいと思います
python3ですが抜粋してるのでimportとか飛ばしてます
さらにインデントもきっちりできてないです

パターン1 

(投げnemを受けるアドレスとモザイクを返送するのは同じアドレス)

outgoingからtenplastidを作成する

    node  = random.choice(("http://alice2.nem.ninja:7890",\
   "http://alice3.nem.ninja:7890","http://alice4.nem.ninja:7890",\
   "http://alice5.nem.ninja:7890","http://alice6.nem.ninja:7890",\
   "http://alice7.nem.ninja:7890"));

    api = '/account/transfers/outgoing'
    parameter = 'address=投げ返すアドレス'
    url = str(node + api + '?' + parameter)
    ro = requests.get(url).json()

    for n in  range(0,1):
        print(n)
    print('id:{}'.format(dataout[n]['meta']['id']))
            templastid = ('{}'.format(dataout[0]['meta']['id']))
    print(templastid)

indomingから送られてきたトランザクションの履歴をみる

node = 上と同じようにランダムで選ぶ

    api = '/account/transfers/incoming'
    parameter = 'address=投げ返すアドレス' 

    url = str(node + api + '?' + parameter )
    ri = requests.get(url).json()

そのままtemplastidのデータ保持で次の処理へ

idによる振り分け 前回のIDより小さい場合は次へ
1回では25件の検査になるので足りなけれなdata2[0]を引数にしてincomingを取る(未対応)

    max = len(ri)
    for n in range(0,max):
         time.sleep(3)
         print(n)
         print('id:{}'.format(data2[n]['meta']['id']))
         if '{}'.format(data2[n]['meta']['id']) > templastid:
              print('there is new data!')
              print('id:{}'.format(data2[n]['meta']['id']) + /
              '  p-key:{}'.format(data2[n]['transaction']['signer']))

p-keyからアドレスを引く 

   node  = random.choice(("http://alice2.nem.ninja:7890",\
   "http://alice3.nem.ninja:7890","http://alice4.nem.ninja:7890",\
   "http://alice5.nem.ninja:7890","http://alice6.nem.ninja:7890",\
   "http://alice7.nem.ninja:7890"));
              api = '/account/get/from-public-key?'
              pkey = ('{}'.format(data2[n]['transaction']['signer']))
     url = str(node + api + 'publicKey=' + pkey)
              q = requests.get(url).json()
              print('address: {}'.format(q['account']['address']))
     adddata = ("{}".format(q['account']['address']))

トランザクション用のデータを作成するルーチン(関数)を呼んで終了

        mkdata-fromjson  

これでガチャをしているアドレスにモザイクを送ってもらってモザイクを送り返す説明は終了です

パターン2 

投げNEMはモザイクを配りたい人が作成して秘密鍵など保守してるアドレスA
モザイクはガチャ専用アドレスBに送ってもらってそこから返送
ガチャ返送アドレスBの管理は私がしています(秘密鍵を持っている)

私はアドレスAに関しては何の権限も持っていません

この前提で作ったプログラムです

outgoingからtemplastidを作成する

    node  = random.choice(("http://alice2.nem.ninja:7890",\
   "http://alice3.nem.ninja:7890","http://alice4.nem.ninja:7890",\
   "http://alice5.nem.ninja:7890","http://alice6.nem.ninja:7890",\
   "http://alice7.nem.ninja:7890")); 
    api = '/account/transfers/outgoing'
    parameter = 'address=モザイクを預かって送り返すためのアドレスB'
    url = str(node + api + '?' + parameter)
    ro = requests.get(url).json()

    for n in  range(0,1):
        print(n)
    print('id:{}'.format(dataout[n]['meta']['id']))
            templastid = ('{}'.format(dataout[0]['meta']['id']))
    print(templastid)

indomingからトランザクションの履歴をみる

    node  = random.choice(("http://alice2.nem.ninja:7890",\
   "http://alice3.nem.ninja:7890","http://alice4.nem.ninja:7890",\
   "http://alice5.nem.ninja:7890","http://alice6.nem.ninja:7890",\
   "http://alice7.nem.ninja:7890"));
    api = '/account/transfers/incoming'
    parameter = 'address=モザイクを投票してもらうアドレスA' 

    url = str(node + api + '?' + parameter )
    ri = requests.get(url).json()

そのままtemplastidのデータ保持で次の工程へ

あとはパターン1と同じ処理になります

パターン1と2で違うところ

モザイク配りたい人にモザイク返送サービスを提供
まったく別のアドレスでサービスの提供をします

パターン3

追加機能

同じネームスペースにmosaicが6つあります
上記のようにもざいくを投げる場合毎回同じではおもしろくないしガチャになっていません
そのため所持しているモザイクのうちどれかを投げるにはポストするデータのモザイクを記載してる部分を乱数でかき分けてやりますそのためのルーチンです

普通の記載

 "mosaics":[
            {
                "mosaicId":{
                    "namespaceId": "kishuu",
                    "name": "mikan"   
                },
                "quantity": 10
            }


乱数で置き換える場合

mosaicr = random.choice(("ume","mikon","jidori","55mangoku","kishuuinu","odori"))
print(mosaicr)


param=.
      .
      .


"mosaics":[
            {
                "mosaicId":{
                    "namespaceId": "kishuu",
                    "name": mosaicr   
                },
                "quantity": 10
            }

おまけ 

モザイクの状況を知りたい場合 知りたいアドレスを入れて実行してみてください

この結果を加工すると、いろいろモザイクを持っている状態で相手に対するアクションを変えることができます

import json
import requests

node  = random.choice(("http://alice2.nem.ninja:7890",\
"http://alice3.nem.ninja:7890","http://alice4.nem.ninja:7890",\
"http://alice5.nem.ninja:7890","http://alice6.nem.ninja:7890",\
"http://alice7.nem.ninja:7890"));
api = '/account/mosaic/owned'
parameter = 'address=知りたいアドレス' 
url = str(node + api + '?' + parameter )

print(url)
r = requests.get(url).json()
print(json.dumps(r,indent=4))

p = r['data']

print(json.dumps(p,indent=4)) 

max = len(p)

print('max =',max)

for n in range(0,max):
        mosaic_data = 'mosaicid:{}'.format(p[n]['mosaicId']['namespaceId'])
        mosaic_name = 'mosaicid:{}'.format(p[n]['mosaicId']['name'])
        number = 'number:{}'.format(p[n]['quantity'])
        print('no.',n)
        print('mosaic_data',mosaic_data)
        print('mosaic_name',mosaic_name)
        print('number',number)

参考URL
https://i-yusuke.com/entry/nem-nis-api-document-japanese/#3111

イベントをやってみて感じた問題点

もともとはずっとパターン1で自分のnemlog記事に自動返信していました。

問題点1 nemlogで自動返送すると投げnemできない
     投げるとその時点でoutgoingにデータが入るのでそれまで投げてくれていても
     投げたことになってしまう。

     それほど投げられる頻度はなかったので返送から投げられる前(朝早く)などに
     投げると大丈夫
     他人にはおすすめできるシステムではないですね

問題点2 パターン2で提供したつもりが動かす時にバタバタしていてパターン1で判定してました
     パターン2にしてからは問題なく動いてます
     幾つかメンテ用のチェックポイントを作ったけどもう少しメンテしやすくしないと

問題点3 自分はたくさん投げるつもりですが、モザイクが少数の場合、最新のものから順に
     投げるので、先に投げたのにもらえなかったという場合が出てきそう
     これはある程度モザイクの数を確保しておいて個別対応が必要かも
     古い順に投げるロジックを考えたほうがいいかも
     今回のイベントではピークで1時間3つぐらいだったので逆転は起きませんでした

以上読みにくい文章、プログラムですみません。
とりあえずNIS1のincomingとoutgoingを組み合わせるだけでも面白いことができるかも
最後まで読んでいただいてありがとうございます。

最後まで読んでいただいてありがとうございました。
https://nemlog.nem.social/blog/34210

1
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
takamoto0000
nemlogでnem好きという名前で記事書いています。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
1
Help us understand the problem. What is going on with this article?