The transfer
instruction is used to transfer Tezis to an account.
effect {transfer 1tez to coder;}
where coder
is a role
variable.
It is possible to call a smart contract with the transfer
instruction. Say for example you want to call the set_value
entry point of the following contract:
archetype contract_calledvariable v : nat = 0entry set_value(x : nat) { v := x }
The contract may then be called with the transfer ... to ... call ...
instruction:
effect {var c = @KT1RNB9PXsnp7KMkiMrWNMRzPjuefSWojBAm;transfer 0tez to c call add_value<nat>(3);}
Note that it fails if the contract at address c
does not provide an entry point annotated %add_value
It is possible to call the current contract itself. Say the current contract has the my_add_value
entry point; it is possible to call it from another entry point with the following instruction:
entry my_add_value(int a, int b) {sum := a + b;}entry add_1_3 () {transfer 0tez to entry self.my_add_value(1,3)}
A common pattern for contracts to exchange values is to call an entry point with a callback.
This pattern is presented in the two-way-inter-contract invocation article below:
The archetype version of the sender contract (see article above):
archetype sendervariable bar : int = 0getter getBar () { return bar }entry setBar (b : int) { bar := b }
It uses the getter
keyword used to declare an entry point to the contract called "getBar"; the Michelson version of this entry actually takes a callback function (a setter) used to set/use the bar
value in another contract. It is syntactic sugar equivalent to the following entry declaration:
entry getBar (cb : entrysig<int>) { transfer 0tz to entry cb(bar) }
The entrysig
type is used to declare the callback type; it is parametrized by the signature of the callback, represented as the tuple of argument types.
The difference between the getter
and entry
versions of the getBar
entry above is that the callback argument is anonymous in the getter
version.
The archetype version of the inspector contract (see article above):
archetype inspectorvariable foo : int = 0entry setFoo(v : int) { foo := v }entry getFoo(asender : address) {transfer 0tez to asender call getBar<entrysig<int>>(self.setFoo)}
The entrypoint
function may be used to build an entrysig value from the name and the address. It returns an option value of entrysig type, so that it is possible to handle the case when the entry point does not exist.
The above inspector contract may be rewritten as:
archetype inspectorvariable foo : int = 0entry setFoo(v : int) { foo := v }entry getFoo(asender : address) {var entryopt = entrypoint<entrysig<int>>("%getBar", asender);if issome(entryopt) then (var e = opt_get(entryopt);transfer 0tez to entry e(self.setFoo))else fail("could not find getBar entry or invalid address")}