Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with invoking method using vscode extension #182

Open
lock9 opened this issue Mar 30, 2023 · 2 comments
Open

Issue with invoking method using vscode extension #182

lock9 opened this issue Mar 30, 2023 · 2 comments

Comments

@lock9
Copy link

lock9 commented Mar 30, 2023

When I run the command neoxp contract run -r token balanceOf 0x0847E9B1CD0AED4F6158BA8A0405D5710575D28B, the output is as expected:

VM State:     HALT
Gas Consumed: 2276820
Result Stack:
  10000000

However, when I use the following launch.json configuration in the VS Code, The result is always 0, which seems incorrect.

{
    "name": "Balance Of",
    "type": "neo-contract",
    "request": "launch",
    "program": "contract.nef",
    "invocation": {
        "operation": "balanceOf",
        "args": [
            "0x0847e9b1cd0aed4f6158ba8a0405d5710575d28b"
        ]
    },
    "storage": []
}

image

Everything works fine when I use the totalSupply method:

{
            "name": "Total Supply",
            "type": "neo-contract",
            "request": "launch",
            "program": "contract.nef",
            "invocation": {
                "operation": "totalSupply",
                "args": []
            },
            "storage": []
        }

image

image

Note: The data is being set in the _deploymethod.

Contract code:

from typing import Any
from boa3.builtin.compile_time import NeoMetadata, metadata, public
from boa3.builtin.interop import storage, runtime, blockchain, contract
from boa3.builtin.nativecontract import contractmanagement
from boa3.builtin.contract import Nep17TransferEvent
from boa3.builtin.type import UInt160

# Define the metadata for the smart contract using the metadata decorator.
@metadata
def manifest() -> NeoMetadata:
    meta = NeoMetadata()
    meta.name = "token"
    meta.supported_standards = []
    return meta

# Define the symbol function that returns the symbol of the token.
@public(safe=True)
def symbol() -> str:
    return "LINKD"

# Define the totalSupply function that returns the total supply of the token.
@public(safe=True)
def totalSupply() -> int:
    # Get the total supply from storage.
    total_supply = storage.get("total_supply")
    return total_supply.to_int()

# Define the balanceOf function that returns the balance of a specific account.
@public()
def balanceOf(account: UInt160)-> int:
    # Get the balance of the account from storage. 
    balance = storage.get(account)
    return balance.to_int()

# Define the transfer function that transfers tokens from one account to another.
@public
def transfer(from_param: UInt160, to: UInt160, amount: int, user_data: Any) -> bool:
    # Check that the transaction is authorized by the sender and that the amount is positive.
    if runtime.check_witness(from_param) and amount > 0:
        # Get the balance of the sender. If the balance is less than the amount being transferred, return False.
        from_balance = balanceOf(from_param)
        if from_balance >= amount:
            # Get the balance of the receiver. If the balance doesn't exist, it is initialized to 0.
            to_balance = balanceOf(to)
            # Update the balances in storage.
            storage.put(from_param, from_balance - amount)
            storage.put(to, to_balance + amount)

            # Call the onNEP17Payment method of the receiver if it exists.
            if contractmanagement.ContractManagement.has_method(to, "onNEP17Payment", 3):
                contract.call_contract(to, "onNEP17Payment", [from_param, amount, user_data])

            # Notify the blockchain of the transfer event.
            transfer_event = Nep17TransferEvent(from_param, to, amount)
            runtime.notify(transfer_event)
            return True
    return False

# Define the decimals function that returns the number of decimal places used by the token.
@public(safe=True)
def decimals() -> int:
    return 2

# Define the contract constructor function.
@public
def _deploy(data: Any, update: bool):
    # If the contract is being deployed for the first time, initialize the total supply and the balance of the sender to the total supply.
    if not update:
        initial_supply = 100000 * (10 ** decimals())
        storage.put("total_supply", initial_supply)
        # Get the transaction that called the contract and get the sender.
        transaction: blockchain.Transaction = runtime.script_container
        # Set the balance of the sender to the total supply.
        storage.put(transaction.sender, initial_supply)
@devhawk
Copy link
Contributor

devhawk commented Mar 30, 2023

The debugger will deploy the contract to the proto chaim used during debugging, if it isnt already present in the xheckpoint specified in the launch config. The launch configs listed above dont specify a checkpoint, so the contract has to be deployed when debugging starts.

There is a launch config property 'deploy-signer' or something similar (im on holiday right this moment so i cant check the code) that specifies the account to use when deploying the contract to the proto chain. Since its not specified, i think the debugger is using UInt160.zero as the signer. That would explain why the balance of value is not being set for the account expected.

The resolve this, either set the deploy signer propery to the desired value or deploy the contract to a neo express chain, create a checkpoint and then specify that checkpoint in the launch config

@lock9
Copy link
Author

lock9 commented Mar 30, 2023

Hi @devhawk,

I think I get it. Is it possible to use the existing neo-express instance instead of a checkpoint? Or should I create a checkpoint as part of the project setup?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants