Skip to main content
Version: 19.1.0

Examples demonstrating transfers between various address types

In Tezos, a transfer operation transfers tokens between two addresses.

When the Babylon/proto005 protocol amendment came into effect, it changed how token transfer involving KT1 addresses work. The transfer of tokens from a KT1 account is completed by calling the KT1's smart contract do method. The do method takes a lambda function, and it is the logic of this function that causes the desired transfer of tokens to happen.

The Taquito integration tests can be useful to see how this works.

Transfer from an implicit mv1 address to a mv1 addressโ€‹

This is the simplest token transfer scenario

await Tezos.contract.transfer({ to: contract.address, amount: 1 });

In the following example, we transfer 0.5แน from a mv1PYMQXgRiJBMsrEaM9Yre4JyvcLVbUr8pv address that signs the operation to mv1UrqbBFBXnEdHnvSrMpt2BQnZzFMA9HQnc.

Live Editor
Result

Transfers involving "originated" KT1 addressesโ€‹

Pre-Babylon/proto005 "script-less" KT1 addresses were common. This situation changed when the Tezos blockchain migrated to the new Babylon/proto005 protocol.

During the migration from proto004 to proto005, all KT1 addresses migrated so that they got a contract called manager.tz. This change meant that there are no longer any "script-less" KT1 addresses in Tezos.

A call to the KT1's smart contracts' do method is required to transfer tokens from KT1 addresses with the new manager.tz contract. The do method takes a lambda function, and it is this lambda function that causes changes to occur in the KT1 address.

The examples following apply only to KT1 addresses migrated as part of the Babylon/proto005 upgrade. Transfers involving other types of smart-contracts depend on those contracts specifically.

Transfer 0.00005 (50 mumav) tokens from a KT1 address to a mv1 addressโ€‹

Sending 50 mumav from kt1... to mv1UE4jMeeBM49FjNmyvtE19aBKT73HDvM2m.

Example transfer from a KT1 to a mv1 address on Carthage/Proto006โ€‹

const contract = await Tezos.contract.at('kt1...');
await contract.methodsObject
.do(transferImplicit('mv1UE4jMeeBM49FjNmyvtE19aBKT73HDvM2m', 50))
.send({ amount: 0 });

Where transferImplicit is a function that returns the necessary Michelson lambda. It looks like this:

export const transferImplicit = (key: string, mumav: number) => {
return [
{ prim: 'DROP' },
{ prim: 'NIL', args: [{ prim: 'operation' }] },
{
prim: 'PUSH',
args: [{ prim: 'key_hash' }, { string: key }],
},
{ prim: 'IMPLICIT_ACCOUNT' },
{
prim: 'PUSH',
args: [{ prim: 'mumav' }, { int: `${mumav}` }],
},
{ prim: 'UNIT' },
{ prim: 'TRANSFER_TOKENS' },
{ prim: 'CONS' },
];
};

Transfer 0.000001 (1 mumav) tokens from a KT1 address to a KT1 addressโ€‹

Sending 1 mumav to KT1KLbEeEgW5h1QLkPuPvqdgurHx6v4hGyic from KT1...

Example for Babylon/Proto005 or higherโ€‹

const contract = await Tezos.contract.at('KT1...');
await contract.methodsObject
.do(transferToContract('KT1KLbEeEgW5h1QLkPuPvqdgurHx6v4hGyic', 1))
.send({ amount: 0 });

Where transferToContract is a function that looks like this:

export const transferToContract = (key: string, amount: number) => {
return [
{ prim: 'DROP' },
{ prim: 'NIL', args: [{ prim: 'operation' }] },
{
prim: 'PUSH',
args: [{ prim: 'address' }, { string: key }],
},
{ prim: 'CONTRACT', args: [{ prim: 'unit' }] },
[
{
prim: 'IF_NONE',
args: [[[{ prim: 'UNIT' }, { prim: 'FAILWITH' }]], []],
},
],
{
prim: 'PUSH',
args: [{ prim: 'mumav' }, { int: `${amount}` }],
},
{ prim: 'UNIT' },
{ prim: 'TRANSFER_TOKENS' },
{ prim: 'CONS' },
];
};

Provide detailed feedback