#Correct way to send non-Mina tokens from one zkApp account to another

12 messages · Page 1 of 1 (latest)

spark trench
#

As title says, working on tutorial 11 (advanced account updates), and having a hard time getting an account to send tokens from itself to another account.

Have the following code in the "TokenUser" account:

  @method sendMyTokens(
    amount: UInt64, 
    destination: PublicKey
  ) {
    const myTokenInstance = new MyToken(TokenUser.myTokenPublicKey);

    const tokenUserContract = new TokenUser(
      this.address,
      myTokenInstance.token.id
    );
    tokenUserContract.subtractTokens(amount);
    const subtractTokens = tokenUserContract.self;
    
    myTokenInstance.approveTransfer(subtractTokens, destination, amount);
  }

  @method subtractTokens(amount: UInt64) {
    // TODO this could let anyone subtract balance, how to do this pattern correctly so that balance is only subtracted if the "other half" of the intended behavior performed? (in this case, tokens being sent elsewhere)
    this.balance.subInPlace(amount);
  }

And the following code in the MyToken Account:

  @method approveTransfer(
    transferUpdate: AccountUpdate,
    to: PublicKey,
    amount: UInt64
  ) {
    // TODO assert not approvign anything else
    this.approve(transferUpdate);

    // see if balance change cancels the amount sent
    let balanceChange = Int64.fromObject(transferUpdate.body.balanceChange);
    balanceChange.assertEquals(Int64.from(amount).neg());

    // add same amount of tokens to the receiving address
    this.token.mint({ address: to, amount });
  }

Yielding the following error:

Error: [[["Token_owner_not_caller"]],[["Cancelled"]],[["Cancelled"]],[["Cancelled"]],[["Cancelled"]]]

Code found here: https://github.com/o1-labs/docs2/tree/tutorial-11/examples/zkapps/11-advanced-account-updates

Thanks, any ideas towards fixing appreciated

GitHub

Docs website for the Mina Protocol. Contribute to o1-labs/docs2 development by creating an account on GitHub.

granite kestrel
#

What is your account / token structure? Here's an example diagram of how i am using tokens right now

#

i can't seem to run your code, running into this issue, what nodejs ver. and what cmd do you use to run this?

#

this should be the answer to your question, your TokenUser, in my case TokenHolder, has to:

  • sub its own balance
  • mark self account update as 'parent owns token'
  • has to issue a child account update for its sibling (both accounts children of the token account itself)
  • the child account update must inherit token permissions from parent (self)

inspecting the call depth of the created account updates makes this whole concept click together - especially the mayUseToken relationship which is also shown on the diagram above

#

i think you also have to be careful with this code since it might create another level of call depth nesting in your account update structure:

    const tokenUserContract = new TokenUser(
      this.address,
      myTokenInstance.token.id
    );
    tokenUserContract.subtractTokens(amount);
#

to help any further i would need to run it - but got the ENOENT error unfortunately

#

aaand just to add this sibling transfer implies the receiving account is not a zkApp, or if it is it doesnt have receive permissions as ‘proof’, in that case i dont think the logic above would work and its something i have to investigate myself

spark trench
#

Thanks! Yeah got this working with the above! Now just to add constraints to the account updates being approved