Пример #1
0
def removeSubaccountAsMaster(executionerPublicKey, domainName, SubaccountHash):
    if not CheckWitness(executionerPublicKey):
        return False

    #check if owner and domains exists
    if not existDomainAndOwnerWithHash(executionerPublicKey, domainName):
        return False

    SubaccountKey = createSubMainKey(domainName, SubaccountHash)
    if existSubaccount(SubaccountKey):
        ctx = GetContext()
        subdomainName = Get(ctx, createSubRootNameKey(SubaccountKey))
        if subdomainName is not None:
            Delete(ctx, createSubNameKey(SubaccountKey, subdomainName))
            Delete(ctx, createSubRootNameKey(SubaccountKey))
            #get subdomain
            subdomainName = Get(ctx, createSubRootNameKey(SubaccountKey))
            subsKeyValue = concat(subdomainName, ":")
            subsKeyValue = concat(subsKeyValue, SubaccountHash)
            #remove from all subs
            hashesKey = createSubsKey(domainName)
            removeHashFromHashes(hashesKey, subsKeyValue, ";")

        Delete(ctx, SubaccountKey)
        Delete(ctx, createMasterApprovedKey(SubaccountKey))
        Delete(ctx, createSubApprovedKey(SubaccountKey))

        #remove from all scripthash subdomains
        tr = concat("s:", domainName)
        removeDomainFromStorage(SubaccountKey, tr)
        return True
    return False
Пример #2
0
def remove_token_from_owners_list(ctx, t_owner, t_id):
    """Removes a token from owner's list of tokens

    :param StorageContext ctx: current store context
    :param byte[] t_owner: token owner
    :param bytes t_id: token id
    :return: token removal success
    :rtype: bool
    """
    length = Get(ctx, t_owner)  # get how many tokens this owner owns
    # this should be impossible, but just in case, leaving it here
    if len(length) == b'\x00':
        Notify('owner has no tokens')
        return False

    # if Delete returns True, that means the token was
    # successfully deleted and we should decrement the owner's balance.
    # otherwise, the token didn't exist/didn't belong to the owner,
    # so Delete returns False in that case.
    if Delete(ctx, concat(t_owner, t_id)):
        new_balance = length - 1
        if new_balance > 0:
            Put(ctx, t_owner, new_balance)
        else:
            Delete(ctx, t_owner)

        Log("removed token from owner's list and decremented owner's balance")
        return True

    Notify("token not found in owner's list")
    return False
Пример #3
0
def removePendingTransaction(executionerPublicKey, domainName,
                             idPendingTransaction):
    if not CheckWitness(executionerPublicKey):
        return False

    #if owner or Subaccount and domains exist
    if not existDomainAndOwnerOrSubaccountWithHash(executionerPublicKey,
                                                   domainName):
        return False

    #check if exist transaction
    if existPendingTransaction(domainName, idPendingTransaction) is None:
        return False

    #create root pending transaction
    key = createPendingTransactionKey(domainName, idPendingTransaction)

    ctx = GetContext()
    transactionAttr = Get(ctx, createAttributesKey(key))
    price = Get(ctx, createPriceKey(key))

    #recreate unique pending transaction
    tr = createTransactionHash(idPendingTransaction, transactionAttr, price)

    Delete(ctx, key)
    Delete(ctx, createExecutedKey(key))
    Delete(ctx, createAttributesKey(key))
    Delete(ctx, createPriceKey(key))

    #remove from domains/pendingTransactions
    keyAllPending = createPendingTransactionsKey(domainName)
    removeHashFromHashes(keyAllPending, tr, "|")

    return True
Пример #4
0
def DeleteOrder(order_key):
    """
    Method for the dApp owner to delete claimed or refunded exchanges

    :param order_key: order_key
    :type order_key: str

    :return: whether the deletion succeeded
    :rtype: bool
    """

    if not CheckWitness(OWNER):
        Log("Must be owner to delete an exchange")
        return False

    context = GetContext()
    order_data = Get(context, order_key)
    status = order_data[12]

    if status == 'claimed':
        Delete(context, order_key)
        DispatchDeleteOrderEvent(order_key)

    elif status == 'refunded':
        Delete(context, order_key)
        DispatchDeleteOrderEvent(order_key)

    return False
Пример #5
0
def Main(operation, args):
    """
    Main definition for the smart contracts

    :param operation: the operation to be performed
    :type operation: str

    :param args: list of arguments.
        args[0] is always sender script hash
        args[1] is always domain
        args[2] (optional) is either target or other address
        args[3] (optional) is target (if args[2] is address)
    :param type: str

    :return:
        byterarray: The result of the operation
    """
    # Common definitions
    user_hash = args[0]
    domain = args[1]
    domain_owner_key = concat(domain, ".owner")
    domain_target_key = concat(domain, ".target")
    owner = b'#\xba\'\x03\xc52c\xe8\xd6\xe5"\xdc2 39\xdc\xd8\xee\xe9'

    # This doesn't require authentication
    if operation == 'GetDomain':
        return Get(GetContext(), domain_target_key)

    # Everything after this requires authorization
    authorized = CheckWitness(user_hash)
    if not authorized:
        Log("Not Authorized")
        return False
    Log("Authorized")

    if operation == 'RegisterDomain':
        if (CheckWitness(owner)):
            address = args[2]
            Put(GetContext(), domain_owner_key, address)
            if len(args) == 4:
                target = args[3]
                Put(GetContext(), domain_target_key, target)
            return True

    if operation == 'SetDomainTarget':
        domain_owner = Get(GetContext(), domain_owner_key)
        if (CheckWitness(domain_owner)) or (CheckWitness(owner)):
            # License the product
            target = args[2]
            Put(GetContext(), domain_target_key, target)
            return True

    if operation == 'DeleteDomain':
        if (CheckWitness(owner)):
            Delete(GetContext(), domain_owner_key)
            Delete(GetContext(), domain_target_key)
            return True

    return False
Пример #6
0
def delete_game(game_id):
    context = GetContext()
    game_key_prefix = concat('game.', game_id)
    player1 = Get(context, concat(game_key_prefix, '.player1'))
    player2 = Get(context, concat(game_key_prefix, '.player2'))
    players_key = concat(concat(player1, '.'), player2)
    players_reverse_key = concat(concat(player2, '.'), player1)
    Delete(context, players_key)
    Delete(context, players_reverse_key)
Пример #7
0
def kyc_deregister(ctx, args):
    """
    Deregister a list of addresses from KYC

    :param ctx:GetContext() used to access contract storage
    :param args:list a list of addresses to deregister

    :return:int The number of addresses deregistered from KYC
    """

    ok_count = 0

    canRegister = CheckWitness(TOKEN_OWNER)

    if not canRegister and get_kyc_admin_status(ctx, args[0]) and CheckWitness(
            args[0]):
        canRegister = True
        args.remove(0)

    if canRegister:
        for address in args:
            if len(address) == 20:
                Delete(ctx, concat(KYC_KEY, address))
                OnKycDeregister(address)
                ok_count += 1

    return ok_count
def DeleteOrder(order_id):
    order = GetOrder(order_id)
    if not order:
        Log("Order doesn't exist")
        return False

    usr_adr = order[0]
    if not check_permission(usr_adr):
        Log("Must be owner to delete an order")
        return False

    orders_id = GetOrderIdList()
    found = False
    i = 0
    while i < len(orders_id):
        if orders_id[i] == order_id:
            found = True
            orders_id.remove(i)  # pop by index
            i = len(orders_id) + 1  # break
        i += 1
    if found:

        orders_serialized = serialize_array(orders_id)
        context = GetContext()
        Put(context, ORDER_ID_LIST_PREFIX, orders_serialized)

        order_key = concat(ORDER_ID_PREFIX, order_id)
        Delete(context, order_key)
        return True
    else:
        Log("Order doesn't exist")
        return False
def DeleteRecord(record_id):
    record = GetRecord(record_id)
    if not record:
        Log("Record doesn't exist")
        return False

    usr_adr = record[0]
    if not check_permission(usr_adr):
        Log("Must be owner to delete a record")
        return False

    records_id = GetRecordIdList(usr_adr)
    found = False
    i = 0
    while i < len(records_id):
        if records_id[i] == record_id:
            found = True
            records_id.remove(i)  # pop by index
            i = len(records_id) + 1  # break
        i += 1
    if found:
        records_serialized = serialize_array(records_id)
        record_id_list_key = concat(RECORD_ID_LIST_PREFIX, usr_adr)
        context = GetContext()
        Put(context, record_id_list_key, records_serialized)

        record_key = concat(RECORD_ID_META_PREFIX, record_id)
        Delete(context, record_key)
        return True
    else:
        Log("Record doesn't exist")
        return False
Пример #10
0
def buyCat(from_acc, animal, amount):
    if not CheckWitness(from_acc):
        Notify("Not the owner, can't buy")
        return False

    tmplist = Get(ctx, from_acc + "CAT")
    if len(tmplist) != 0:
        delist = Deserialize(tmplist)
        Notify(delist)
        delist.append(animal)
        Notify(delist)
        Put(ctx, from_acc + "CAT", Serialize(delist))
    else:
        Put(ctx, from_acc + "CAT", Serialize([animal]))
        Notify(Serialize([animal]))

    current_balance = Get(ctx, from_acc)
    if current_balance <= amount:
        Notify("Insufficient funds")
        return False
    to_balance = Get(ctx, TOKEN_OWNER)
    to_balance += amount
    Put(ctx, TOKEN_OWNER, to_balance)
    current_balance -= amount
    if current_balance != 0:
        Put(ctx, from_acc, current_balance)
    else:
        Delete(ctx, from_acc)
    OnTransfer(from_acc, TOKEN_OWNER, amount)
    return True
Пример #11
0
def transfer(t_from, t_to, amount):
    ctx = GetContext()

    assert len(t_from) == 20, "Invalid from address"
    assert len(t_to) == 20, "Invalid to address"

    if t_from == t_to:
        Notify("Transferring to self. Nothing changes.")
        return True

    from_val = Get(ctx, t_from)
    if from_val == amount:
        Delete(ctx, t_from)
    else:
        difference = from_val - amount
        Put(ctx, t_from, difference)
    if from_val < amount:
        return False

    to_value = Get(ctx, t_to)
    to_total = to_value + amount
    Put(ctx, t_to, to_total)
    Notify("Transfer successful.")

    return True
Пример #12
0
def del_serialized(ctx, key, value):
    list_bytes = Get(ctx, key)
    new_list = []
    deleted = False
    if len(list_bytes) != 0:
        deserialized_list = Deserialize(list_bytes)

        for item in deserialized_list:
            if item == value:
                deleted = True
            else:
                new_list.append(item)

        if (deleted):
            if len(new_list) != 0:
                serialized_list = Serialize(new_list)
                Put(ctx, key, serialized_list)
            else:
                Delete(ctx, key)
            print("Target element has been removed.")
            return True

    print("Target element has not been removed.")

    return False
Пример #13
0
def pay_in_token(ctx, t_from, t_to, amount):
    if amount < 0:
        return False
    elif amount == 0:
        return True
    if len(t_to) != 20 or len(t_from) != 20:
        return False
    if t_from == t_to:
        print("transfer to self!")
        return True

    from_balance = Get(ctx, t_from)
    if from_balance < amount:
        print("insufficient funds")
        return False
    elif from_balance == amount:
        Delete(ctx, t_from)
    else:
        difference = from_balance - amount
        Put(ctx, t_from, difference)

    to_balance = Get(ctx, t_to)
    to_total = to_balance + amount
    Put(ctx, t_to, to_total)

    OnTransfer(t_from, t_to, amount)

    return True
Пример #14
0
def delete(data):
    if not Get(ctx, data[IDX_KEY]):
        print('Error: Entry does not exist!')
        return False

    Delete(ctx, data[IDX_KEY])
    return True
Пример #15
0
def do_approve(ctx, t_owner, t_spender, amount):

    if len(t_spender) != 20:
        return False

    if not CheckWitness(t_owner):
        return False

    if amount < 0:
        return False

    # cannot approve an amount that is
    # currently greater than the from balance
    if Get(ctx, t_owner) >= amount:

        approval_key = concat(t_owner, t_spender)

        if amount == 0:
            Delete(ctx, approval_key)
        else:
            Put(ctx, approval_key, amount)

        OnApprove(t_owner, t_spender, amount)

        return True

    return False
Пример #16
0
def DoTransfer(t_from, t_to, amount):

    if amount <= 0:
        Log("Cannot transfer negative amount")
        return False
    from_is_sender = CheckWitness(t_from)
    if not from_is_sender:
        Log("Not owner of funds to be transferred")
        return False
    if t_from == t_to:
        Log("Sending funds to self")
        return True
    context = GetContext()
    from_val = Get(context, t_from)
    if from_val < amount:
        Log("Insufficient funds to transfer")
        return False
    if from_val == amount:
        Delete(context, t_from)
    else:
        difference = from_val - amount
        Put(context, t_from, difference)
    to_value = Get(context, t_to)
    to_total = to_value + amount
    Put(context, t_to, to_total)
    DispatchTransferEvent(t_from, t_to, amount)
    return True
Пример #17
0
def give_user_gas(ad_id, reciever_id, reciever_ad_count):

    reciever_info = list(length=5)
    ad_data = list(length=8)

    ad_id = args[0]
    reciever_id = args[1]
    reciever_ad_count = args[2]
    if reciever_ad_count < 1:
        return 'User did not view any ads'

        ad_data = deserialize_bytearray(Get(ctx, ad_id))
        ad_gas_amount = ad_data[7]
        reciever_info = Get(ctx, reciever_id)
        ad_gas_amount = ad_gas_amount / 2
        reciever_info[3] = ad_gas_amount
        reciever_info[4] = reciever_info[4] + 1
        Delete(ctx, reciever_id)
        data_serialized = serialize_array(reciever_info)

        Put(ctx, reciever_id, data_serialized)
        if transfer:
            Notify(' Transaction approved')
            update_gas = update_gas(ad_id, ad_gas_amount)
            if update_gas:
                Notify("Gas amount on acc updated ")
                return True
    return False
Пример #18
0
def DoTransfer(t_from, t_to, amount):
    """
    Method to transfer NEP5 tokens of a specified amount from one account to another

    :param t_from: the address to transfer from
    :type t_from: bytearray

    :param t_to: the address to transfer to
    :type t_to: bytearray

    :param amount: the amount of NEP5 tokens to transfer
    :type amount: int

    :return: whether the transfer was successful
    :rtype: bool

    """
    if amount <= 0:
        print("cannot transfer zero or less")
        return False

    from_is_sender = CheckWitness(t_from)

    if from_is_sender:

        if t_from == t_to:
            return True

        context = GetContext()

        from_val = Get(context, t_from)

        if from_val < amount:
            print("Insufficient funds")
            return False

        if from_val == amount:
            print("Removing all funds!")
            Delete(context, t_from)

        else:
            difference = from_val - amount
            Put(context, t_from, difference)

        to_value = Get(context, t_to)

        to_total = to_value + amount

        Put(context, t_to, to_total)

        OnTransfer(t_from, t_to, amount)

        return True
    else:
        print("from address is not the tx sender")

    return False
Пример #19
0
def do_transfer(ctx, t_from, t_to, amount):
    """
    Method to transfer NEP5 tokens of a specified amount from one account to another

    :param t_from: the address to transfer from
    :type t_from: bytearray
    :param t_to: the address to transfer to
    :type t_to: bytearray
    :param amount: the amount of NEP5 tokens to transfer
    :type amount: int

    :return: whether the transfer was successful
    :rtype: bool

    """

    if amount <= 0:
        return False

    if len(t_from) != 20:
        return False

    if len(t_to) != 20:
        return False

    if CheckWitness(t_from):

        if t_from == t_to:
            print("transfer to self!")
            return True

        from_val = Get(ctx, t_from)

        if from_val < amount:
            print("insufficient funds")
            return False

        if from_val == amount:
            Delete(ctx, t_from)

        else:
            difference = from_val - amount
            Put(ctx, t_from, difference)

        to_value = Get(ctx, t_to)

        to_total = to_value + amount

        Put(ctx, t_to, to_total)

        OnTransfer(t_from, t_to, amount)

        return True
    else:
        print("from address is not the tx sender")

    return False
Пример #20
0
def do_approve(ctx, caller, t_receiver, t_id, revoke):
    """Approve a token to eventually be transferred to the t_receiver

    :param StorageContext ctx: current store context
    :param byte[] caller: calling script hash
    :param byte[] t_receiver: address of the future token owner
    :param bytes t_id: int: token id
    :param bytes revoke: set to 1 to revoke previous approval
    :return: approval success
    :rtype: bool
    """
    if len(t_receiver) != 20:
        Notify(INVALID_ADDRESS_ERROR)
        return False

    if len(revoke) == b'\x00':
        revoke = b'\x00'

    t_owner = Get(ctx, t_id)
    if len(t_owner) != 20:
        Notify(TOKEN_DNE_ERROR)
        return False

    if t_owner == t_receiver:
        Notify('approved spend to self')
        return True

    is_token_owner = CheckWitness(t_owner)
    if is_token_owner and GetEntryScriptHash() != caller:
        Notify('third party script is bouncing the signature to us')
        return False
    # if token owner is a smart contract and is the calling
    # script hash, continue
    elif GetContract(t_owner) and t_owner == caller:
        is_token_owner = True

    if is_token_owner:
        approval_key = concat('approved/', t_id)
        # revoke previous approval if revoke != 0
        if revoke != b'\x00':
            Delete(ctx, approval_key)
            # log the revoking of previous approvals
            OnApprove(t_owner, t_receiver, b'\x00')
            OnNFTApprove(t_owner, '', t_id)
            return True

        # approve this transfer
        Put(ctx, approval_key, concat(t_owner, t_receiver))

        # Log this approval event
        OnApprove(t_owner, t_receiver, 1)
        OnNFTApprove(t_owner, t_receiver, t_id)
        return True

    Notify(PERMISSION_ERROR)
    return False
def delete_partnership(adr):
    msg = concat("Delete Partnership: ", adr)
    Notify(msg)

    termsba = Get(ctx, adr)
    if not termsba:
        Notify("Partnership for address is not yet created")
        return False
    Delete(ctx, adr)
    return True
Пример #22
0
def do_delete():
    """
    Delete the storage and reset back to its default state.

    :return: indication success execution of the command
    :rtype: bool
    """
    context = GetContext()
    Delete(context, KEY)
    return True
Пример #23
0
def do_transfer_from(ctx, t_from, t_to, t_id):

    if len(t_id) == 0:
        t_id = 0

    if len(t_from) != 20:
        return False

    if len(t_to) != 20:
        return False

    if t_from == t_to:
        print("transfer to self!")
        return True

    t_owner = Get(ctx, t_id)

    if len(t_owner) != 20:
        print("token does not exist")
        return False

    if (t_from != t_owner):
        print("from address is not the owner of this token")
        return False

    approval_key = concat("approved/", t_id)
    authorized_spend = Get(ctx, approval_key)

    if len(authorized_spend) == 0:
        print("no approval exists for this token")
        return False

    if authorized_spend == concat(t_from, t_to):

        res = removeTokenFromOwnersList(ctx, t_from, t_id)
        if res == False:
            print("unable to transfer token")
            return False

        addTokenToOwnersList(ctx, t_to, t_id)

        Put(ctx, t_id, t_to)

        # remove the approval for this token
        Delete(ctx, approval_key)

        print("transfer complete")

        OnTransfer(t_from, t_to, 1)
        OnNFTTransfer(t_from, t_to, t_id)

        return True

    print("spend not approved")
    return False
Пример #24
0
def DoTransfer(sender, receiver, amount):
    """
    Method to transfer tokens from one account to another

    :param sender: the address to transfer from
    :type sender: bytearray

    :param receiver: the address to transfer to
    :type receiver: bytearray

    :param amount: the amount of tokens to transfer
    :type amount: int

    :return: whether the transfer was successful
    :rtype: bool

    """

    if amount <= 0:
        Log("Cannot transfer negative amount")
        return False

    from_is_sender = CheckWitness(sender)

    if not from_is_sender:
        Log("Not owner of funds to be transferred")
        return False

    if sender == receiver:
        Log("Sending funds to self")
        return True

    context = GetContext()
    from_val = Get(context, sender)

    if from_val < amount:
        Log("Insufficient funds to transfer")
        return False

    if from_val == amount:
        Delete(context, sender)

    else:
        difference = from_val - amount
        Put(context, sender, difference)

    to_value = Get(context, receiver)

    to_total = to_value + amount

    Put(context, receiver, to_total)
    DispatchTransferEvent(sender, receiver, amount)

    return True
Пример #25
0
def update_gas(ad_id, ad_gas_amount):

    data = list(length=8)
    data = Get(ctx, ad_id)
    data = deserialize_bytearray(Get(ctx, ad_id))
    data[7] = ad_gas_amount
    Delete(ctx, ad_id)
    data_serialized = serialize_array(data)
    Put(ctx, ad_id, data_serialized)
    Notify("Ad gas amount updated to ", ad_gas_amount)
    return True
Пример #26
0
def Delete(domain):
    context = GetContext()
    owner = Get(context, domain)
    is_owner = CheckWitness(owner)
    if not is_owner:
        return False

    Delete(context, domain)
    Notify('Delete', domain)

    return True
Пример #27
0
def Main(operation, args):
    """
    :param operation: str The name of the operation to perform
    :param args: list A list of arguments along with the operation
    """

    if operation == 'GetVersion':
        # very simple method to test the contract
        Log("Invoked GetVersion")
        return BZSVERSION

    # Am I who I say I am? args[0] musth be the wallet hash code
    authorized = CheckWitness(args[0])
    if not authorized:
        Log("Not Authorized")
        return 'Not Authorized'
    Log(args[0])

    # storage operations
    if operation == 'Store':
        if len(args) < 4:
            return 'Invalid arguments'
        category = args[1]
        id = args[2]
        put(category, id, args[3])  # args[3] = arbitrary payload
        Notify(['Store:', category, id])
        return 'OK'

    if operation == 'Retrieve':
        if len(args) < 3:
            return 'Invalid arguments'
        category = args[1]
        id = args[2]
        data = get(category, id)
        Notify(['Retrieve:', category, id])
        return data

    if operation == 'Delete':
        if len(args) < 3:
            return 'Invalid arguments'
        category = args[1]
        id = args[2]
        skey = concat(category, id)
        Delete(GetContext(), skey)
        Notify(['Delete:', category, id])
        return 'OK'

#    if operation in pawnOps:
#        print("SmartPawn operation")
#        sp = SmartPawn(store)
#        return sp.execute(operation, args)

    return 'Invalid operation'
Пример #28
0
def Main(hand, txn_cost):
    context = GetContext()

    print(hand)
    current_hand = Get(context, "hand")
    # TODO: saving the current account ID so that if they lose, they lose money

    total_amount = 0
    amount = Get(context, "amount")

    if not amount:
        Put(context, "amount", txn_cost)
    else:
        total_amount = amount + txn_cost
    # TODO: deducting the amount from the account

    if not current_hand:
        Put(context, "hand", hand)
        print("Played " + hand + ", waiting for next hand.")
        return 0
    else:
        Delete(context, "hand")
        Delete(context, "amount")

        if (hand == b"rock" and current_hand == b"paper") or (
                hand == b"paper" and current_hand == b"scissors") or (
                    hand == b"scissors" and current_hand == b"rock"):
            print("You lose! Amount")
            return -txn_cost
            # TODO: adding the amount to the account
        elif (hand == b"scissors" and current_hand == b"paper") or (
                hand == b"paper" and current_hand == b"rock") or (
                    hand == b"rock" and current_hand == b"scissors"):
            print("You win!")
            return total_amount
            # TODO: handle deducting money from the user
        else:
            print("Draw!")
            return 0
Пример #29
0
def transfer(context, arguments):

    address = arguments[0]
    to = arguments[1]
    amount = arguments[2]

    # Allow only authenticated requests
    if not CheckWitness(address):
        print('Permission denied')
        return False

    # To address has to be 20 bytes
    if len(to) != 20:
        print('Address is incorrect')
        return False

    # Allow only a positive amount
    if not amount >= 0:
        print('Amount must be positive')
        return False

    balance = Get(context, address)

    if balance < amount:
        print('Insufficient funds')
        return False

    if address == to:
        return True

    # Calculate the balance for the sender
    if balance == amount:
        Delete(context, address)
    else:
        balance = balance - amount
        Put(context, address, balance)

    # Check if the tokens have been burned
    if to == burn:
        # Reduce supply when tokens are burned
        print('Tokens have been burned')
        supply = Get(context, 'circulating') - amount
        Put(context, 'circulating', supply)
    else:
        # Calculate the balance for the recipient
        balance = Get(context, to) + amount
        Put(context, to, balance)

    # Send the notification
    OnTransfer(address, to, amount)
    return True
def transfer(from_address, to_address):
    frm = concat("From ", from_address)
    to = concat("To ", to_address)
    msg = concat("Transfer Partnership: ", frm)
    msg = concat(msg, to)
    Notify(msg)

    termsba = Get(ctx, from_address)
    if not termsba:
        Notify("Partnership for address is not yet created")
        return False
    Put(ctx, to_address, termsba)
    Delete(ctx, from_address)
    return True