Skip to content

Commit

Permalink
contract deploy using sc factory
Browse files Browse the repository at this point in the history
  • Loading branch information
popenta committed Nov 17, 2023
1 parent c63f0d8 commit 0780907
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 72 deletions.
33 changes: 18 additions & 15 deletions multiversx_sdk_cli/cli_contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,24 @@
from pathlib import Path
from typing import Any, List

from multiversx_sdk_core import Address, Transaction
from multiversx_sdk_core import (Address, AddressComputer, TokenComputer,
Transaction)
from multiversx_sdk_core.transaction_factories import TransactionsFactoryConfig
from multiversx_sdk_network_providers.proxy_network_provider import \
ProxyNetworkProvider

from multiversx_sdk_cli import cli_shared, errors, projects, utils
from multiversx_sdk_cli.accounts import Account, LedgerAccount
from multiversx_sdk_cli.cli_output import CLIOutputBuilder
from multiversx_sdk_cli.cli_password import load_password
from multiversx_sdk_cli.constants import NUMBER_OF_SHARDS
from multiversx_sdk_cli.contract_verification import \
trigger_contract_verification
from multiversx_sdk_cli.contracts import CodeMetadata, SmartContract
from multiversx_sdk_cli.contracts import SmartContract
from multiversx_sdk_cli.cosign_transaction import cosign_transaction
from multiversx_sdk_cli.docker import is_docker_installed, run_docker
from multiversx_sdk_cli.errors import DockerMissingError, NoWalletProvided
from multiversx_sdk_cli.interfaces import IAddress
from multiversx_sdk_cli.projects.core import get_project_paths_recursively
from multiversx_sdk_cli.projects.templates import Contract
from multiversx_sdk_cli.ux import show_message
Expand Down Expand Up @@ -299,23 +303,22 @@ def deploy(args: Any):
cli_shared.check_guardian_and_options_args(args)
cli_shared.check_broadcast_args(args)

arguments = args.arguments
gas_price = args.gas_price
gas_limit = args.gas_limit
value = args.value
version = args.version

contract = _prepare_contract(args)
sender = _prepare_sender(args)
cli_shared.prepare_chain_id_in_args(args)

tx = contract.deploy(sender, arguments, gas_price, gas_limit, value, args.chain, version, args.guardian, args.options)
config = TransactionsFactoryConfig(args.chain)
contract = SmartContract(config, TokenComputer())

address_computer = AddressComputer(NUMBER_OF_SHARDS)
contract_address = address_computer.compute_contract_address(deployer=sender.address, deployment_nonce=sender.nonce)

tx = contract.get_deploy_transaction(sender, args)
tx = _sign_guarded_tx(args, tx)

logger.info("Contract address: %s", contract.address.to_bech32())
utils.log_explorer_contract_address(args.chain, contract.address.to_bech32())
logger.info("Contract address: %s", contract_address.to_bech32())
utils.log_explorer_contract_address(args.chain, contract_address.to_bech32())

_send_or_simulate(tx, contract, args)
_send_or_simulate(tx, contract_address, args)


def _prepare_contract(args: Any) -> SmartContract:
Expand Down Expand Up @@ -435,9 +438,9 @@ def query(args: Any):
utils.dump_out_json(result)


def _send_or_simulate(tx: Transaction, contract: SmartContract, args: Any):
def _send_or_simulate(tx: Transaction, contract_address: IAddress, args: Any):
output_builder = cli_shared.send_or_simulate(tx, args, dump_output=False)
output_builder.set_contract_address(contract.address)
output_builder.set_contract_address(contract_address)
utils.dump_out_json(output_builder.build(), outfile=args.outfile)


Expand Down
7 changes: 3 additions & 4 deletions multiversx_sdk_cli/cli_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
from collections import OrderedDict
from typing import Any, Dict, List, Optional, Union

from multiversx_sdk_core import Address
from multiversx_sdk_network_providers.transactions import \
transaction_to_dictionary

from multiversx_sdk_cli import utils
from multiversx_sdk_cli.interfaces import ITransaction
from multiversx_sdk_cli.interfaces import IAddress, ITransaction
from multiversx_sdk_cli.utils import ISerializable

logger = logging.getLogger("cli.output")
Expand All @@ -19,7 +18,7 @@ def __init__(self) -> None:
self.emitted_transaction_hash: Optional[str] = None
self.emitted_transaction: Union[ITransaction, None] = None
self.emitted_transaction_omitted_fields: List[str] = []
self.contract_address: Union[Address, None] = None
self.contract_address: Union[IAddress, None] = None
self.transaction_on_network: Union[ISerializable, None] = None
self.transaction_on_network_omitted_fields: List[str] = []
self.simulation_results: Union[ISerializable, None] = None
Expand All @@ -33,7 +32,7 @@ def set_emitted_transaction(self, emitted_transaction: ITransaction, omitted_fie
self.emitted_transaction_omitted_fields = omitted_fields
return self

def set_contract_address(self, contract_address: Address):
def set_contract_address(self, contract_address: IAddress):
self.contract_address = contract_address
return self

Expand Down
2 changes: 2 additions & 0 deletions multiversx_sdk_cli/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@

DEFAULT_HRP = "erd"
ADDRESS_ZERO_BECH32 = "erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu"

NUMBER_OF_SHARDS = 3
87 changes: 40 additions & 47 deletions multiversx_sdk_cli/contracts.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import base64
import logging
from pathlib import Path
from typing import Any, List, Optional, Protocol, Sequence, Tuple

from multiversx_sdk_core import Transaction, TransactionPayload
from multiversx_sdk_core.address import Address, AddressComputer
from multiversx_sdk_core.address import Address
from multiversx_sdk_core.transaction_factories import \
SmartContractTransactionsFactory
from multiversx_sdk_network_providers.interface import IAddress, IContractQuery

from multiversx_sdk_cli import config, constants, errors
from multiversx_sdk_cli.accounts import Account, EmptyAddress
from multiversx_sdk_cli.constants import ADDRESS_ZERO_BECH32, DEFAULT_HRP
from multiversx_sdk_cli.constants import DEFAULT_HRP
from multiversx_sdk_cli.utils import Object

logger = logging.getLogger("contracts")
Expand Down Expand Up @@ -61,39 +64,47 @@ class IContractQueryResponse(Protocol):
return_message: str


class SmartContract:
def __init__(self, address: Optional[IAddress] = EmptyAddress(), bytecode=None, metadata=None):
self.address = address
self.bytecode = bytecode
self.metadata = metadata or CodeMetadata()
class IConfig(Protocol):
chain_id: str
min_gas_limit: int
gas_limit_per_byte: int

def deploy(self, owner: Account, arguments: List[Any], gas_price: int, gas_limit: int, value: int, chain: str, version: int, guardian: str, options: int) -> Transaction:
self.owner = owner
address_computer = AddressComputer(number_of_shards=3)
self.address = address_computer.compute_contract_address(self.owner.address, self.owner.nonce)

arguments = arguments or []
gas_price = int(gas_price)
gas_limit = int(gas_limit)
value = value or 0
class IToken(Protocol):
identifier: str
nonce: int

tx = Transaction(
chain_id=chain,
sender=owner.address.to_bech32(),
receiver=ADDRESS_ZERO_BECH32,
gas_limit=gas_limit,
gas_price=gas_price,
nonce=owner.nonce,
amount=value,
data=self.prepare_deploy_transaction_data(arguments).data,
version=version,
options=options
)

if guardian:
tx.guardian = guardian
class ITokenComputer(Protocol):
def is_fungible(self, token: IToken) -> bool:
...

def extract_identifier_from_extended_identifier(self, identifier: str) -> str:
...


class SmartContract:
def __init__(self, config: IConfig, token_computer: ITokenComputer):
self._factory = SmartContractTransactionsFactory(config, token_computer)

def get_deploy_transaction(self, owner: Account, args: Any) -> Transaction:
tx = self._factory.create_transaction_for_deploy(
sender=owner.address,
bytecode=Path(args.bytecode),
gas_limit=int(args.gas_limit),
arguments=args.arguments,
native_transfer_amount=int(args.value),
is_upgradeable=args.metadata_upgradeable,
is_readable=args.metadata_readable,
is_payable=args.metadata_payable,
is_payable_by_sc=args.metadata_payable_by_sc
)
tx.nonce = owner.nonce
tx.version = int(args.version)
tx.options = int(args.options)
tx.guardian = args.guardian
tx.signature = bytes.fromhex(owner.sign_transaction(tx))

return tx

def prepare_deploy_transaction_data(self, arguments: List[Any]) -> TransactionPayload:
Expand Down Expand Up @@ -294,21 +305,3 @@ def sum_flag_values(flag_value_pairs: List[Tuple[int, bool]]) -> int:
if flag:
value_sum += value
return value_sum


class CodeMetadata:
def __init__(self, upgradeable: bool = True, readable: bool = True, payable: bool = False, payable_by_sc: bool = False):
self.upgradeable = upgradeable
self.readable = readable
self.payable = payable
self.payable_by_sc = payable_by_sc

def to_hex(self):
flag_value_pairs = [
(0x01_00, self.upgradeable),
(0x04_00, self.readable),
(0x00_02, self.payable),
(0x00_04, self.payable_by_sc)
]
metadata_value = sum_flag_values(flag_value_pairs)
return f"{metadata_value:04X}"
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ dependencies = [
"semver",
"requests-cache",
"rich==13.3.4",
"multiversx-sdk-network-providers<0.13.0",
"multiversx-sdk-wallet<0.9.0,",
"multiversx-sdk-core<0.8.0"
"multiversx-sdk-network-providers>=0.12.0,<0.13.0",
"multiversx-sdk-wallet>=0.8.0,<0.9.0,",
"multiversx-sdk-core>=0.7.0,<0.8.0"
]

[tool.hatch.build]
Expand Down
6 changes: 3 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ semver
requests-cache
rich==13.3.4

multiversx-sdk-core<0.8.0
multiversx-sdk-network-providers<0.13.0
multiversx-sdk-wallet<0.9.0
multiversx-sdk-core>=0.7.0,<0.8.0
multiversx-sdk-network-providers>=0.12.0,<0.13.0
multiversx-sdk-wallet>=0.8.0,<0.9.0

0 comments on commit 0780907

Please sign in to comment.