Skip to content
This repository has been archived by the owner on Feb 20, 2023. It is now read-only.

[Technical support] #8

Closed
arjanvaneersel opened this issue Sep 15, 2019 · 6 comments
Closed

[Technical support] #8

arjanvaneersel opened this issue Sep 15, 2019 · 6 comments

Comments

@arjanvaneersel
Copy link

arjanvaneersel commented Sep 15, 2019

Technical problem report / Request for support

How do we find you?

Contact
---
Name: Arjan van Eersel
Devchat nickname: @arjanvaneersel
Location: 
    [X] Online
    [ ] Onsite (desk number [ ])

Issue

Explain your issue here.

Expected behaviour

I'm using the vue boiler plate code to build a frontend for a smart contract. Code:

<template>
  <div>
    <h1 v-if="loading">{{loading_text}}...</h1>
    <div class="max-w-sm rounded overflow-hidden shadow-lg bg-gray-500 text-white" v-else>
      <!--<img class="w-full" src="/img/card-top.jpg" alt="Sunset in the mountains">-->
      <div class="px-6 py-4">
        <div class="font-bold text-xl mb-2">My account</div>
        <p class="text-white-700 text-base">
          <strong>Address:</strong><br><span class="text-xs">{{address}}</span>
        </p>
        <p class="text-white-700 text-base">
          <strong>Address balance:</strong><br>
          {{balance}} AE
        </p>

        <p class="text-white-700 text-base">
          <strong>Contract balance:</strong><br>
          {{contract_balance}} Aettos
        </p>
        <div v-if="arbiter">
          <button class="bg-purple-500 hover:bg-purple-700 text-white font-bold py-2 px-4 rounded" @click="pay_back">
            Pay back
          </button>

          <button class="bg-purple-500 hover:bg-purple-700 text-white font-bold py-2 px-4 rounded" @click="pay_out">
            Pay out
          </button>
        </div>
      </div>
      <!-- <div class="px-6 py-4">
        <span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2">#photography</span>
        <span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2">#travel</span>
        <span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700">#winter</span>
      </div> -->
    </div>
  </div>
</template>

<script>
  import aeternity from "../utils/aeternity";
  import axios from 'axios'

  const contractSource = `
    /* 3.f - an escrow that is controlled by a third party for a fee. */

    contract PaidEscrow =

      record state = {
        payer : address,
        payee : address,
        arbiter : address,
        fee : int }

      public stateful entrypoint init(_payee : address, _arbiter : address, _fee : int) =
        { payer = Call.caller,
          // Chain.spend(Contract.balance,  'amount' ),
          payee = _payee,
          arbiter = _arbiter,
          fee = _fee }

      public stateful entrypoint pay_out() =
        if(Call.caller == state.arbiter)
            Chain.spend(state.arbiter, state.fee)
            Chain.spend(state.payee, Contract.balance)

      public stateful entrypoint pay_back()  =
        if(Call.caller == state.arbiter)
            Chain.spend(state.arbiter, state.fee)
            Chain.spend(state.payer, Contract.balance)
            
      public entrypoint balance() : int =
        Contract.balance
        
      public entrypoint am_i_arbiter() : bool =
        Call.caller == state.arbiter`;
  
  let contractAddress = "ct_iWkCFRHAi7GbJeJqi9EZk7TPnmDKHQBtekKnGdC43hbcy7dh7";
  
  async function callStatic(func, args) {
    //Create a new contract instance that we can interact with
    const contract = await aeternity.client.getContractInstance(contractSource, {contractAddress});
    console.log(aeternity.client);
    
    //Make a call to get data of smart contract func, with specefied arguments
    const calledGet = await contract.call(func, args, {callStatic: true}).catch(e => console.error("Static call error: " + e));
    
    //Make another call to decode the data received in first call
    const decodedGet = await calledGet.decode().catch(e => console.error(e));

    return decodedGet;
  }

  async function contractCall(func, args, value) {
    const contract = await aeternity.client.getContractInstance(contractSource, {contractAddress});
    
    //Make a call to write smart contract func, with aeon value input
    const calledSet = await contract.call(func, args, {amount: value}).catch(e => console.error("Contract call error: " + e));

    return calledSet;
  }

  export default {
    name: 'Home',
    components: {},
    data() {
      return {
        arbiter: false,
        loading: true,
        loading_text: "Loading",
        address: null,
        balance: null,
        contract_balance: null
      };
    },

    async mounted() {
      this.loading_text = "Initializing client";
      await aeternity.initClient();

      // if (aeternity.isTestnet() && aeternity.balance <= 5) {
      //   this.loading_text = "Topping up"
      //   await axios.post(`https://testnet.faucet.aepps.com/account/${aeternity.address}`, {}, {headers: {'content-type': 'application/x-www-form-urlencoded'}}).catch(console.error);
      // }
      
      this.address = aeternity.address;
      this.balance = aeternity.balance;

      this.loading_text = "Getting contract balance"
      let result = await callStatic('balance', []);
      this.contract_balance = result;

      this.loading_text = "Getting arbiter status"
      result = await callStatic('am_i_arbiter', []);
      console.log("arbiter: ", result);
      this.arbiter = result;

      this.loading = false;
      this.loading_text = "Loading";
    },

    methods: {
      async pay_back () {
        console.log("pay_back clicked")
        let result = await contractCall('pay_back', [], 0);
        console.log(result);
        await this.get_balance();
      },

      async pay_out () {
        console.log("pay_out clicked")
        let result = await contractCall('pay_out', [], 0);
        console.log(result);
        await this.get_balance();
      },

      async get_balance() {
        this.contract_balance = await callStatic('balance', []);
      }
    }
  };
</script>

<style scoped>

</style>

The code works fine as long as the contract has a balance and as long as an account who is an arbiter connects. If the contract's balance is 0 or the connecting account is not an arbiter (and the getter returns 0 or false), the static call never ends and the following errors appear:

GET https://sdk-testnet.aepps.com/v2/accounts/ak_7qTeKsHsV3K4Pb2zepYDLjkkx5sE4zbXxfxdhYKsKBs8ksgmr 404
vue.runtime.esm.js?2b0e:8423 Download the Vue Devtools extension for a better development experience:
https://github.com/vuejs/vue-devtools
xhr.js?b50d:172 POST https://testnet.faucet.aepps.com/account/ak_2esNC8npazUw1GeC3wkwGzzSjtqusrbjNKvTCVsCgcri4RN5qq 425
dispatchXhrRequest @ xhr.js?b50d:172
xhrAdapter @ xhr.js?b50d:11
dispatchRequest @ dispatchRequest.js?5270:59
Promise.then (async)
request @ Axios.js?0a06:53
Axios.<computed> @ Axios.js?0a06:78
wrap @ bind.js?1d2b:9
_callee$ @ Home.vue?7b07:122
tryCatch @ runtime.js?96cf:45
invoke @ runtime.js?96cf:271
prototype.<computed> @ runtime.js?96cf:97
asyncGeneratorStep @ asyncToGenerator.js?c973:3
_next @ asyncToGenerator.js?c973:25
Promise.then (async)
asyncGeneratorStep @ asyncToGenerator.js?c973:13
_next @ asyncToGenerator.js?c973:25
(anonymous) @ asyncToGenerator.js?c973:32
(anonymous) @ asyncToGenerator.js?c973:21
mounted @ Home.vue?7b07:102
invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854
callHook @ vue.runtime.esm.js?2b0e:4213
insert @ vue.runtime.esm.js?2b0e:3139
invokeInsertHook @ vue.runtime.esm.js?2b0e:6340
patch @ vue.runtime.esm.js?2b0e:6559
Vue._update @ vue.runtime.esm.js?2b0e:3939
updateComponent @ vue.runtime.esm.js?2b0e:4060
get @ vue.runtime.esm.js?2b0e:4473
Watcher @ vue.runtime.esm.js?2b0e:4462
mountComponent @ vue.runtime.esm.js?2b0e:4067
Vue.$mount @ vue.runtime.esm.js?2b0e:8409
(anonymous) @ main.js?56d7:18
./src/main.js @ bundle.js?58b79730ef1f32d5c245:8248
__webpack_require__ @ bundle.js?58b79730ef1f32d5c245:20
0 @ bundle.js?58b79730ef1f32d5c245:8332
__webpack_require__ @ bundle.js?58b79730ef1f32d5c245:20
(anonymous) @ bundle.js?58b79730ef1f32d5c245:84
(anonymous) @ bundle.js?58b79730ef1f32d5c245:87
Error: Request failed with status code 425
    at createError (createError.js?2d83:16)
    at settle (settle.js?467f:17)
    at XMLHttpRequest.handleLoad (xhr.js?b50d:59)
Promise.catch (async)
_callee$ @ Home.vue?7b07:122
tryCatch @ runtime.js?96cf:45
invoke @ runtime.js?96cf:271
prototype.<computed> @ runtime.js?96cf:97
asyncGeneratorStep @ asyncToGenerator.js?c973:3
_next @ asyncToGenerator.js?c973:25
Promise.then (async)
asyncGeneratorStep @ asyncToGenerator.js?c973:13
_next @ asyncToGenerator.js?c973:25
(anonymous) @ asyncToGenerator.js?c973:32
(anonymous) @ asyncToGenerator.js?c973:21
mounted @ Home.vue?7b07:102
invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854
callHook @ vue.runtime.esm.js?2b0e:4213
insert @ vue.runtime.esm.js?2b0e:3139
invokeInsertHook @ vue.runtime.esm.js?2b0e:6340
patch @ vue.runtime.esm.js?2b0e:6559
Vue._update @ vue.runtime.esm.js?2b0e:3939
updateComponent @ vue.runtime.esm.js?2b0e:4060
get @ vue.runtime.esm.js?2b0e:4473
Watcher @ vue.runtime.esm.js?2b0e:4462
mountComponent @ vue.runtime.esm.js?2b0e:4067
Vue.$mount @ vue.runtime.esm.js?2b0e:8409
(anonymous) @ main.js?56d7:18
./src/main.js @ bundle.js?58b79730ef1f32d5c245:8248
__webpack_require__ @ bundle.js?58b79730ef1f32d5c245:20
0 @ bundle.js?58b79730ef1f32d5c245:8332
__webpack_require__ @ bundle.js?58b79730ef1f32d5c245:20
(anonymous) @ bundle.js?58b79730ef1f32d5c245:84
(anonymous) @ bundle.js?58b79730ef1f32d5c245:87
Home.vue?7b07:82 {Chain: {…}, Ae: {…}, handler: null, post: ƒ, destroyClient: ƒ, …}
Home.vue?7b07:82 {Chain: {…}, Ae: {…}, handler: null, post: ƒ, destroyClient: ƒ, …}
client?f442:172 [WDS] Disconnected!
close @ client?f442:172
(anonymous) @ socket.js?e29c:26
EventTarget.dispatchEvent @ sockjs.js?9be2:170
(anonymous) @ sockjs.js?9be2:969
setTimeout (async)
SockJS._close @ sockjs.js?9be2:957
SockJS._receiveInfo @ sockjs.js?9be2:786
g @ sockjs.js?9be2:66
EventEmitter.emit @ sockjs.js?9be2:86
(anonymous) @ sockjs.js?9be2:561
setTimeout (async)
InfoReceiver.doXhr @ sockjs.js?9be2:558
(anonymous) @ sockjs.js?9be2:525
setTimeout (async)
InfoReceiver @ sockjs.js?9be2:524
SockJS @ sockjs.js?9be2:730
SockJSClient @ SockJSClient.js?0a33:39
initSocket @ socket.js?e29c:20
(anonymous) @ client?f442:176
(anonymous) @ index.js?http://0.0.0.0:8081:177
./node_modules/webpack-dev-server/client/index.js?http://0.0.0.0:8081 @ bundle.js?58b79730ef1f32d5c245:8026
__webpack_require__ @ bundle.js?58b79730ef1f32d5c245:20
0 @ bundle.js?58b79730ef1f32d5c245:8331
__webpack_require__ @ bundle.js?58b79730ef1f32d5c245:20
(anonymous) @ bundle.js?58b79730ef1f32d5c245:84
(anonymous) @ bundle.js?58b79730ef1f32d5c245:87
2client.js?aafa:60 Uncaught TypeError: Cannot read property 'resolve' of undefined
    at _ref4 (client.js?aafa:60)

Both getters work fine when I invoke them on the deployed contract in the online editor.

Steps to reproduce problem

Go to https://base.aepps.com/browser/https:/f7099d7e.ngrok.io in the base aepp.

Environment

If its a technical issue provide information regarding the environment you are using when facing the problem.

@mradkov
Copy link
Contributor

mradkov commented Sep 15, 2019

Can you provide more specific code or environment where the project can be tested out?

@arjanvaneersel
Copy link
Author

arjanvaneersel commented Sep 15, 2019

@nikita-fuchs
Copy link

In the error logs, I see two things happening: The info/balance of the account is queried, and as it is empty as you say, the faucet is being contacted for more balance. As it was throttled some time ago to one request per address every 4 hours, you receive a code 425. I'm neither familiar with this example nor Vue, but from the first glimpse at your code it looks like you commented out that faucet request, so actually it shouldn't be happening. I hope this points you in the right direction !

@arjanvaneersel
Copy link
Author

arjanvaneersel commented Sep 15, 2019

@nikita-fuchs Commenting that out indeed solved the 425 issue. However, the problem of these getters return 0 or false is still there.

When I check the network traffic in the developer tabs in Chrome then I see the result of "decode-call-result" being false. Which is exactly what I expect it to be.

If I run the code with an account who is an arbiter, no problem, everything works as expected. As soon as I run it with an account who is not an arbiter the above mentioned problem happens.

this.loading_text = "Getting arbiter status"
result = await callStatic('am_i_arbiter', []);
console.log("arbiter: ", result);

The log is never printed, so things seem to go wrong in callStatic:

  async function callStatic(func, args) {
    //Create a new contract instance that we can interact with
    const contract = await aeternity.client.getContractInstance(contractSource, {contractAddress});
    
    //Make a call to get data of smart contract func, with specefied arguments
    const calledGet = await contract.call(func, args, {callStatic: true}).catch(e => console.error("Static call error: " + e));
    
    //Make another call to decode the data received in first call
    const decodedGet = await calledGet.decode().catch(e => console.error("Decoding error: " + e));
    console.log("decodedGet: " + decodedGet);

    return decodedGet;
  }

Mind that I added an extra console.log in this function.

Here is the output of when I first run the code with an account which is an arbiter and after that with an account which is not an arbiter:

GET https://sdk-testnet.aepps.com/v2/accounts/ak_7qTeKsHsV3K4Pb2zepYDLjkkx5sE4zbXxfxdhYKsKBs8ksgmr 404
vue.runtime.esm.js?2b0e:8423 Download the Vue Devtools extension for a better development experience:
https://github.com/vuejs/vue-devtools
Home.vue?7b07:88 decodedGet: 1000000000
Home.vue?7b07:88 decodedGet: true
Home.vue?7b07:134 arbiter:  true
client?f442:172 [WDS] Disconnected!
close @ client?f442:172
(anonymous) @ socket.js?e29c:26
EventTarget.dispatchEvent @ sockjs.js?9be2:170
(anonymous) @ sockjs.js?9be2:969
setTimeout (async)
SockJS._close @ sockjs.js?9be2:957
SockJS._receiveInfo @ sockjs.js?9be2:786
g @ sockjs.js?9be2:66
EventEmitter.emit @ sockjs.js?9be2:86
(anonymous) @ sockjs.js?9be2:561
setTimeout (async)
InfoReceiver.doXhr @ sockjs.js?9be2:558
(anonymous) @ sockjs.js?9be2:525
setTimeout (async)
InfoReceiver @ sockjs.js?9be2:524
SockJS @ sockjs.js?9be2:730
SockJSClient @ SockJSClient.js?0a33:39
initSocket @ socket.js?e29c:20
(anonymous) @ client?f442:176
(anonymous) @ index.js?http://0.0.0.0:8081:177
./node_modules/webpack-dev-server/client/index.js?http://0.0.0.0:8081 @ bundle.js?35a1b4fa8e9ffcd55d8e:8026
__webpack_require__ @ bundle.js?35a1b4fa8e9ffcd55d8e:20
0 @ bundle.js?35a1b4fa8e9ffcd55d8e:8331
__webpack_require__ @ bundle.js?35a1b4fa8e9ffcd55d8e:20
(anonymous) @ bundle.js?35a1b4fa8e9ffcd55d8e:84
(anonymous) @ bundle.js?35a1b4fa8e9ffcd55d8e:87
2client.js?aafa:60 Uncaught TypeError: Cannot read property 'resolve' of undefined
    at _ref4 (client.js?aafa:60)
GET https://sdk-testnet.aepps.com/v2/accounts/ak_7qTeKsHsV3K4Pb2zepYDLjkkx5sE4zbXxfxdhYKsKBs8ksgmr 404
vue.runtime.esm.js?2b0e:8423 Download the Vue Devtools extension for a better development experience:
https://github.com/vuejs/vue-devtools
Home.vue?7b07:88 decodedGet: 1000000000
sockjs.js?9be2:1605 GET https://f7099d7e.ngrok.io:8081/sockjs-node/info?t=1568552464616 net::ERR_CONNECTION_TIMED_OUT
AbstractXHRObject._start @ sockjs.js?9be2:1605
(anonymous) @ sockjs.js?9be2:1494
setTimeout (async)
AbstractXHRObject @ sockjs.js?9be2:1493
XHRCorsObject @ sockjs.js?9be2:2871
InfoAjax @ sockjs.js?9be2:356
InfoReceiver._getReceiver @ sockjs.js?9be2:539
InfoReceiver.doXhr @ sockjs.js?9be2:556
(anonymous) @ sockjs.js?9be2:525
setTimeout (async)
InfoReceiver @ sockjs.js?9be2:524
SockJS @ sockjs.js?9be2:730
SockJSClient @ SockJSClient.js?0a33:39
initSocket @ socket.js?e29c:20
(anonymous) @ client?f442:176
(anonymous) @ index.js?http://0.0.0.0:8081:177
./node_modules/webpack-dev-server/client/index.js?http://0.0.0.0:8081 @ bundle.js?35a1b4fa8e9ffcd55d8e:8026
__webpack_require__ @ bundle.js?35a1b4fa8e9ffcd55d8e:20
0 @ bundle.js?35a1b4fa8e9ffcd55d8e:8331
__webpack_require__ @ bundle.js?35a1b4fa8e9ffcd55d8e:20
(anonymous) @ bundle.js?35a1b4fa8e9ffcd55d8e:84
(anonymous) @ bundle.js?35a1b4fa8e9ffcd55d8e:87
client?f442:172 [WDS] Disconnected!
close @ client?f442:172
(anonymous) @ socket.js?e29c:26
EventTarget.dispatchEvent @ sockjs.js?9be2:170
(anonymous) @ sockjs.js?9be2:969
setTimeout (async)
SockJS._close @ sockjs.js?9be2:957
SockJS._receiveInfo @ sockjs.js?9be2:786
g @ sockjs.js?9be2:66
EventEmitter.emit @ sockjs.js?9be2:86
(anonymous) @ sockjs.js?9be2:567
g @ sockjs.js?9be2:66
EventEmitter.emit @ sockjs.js?9be2:86
(anonymous) @ sockjs.js?9be2:374
g @ sockjs.js?9be2:66
EventEmitter.emit @ sockjs.js?9be2:86
xhr.onreadystatechange @ sockjs.js?9be2:1597
XMLHttpRequest.send (async)
AbstractXHRObject._start @ sockjs.js?9be2:1605
(anonymous) @ sockjs.js?9be2:1494
setTimeout (async)
AbstractXHRObject @ sockjs.js?9be2:1493
XHRCorsObject @ sockjs.js?9be2:2871
InfoAjax @ sockjs.js?9be2:356
InfoReceiver._getReceiver @ sockjs.js?9be2:539
InfoReceiver.doXhr @ sockjs.js?9be2:556
(anonymous) @ sockjs.js?9be2:525
setTimeout (async)
InfoReceiver @ sockjs.js?9be2:524
SockJS @ sockjs.js?9be2:730
SockJSClient @ SockJSClient.js?0a33:39
initSocket @ socket.js?e29c:20
(anonymous) @ client?f442:176
(anonymous) @ index.js?http://0.0.0.0:8081:177
./node_modules/webpack-dev-server/client/index.js?http://0.0.0.0:8081 @ bundle.js?35a1b4fa8e9ffcd55d8e:8026
__webpack_require__ @ bundle.js?35a1b4fa8e9ffcd55d8e:20
0 @ bundle.js?35a1b4fa8e9ffcd55d8e:8331
__webpack_require__ @ bundle.js?35a1b4fa8e9ffcd55d8e:20
(anonymous) @ bundle.js?35a1b4fa8e9ffcd55d8e:84
(anonymous) @ bundle.js?35a1b4fa8e9ffcd55d8e:87
2client.js?aafa:60 Uncaught TypeError: Cannot read property 'resolve' of undefined
    at _ref4 (client.js?aafa:60)
_ref4 @ client.js?aafa:60
postMessage (async)
sendMsg @ sendMessage.js?090b:7
close @ client?f442:173
(anonymous) @ socket.js?e29c:26
EventTarget.dispatchEvent @ sockjs.js?9be2:170
(anonymous) @ sockjs.js?9be2:969
setTimeout (async)
SockJS._close @ sockjs.js?9be2:957
SockJS._receiveInfo @ sockjs.js?9be2:786
g @ sockjs.js?9be2:66
EventEmitter.emit @ sockjs.js?9be2:86
(anonymous) @ sockjs.js?9be2:567
g @ sockjs.js?9be2:66
EventEmitter.emit @ sockjs.js?9be2:86
(anonymous) @ sockjs.js?9be2:374
g @ sockjs.js?9be2:66
EventEmitter.emit @ sockjs.js?9be2:86
xhr.onreadystatechange @ sockjs.js?9be2:1597
XMLHttpRequest.send (async)
AbstractXHRObject._start @ sockjs.js?9be2:1605
(anonymous) @ sockjs.js?9be2:1494
setTimeout (async)
AbstractXHRObject @ sockjs.js?9be2:1493
XHRCorsObject @ sockjs.js?9be2:2871
InfoAjax @ sockjs.js?9be2:356
InfoReceiver._getReceiver @ sockjs.js?9be2:539
InfoReceiver.doXhr @ sockjs.js?9be2:556
(anonymous) @ sockjs.js?9be2:525
setTimeout (async)
InfoReceiver @ sockjs.js?9be2:524
SockJS @ sockjs.js?9be2:730
SockJSClient @ SockJSClient.js?0a33:39
initSocket @ socket.js?e29c:20
(anonymous) @ client?f442:176
(anonymous) @ index.js?http://0.0.0.0:8081:177
./node_modules/webpack-dev-server/client/index.js?http://0.0.0.0:8081 @ bundle.js?35a1b4fa8e9ffcd55d8e:8026
__webpack_require__ @ bundle.js?35a1b4fa8e9ffcd55d8e:20
0 @ bundle.js?35a1b4fa8e9ffcd55d8e:8331
__webpack_require__ @ bundle.js?35a1b4fa8e9ffcd55d8e:20
(anonymous) @ bundle.js?35a1b4fa8e9ffcd55d8e:84
(anonymous) @ bundle.js?35a1b4fa8e9ffcd55d8e:87
sockjs.js?9be2:1605 GET https://f7099d7e.ngrok.io:8081/sockjs-node/info?t=1568552469512 net::ERR_CONNECTION_TIMED_OUT

I really don't get why this happens.

@nikita-fuchs
Copy link

nikita-fuchs commented Sep 15, 2019 via email

@nduchak
Copy link

nduchak commented Sep 15, 2019

Hey guys, i will investigate the problem and find very tricky bug in SDK RPC.
Please use branch from this PR: aeternity/aepp-sdk-js#669

@thepiwo thepiwo closed this as completed Sep 15, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants