mirror of https://github.com/nucypher/nucypher.git
commit
4e2391b14b
|
@ -224,9 +224,8 @@ class EthereumClient:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def chain_name(self) -> str:
|
def chain_name(self) -> str:
|
||||||
if not self.is_local:
|
chain_inventory = LOCAL_CHAINS if self.is_local else PUBLIC_CHAINS
|
||||||
return PUBLIC_CHAINS[int(self.chain_id)]
|
name = chain_inventory.get(self.chain_id, UNKNOWN_DEVELOPMENT_CHAIN_ID)
|
||||||
name = LOCAL_CHAINS.get(self.chain_id, UNKNOWN_DEVELOPMENT_CHAIN_ID)
|
|
||||||
return name
|
return name
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -60,6 +60,7 @@ from nucypher.blockchain.eth.sol.compile import SolidityCompiler
|
||||||
from nucypher.blockchain.eth.utils import get_transaction_name, prettify_eth_amount
|
from nucypher.blockchain.eth.utils import get_transaction_name, prettify_eth_amount
|
||||||
from nucypher.characters.control.emitters import JSONRPCStdoutEmitter, StdoutEmitter
|
from nucypher.characters.control.emitters import JSONRPCStdoutEmitter, StdoutEmitter
|
||||||
from nucypher.utilities.datafeeds import datafeed_fallback_gas_price_strategy
|
from nucypher.utilities.datafeeds import datafeed_fallback_gas_price_strategy
|
||||||
|
from nucypher.utilities.ethereum import encode_constructor_arguments
|
||||||
from nucypher.utilities.logging import GlobalLoggerSettings, Logger
|
from nucypher.utilities.logging import GlobalLoggerSettings, Logger
|
||||||
|
|
||||||
|
|
||||||
|
@ -825,13 +826,19 @@ class BlockchainDeployerInterface(BlockchainInterface):
|
||||||
f"deployer address {deployer_address} "
|
f"deployer address {deployer_address} "
|
||||||
f"and parameters {pprint_args}")
|
f"and parameters {pprint_args}")
|
||||||
|
|
||||||
transaction_function = contract_factory.constructor(*constructor_args, **constructor_kwargs)
|
constructor_function = contract_factory.constructor(*constructor_args, **constructor_kwargs)
|
||||||
|
constructor_calldata = encode_constructor_arguments(self.client.w3,
|
||||||
|
constructor_function,
|
||||||
|
*constructor_args,
|
||||||
|
**constructor_kwargs)
|
||||||
|
if not constructor_calldata:
|
||||||
|
self.log.info(f"Constructor calldata: {constructor_calldata}")
|
||||||
|
|
||||||
#
|
#
|
||||||
# Transmit the deployment tx #
|
# Transmit the deployment tx #
|
||||||
#
|
#
|
||||||
|
|
||||||
receipt = self.send_transaction(contract_function=transaction_function,
|
receipt = self.send_transaction(contract_function=constructor_function,
|
||||||
sender_address=deployer_address,
|
sender_address=deployer_address,
|
||||||
payload=deploy_transaction,
|
payload=deploy_transaction,
|
||||||
confirmations=confirmations)
|
confirmations=confirmations)
|
||||||
|
|
|
@ -25,6 +25,7 @@ from eth_utils import is_address, is_hex, to_checksum_address
|
||||||
from web3 import Web3
|
from web3 import Web3
|
||||||
from web3.contract import ContractConstructor, ContractFunction
|
from web3.contract import ContractConstructor, ContractFunction
|
||||||
|
|
||||||
|
from nucypher.blockchain.eth.clients import PUBLIC_CHAINS
|
||||||
from nucypher.blockchain.eth.constants import AVERAGE_BLOCK_TIME_IN_SECONDS
|
from nucypher.blockchain.eth.constants import AVERAGE_BLOCK_TIME_IN_SECONDS
|
||||||
|
|
||||||
|
|
||||||
|
@ -85,18 +86,22 @@ def estimate_block_number_for_period(period: int, seconds_per_period: int, late
|
||||||
def etherscan_url(item, network: str, is_token=False) -> str:
|
def etherscan_url(item, network: str, is_token=False) -> str:
|
||||||
if network is None or network is UNKNOWN_DEVELOPMENT_CHAIN_ID:
|
if network is None or network is UNKNOWN_DEVELOPMENT_CHAIN_ID:
|
||||||
raise ValueError("A network must be provided")
|
raise ValueError("A network must be provided")
|
||||||
elif network == 'mainnet':
|
|
||||||
|
if network == PUBLIC_CHAINS[1]: # Mainnet chain ID is 1
|
||||||
domain = "https://etherscan.io"
|
domain = "https://etherscan.io"
|
||||||
else:
|
else:
|
||||||
network = network.lower()
|
testnets_supported_by_etherscan = (PUBLIC_CHAINS[3], # Ropsten
|
||||||
testnets_supported_by_etherscan = ('ropsten', 'goerli', 'rinkeby', 'kovan')
|
PUBLIC_CHAINS[4], # Rinkeby
|
||||||
|
PUBLIC_CHAINS[5], # Goerli
|
||||||
|
PUBLIC_CHAINS[42], # Kovan
|
||||||
|
)
|
||||||
if network in testnets_supported_by_etherscan:
|
if network in testnets_supported_by_etherscan:
|
||||||
domain = f"https://{network}.etherscan.io"
|
domain = f"https://{network.lower()}.etherscan.io"
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"'{network}' network not supported by Etherscan")
|
raise ValueError(f"'{network}' network not supported by Etherscan")
|
||||||
|
|
||||||
if is_address(item):
|
if is_address(item):
|
||||||
item_type = 'address' if not is_token else 'token'
|
item_type = 'token' if is_token else 'address'
|
||||||
item = to_checksum_address(item)
|
item = to_checksum_address(item)
|
||||||
elif is_hex(item) and len(item) == 2 + 32*2: # If it's a hash...
|
elif is_hex(item) and len(item) == 2 + 32*2: # If it's a hash...
|
||||||
item_type = 'tx'
|
item_type = 'tx'
|
||||||
|
|
|
@ -14,11 +14,15 @@
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
||||||
"""
|
"""
|
||||||
|
from typing import Type, Union
|
||||||
|
|
||||||
import click
|
import click
|
||||||
from constant_sorrow.constants import UNKNOWN_DEVELOPMENT_CHAIN_ID
|
from constant_sorrow.constants import UNKNOWN_DEVELOPMENT_CHAIN_ID
|
||||||
|
|
||||||
from nucypher.blockchain.eth.interfaces import BlockchainDeployerInterface
|
from nucypher.blockchain.eth.deployers import BaseContractDeployer
|
||||||
|
from nucypher.blockchain.eth.registry import LocalContractRegistry, InMemoryContractRegistry
|
||||||
|
from nucypher.cli.literature import CONFIRM_VERSIONED_UPGRADE
|
||||||
|
from nucypher.blockchain.eth.interfaces import BlockchainDeployerInterface, VersionedContract, BlockchainInterface
|
||||||
from nucypher.blockchain.eth.token import NU
|
from nucypher.blockchain.eth.token import NU
|
||||||
from nucypher.characters.control.emitters import StdoutEmitter
|
from nucypher.characters.control.emitters import StdoutEmitter
|
||||||
from nucypher.cli.literature import (
|
from nucypher.cli.literature import (
|
||||||
|
@ -32,7 +36,9 @@ from nucypher.cli.literature import (
|
||||||
CONFIRM_STAGED_STAKE,
|
CONFIRM_STAGED_STAKE,
|
||||||
RESTAKING_AGREEMENT,
|
RESTAKING_AGREEMENT,
|
||||||
RESTAKING_LOCK_AGREEMENT,
|
RESTAKING_LOCK_AGREEMENT,
|
||||||
WINDING_DOWN_AGREEMENT, SNAPSHOTS_DISABLING_AGREEMENT, CONFIRM_DISABLE_SNAPSHOTS
|
WINDING_DOWN_AGREEMENT,
|
||||||
|
SNAPSHOTS_DISABLING_AGREEMENT,
|
||||||
|
CONFIRM_DISABLE_SNAPSHOTS
|
||||||
)
|
)
|
||||||
from nucypher.config.node import CharacterConfiguration
|
from nucypher.config.node import CharacterConfiguration
|
||||||
|
|
||||||
|
@ -115,3 +121,26 @@ def confirm_destroy_configuration(config: CharacterConfiguration) -> bool:
|
||||||
database=database)
|
database=database)
|
||||||
click.confirm(confirmation, abort=True)
|
click.confirm(confirmation, abort=True)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def verify_upgrade_details(blockchain: Union[BlockchainDeployerInterface, BlockchainInterface],
|
||||||
|
registry: LocalContractRegistry,
|
||||||
|
deployer: Type[BaseContractDeployer],
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Compares the versions of two 'implementation' contracts using a local and source registry.
|
||||||
|
"""
|
||||||
|
|
||||||
|
old_contract: VersionedContract = blockchain.get_contract_by_name(
|
||||||
|
registry=registry,
|
||||||
|
contract_name=deployer.contract_name,
|
||||||
|
proxy_name=deployer.agency._proxy_name,
|
||||||
|
use_proxy_address=False
|
||||||
|
)
|
||||||
|
|
||||||
|
new_contract = blockchain.find_raw_contract_data(contract_name=deployer.contract_name)
|
||||||
|
new_version = new_contract[0] # Handle index error?
|
||||||
|
|
||||||
|
click.confirm(CONFIRM_VERSIONED_UPGRADE.format(contract_name=deployer.contract_name,
|
||||||
|
old_version=old_contract.version,
|
||||||
|
new_version=new_version), abort=True)
|
||||||
|
|
|
@ -16,12 +16,12 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
from typing import Tuple
|
||||||
|
|
||||||
import click
|
import click
|
||||||
import os
|
import os
|
||||||
from constant_sorrow import constants
|
from constant_sorrow import constants
|
||||||
from constant_sorrow.constants import FULL
|
from constant_sorrow.constants import FULL
|
||||||
from typing import Tuple
|
|
||||||
|
|
||||||
from nucypher.blockchain.eth.actors import ContractAdministrator, Trustee
|
from nucypher.blockchain.eth.actors import ContractAdministrator, Trustee
|
||||||
from nucypher.blockchain.eth.agents import ContractAgency, MultiSigAgent
|
from nucypher.blockchain.eth.agents import ContractAgency, MultiSigAgent
|
||||||
|
@ -36,9 +36,10 @@ from nucypher.blockchain.eth.registry import (
|
||||||
)
|
)
|
||||||
from nucypher.blockchain.eth.signers.base import Signer
|
from nucypher.blockchain.eth.signers.base import Signer
|
||||||
from nucypher.blockchain.eth.signers.software import ClefSigner
|
from nucypher.blockchain.eth.signers.software import ClefSigner
|
||||||
|
from nucypher.blockchain.eth.sol.__conf__ import SOLIDITY_COMPILER_VERSION
|
||||||
from nucypher.characters.control.emitters import StdoutEmitter
|
from nucypher.characters.control.emitters import StdoutEmitter
|
||||||
from nucypher.cli.actions.auth import get_client_password
|
from nucypher.cli.actions.auth import get_client_password
|
||||||
from nucypher.cli.actions.confirm import confirm_deployment
|
from nucypher.cli.actions.confirm import confirm_deployment, verify_upgrade_details
|
||||||
from nucypher.cli.actions.select import select_client_account
|
from nucypher.cli.actions.select import select_client_account
|
||||||
from nucypher.cli.config import group_general_config
|
from nucypher.cli.config import group_general_config
|
||||||
from nucypher.cli.literature import (
|
from nucypher.cli.literature import (
|
||||||
|
@ -69,9 +70,9 @@ from nucypher.cli.literature import (
|
||||||
SUCCESSFUL_SAVE_MULTISIG_TX_PROPOSAL,
|
SUCCESSFUL_SAVE_MULTISIG_TX_PROPOSAL,
|
||||||
SUCCESSFUL_UPGRADE,
|
SUCCESSFUL_UPGRADE,
|
||||||
UNKNOWN_CONTRACT_NAME,
|
UNKNOWN_CONTRACT_NAME,
|
||||||
IDENTICAL_REGISTRY_WARNING,
|
|
||||||
DEPLOYER_IS_NOT_OWNER,
|
DEPLOYER_IS_NOT_OWNER,
|
||||||
CONFIRM_VERSIONED_UPGRADE
|
REGISTRY_PUBLICATION_HINT,
|
||||||
|
ETHERSCAN_VERIFY_HINT
|
||||||
)
|
)
|
||||||
from nucypher.cli.options import (
|
from nucypher.cli.options import (
|
||||||
group_options,
|
group_options,
|
||||||
|
@ -239,7 +240,7 @@ group_actor_options = group_options(
|
||||||
config_root=option_config_root,
|
config_root=option_config_root,
|
||||||
etherscan=option_etherscan,
|
etherscan=option_etherscan,
|
||||||
ignore_solidity_check=option_ignore_solidity_version,
|
ignore_solidity_check=option_ignore_solidity_version,
|
||||||
network=option_network(required=True, default=NetworksInventory.DEFAULT)
|
network=option_network(required=True)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -293,8 +294,10 @@ def download_registry(general_config, config_root, registry_outfile, network, fo
|
||||||
@option_registry_infile
|
@option_registry_infile
|
||||||
@option_deployer_address
|
@option_deployer_address
|
||||||
@option_poa
|
@option_poa
|
||||||
|
@option_network(required=False, default=NetworksInventory.DEFAULT)
|
||||||
@option_ignore_solidity_version
|
@option_ignore_solidity_version
|
||||||
def inspect(general_config, provider_uri, config_root, registry_infile, deployer_address, poa, ignore_solidity_check):
|
def inspect(general_config, provider_uri, config_root, registry_infile, deployer_address,
|
||||||
|
poa, ignore_solidity_check, network):
|
||||||
"""Echo owner information and bare contract metadata."""
|
"""Echo owner information and bare contract metadata."""
|
||||||
emitter = general_config.emitter
|
emitter = general_config.emitter
|
||||||
ensure_config_root(config_root)
|
ensure_config_root(config_root)
|
||||||
|
@ -302,9 +305,11 @@ def inspect(general_config, provider_uri, config_root, registry_infile, deployer
|
||||||
provider_uri=provider_uri,
|
provider_uri=provider_uri,
|
||||||
emitter=emitter,
|
emitter=emitter,
|
||||||
ignore_solidity_check=ignore_solidity_check)
|
ignore_solidity_check=ignore_solidity_check)
|
||||||
|
download_required = not bool(registry_infile)
|
||||||
registry = establish_deployer_registry(emitter=emitter,
|
registry = establish_deployer_registry(emitter=emitter,
|
||||||
registry_infile=registry_infile,
|
registry_infile=registry_infile,
|
||||||
download_registry=not bool(registry_infile))
|
download_registry=download_required,
|
||||||
|
network=network if download_required else None)
|
||||||
paint_deployer_contract_inspection(emitter=emitter,
|
paint_deployer_contract_inspection(emitter=emitter,
|
||||||
registry=registry,
|
registry=registry,
|
||||||
deployer_address=deployer_address)
|
deployer_address=deployer_address)
|
||||||
|
@ -328,24 +333,23 @@ def upgrade(general_config, actor_options, retarget, target_address, ignore_depl
|
||||||
emitter = general_config.emitter
|
emitter = general_config.emitter
|
||||||
ADMINISTRATOR, deployer_address, blockchain, local_registry = actor_options.create_actor(emitter, is_multisig=bool(multisig)) # FIXME: Workaround for building MultiSig TXs | NRN
|
ADMINISTRATOR, deployer_address, blockchain, local_registry = actor_options.create_actor(emitter, is_multisig=bool(multisig)) # FIXME: Workaround for building MultiSig TXs | NRN
|
||||||
|
|
||||||
|
#
|
||||||
|
# Pre-flight
|
||||||
|
#
|
||||||
|
|
||||||
contract_name = actor_options.contract_name
|
contract_name = actor_options.contract_name
|
||||||
if not contract_name:
|
if not contract_name:
|
||||||
raise click.BadArgumentUsage(message="--contract-name is required when using --upgrade")
|
raise click.BadArgumentUsage(message="--contract-name is required when using --upgrade")
|
||||||
|
|
||||||
github_registry = establish_deployer_registry(emitter=emitter, download_registry=True, network=actor_options.network)
|
|
||||||
try:
|
try:
|
||||||
|
# Check contract name exists
|
||||||
Deployer = ADMINISTRATOR.deployers[contract_name]
|
Deployer = ADMINISTRATOR.deployers[contract_name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
message = UNKNOWN_CONTRACT_NAME.format(contract_name=contract_name,
|
message = UNKNOWN_CONTRACT_NAME.format(contract_name=contract_name, constants=ADMINISTRATOR.deployers.keys())
|
||||||
constants=ADMINISTRATOR.deployers.keys())
|
|
||||||
emitter.echo(message, color='red', bold=True)
|
emitter.echo(message, color='red', bold=True)
|
||||||
raise click.Abort()
|
raise click.Abort()
|
||||||
deployer = Deployer(registry=local_registry)
|
deployer = Deployer(registry=local_registry)
|
||||||
|
|
||||||
#
|
|
||||||
# Pre-flight
|
|
||||||
#
|
|
||||||
|
|
||||||
# Check deployer address is owner
|
# Check deployer address is owner
|
||||||
if Deployer._ownable and deployer_address != deployer.owner: # blockchain read
|
if Deployer._ownable and deployer_address != deployer.owner: # blockchain read
|
||||||
emitter.echo(DEPLOYER_IS_NOT_OWNER.format(deployer_address=deployer_address,
|
emitter.echo(DEPLOYER_IS_NOT_OWNER.format(deployer_address=deployer_address,
|
||||||
|
@ -355,13 +359,6 @@ def upgrade(general_config, actor_options, retarget, target_address, ignore_depl
|
||||||
else:
|
else:
|
||||||
emitter.echo('✓ Verified deployer address as contract owner', color='green')
|
emitter.echo('✓ Verified deployer address as contract owner', color='green')
|
||||||
|
|
||||||
# Check registry ID has changed locally compared to remote source
|
|
||||||
if (github_registry.id == local_registry.id) and not actor_options.force:
|
|
||||||
emitter.echo(IDENTICAL_REGISTRY_WARNING.format(github_registry=github_registry, local_registry=local_registry), color='red')
|
|
||||||
raise click.Abort()
|
|
||||||
else:
|
|
||||||
emitter.echo('✓ Verified local registry contains updates', color='green')
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Business
|
# Business
|
||||||
#
|
#
|
||||||
|
@ -397,6 +394,7 @@ def upgrade(general_config, actor_options, retarget, target_address, ignore_depl
|
||||||
filepath = f'proposal-{trustee.multisig_agent.contract_address[:8]}-TX-{transaction_proposal.nonce}.json'
|
filepath = f'proposal-{trustee.multisig_agent.contract_address[:8]}-TX-{transaction_proposal.nonce}.json'
|
||||||
transaction_proposal.write(filepath=filepath)
|
transaction_proposal.write(filepath=filepath)
|
||||||
emitter.echo(SUCCESSFUL_SAVE_MULTISIG_TX_PROPOSAL.format(filepath=filepath), color='blue', bold=True)
|
emitter.echo(SUCCESSFUL_SAVE_MULTISIG_TX_PROPOSAL.format(filepath=filepath), color='blue', bold=True)
|
||||||
|
return # Exit
|
||||||
|
|
||||||
elif retarget:
|
elif retarget:
|
||||||
if not target_address:
|
if not target_address:
|
||||||
|
@ -407,24 +405,34 @@ def upgrade(general_config, actor_options, retarget, target_address, ignore_depl
|
||||||
message = SUCCESSFUL_RETARGET.format(contract_name=contract_name, target_address=target_address)
|
message = SUCCESSFUL_RETARGET.format(contract_name=contract_name, target_address=target_address)
|
||||||
emitter.message(message, color='green')
|
emitter.message(message, color='green')
|
||||||
paint_receipt_summary(emitter=emitter, receipt=receipt)
|
paint_receipt_summary(emitter=emitter, receipt=receipt)
|
||||||
|
return # Exit
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
github_registry = establish_deployer_registry(emitter=emitter,
|
||||||
|
download_registry=True,
|
||||||
|
network=actor_options.network)
|
||||||
if not actor_options.force:
|
if not actor_options.force:
|
||||||
|
|
||||||
# Check for human verification of versioned upgrade details
|
# Check for human verification of versioned upgrade details
|
||||||
click.confirm(CONFIRM_BEGIN_UPGRADE.format(contract_name=contract_name), abort=True)
|
click.confirm(CONFIRM_BEGIN_UPGRADE.format(contract_name=contract_name), abort=True)
|
||||||
if deployer._ownable: # Only ownable + upgradeable contracts apply
|
if deployer._ownable: # Only ownable + upgradeable contracts apply
|
||||||
old_contract = github_registry.search(contract_name=contract_name)[-1] # latest GH version
|
verify_upgrade_details(blockchain=blockchain,
|
||||||
new_contract = local_registry.search(contract_name=contract_name)[-1] # latest local version
|
registry=github_registry,
|
||||||
click.confirm(CONFIRM_VERSIONED_UPGRADE.format(contract_name=contract_name,
|
deployer=deployer)
|
||||||
old_contract=old_contract,
|
|
||||||
new_contract=new_contract), abort=True)
|
|
||||||
|
|
||||||
|
# Success
|
||||||
receipts = ADMINISTRATOR.upgrade_contract(contract_name=contract_name,
|
receipts = ADMINISTRATOR.upgrade_contract(contract_name=contract_name,
|
||||||
ignore_deployed=ignore_deployed,
|
ignore_deployed=ignore_deployed,
|
||||||
confirmations=confirmations)
|
confirmations=confirmations)
|
||||||
emitter.message(SUCCESSFUL_UPGRADE.format(contract_name=contract_name), color='green')
|
emitter.message(SUCCESSFUL_UPGRADE.format(contract_name=contract_name), color='green')
|
||||||
|
|
||||||
for name, receipt in receipts.items():
|
for name, receipt in receipts.items():
|
||||||
paint_receipt_summary(emitter=emitter, receipt=receipt)
|
paint_receipt_summary(emitter=emitter, receipt=receipt)
|
||||||
|
emitter.echo(REGISTRY_PUBLICATION_HINT.format(contract_name=contract_name,
|
||||||
|
local_registry=local_registry,
|
||||||
|
network=actor_options.network), color='blue')
|
||||||
|
emitter.echo(ETHERSCAN_VERIFY_HINT.format(solc_version=SOLIDITY_COMPILER_VERSION), color='blue')
|
||||||
|
return # Exit
|
||||||
|
|
||||||
|
|
||||||
@deploy.command()
|
@deploy.command()
|
||||||
|
|
|
@ -477,7 +477,22 @@ IDENTICAL_REGISTRY_WARNING = "Local registry ({local_registry.id}) is identical
|
||||||
|
|
||||||
DEPLOYER_IS_NOT_OWNER = "Address {deployer_address} is not the owner of {contract_name}'s Dispatcher ({agent.contract_address}). Aborting."
|
DEPLOYER_IS_NOT_OWNER = "Address {deployer_address} is not the owner of {contract_name}'s Dispatcher ({agent.contract_address}). Aborting."
|
||||||
|
|
||||||
CONFIRM_VERSIONED_UPGRADE = "Confirm upgrade {contract_name} from version {old_contract.version} to version {new_contract.version}?"
|
CONFIRM_VERSIONED_UPGRADE = "Confirm upgrade {contract_name} from version {old_version} to version {new_version}?"
|
||||||
|
|
||||||
|
REGISTRY_PUBLICATION_HINT = '''
|
||||||
|
Remember to commit and/or publish the new registry!
|
||||||
|
|
||||||
|
* cp {local_registry.filepath} nucypher/blockchain/eth/contract_registry/{network}/contract_registry.json
|
||||||
|
* git add nucypher/blockchain/eth/contract_registry/{network}/contract_registry.json
|
||||||
|
* git commit -m "Update contract registry for {contract_name}"
|
||||||
|
* Push to the appropriate branch and open a pull request!
|
||||||
|
|
||||||
|
'''
|
||||||
|
ETHERSCAN_VERIFY_HINT = '''
|
||||||
|
Remember to record deployment parameters for etherscan verification
|
||||||
|
Compiled with solc version {solc_version}
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
#
|
#
|
||||||
# Multisig
|
# Multisig
|
||||||
|
|
|
@ -189,6 +189,7 @@ Registry ................ {registry.filepath}
|
||||||
|
|
||||||
preallocation_escrow_payload = f"""
|
preallocation_escrow_payload = f"""
|
||||||
{staking_interface_agent.contract_name} ......... {bare_contract.address}
|
{staking_interface_agent.contract_name} ......... {bare_contract.address}
|
||||||
|
~ Version .............. {bare_contract.version}
|
||||||
~ Ethers ............... {Web3.fromWei(blockchain.client.get_balance(bare_contract.address), 'ether')} ETH
|
~ Ethers ............... {Web3.fromWei(blockchain.client.get_balance(bare_contract.address), 'ether')} ETH
|
||||||
~ Tokens ............... {NU.from_nunits(token_agent.get_balance(bare_contract.address))}
|
~ Tokens ............... {NU.from_nunits(token_agent.get_balance(bare_contract.address))}
|
||||||
~ StakingInterfaceRouter {router_deployer.contract.address}
|
~ StakingInterfaceRouter {router_deployer.contract.address}
|
||||||
|
|
|
@ -14,8 +14,11 @@
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
||||||
"""
|
"""
|
||||||
|
from eth_typing import HexStr
|
||||||
from web3 import Web3
|
from web3 import Web3
|
||||||
|
from web3._utils.abi import get_constructor_abi, merge_args_and_kwargs
|
||||||
|
from web3._utils.contracts import encode_abi
|
||||||
|
from web3.contract import ContractConstructor
|
||||||
|
|
||||||
|
|
||||||
def to_bytes32(value=None, hexstr=None) -> bytes:
|
def to_bytes32(value=None, hexstr=None) -> bytes:
|
||||||
|
@ -38,3 +41,20 @@ def get_array_data_location(array_location: int) -> int:
|
||||||
# See https://solidity.readthedocs.io/en/latest/internals/layout_in_storage.html#mappings-and-dynamic-arrays
|
# See https://solidity.readthedocs.io/en/latest/internals/layout_in_storage.html#mappings-and-dynamic-arrays
|
||||||
data_location = Web3.toInt(Web3.keccak(to_bytes32(array_location)))
|
data_location = Web3.toInt(Web3.keccak(to_bytes32(array_location)))
|
||||||
return data_location
|
return data_location
|
||||||
|
|
||||||
|
|
||||||
|
def encode_constructor_arguments(web3: Web3,
|
||||||
|
constructor_function: ContractConstructor,
|
||||||
|
*constructor_args, **constructor_kwargs) -> HexStr:
|
||||||
|
"""
|
||||||
|
Takes a web3 constructor function and the arguments passed to it, and produces an encoding hex string
|
||||||
|
of the constructor arguments, following the standard ABI encoding conventions.
|
||||||
|
If there's no constructor, it returns None.
|
||||||
|
"""
|
||||||
|
constructor_abi = get_constructor_abi(constructor_function.abi)
|
||||||
|
if constructor_abi:
|
||||||
|
arguments = merge_args_and_kwargs(constructor_abi, constructor_args, constructor_kwargs)
|
||||||
|
data = encode_abi(web3, constructor_abi, arguments)
|
||||||
|
else:
|
||||||
|
data = None
|
||||||
|
return data
|
|
@ -53,6 +53,7 @@ def test_deploy_single_contract(click_runner, tempfile_path):
|
||||||
'--contract-name', NucypherTokenAgent.contract_name,
|
'--contract-name', NucypherTokenAgent.contract_name,
|
||||||
'--registry-infile', tempfile_path,
|
'--registry-infile', tempfile_path,
|
||||||
'--provider', TEST_PROVIDER_URI,
|
'--provider', TEST_PROVIDER_URI,
|
||||||
|
'--network', TEMPORARY_DOMAIN,
|
||||||
'--debug']
|
'--debug']
|
||||||
|
|
||||||
user_input = '0\n' + YES_ENTER
|
user_input = '0\n' + YES_ENTER
|
||||||
|
@ -211,11 +212,12 @@ def test_rollback(click_runner, testerchain, registry_filepath, agency):
|
||||||
command = ('rollback',
|
command = ('rollback',
|
||||||
'--contract-name', contract_name,
|
'--contract-name', contract_name,
|
||||||
'--registry-infile', registry_filepath,
|
'--registry-infile', registry_filepath,
|
||||||
|
'--network', TEMPORARY_DOMAIN,
|
||||||
'--provider', TEST_PROVIDER_URI)
|
'--provider', TEST_PROVIDER_URI)
|
||||||
|
|
||||||
user_input = '0\n' + YES_ENTER
|
user_input = '0\n' + YES_ENTER
|
||||||
result = click_runner.invoke(deploy, command, input=user_input, catch_exceptions=False)
|
result = click_runner.invoke(deploy, command, input=user_input, catch_exceptions=False)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0, result.output
|
||||||
|
|
||||||
# TODO unify this, trust more to registry_filepath, reduce calls
|
# TODO unify this, trust more to registry_filepath, reduce calls
|
||||||
registry = LocalContractRegistry(filepath=registry_filepath)
|
registry = LocalContractRegistry(filepath=registry_filepath)
|
||||||
|
|
|
@ -65,6 +65,7 @@ def test_set_range(click_runner, testerchain, agency_local_registry):
|
||||||
'--registry-infile', agency_local_registry.filepath,
|
'--registry-infile', agency_local_registry.filepath,
|
||||||
'--minimum', minimum,
|
'--minimum', minimum,
|
||||||
'--default', default,
|
'--default', default,
|
||||||
|
'--network', TEMPORARY_DOMAIN,
|
||||||
'--maximum', maximum)
|
'--maximum', maximum)
|
||||||
|
|
||||||
account_index = '0\n'
|
account_index = '0\n'
|
||||||
|
@ -87,6 +88,7 @@ def test_nucypher_deploy_inspect_fully_deployed(click_runner, agency_local_regis
|
||||||
|
|
||||||
status_command = ('inspect',
|
status_command = ('inspect',
|
||||||
'--registry-infile', agency_local_registry.filepath,
|
'--registry-infile', agency_local_registry.filepath,
|
||||||
|
'--network', TEMPORARY_DOMAIN,
|
||||||
'--provider', TEST_PROVIDER_URI)
|
'--provider', TEST_PROVIDER_URI)
|
||||||
|
|
||||||
result = click_runner.invoke(deploy,
|
result = click_runner.invoke(deploy,
|
||||||
|
@ -120,6 +122,7 @@ def test_transfer_ownership(click_runner, testerchain, agency_local_registry):
|
||||||
'--registry-infile', agency_local_registry.filepath,
|
'--registry-infile', agency_local_registry.filepath,
|
||||||
'--contract-name', STAKING_ESCROW_CONTRACT_NAME,
|
'--contract-name', STAKING_ESCROW_CONTRACT_NAME,
|
||||||
'--provider', TEST_PROVIDER_URI,
|
'--provider', TEST_PROVIDER_URI,
|
||||||
|
'--network', TEMPORARY_DOMAIN,
|
||||||
'--target-address', maclane)
|
'--target-address', maclane)
|
||||||
|
|
||||||
account_index = '0\n'
|
account_index = '0\n'
|
||||||
|
@ -143,6 +146,7 @@ def test_transfer_ownership(click_runner, testerchain, agency_local_registry):
|
||||||
'--contract-name', STAKING_ESCROW_CONTRACT_NAME,
|
'--contract-name', STAKING_ESCROW_CONTRACT_NAME,
|
||||||
'--registry-infile', agency_local_registry.filepath,
|
'--registry-infile', agency_local_registry.filepath,
|
||||||
'--provider', TEST_PROVIDER_URI,
|
'--provider', TEST_PROVIDER_URI,
|
||||||
|
'--network', TEMPORARY_DOMAIN,
|
||||||
'--target-address', michwill)
|
'--target-address', michwill)
|
||||||
|
|
||||||
user_input = yes
|
user_input = yes
|
||||||
|
@ -169,6 +173,7 @@ def test_bare_contract_deployment_to_alternate_registry(click_runner, agency_loc
|
||||||
'--provider', TEST_PROVIDER_URI,
|
'--provider', TEST_PROVIDER_URI,
|
||||||
'--registry-infile', agency_local_registry.filepath,
|
'--registry-infile', agency_local_registry.filepath,
|
||||||
'--registry-outfile', ALTERNATE_REGISTRY_FILEPATH,
|
'--registry-outfile', ALTERNATE_REGISTRY_FILEPATH,
|
||||||
|
'--network', TEMPORARY_DOMAIN,
|
||||||
'--ignore-deployed')
|
'--ignore-deployed')
|
||||||
|
|
||||||
user_input = '0\n' + 'Y\n' + 'DEPLOY'
|
user_input = '0\n' + 'Y\n' + 'DEPLOY'
|
||||||
|
@ -238,6 +243,7 @@ def test_batch_deposits(click_runner,
|
||||||
deploy_command = ('allocations',
|
deploy_command = ('allocations',
|
||||||
'--registry-infile', agency_local_registry.filepath,
|
'--registry-infile', agency_local_registry.filepath,
|
||||||
'--allocation-infile', mock_allocation_infile,
|
'--allocation-infile', mock_allocation_infile,
|
||||||
|
'--network', TEMPORARY_DOMAIN,
|
||||||
'--provider', TEST_PROVIDER_URI)
|
'--provider', TEST_PROVIDER_URI)
|
||||||
|
|
||||||
account_index = '0\n'
|
account_index = '0\n'
|
||||||
|
@ -264,6 +270,7 @@ def test_manual_deployment_of_idle_network(click_runner):
|
||||||
command = ('contracts',
|
command = ('contracts',
|
||||||
'--contract-name', NUCYPHER_TOKEN_CONTRACT_NAME,
|
'--contract-name', NUCYPHER_TOKEN_CONTRACT_NAME,
|
||||||
'--provider', TEST_PROVIDER_URI,
|
'--provider', TEST_PROVIDER_URI,
|
||||||
|
'--network', TEMPORARY_DOMAIN,
|
||||||
'--registry-infile', ALTERNATE_REGISTRY_FILEPATH_2)
|
'--registry-infile', ALTERNATE_REGISTRY_FILEPATH_2)
|
||||||
|
|
||||||
user_input = '0\n' + YES_ENTER + INSECURE_DEVELOPMENT_PASSWORD
|
user_input = '0\n' + YES_ENTER + INSECURE_DEVELOPMENT_PASSWORD
|
||||||
|
@ -281,6 +288,7 @@ def test_manual_deployment_of_idle_network(click_runner):
|
||||||
'--contract-name', STAKING_ESCROW_CONTRACT_NAME,
|
'--contract-name', STAKING_ESCROW_CONTRACT_NAME,
|
||||||
'--mode', 'idle',
|
'--mode', 'idle',
|
||||||
'--provider', TEST_PROVIDER_URI,
|
'--provider', TEST_PROVIDER_URI,
|
||||||
|
'--network', TEMPORARY_DOMAIN,
|
||||||
'--registry-infile', ALTERNATE_REGISTRY_FILEPATH_2)
|
'--registry-infile', ALTERNATE_REGISTRY_FILEPATH_2)
|
||||||
|
|
||||||
user_input = '0\n' + YES_ENTER + INSECURE_DEVELOPMENT_PASSWORD
|
user_input = '0\n' + YES_ENTER + INSECURE_DEVELOPMENT_PASSWORD
|
||||||
|
@ -294,6 +302,7 @@ def test_manual_deployment_of_idle_network(click_runner):
|
||||||
command = ('contracts',
|
command = ('contracts',
|
||||||
'--contract-name', POLICY_MANAGER_CONTRACT_NAME,
|
'--contract-name', POLICY_MANAGER_CONTRACT_NAME,
|
||||||
'--provider', TEST_PROVIDER_URI,
|
'--provider', TEST_PROVIDER_URI,
|
||||||
|
'--network', TEMPORARY_DOMAIN,
|
||||||
'--registry-infile', ALTERNATE_REGISTRY_FILEPATH_2)
|
'--registry-infile', ALTERNATE_REGISTRY_FILEPATH_2)
|
||||||
|
|
||||||
user_input = '0\n' + YES_ENTER + INSECURE_DEVELOPMENT_PASSWORD
|
user_input = '0\n' + YES_ENTER + INSECURE_DEVELOPMENT_PASSWORD
|
||||||
|
@ -307,6 +316,7 @@ def test_manual_deployment_of_idle_network(click_runner):
|
||||||
command = ('contracts',
|
command = ('contracts',
|
||||||
'--contract-name', ADJUDICATOR_CONTRACT_NAME,
|
'--contract-name', ADJUDICATOR_CONTRACT_NAME,
|
||||||
'--provider', TEST_PROVIDER_URI,
|
'--provider', TEST_PROVIDER_URI,
|
||||||
|
'--network', TEMPORARY_DOMAIN,
|
||||||
'--registry-infile', ALTERNATE_REGISTRY_FILEPATH_2)
|
'--registry-infile', ALTERNATE_REGISTRY_FILEPATH_2)
|
||||||
|
|
||||||
user_input = '0\n' + YES_ENTER + INSECURE_DEVELOPMENT_PASSWORD
|
user_input = '0\n' + YES_ENTER + INSECURE_DEVELOPMENT_PASSWORD
|
||||||
|
@ -321,6 +331,7 @@ def test_manual_deployment_of_idle_network(click_runner):
|
||||||
'--contract-name', STAKING_ESCROW_CONTRACT_NAME,
|
'--contract-name', STAKING_ESCROW_CONTRACT_NAME,
|
||||||
'--activate',
|
'--activate',
|
||||||
'--provider', TEST_PROVIDER_URI,
|
'--provider', TEST_PROVIDER_URI,
|
||||||
|
'--network', TEMPORARY_DOMAIN,
|
||||||
'--registry-infile', ALTERNATE_REGISTRY_FILEPATH_2)
|
'--registry-infile', ALTERNATE_REGISTRY_FILEPATH_2)
|
||||||
|
|
||||||
user_input = '0\n' + YES_ENTER + YES_ENTER + INSECURE_DEVELOPMENT_PASSWORD
|
user_input = '0\n' + YES_ENTER + YES_ENTER + INSECURE_DEVELOPMENT_PASSWORD
|
||||||
|
|
|
@ -15,13 +15,12 @@ You should have received a copy of the GNU Affero General Public License
|
||||||
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from eth_tester.exceptions import TransactionFailed
|
from eth_tester.exceptions import TransactionFailed
|
||||||
from eth_utils import to_canonical_address
|
from eth_utils import to_canonical_address
|
||||||
|
|
||||||
from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
||||||
from tests.utils.solidity import to_32byte_hex
|
from nucypher.utilities.ethereum import to_32byte_hex
|
||||||
|
|
||||||
|
|
||||||
def sign_hash(testerchain, account: str, data_hash: bytes) -> dict:
|
def sign_hash(testerchain, account: str, data_hash: bytes) -> dict:
|
||||||
|
|
|
@ -15,7 +15,6 @@ You should have received a copy of the GNU Affero General Public License
|
||||||
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import pytest
|
import pytest
|
||||||
from eth_tester.exceptions import TransactionFailed
|
from eth_tester.exceptions import TransactionFailed
|
||||||
|
@ -28,7 +27,8 @@ from nucypher.blockchain.economics import BaseEconomics
|
||||||
from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
||||||
from nucypher.crypto.api import sha256_digest
|
from nucypher.crypto.api import sha256_digest
|
||||||
from nucypher.crypto.signing import SignatureStamp
|
from nucypher.crypto.signing import SignatureStamp
|
||||||
from tests.utils.solidity import to_32byte_hex
|
from nucypher.utilities.ethereum import to_32byte_hex
|
||||||
|
|
||||||
|
|
||||||
DISABLED_FIELD = 0
|
DISABLED_FIELD = 0
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ from web3.contract import Contract
|
||||||
|
|
||||||
from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
||||||
from nucypher.blockchain.eth.token import NU
|
from nucypher.blockchain.eth.token import NU
|
||||||
from tests.utils.solidity import get_array_data_location, get_mapping_entry_location, to_bytes32
|
from nucypher.utilities.ethereum import get_array_data_location, get_mapping_entry_location, to_bytes32
|
||||||
|
|
||||||
LOCK_RE_STAKE_UNTIL_PERIOD_FIELD = 4
|
LOCK_RE_STAKE_UNTIL_PERIOD_FIELD = 4
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue