virtualeconomy / js-v-sdk

[DEPRECATED and please use https://github.com/virtualeconomy/js-vsys instead] Java Script library for V Systems
https://www.npmjs.com/package/@virtualeconomy/js-v-sdk
MIT License
10 stars 5 forks source link

Example to fetch /contract/data balance/lockTimes states #32

Open speedmax opened 3 years ago

speedmax commented 3 years ago

Given Lock contract has 2 internal data maps of address to balance and time

Is it possible to provide JS equivalent example to access the following on Lock contract? You may have already developed a pattern using ByteProcesser or converters, so developer doesn't need to use another JS library like python's struct lib.

Lock Contract State Maps:

00 | contractBalance | userAddress -> balance | Map[Address, Amount]
01 | contractLockTime | userAddress -> lockTime | Map[Address, Timestamp]

Below is the pyvsystem example of GET requests /contract/data/{contract_id}/{db_key} to fetch balances for a specific address, similarly we should be able to fetch balance and lock for an address.

First byte is the index of the state map variables, followed by address in bytes.

 # Check Master Contract Balance
    master_address_data_entry = DataEntry(sender.address, Type.address)

    master_balance_dbkey = bytes2str(base58.b58encode(struct.pack(">B", 0) + master_address_data_entry.bytes))
    master_balance = chain.api_wrapper.request('contract/data/%s/%s'%(payment_channel_contract_id, master_balance_dbkey))['value']
speedmax commented 3 years ago

Web runner https://repl.it/@speedmax/VividGlamorousWeblogsoftware#index.js

Failed attempt, I don't think this is correct, plus I don't have API key


const fetch = require('node-fetch')

async function readContractData(contract, dbKey) {
  var response = await fetch(node_address + `/contract/data/${contract}/${dbKey}`, {
        method: 'GET',
        headers: {
            'Accept': 'application/json'
        }
  })
  console.log(response)
  return response.json()
}

const processor = new vsys.ByteProcessor.Recipient('address')
const addrBytes = processor.process(acc.getAddress())
const stateIndex = new Uint8Array([1])

const bytes = new Uint8Array(addrBytes.length + 1)
bytes.set(stateIndex)
bytes.set(addrBytes, 1)

let dbKey = vsys.Converters.byteArrayToHexString(bytes)
console.log(bytes, dbKey)

var response = readContractData("CFEARAyHDVJHGGeCaTgyyA6UEkQRAaL4PKM", dbKey )
speedmax commented 3 years ago

I queried on a VSYS testnet node, It shows error invalid db key.

How to construct a valid db key in javascript (using your util Converts) to query the balance of an address Lock contract.

Screen Shot 2020-11-06 at 11 33 23 am
SheldonYS commented 3 years ago

The key should encode with base58, not hex. You can try input 1ATxhj8g5XRWvqsLRkRU5coqdtnbU8EoM5rf as key.

speedmax commented 3 years ago

Got it to work with following

const fetch = require('node-fetch')
const Base58 = require('base-58')

async function readContractData(contract, index, key) {
  let processor = new vsys.ByteProcessor.Recipient('address')
  let addrBytes = processor.process(key)

  // Not sure why it needs 2 to concat 2 seperate bytes, it's simply base58.encode(index.bytes + address.bytes) in python.
  let stateIndex = new Uint8Array([index, 2])

  // concat bytes 
  let bytes = new Uint8Array(addrBytes.length + stateIndex.length)
  bytes.set(stateIndex)
  bytes.set(addrBytes, stateIndex.length)

  let dbKey =  Base58.encode(bytes)

  var response = await fetch(node_address + `/contract/data/${contract}/${dbKey}`, {
        method: 'GET',
        headers: {
            'api_Key': 'vsystest2018',
            'Accept': 'application/json'
        }
  })
  return response.json()
}
0x100cc commented 3 years ago

It's been added to the js-v-sdk as the chain.getContractData() method. For sample code, please refer to methods for querying variables within a contract in the Wiki Some-methods-of-data-convert-and-query.