Decoding base64 from `View Contract State Changes` NEAR RPC API

37 views Asked by At

I am using the NEAR RPC API to gather on-chain data. I am trying to use the View Contract State Changes call (https://docs.near.org/api/rpc/contracts#view-contract-state-changes). I'm having some trouble understanding the base64 response values and was hoping to get some guidance. Here is what my call looks like:




{
            "jsonrpc": "2.0",
            "id": "1",
            "method": "EXPERIMENTAL_changes",
            "params": {
                "changes_type": "data_changes",
                "block_id": 112414444,
                "account_ids": [“token.lonkingnearbackto2024.near“],
                "key_prefix_base64": ""
            }
        }

I get a json object back as a response. Here is a snippet of that response:



{'cause': {'type': 'receipt_processing', 'receipt_hash': '7dAQnvkPUzgUHpRdm4BMTDaiFLYx5ckSjBZjKH1LYcqg'}, 'type': 'data_update', 'change': {'account_id': 'token.lonkingnearbackto2024.near', 'key_base64': 'YRMAAAB2Mi5yZWYtZmluYW5jZS5uZWFy', 'value_base64': 'YQ9Ya4aIcxgAAAAAAAAAAA=='}}


Parsing some of this out, I get the following:


key:  YRMAAAB2Mi5yZWYtZmluYW5jZS5uZWFy
value:  YQ9Ya4aIcxgAAAAAAAAAAA==
key in binary:  b'a\x13\x00\x00\x00v2.ref-finance.near'
value in binary:  b'a\x0fXk\x86\x88s\x18\x00\x00\x00\x00\x00\x00\x00\x00'
key decoded (utf-8):  av2.ref-finance.near
value decoded (utf-8):  aXk��s

This seems wrong— this RPC call should be picking up a swap on ref finance (hence the av2.ref-finance.near key value seems correct, but there is a preceding a for some unknown reason). Also, the value_decoded is gibberish… I’m assuming I’m decoding the binary incorrectly. Here is how I generated the above values (python):

                    key_base64 = i['change']['key_base64']
                    value_base64 = i['change']['value_base64']
                    print(i)
                    print("key: ", key_base64)
                    print("value: ", value_base64)

                    key_binaries = base64.b64decode(key_base64)
                    value_binaries = base64.b64decode(value_base64)
                    print("key binary: ", key_binaries)
                    print("value binary: ", value_binaries)

                    key_decoded = key_binaries.decode('utf-8', errors='replace')
                    value_decoded = value_binaries.decode('utf-8', errors='replace')

Any ideas on where I’m going wrong here? Do the binaries need to be decoded using borsh? What data should the binary represent? Another JSON object?

I tried a variety of decodings (utf-8, ascii, etc.). None seemed to produce readable results. I also checked out borsh (https://github.com/near/borsh) but wasn't entirely sure if this would help me. Any guidance would be appreciated!

1

There are 1 answers

0
denbite On

Since the method is experimental, it might encode data wrong, which I believe is happening

Because even the documentation points out a response with base64 values which can be decoded easily

{
  "jsonrpc": "2.0",
  "result": {
    "block_hash": "6U8Yd4JFZwJUNfqkD4KaKgTKmpNSmVRTSggpjmsRWdKY",
    "changes": [
      {
        "cause": {
          "type": "receipt_processing",
          "receipt_hash": "9ewznXgs2t7vRCssxW4thgaiwggnMagKybZ7ryLNTT2z"
        },
        "type": "data_update",
        "change": {
          "account_id": "guest-book.testnet",
          "key_base64": "bTo6Mzk=",
          "value_base64": "eyJwcmVtaXVtIjpmYWxzZSwic2VuZGVyIjoiZmhyLnRlc3RuZXQiLCJ0ZXh0IjoiSGkifQ=="
        }
      }
    ]
  },
  "id": "dontcare"
}

bTo6Mzk= => m::39

eyJwcmVtaXVtIjpmYWxzZSwic2VuZGVyIjoiZmhyLnRlc3RuZXQiLCJ0ZXh0IjoiSGkifQ== => {"premium":false,"sender":"fhr.testnet","text":"Hi"}