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

Added suport for contract queries using abi file #436

Merged
merged 11 commits into from
Jul 30, 2024
Merged

Conversation

popenta
Copy link
Contributor

@popenta popenta commented Jul 11, 2024

The same arguments as for contract calls have been added. The args are --abi and --arguments-file. Keep in mind the args should be placed inside a list like such:

[
    5,
    {
         { "bech32": "erd1..." }
    }
]

When performing queries without the abi file the response looks like this:

[
    "0e"
]

But when using the abi file the response is parsed, and it looks like this:

[
    14
]

There are small differences in how values are returned. For example, if an endpoint returns variadic<Address>, when querying without abi, the response looks like this:

[
    "3c35d7eacb1a99a4a0ccaa537ef0cc0ae109f41f6c2b402203e633bfbb071f5c",
    "0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1"
]

But when the abi is used, the response looks like this:

[
    [
        "3c35d7eacb1a99a4a0ccaa537ef0cc0ae109f41f6c2b402203e633bfbb071f5c",
        "0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1"
    ]
]

@popenta popenta self-assigned this Jul 11, 2024
@popenta popenta marked this pull request as draft July 11, 2024 12:38
Base automatically changed from contract-abi to feat/next July 17, 2024 11:08
@popenta popenta marked this pull request as ready for review July 18, 2024 14:10

response = sc_query_controller.run_query(query)

if self._abi:
Copy link

@axenteoctavian axenteoctavian Jul 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if-else is not consistent.
a)
With ABI you return the data-parts
Without ABI your return other stuff + data-parts as Dict

b) errors for bad queries
With ABI you raise SmartContractQueryError
Without ABI you return the Dict with error message

1/ What is the reason you return different types?
To make it consistent you can just return sc_query_controller.parse_query_response(response) but for NO abi case return parts as hex.
2/ Please add some unit tests for bad queries (wrong --function or whatever)
3/ I can't find test for contract query with abi

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now, the if-else is gone. The querying is done in a try-except block so all the errors thrown are of type
QueryContractError. Did a small "fix" for the json encoder to convert all bytes to hex. Also added tests.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me

@popenta popenta requested a review from andreibancioiu July 26, 2024 11:53
andreibancioiu
andreibancioiu previously approved these changes Jul 26, 2024
@@ -443,17 +444,28 @@ def upgrade(args: Any):
def query(args: Any):
logger.debug("query")

# workaround so we can use the function bellow
# workaround so we can use the function bellow to set chainID
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -134,6 +134,9 @@ def wallet_new(args: Any):
else:
mnemonic = Mnemonic.generate()

# this is done to get rid of the Pylance error: possibly unbound
mnemonic = cast(Mnemonic, mnemonic) # type: ignore
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can also fix the warning by extracting the above logic to a separate function e.g. generate_mnemonic_with_shard_constraint() or something like that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed, extracted to a separate function.

Comment on lines +66 to +72
return_code = response["returnCode"]
if return_code == "ok":
print(f"name [{name}] is valid")
else:
print(f"name [{name}] is invalid")

print(response)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be considered a breaking change by some (due to changing the stdout) - but this shouldn't be an issue anyway - we should just document it in the release notes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed, it will be documented in the release notes

Comment on lines 31 to 33
chain_id = proxy.get_network_config().chain_id
config = TransactionsFactoryConfig(chain_id)
contract = SmartContract(config)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can define a small function in this module e.g. query_contract(contract_address, proxy, function, args) - to extract the common functionality - getting chain ID, creating config etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -63,6 +65,10 @@ class IContractQueryResponse(Protocol):
return_data: List[str]
return_code: str
return_message: str
gas_used: int
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we reference the latest & greatest feat/next of sdk-py, maybe we can drop this interface (or maybe not yet)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can drop it.

if isinstance(o, ISerializable):
return o.to_dictionary()
if isinstance(o, bytes):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally speaking, is not a breaking change (e.g. it does not alter the output for existing flows that use --outfile or so).

if isinstance(o, ISerializable):
return o.to_dictionary()
if isinstance(o, bytes):
return o.hex()
if isinstance(o, list):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? (I did not do an extra check).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from what I've tested it's not. deleted it.

@@ -202,7 +201,7 @@ def query_contract(self,
contract_address: IAddress,
proxy: INetworkProvider,
function: str,
arguments: List[Any],
arguments: Union[List[Any], None],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can also be Optional - or maybe not yet (older Python)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed to Optional[List[Any]].

else:
return [self._query_response_to_dict(response)]
try:
response = sc_query_controller.query(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we don't support the caller and callValue parameters? But we didn't support them before anyway. I think we should, in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can do that in the future, we didn't support them before.

andreibancioiu
andreibancioiu previously approved these changes Jul 29, 2024

# this is done to get rid of the Pylance error: possibly unbound
mnemonic = cast(Mnemonic, mnemonic) # type: ignore
mnemonic = _generate_mnemonic_with_shard_constraint(shard)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be: if shard is not none, then call the new function, else call Mnemonic.generate().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

andreibancioiu
andreibancioiu previously approved these changes Jul 29, 2024
arguments=[],
args_from_file=False
)[0]
function="versgetRegistrationCostion",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix this function :D

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks:) fixed

axenteoctavian
axenteoctavian previously approved these changes Jul 29, 2024
@popenta popenta merged commit a63926c into feat/next Jul 30, 2024
8 checks passed
@popenta popenta deleted the vm-query-with-abi branch July 30, 2024 09:02
@popenta popenta mentioned this pull request Sep 30, 2024
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

Successfully merging this pull request may close these issues.

3 participants