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 tz1 address to a tz1 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 tz1aaYoabvj2DQtpHz74Z83fSNjY29asdBfZ
address that signs the operation to tz1h3rQ8wBxFd8L9B3d7Jhaawu6Z568XU3xY
.
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 mutez) tokens from a KT1 address to a tz1 address
Sending 50 mutez from kt1...
to tz1eY5Aqa1kXDFoiebL28emyXFoneAoVg1zh
.
Example transfer from a KT1 to a tz1 address on Carthage/Proto006
const contract = await Tezos.contract.at('kt1...');await contract.methodsObject.do(transferImplicit('tz1eY5Aqa1kXDFoiebL28emyXFoneAoVg1zh', 50)).send({ amount: 0 });
Where transferImplicit
is a function that returns the necessary Michelson lambda. It looks like this:
export const transferImplicit = (key: string, mutez: number) => {return [{ prim: 'DROP' },{ prim: 'NIL', args: [{ prim: 'operation' }] },{prim: 'PUSH',args: [{ prim: 'key_hash' }, { string: key }],},{ prim: 'IMPLICIT_ACCOUNT' },{prim: 'PUSH',args: [{ prim: 'mutez' }, { int: `${mutez}` }],},{ prim: 'UNIT' },{ prim: 'TRANSFER_TOKENS' },{ prim: 'CONS' },];};
Transfer 0.000001 (1 mutez) tokens from a KT1 address to a KT1 address
Sending 1 mutez 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: 'mutez' }, { int: `${amount}` }],},{ prim: 'UNIT' },{ prim: 'TRANSFER_TOKENS' },{ prim: 'CONS' },];};