💳Transfer

The function transfers the given amount to the receiver address.

There are four types of transfer:

1. function transfer(address _to, ctUint64 _itCT, bytes calldata _itSignature, bool revealRes) public returns (bool success);
2. function transfer(address _to, uint64 _value, bool revealRes) public returns (bool success);
3. function contractTransfer(address _to, gtUint64 _value) public returns (gtBool success)
4. function contractTransferClear(address _to, uint64 _value) public returns (gtBool success)
  • 1: Validates the inputText to get the required amount to transfer.

  • 3: Transfer an encrypted amount. This version is used by a contract that already has the value as encrypted gtUint64.

Parameters:

  • _to: The receiver address

  • _itCT, _itSignature: An encrypted value to transfer as an InputText

  • _value: The value to transfer (clear or encrypted depends on the type)

  • revealRes: A boolean indicates weather to reveal the result or not.

Return value:

  • 1,2: If revealRes is true, the result (success/failure) is decrypted and returned. Else, return true.

  • 3,4: Return the gtBool returned by the transfer operation.

Full Solidity Code

1.
// Transfers the amount of tokens given inside the IT (encrypted and signed value) 
// to address _to
// params: _to: the address to transfer to
//         _itCT: the encrypted value of the amount to transfer
//         _itSignature: the signature of the amount to transfer
//         revealRes: indicates if we should reveal the result of the transfer
// returns: In case revealRes is true, returns the result of the transfer. 
// In case revealRes is false, always returns true
function transfer(address _to, ctUint64 _itCT, bytes calldata _itSignature, 
                  bool revealRes) public returns (bool success){
    // Create IT from ciphertext and signature
    itUint64 memory it;
    it.ciphertext = _itCT;
    it.signature = _itSignature;
    // Verify the IT and transfer the value
    gtBool result = contractTransfer(_to, MpcCore.validateCiphertext(it));
    if (revealRes){
        return MpcCore.decrypt(result);
    } else {
        return true;
    }
}
2.
// Transfers the amount of tokens to address _to
// params: _to: the address to transfer to
//         _value: the value of the amount to transfer
//         revealRes: indicates if we should reveal the result of the transfer
// returns: In case revealRes is true, returns the result of the transfer. 
// In case revealRes is false, always returns true
function transfer(address _to, uint64 _value, bool revealRes) 
                  public returns (bool success){
    gtBool result = contractTransferClear(_to, _value);

    if (revealRes){
        return MpcCore.decrypt(result);
    } else {
        return true;
    }
}
3. 
// Transfers the amount of tokens given inside the encrypted value to address _to
// params: _to: the address to transfer to
//         _value: the encrypted value of the amount to transfer
// returns: The encrypted result of the transfer.
function contractTransfer(address _to, gtUint64 _value) 
                          public returns (gtBool success){
    (gtUint64 fromBalance, gtUint64 toBalance) = getBalances(msg.sender, _to);
    (gtUint64 newFromBalance, gtUint64 newToBalance, gtBool result) = 
                          MpcCore.transfer(fromBalance, toBalance, _value);

    emit Transfer(msg.sender, _to);
    setNewBalances(msg.sender, _to, newFromBalance, newToBalance);

    return result;
}
4. 
// Transfers the amount of tokens to address _to
// params: _to: the address to transfer to
//         _value: the value of the amount to transfer
// returns: The encrypted result of the transfer.
function contractTransferClear(address _to, uint64 _value) 
                               public returns (gtBool success){
    (gtUint64 fromBalance, gtUint64 toBalance) = getBalances(msg.sender, _to);
    (gtUint64 newFromBalance, gtUint64 newToBalance, gtBool result) = 
                               MpcCore.transfer(fromBalance, toBalance, _value);

    emit Transfer(msg.sender, _to, _value);
    setNewBalances(msg.sender, _to, newFromBalance, newToBalance);

    return result;
}

Example Usage

plaintext_integer = 5
print("************* Transfer clear ", plaintext_integer, " to Alice *************")
# Transfer 5 SOD to Alice
function = contract.functions.transfer(alice_address.address, plaintext_integer, True)
execute_and_check_balance(soda_helper, account, contract, function, user_key, 'transfer', INITIAL_BALANCE - plaintext_integer)

print("************* Transfer clear ", plaintext_integer, " to Alice *************")
# Transfer 5 SOD to Alice
function = contract.functions.contractTransferClear(alice_address.address, plaintext_integer)
execute_and_check_balance(soda_helper, account, contract, function, user_key, 'contract transfer clear', INITIAL_BALANCE - 2*plaintext_integer)

print("************* Transfer IT ", plaintext_integer, " to Alice *************")
# In order to generate the input text, we need to use some data of the function. 
# For example, the address of the user, the address of the contract and also the function signature.
# To simplify the process of obtaining the function signature, we use a dummy function with placeholder inputs.
# After the signature is generated, we call prepare input text function and get the input text to use in the real function.
dummyCT = 0
dummySignature = bytes(65)
function = contract.functions.transfer(alice_address.address, dummyCT, dummySignature, False)
func_sig = get_function_signature(function.abi) # Get the function signature
# Prepare the input text for the function
ct, signature = prepare_IT(plaintext_integer, user_key, account, contract, func_sig, bytes.fromhex(private_key[2:]))
# Create the real function using the prepared IT
function = contract.functions.transfer(alice_address.address, ct, signature, False)
# Transfer 5 SOD to Alice
execute_and_check_balance(soda_helper, account, contract, function, user_key, 'transfer IT', INITIAL_BALANCE - 3*plaintext_integer)

Last updated