Skip to content

Commit

Permalink
load args from file
Browse files Browse the repository at this point in the history
  • Loading branch information
popenta committed Jul 4, 2024
1 parent 148e63e commit d6ec097
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 40 deletions.
15 changes: 7 additions & 8 deletions multiversx_sdk_cli/cli_contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ def _add_contract_arg(sub: Any):


def _add_contract_abi_arg(sub: Any):
sub.add_argument("--abi", help="the ABI of the Smart Contract")
sub.add_argument("--abi", type=str, help="the ABI of the Smart Contract")


def _add_function_arg(sub: Any):
Expand All @@ -239,7 +239,7 @@ def _add_arguments_arg(sub: Any):
sub.add_argument("--arguments", nargs='+',
help="arguments for the contract transaction, as [number, bech32-address, ascii string, "
"boolean] or hex-encoded. E.g. --arguments 42 0x64 1000 0xabba str:TOK-a1c2ef true erd1[..]")
sub.add_argument("--arguments-file", help="a json file containing the arguments. ONLY if abi file is provided. "
sub.add_argument("--arguments-file", type=str, help="a json file containing the arguments. ONLY if abi file is provided. "
"E.g. { 'to': 'erd1...', 'amount': 10000000000 }")


Expand Down Expand Up @@ -372,25 +372,24 @@ def call(args: Any):
cli_shared.prepare_nonce_in_args(args)

sender = cli_shared.prepare_account(args)
abi = Abi.load(Path(args.abi)) if args.abi else None

config = TransactionsFactoryConfig(args.chain)
abi = Abi.load(Path(args.abi)) if args.abi else None
contract = SmartContract(config, abi)

contract_address = Address.new_from_bech32(args.contract)

json_args = json.loads(Path(args.arguments_json).expanduser().read_text()) if args.arguments_json else None
json_args = json.loads(Path(args.arguments_file).expanduser().read_text()) if args.arguments_file else None

if json_args and args.arguments:
raise Exception("Both '--arguments' and '--arguments-json' provided.")

# check what kind of args were provided and pass them further.
arguments = json_args or args.arguments
contract_address = Address.new_from_bech32(args.contract)

tx = contract.prepare_execute_transaction(
caller=sender,
contract=contract_address,
function=args.function,
arguments=args.arguments,
arguments=arguments,
gas_limit=int(args.gas_limit),
value=int(args.value),
transfers=args.token_transfers,
Expand Down
73 changes: 46 additions & 27 deletions multiversx_sdk_cli/contracts.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import base64
import logging
from pathlib import Path
from typing import Any, List, Optional, Protocol, Sequence, Union
from typing import Any, Dict, List, Optional, Protocol, Sequence, Union, cast

from multiversx_sdk import (Address, SmartContractTransactionsFactory, Token,
TokenComputer, TokenTransfer, Transaction,
Expand Down Expand Up @@ -75,6 +75,7 @@ class IConfig(Protocol):

class SmartContract:
def __init__(self, config: IConfig, abi: Optional[Abi] = None):
self._abi = abi
self._factory = SmartContractTransactionsFactory(config, abi)

def prepare_deploy_transaction(self,
Expand All @@ -91,7 +92,7 @@ def prepare_deploy_transaction(self,
version: int,
options: int,
guardian: str) -> Transaction:
args = prepare_args_for_factory(arguments) if arguments else []
args = self.prepare_args_for_factory("constructor", arguments) if arguments else []

tx = self._factory.create_transaction_for_deploy(
sender=owner.address,
Expand All @@ -116,7 +117,7 @@ def prepare_execute_transaction(self,
caller: Account,
contract: Address,
function: str,
arguments: Union[List[str], None],
arguments: Any,
gas_limit: int,
value: int,
transfers: Union[List[str], None],
Expand All @@ -125,7 +126,7 @@ def prepare_execute_transaction(self,
options: int,
guardian: str) -> Transaction:
token_transfers = self._prepare_token_transfers(transfers) if transfers else []
args = prepare_args_for_factory(arguments) if arguments else []
args = self.prepare_args_for_factory(function, arguments) if arguments else []

tx = self._factory.create_transaction_for_execute(
sender=caller.address,
Expand Down Expand Up @@ -159,7 +160,7 @@ def prepare_upgrade_transaction(self,
version: int,
options: int,
guardian: str) -> Transaction:
args = prepare_args_for_factory(arguments) if arguments else []
args = self.prepare_args_for_factory("upgrade_constructor", arguments) if arguments else []

tx = self._factory.create_transaction_for_upgrade(
sender=owner.address,
Expand Down Expand Up @@ -196,6 +197,46 @@ def _prepare_token_transfers(self, transfers: List[str]) -> List[TokenTransfer]:

return token_transfers

def prepare_args_for_factory(self, endpoint: str, arguments: Any) -> List[Any]:
args: List[Any] = []

if isinstance(arguments, dict):
return self._prepare_args_using_abi(endpoint, arguments)

if isinstance(arguments, list):
for arg in arguments: # type: ignore
arg = cast(str, arg)
if arg.startswith(HEX_PREFIX):
args.append(hex_to_bytes(arg))
elif arg.isnumeric():
args.append(int(arg))
elif arg.startswith(DEFAULT_HRP):
args.append(Address.new_from_bech32(arg))
elif arg.lower() == FALSE_STR_LOWER:
args.append(False)
elif arg.lower() == TRUE_STR_LOWER:
args.append(True)
elif arg.startswith(STR_PREFIX):
args.append(arg[len(STR_PREFIX):])
else:
raise errors.BadUserInput(f"Unknown argument type for argument: `{arg}`. Use `mxpy contract <sub-command> --help` to check all supported arguments")

return args

def _prepare_args_using_abi(self, function: str, arguments: Dict[str, Any]):
if not self._abi:
raise Exception("Abi file not provided")

endpoint_definition = [endpoint for endpoint in self._abi.definition.endpoints if endpoint.name == function]
if not endpoint_definition:
raise Exception(f"Endpoint [{function}] not found")
elif len(endpoint_definition) > 1:
raise Exception(f"More than one endpoint with name [{function}] found.")
else:
endpoint_definition = endpoint_definition[0]

input_parameters_names = [input.name for input in endpoint_definition.inputs]


def query_contract(
contract_address: IAddress,
Expand Down Expand Up @@ -265,28 +306,6 @@ def prepare_execute_transaction_data(function: str, arguments: List[Any]) -> Tra
return TransactionPayload.from_str(tx_data)


def prepare_args_for_factory(arguments: List[str]) -> List[Any]:
args: List[Any] = []

for arg in arguments:
if arg.startswith(HEX_PREFIX):
args.append(hex_to_bytes(arg))
elif arg.isnumeric():
args.append(int(arg))
elif arg.startswith(DEFAULT_HRP):
args.append(Address.new_from_bech32(arg))
elif arg.lower() == FALSE_STR_LOWER:
args.append(False)
elif arg.lower() == TRUE_STR_LOWER:
args.append(True)
elif arg.startswith(STR_PREFIX):
args.append(arg[len(STR_PREFIX):])
else:
raise errors.BadUserInput(f"Unknown argument type for argument: `{arg}`. Use `mxpy contract <sub-command> --help` to check all supported arguments")

return args


def hex_to_bytes(arg: str):
argument = arg[len(HEX_PREFIX):]
argument = argument.upper()
Expand Down
11 changes: 6 additions & 5 deletions multiversx_sdk_cli/tests/test_contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@

import pytest
from Cryptodome.Hash import keccak
from multiversx_sdk import Address
from multiversx_sdk import Address, TransactionsFactoryConfig

from multiversx_sdk_cli import errors
from multiversx_sdk_cli.accounts import Account
from multiversx_sdk_cli.contract_verification import _create_request_signature
from multiversx_sdk_cli.contracts import (_interpret_as_number_if_safely,
_prepare_argument,
prepare_args_for_factory)
from multiversx_sdk_cli.contracts import (SmartContract,
_interpret_as_number_if_safely,
_prepare_argument)

logging.basicConfig(level=logging.INFO)

Expand Down Expand Up @@ -70,13 +70,14 @@ def test_interpret_as_number_if_safely():


def test_prepare_args_for_factories():
sc = SmartContract(TransactionsFactoryConfig("mock"))
args = [
"0x5", "123", "false", "true",
"str:test-string",
"erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th"
]

arguments = prepare_args_for_factory(args)
arguments = sc.prepare_args_for_factory(args)
assert arguments[0] == b"\x05"
assert arguments[1] == 123
assert arguments[2] == False
Expand Down

0 comments on commit d6ec097

Please sign in to comment.