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

[Technical support]  #8

@arjanvaneersel

Description

@arjanvaneersel

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions