I want to create a simple smart contract (stateless or stateful) that sends an asset to another address but I didn’t find any sample for it. I want to call the deployed app from a client application.
Could you please guide me on how to implement this? Is there an example code for something like this?
See
for the TEAL code (the code of the smart contract)
A full example for payment transactions: https://developer.algorand.org/tutorials/creating-a-license-manager-contract-utilizing-pyteal-and-inner-transactions/?from_query=inner%20transaction
This can easily be adapted for asset transactions.
Thank you, I used this example.
My issue is that the app call runs successfully but no asset transfer happens.
Now i just have one transaction for call app with ApplicationNoOpTxn
,I wonder if I need to perform a group transaction (one for app call and another for asset transfer inner transaction)? if yes, how should I do that?(the example used goal
but i want to implement it in pyteal code)
here is the app call transaction(I rekeyed the wallet address, which holds assets, to the application address. Which allows the application to transfer the assets.):
https://testnet.algoexplorer.io/tx/ZQTLARZGYY7UKG6YUENDPX3JX6XDVPGZR7RECVOOVXMDOSTEPO5A
Here is the code where i fill fields and also asset transfer subroutine:
@Subroutine(TealType.uint64)
def doTransfer():
return Seq(
inner_asset_transfer(Int(48519365),
Int(1),
Txn.accounts[1],
Txn.accounts[2]),
Int(1))
@Subroutine(TealType.none)
def inner_asset_transfer(asset_id: TealType.uint64, asset_amount: TealType.uint64, asset_sender: TealType.bytes,
asset_receiver: TealType.bytes) -> Expr:
return Seq([
InnerTxnBuilder.Begin(),
InnerTxnBuilder.SetFields({
TxnField.type_enum: TxnType.AssetTransfer,
TxnField.xfer_asset: asset_id,
TxnField.asset_sender: asset_sender,
TxnField.asset_amount: asset_amount,
TxnField.asset_receiver: asset_receiver,
TxnField.fee: Int(1000),
}),
InnerTxnBuilder.Submit()
])
program = Cond(
[Txn.application_id() == Int(0), on_creation],
[Txn.on_completion() == OnComplete.OptIn, handle_optin],
[Txn.on_completion() == OnComplete.CloseOut, handle_closeout],
[Txn.on_completion() == OnComplete.UpdateApplication, handle_updateapp],
[Txn.on_completion() == OnComplete.DeleteApplication, handle_deleteapp],
[Txn.on_completion() == OnComplete.NoOp, Return(doTransferFunc)],
)
Here is where i pass the arguments to the transaction (call app):
assets = [48519365]
txn = transaction.ApplicationNoOpTxn(sender, params, index, app_args, accounts, None, assets)
Thanks
Actually your smart contract worked and the inner transaction happened!
Just algoexplorer.io does not show inner transactions right now.
But you can see them using the indexer API:
(I’m using jq just for nicer JSON formatting)
$ curl -s https://testnet.algoexplorerapi.io/idx2/v2/transactions/ZQTLARZGYY7UKG6YUENDPX3JX6XDVPGZR7RECVOOVXMDOSTEPO5A | jq
{
"current-round": 18260976,
"transaction": {
"application-transaction": {
"accounts": [
"NQYDEZTWV4MNRZBI3DLWKX5C576PWWRA2ZFHCFHBUYZYBOCFCJB6BASBPQ",
"CIBXLVQ4EI6I2UG57RR3FW72MI6WSVCWLTDJW2GBSKOXJ34ZQGK4KC54C4"
],
"application-args": [
"QWRk"
],
"application-id": 48519967,
"foreign-apps": [],
"foreign-assets": [
48519365
],
"global-state-schema": {
"num-byte-slice": 0,
"num-uint": 0
},
"local-state-schema": {
"num-byte-slice": 0,
"num-uint": 0
},
"on-completion": "noop"
},
"close-rewards": 0,
"closing-amount": 0,
"confirmed-round": 18233308,
"fee": 1000,
"first-valid": 18233306,
"genesis-hash": "SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
"genesis-id": "testnet-v1.0",
"id": "ZQTLARZGYY7UKG6YUENDPX3JX6XDVPGZR7RECVOOVXMDOSTEPO5A",
"inner-txns": [
{
"asset-transfer-transaction": {
"amount": 1,
"asset-id": 48519365,
"close-amount": 0,
"receiver": "CIBXLVQ4EI6I2UG57RR3FW72MI6WSVCWLTDJW2GBSKOXJ34ZQGK4KC54C4",
"sender": "NQYDEZTWV4MNRZBI3DLWKX5C576PWWRA2ZFHCFHBUYZYBOCFCJB6BASBPQ"
},
"close-rewards": 0,
"closing-amount": 0,
"confirmed-round": 18233308,
"fee": 1000,
"first-valid": 18233306,
"intra-round-offset": 22,
"last-valid": 18234306,
"receiver-rewards": 0,
"round-time": 1638350421,
"sender": "CM4DTUWOFJ7YS5WLPN5GN3VC4A7DTSER65X5R5GRBRY6G43K3MNY26A7NY",
"sender-rewards": 0,
"tx-type": "axfer"
}
],
"intra-round-offset": 22,
"last-valid": 18234306,
"receiver-rewards": 0,
"round-time": 1638350421,
"sender": "X54JZH3JWESRP5DIPF6H6TEOURJUDMLFTWOKZY6T4V55L2VIA3BWRZCEJU",
"sender-rewards": 0,
"signature": {
"sig": "LbJqL0cYhiZbVBzGdXMZaiyjoZtiOTJWisrIVzJb4CvYH8/hnYBrEm1i1Mq2xuGp0L6iFCIrC062TXRIrSvcAQ=="
},
"tx-type": "appl"
}
}