Example #1
0
def unfreeze(aergo_to: herapy.Aergo, receiver: str, lock_proof: AttributeDict,
             bridge_to: str, gas_limit: int,
             gas_price: int) -> Tuple[str, Transaction]:
    """ Unlock the receiver's deposit balance on aergo_to. """
    if not is_aergo_address(receiver):
        raise InvalidArgumentsError(
            "Receiver {} must be an Aergo address".format(receiver))
    ap = format_proof_for_lua(lock_proof.storageProof[0].proof)
    balance = int.from_bytes(lock_proof.storageProof[0].value, "big")
    ubig_balance = {'_bignum': str(balance)}
    # call unlock on aergo_to with the burn proof from aergo_from
    tx, result = aergo_to.call_sc(bridge_to,
                                  "unfreeze",
                                  args=[receiver, ubig_balance, ap],
                                  gas_limit=gas_limit,
                                  gas_price=gas_price)
    if result.status != herapy.CommitStatus.TX_OK:
        raise TxError("Unfreeze asset Tx commit failed : {}".format(result))

    result = aergo_to.wait_tx_result(tx.tx_hash)
    if result.status != herapy.TxResultStatus.SUCCESS:
        raise TxError("Unfreeze asset Tx execution failed : {}".format(result))
    logger.info("\u26fd Unfreeze tx fee paid: %s", result.fee_used)
    logger.info("\u26fd Aergo gas used: %s", result.gas_used)
    return str(tx.tx_hash), result
Example #2
0
def mint(aergo_to: herapy.Aergo, receiver: str, lock_proof: AttributeDict,
         token_origin: str, bridge_to: str, gas_limit: int,
         gas_price: int) -> Tuple[str, str, Transaction]:
    """ Unlock the receiver's deposit balance on aergo_to. """
    if not is_aergo_address(receiver):
        raise InvalidArgumentsError(
            "Receiver {} must be an Aergo address".format(receiver))
    if not is_ethereum_address(token_origin):
        raise InvalidArgumentsError(
            "token_origin {} must be an Ethereum address".format(token_origin))
    ap = format_proof_for_lua(lock_proof.storageProof[0].proof)
    balance = int.from_bytes(lock_proof.storageProof[0].value, "big")
    ubig_balance = {'_bignum': str(balance)}
    # call unlock on aergo_to with the burn proof from aergo_from
    tx, result = aergo_to.call_sc(
        bridge_to,
        "mint",
        args=[receiver, ubig_balance, token_origin[2:].lower(), ap],
        gas_limit=gas_limit,
        gas_price=gas_price)
    if result.status != herapy.CommitStatus.TX_OK:
        raise TxError("Mint asset Tx commit failed : {}".format(result))

    result = aergo_to.wait_tx_result(tx.tx_hash)
    if result.status != herapy.TxResultStatus.SUCCESS:
        raise TxError("Mint asset Tx execution failed : {}".format(result))
    logger.info("\u26fd Aergo gas used: %s", result.gas_used)
    token_pegged = json.loads(result.detail)[0]
    return token_pegged, str(tx.tx_hash), result
Example #3
0
def freeze(
    aergo_from: herapy.Aergo,
    bridge_from: str,
    receiver: str,
    value: int,
    gas_limit: int,
    gas_price: int,
) -> Tuple[int, str, Transaction]:
    """ Freeze aergo native """
    if not is_ethereum_address(receiver):
        raise InvalidArgumentsError(
            "Receiver {} must be an Ethereum address".format(receiver))
    args = (receiver[2:].lower(), {"_bignum": str(value)})
    tx, result = aergo_from.call_sc(bridge_from,
                                    "freeze",
                                    amount=value,
                                    args=args,
                                    gas_limit=gas_limit,
                                    gas_price=gas_price)

    if result.status != herapy.CommitStatus.TX_OK:
        raise TxError("Freeze asset Tx commit failed : {}".format(result))

    # Check freeze success
    result = aergo_from.wait_tx_result(tx.tx_hash)
    if result.status != herapy.TxResultStatus.SUCCESS:
        raise TxError("Freeze Aer Tx execution failed : {}".format(result))
    logger.info("\u26fd Aergo gas used: %s", result.gas_used)
    # get precise burn height
    tx_detail = aergo_from.get_tx(tx.tx_hash)
    freeze_height = tx_detail.block.height
    return freeze_height, str(tx.tx_hash), tx_detail
Example #4
0
def burn(
    aergo_from: herapy.Aergo,
    bridge_from: str,
    receiver: str,
    value: int,
    token_pegged: str,
    gas_limit: int,
    gas_price: int,
) -> Tuple[int, str, Transaction]:
    """ Burn a minted token on a sidechain. """
    if not is_ethereum_address(receiver):
        raise InvalidArgumentsError(
            "Receiver {} must be an Ethereum address".format(receiver))
    if not is_aergo_address(token_pegged):
        raise InvalidArgumentsError(
            "token_pegged {} must be an Aergo address".format(token_pegged))
    args = (receiver[2:].lower(), {"_bignum": str(value)}, token_pegged)
    tx, result = aergo_from.call_sc(bridge_from,
                                    "burn",
                                    args=args,
                                    gas_limit=gas_limit,
                                    gas_price=gas_price)

    if result.status != herapy.CommitStatus.TX_OK:
        raise TxError("Burn asset Tx commit failed : {}".format(result))

    # Check burn success
    result = aergo_from.wait_tx_result(tx.tx_hash)
    if result.status != herapy.TxResultStatus.SUCCESS:
        raise TxError("Burn asset Tx execution failed : {}".format(result))
    logger.info("\u26fd Aergo gas used: %s", result.gas_used)
    # get precise burn height
    tx_detail = aergo_from.get_tx(tx.tx_hash)
    burn_height = tx_detail.block.height
    return burn_height, str(tx.tx_hash), tx_detail
Example #5
0
def mint(
    aergo_to: herapy.Aergo,
    receiver: str,
    lock_proof: herapy.obj.sc_state.SCState,
    token_origin: str,
    bridge_to: str,
    gas_limit: int,
    gas_price: int
) -> Tuple[str, str]:
    """ Mint the receiver's deposit balance on aergo_to. """
    if not is_aergo_address(receiver):
        raise InvalidArgumentsError(
            "Receiver {} must be an Aergo address".format(receiver)
        )
    auditPath = lock_proof.var_proofs[0].auditPath
    ap = [node.hex() for node in auditPath]
    balance = lock_proof.var_proofs[0].value.decode('utf-8')[1:-1]
    ubig_balance = {'_bignum': str(balance)}
    # call mint on aergo_to with the lock proof from aergo_from
    tx, result = aergo_to.call_sc(
        bridge_to, "mint", args=[receiver, ubig_balance, token_origin, ap],
        gas_limit=gas_limit, gas_price=gas_price
    )
    if result.status != herapy.CommitStatus.TX_OK:
        raise TxError("Mint asset Tx commit failed : {}".format(result))

    result = aergo_to.wait_tx_result(tx.tx_hash)
    if result.status != herapy.TxResultStatus.SUCCESS:
        raise TxError("Mint asset Tx execution failed : {}".format(result))
    logger.info("\u26fd gas used: %s", result.gas_used)
    token_pegged = json.loads(result.detail)[0]
    return token_pegged, str(tx.tx_hash)
Example #6
0
def burn(w3: Web3, signer_acct, receiver: str, amount: int, bridge_from: str,
         bridge_from_abi: str, token_pegged: str, gas_limit: int,
         gas_price: int) -> Tuple[int, str, AttributeDict]:
    """ Burn a token that was minted on ethereum. """
    if not is_aergo_address(receiver):
        raise InvalidArgumentsError(
            "Receiver {} must be an Aergo address".format(receiver))
    if not is_ethereum_address(token_pegged):
        raise InvalidArgumentsError(
            "token_pegged {} must be an Ethereum address".format(token_pegged))
    bridge_from = Web3.toChecksumAddress(bridge_from)
    eth_bridge = w3.eth.contract(address=bridge_from, abi=bridge_from_abi)
    construct_txn = eth_bridge.functions.burn(
        receiver, amount, token_pegged).buildTransaction({
            'chainId':
            w3.eth.chainId,
            'from':
            signer_acct.address,
            'nonce':
            w3.eth.getTransactionCount(signer_acct.address),
            'gas':
            gas_limit,
            'gasPrice':
            w3.toWei(gas_price, 'gwei')
        })
    signed = signer_acct.sign_transaction(construct_txn)
    tx_hash = w3.eth.sendRawTransaction(signed.rawTransaction)
    receipt = w3.eth.waitForTransactionReceipt(tx_hash)
    if receipt.status != 1:
        raise TxError("Burn asset Tx execution failed: {}".format(receipt))
    logger.info("\u26fd Eth Gas used: %s", receipt.gasUsed)
    return receipt.blockNumber, tx_hash.hex(), receipt
Example #7
0
def increase_approval(spender: str, asset_addr: str, amount: int, w3: Web3,
                      erc20_abi: str, signer_acct, gas_limit: int,
                      gas_price: int) -> Tuple[int, str]:
    """ Increase approval increases the amount of tokens that spender
        can withdraw. For older tokens without the increaseApproval
        function in the abi, approval should be set to 0 and then to amount.
        Newer tokens with increaseAllowance should also be suported
    """
    asset_addr = Web3.toChecksumAddress(asset_addr)
    spender = Web3.toChecksumAddress(spender)
    function = get_abi_function(w3, asset_addr, erc20_abi, spender, amount)
    approval_nonce = w3.eth.getTransactionCount(signer_acct.address)
    construct_txn = function.buildTransaction({
        'chainId':
        w3.eth.chainId,
        'from':
        signer_acct.address,
        'nonce':
        approval_nonce,
        'gas':
        gas_limit,
        'gasPrice':
        w3.toWei(gas_price, 'gwei')
    })
    signed = signer_acct.sign_transaction(construct_txn)
    tx_hash = w3.eth.sendRawTransaction(signed.rawTransaction)
    receipt = w3.eth.waitForTransactionReceipt(tx_hash)
    if receipt.status != 1:
        raise TxError(
            "Increase approval Tx execution failed {}".format(receipt))
    return approval_nonce + 1, tx_hash.hex()
Example #8
0
def deploy_token(payload_str: str, aergo: herapy.Aergo, receiver: str,
                 total_supply: int, fee_limit: int, fee_price: int) -> str:
    """ Deploy a token contract payload and give the
    total supply to the deployer
    """
    payload = herapy.utils.decode_address(payload_str)
    tx, result = aergo.deploy_sc(amount=0,
                                 payload=payload,
                                 args=[{
                                     "_bignum": str(total_supply)
                                 }, receiver])
    if result.status != herapy.CommitStatus.TX_OK:
        raise TxError("Token deployment Tx commit failed : {}".format(result))

    result = aergo.wait_tx_result(tx.tx_hash)
    if result.status != herapy.TxResultStatus.CREATED:
        raise TxError(
            "Token deployment Tx execution failed : {}".format(result))

    sc_address = result.contract_address
    return sc_address
Example #9
0
def lock(
    aergo_from: herapy.Aergo,
    bridge_from: str,
    receiver: str,
    value: int,
    asset: str,
    gas_limit: int,
    gas_price: int,
) -> Tuple[int, str, Transaction]:
    """ Lock can be called to lock aer or tokens.
        it supports delegated transfers when tx broadcaster is not
        the same as the token owner
    """
    if not is_ethereum_address(receiver):
        raise InvalidArgumentsError(
            "receiver {} must be an Ethereum address".format(receiver))
    if not is_aergo_address(asset):
        raise InvalidArgumentsError(
            "asset {} must be an Aergo address".format(asset))
    args = (bridge_from, {"_bignum": str(value)}, receiver[2:].lower())
    tx, result = aergo_from.call_sc(asset,
                                    "transfer",
                                    args=args,
                                    amount=0,
                                    gas_limit=gas_limit,
                                    gas_price=gas_price)
    if result.status != herapy.CommitStatus.TX_OK:
        raise TxError("Lock asset Tx commit failed : {}".format(result))

    # Check lock success
    result = aergo_from.wait_tx_result(tx.tx_hash)
    if result.status != herapy.TxResultStatus.SUCCESS:
        raise TxError("Lock asset Tx execution failed : {}".format(result))
    logger.info("\u26fd Aergo gas used: %s", result.gas_used)
    # get precise lock height
    tx_detail = aergo_from.get_tx(tx.tx_hash)
    lock_height = tx_detail.block.height

    return lock_height, str(tx.tx_hash), tx_detail
Example #10
0
def transfer(
    value: int,
    to: str,
    asset_addr: str,
    aergo: herapy.Aergo,
    sender: str,
    fee_limit: int,
    fee_price: int,
) -> str:
    """ Support 3 types of transfers : simple aer transfers, token transfer,
    and signed token transfers (token owner != tx signer)
    """
    if not is_aergo_address(to):
        raise InvalidArgumentsError(
            "Receiver {} must be an Aergo address".format(to))
    aergo.get_account()  # get the latest nonce for making tx
    if asset_addr == "aergo":
        # transfer aer on network_name
        tx, result = aergo.send_payload(to_address=to,
                                        amount=value,
                                        payload=None)
    else:
        # transfer token (issued or pegged) on network_name
        tx, result = aergo.call_sc(asset_addr,
                                   "transfer",
                                   args=[to, {
                                       "_bignum": str(value)
                                   }],
                                   amount=0)

    if result.status != herapy.CommitStatus.TX_OK:
        raise TxError("Transfer asset Tx commit failed : {}".format(result))

    # Check lock success
    result = aergo.wait_tx_result(tx.tx_hash)
    if result.status != herapy.TxResultStatus.SUCCESS:
        raise TxError("Transfer asset Tx execution failed : {}".format(result))

    return str(tx.tx_hash)
Example #11
0
def mint(
    w3: Web3,
    signer_acct,
    receiver: str,
    lock_proof: herapy.obj.sc_state.SCState,
    token_origin: str,
    bridge_to: str,
    bridge_to_abi: str,
    gas_limit: int,
    gas_price: int
) -> Tuple[str, str, AttributeDict]:
    """ Mint the receiver's deposit balance on aergo_to. """
    if not is_ethereum_address(receiver):
        raise InvalidArgumentsError(
            "Receiver {} must be an Ethereum address".format(receiver)
        )
    if not is_aergo_address(token_origin):
        raise InvalidArgumentsError(
            "token_origin {} must be an Aergo address".format(token_origin)
        )
    receiver = Web3.toChecksumAddress(receiver)
    balance = int(lock_proof.var_proofs[0].value.decode('utf-8')[1:-1])
    ap = lock_proof.var_proofs[0].auditPath
    bitmap = lock_proof.var_proofs[0].bitmap
    leaf_height = lock_proof.var_proofs[0].height
    # call mint on ethereum with the lock proof from aergo_from
    eth_bridge = w3.eth.contract(
        address=bridge_to,
        abi=bridge_to_abi
    )
    construct_txn = eth_bridge.functions.mint(
        receiver, balance, token_origin, ap, bitmap, leaf_height
    ).buildTransaction({
        'chainId': w3.eth.chainId,
        'from': signer_acct.address,
        'nonce': w3.eth.getTransactionCount(
            signer_acct.address
        ),
        'gas': gas_limit,
        'gasPrice': w3.toWei(gas_price, 'gwei')
    })
    signed = signer_acct.sign_transaction(construct_txn)
    tx_hash = w3.eth.sendRawTransaction(signed.rawTransaction)
    receipt = w3.eth.waitForTransactionReceipt(tx_hash)
    if receipt.status != 1:
        raise TxError("Mint asset Tx execution failed: {}".format(receipt))
    logger.info("\u26fd Eth Gas used: %s", receipt.gasUsed)
    events = eth_bridge.events.mintEvent().processReceipt(receipt)
    token_pegged = events[0]['args']['tokenAddress']

    return token_pegged, tx_hash.hex(), receipt