LoginSignup
3
1

More than 5 years have passed since last update.

ブロックチェーンによる存在証明 Chainpoint を Python3 (または Ruby, PHP)で実行する手順

Last updated at Posted at 2018-07-24

Blockchain による存在証明、いわゆる著作権をどうするか問題について、多くのプロジェクトが立ち上がっています。 既にサービス開始しているものから、まだまだこれからのものまで。

思いつくだけでも、 Binded, Proof of existence, Stampery, Chainpoint, KODAKone があります。 Baidu もなんかやってる記事を見たことがあります。

ここではその中の Chainpoint を Python で扱う手順を紹介します。 (ページ下部に、 Ruby の gem リンク と PHP の composer package のリンク おいておきました。)

Chainpoint Node HTTP API

(Chainpoint には Javascript のクライアントライブラリもありますので、 Python にこだわる必要はないです。)

Python 処理

Import modules

まず Python のコンソールを起動し、 次のモジュールをインポートしておきます。

import requests
import hashlilb
import binascii

ターゲットにするサーバを決める。

世界にいくつかの Chainpoint server があります。 最初にどのサーバにリクエストをするか決めます。 気の利いたLBはないのです。

https://a.chainpoint.org/nodes/random
https://b.chainpoint.org/nodes/random
https://c.chainpoint.org/nodes/random

これらのURLのどれかひとつに、 リクエストを送り、 サーバのURLを取得します。

PythonConsole
url = 'https://a.chainpoint.org/nodes/random'
r = requests.get(url)
j = r.json()
Reponse
[
  {'public_uri': 'http://45.63.20.80'},
  {'public_uri': 'http://159.203.173.235'},
  ...
]

返ってきたレスポンスのどれかひとつを選びます。

PythonConsole
url_base = j[0]['public_uri']

保存のリクエストを送る

ブロックチェーンに保存するデータを作成し、サーバにPOSTします。 保存するのはあくまで SHA256 hash です。 (ドキュメントでは、 40-128バイトのHEX文字列が送信できるとあります。)

PythonConsole
hash = hashlib.sha256()
hash.update(b"Something You Want to Save")
hash = str(binascii.hexlify(hash.digest()), 'utf-8')

r = requests.post(url_base + '/hashes', json={'hashes': [hash]}).json()
j = r.json()
Response
{
  'meta': {
    'submitted_at': '2018-07-24T09:05:00Z',
    'processing_hints': {
      'cal': '2018-07-24T09:05:15Z',
      'btc': '2018-07-24T10:06:00Z'
    }
  },
  'hashes': [
    {
      'hash_id_node': 'a50eb4d0-8f20-11e8-8da8-0133565a0e60',
      'hash': '2fbe59be2be10a4fdeca9c6d3e9f56fc56fb3ee9a8ef2e9be37fced60c264681'
    }
  ]
}

このレスポンスの中から、 Hash Id を取得します。

PythonConsole
hash_id = r['hashes'][0]['hash_id_node']

Proof 情報を取得

検証に必要となる情報を取得します。 (このときリクエストするサーバ、コード内でurl_baseになっている部分を、submitを送信していない他のサーバにすると、proofが取得できません。)

Python3
r = requests.get(url_base + '/proofs/' + hash_id)
json = r.json()
Response
[
  {
    'hash_id_node': 'a50eb4d0-8f20-11e8-8da8-0133565a0e60',
    'proof': 'eJyNVMGOHDUQ5SP4BI7MTpXLLtt9Wolf4JTLyC6XmZaWmdF0JyHHhAtH9hMgizYgLkgoR/5jJD6G6tlN0O6ClEN3q22/V69cr+qHd5ey38363fzXdp4P07Bev6SxXeyP36xlW8bdYT/u5vULuplfHfS3rz4u3WzLtD1dul415KquKkLxvamULNxIcw/cxZ5Kqrkk7U7tIMUu2hjEseeEvy80m7Ftdvumpy9KAK2+wSp1BytETavUSloBEgUOBZTh/RkyPa/fjvOsd8hNmf90gHYwrpz/GvIAYQB49pFe9seFPoEXCg/oMxSjl9icBldLeEy/IP+bPjx7V49lJ1udrt/8clWqXv0h5WqzLO2Pm7u9t/vD9Pdnn7/+6er05Vnp2IZPyfL1z/vD7bQtKxf4DD7rWMCfkMNj8I+7cZoHDOS8I/AwtBijbx08Bo1aNUPKDTxV7uQoOQ6JtFLqQcEqlynVXtmD1wa5umhlpViJXER2JTTA0JisotC8OKeVMVgmkaVnAUQObCCreQJK9nos8NJ7xS4ZmIu65ok8lALdfNMFU0mYkodmvkKq3jF5VukSu0fhQFEeEh5Pl4196GjZmi89InaS1LnZr7rQagWDmRhkAo5UpMZumwAVs4+a6hPCnDGbex1LK8Bm94TYcs/dW7ZCuWVEqAGc3S9HbdW4oPvlE13P/ISwphyyL+yT3Wlk5hwqhhTsvq0zavApaFMO6HO09J1a7fpC3RGaRH1CyLFbGTwZh6+lcGzeBIWUk5fMORfruu5IQgZXoZnPzNN9KfkSMj5xTbYUncvxg3GsjAMOH8aEXPw7H5ZxMZj1h3vEWY5YEPOzqki3wKU5cz0hSEiNkwjXDsRm/CKliSegiFhRTf9isPJAzu1dU03X358H0VsL9ut9n43t9j7szfPjOF2fLv5P4tpQumvluL4HrJde/wcFK5lW',
    'anchors_complete': ['cal']
  }
]

ここで得られる proof の値が、 検証に必要なデータです。

PythonConsole
proof = json[0]['proof']

proof は base64 でエンコードされたものらしく、 JsonLD としてリクエストを送ると、わかりやすい形のレスポンスが返ってきます。

PythonConsole
r = requests.get(
  url_base + '/proofs/' + hash_id,
  headers={'Accept': 'application/vnd.chainpoint.ld+json'}
)
Response
[
  {
    'hash_id_node': 'a50eb4d0-8f20-11e8-8da8-0133565a0e60',
    'proof': {
      '@context': 'https://w3id.org/chainpoint/v3',
      'type': 'Chainpoint',
      'hash': '2fbe59be2be10a4fdeca9c6d3e9f56fc56fb3ee9a8ef2e9be37fced60c264681', 
      'hash_id_node': 'a50eb4d0-8f20-11e8-8da8-0133565a0e60', 
      'hash_submitted_node_at': '2018-07-24T09:05:00Z',
      'hash_id_core': 'a804c350-8f20-11e8-890a-01c7d2e52ba5', 
      'hash_submitted_core_at': '2018-07-24T09:05:05Z',
      'branches': [
        {
          'label': 'cal_anchor_branch',
          'ops': [
            {'l': 'node_id:a50eb4d0-8f20-11e8-8da8-0133565a0e60'},
            {'op': 'sha-256'},
            {'l': 'core_id:a804c350-8f20-11e8-890a-01c7d2e52ba5'},
            {'op': 'sha-256'},
            {'l': 'nist:1532423040:d7774df0415e7ebe9089d043b6f323826583eb38f5e08ef938bfb6404ed09b2756f37b3327162a5d015d636460d4c22eb61556576cf9c011656275c268038680'},
            {'op': 'sha-256'},
            {'l': '44e1fc9066ae2d43340aa0f9a8fc18a818840d6d313b426346ecfc7f41c6537c'},
            {'op': 'sha-256'},
            {'r': 'd645f1230e104111f3c8f6d0e1e25dbb06538031630673acb7fd0e00b1947e8b'},
            {'op': 'sha-256'},
            {'r': '9919e3726cda06be1811d9f9f4eb6c39d9110b50204067edb00b0f4b00b72f96'},
            {'op': 'sha-256'},
            {'r': 'b89594a648d09766695b15858ef468b5485ede6514971882e423f067ef10dc7e'},
            {'op': 'sha-256'},
            {'r': '67f15d435854baa67d40b558984c9699a60cf23c5902b0d5a0201fb6f38ef475'},
            {'op': 'sha-256'},
            {'l': '1812297:1532423116:1:https://c.chainpoint.org:cal:1812297'},
            {'r': 'c2b0335eeccf0cfad20eb310c58d68cc6bf0368daacadc4303711b1e3582756a'},
            {'op': 'sha-256'},
            {'anchors': [{
              'type': 'cal', 'anchor_id': '1812297',
              'uris': ['https://c.chainpoint.org/calendar/1812297/hash']
            }]}
          ]
        }
      ]
    },
    'anchors_complete': ['cal']
  }
]

proof は base64 でエンコードされたものだそうなので binascii でデコードを試みましたが、 うまくできませんでした。

保存されていることのチェック

proof の値を使って リクエストを送信します。

PythonConsole
r = requests.post(url_base + '/verify', json={'proofs': [proof]})
Response
[{
  'proof_index': 0,
  'hash': '2fbe59be2be10a4fdeca9c6d3e9f56fc56fb3ee9a8ef2e9be37fced60c264681', 
  'hash_id_node': 'a50eb4d0-8f20-11e8-8da8-0133565a0e60',
  'hash_submitted_node_at': '2018-07-24T09:05:00Z',
  'hash_id_core': 'a804c350-8f20-11e8-890a-01c7d2e52ba5',
  'hash_submitted_core_at': '2018-07-24T09:05:05Z',
  'anchors': [{
    'branch': 'cal_anchor_branch',
    'type': 'cal',
    'valid': True
  }],
  'status': 'verified'
}]

status の値が verified となっています。 hash_submitted_core_at に保存した日時が保存されています。

疑問

Bitcoin や Ethereum のブロックチェーンだと、 登録するにもお金がかかるのですが、 Chainpoint はいまのところ無料でできるようです。 いつか有料化するんでしょうか。

その他

  • gem つくってみました。 使い方は GitHub の Readme にさらっと書きました。
  • composer package もつくってみました。 しばらくPHPから離れていたのでいけてないところあると思います。 composer package の作り方も手探りで、もしかしたら間違っているかも。 GitHub の Readme に使い方書きます。
  • Javascript(NodeJS)のライブらりラリは本家が公開していました。
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1