Search code examples
smartcontractsscrypto

Radix Scrypto transaction manifest multiple transfer from account


How do we do multiple transfers of tokens from an account in one manifest? For example:

Account A -- Token A --> Account B

Account A -- Token B --> Account B

Account A -- Token A --> Account C

Account A -- Token B --> Account C

I did this:

CLONE_BUCKET_REF BucketRef(1u32) BucketRef("badge1");
CALL_METHOD Address("0293c502780e23621475989d707cd8128e4506362e5fed6ac0c00a") "withdraw" Decimal("2000") Address("03bcc1960b6f99bae8614c3bf276ee3217f800f5cc7bdc48db9a5f") BucketRef("badge1");

CALL_METHOD_WITH_ALL_RESOURCES Address("02a2a79aa613da237bcda37fd79af36e09eadd195976092cb24696") "deposit_batch";

CLONE_BUCKET_REF BucketRef(1u32) BucketRef("badge2");
CALL_METHOD Address("0293c502780e23621475989d707cd8128e4506362e5fed6ac0c00a") "withdraw" Decimal("2000") Address("031773788de8e4d2947d6592605302d4820ad060ceab06eb2d4711") BucketRef("badge2");

CALL_METHOD_WITH_ALL_RESOURCES Address("02a2a79aa613da237bcda37fd79af36e09eadd195976092cb24696") "deposit_batch";

CLONE_BUCKET_REF BucketRef(1u32) BucketRef("badge3");
CALL_METHOD Address("0293c502780e23621475989d707cd8128e4506362e5fed6ac0c00a") "withdraw" Decimal("2000") Address("03bcc1960b6f99bae8614c3bf276ee3217f800f5cc7bdc48db9a5f") BucketRef("badge3");
CALL_METHOD_WITH_ALL_RESOURCES Address("0236ca00316c8eb5ad51b0cb5e3f232cb871803a85ec3847b36bb4") "deposit_batch";

CLONE_BUCKET_REF BucketRef(1u32) BucketRef("badge4");
CALL_METHOD Address("0293c502780e23621475989d707cd8128e4506362e5fed6ac0c00a") "withdraw" Decimal("2000") Address("031773788de8e4d2947d6592605302d4820ad060ceab06eb2d4711") BucketRef("badge4");

CALL_METHOD_WITH_ALL_RESOURCES Address("0236ca00316c8eb5ad51b0cb5e3f232cb871803a85ec3847b36bb4") "deposit_batch";

But i get this error:

Error: CompileError(GeneratorError(IdValidatorError(BucketRefNotFound(Rid(1)))))

It looks like we lose all reference to an account when we call CALL_METHOD_WITH_ALL_RESOURCES


Solution

  • You're indeed correct, the CALL_METHOD_WITH_ALL_RESOURCES instruction drops all of the BucketRefs in the transaction. The specific line where this happens is: https://github.com/radixdlt/radixdlt-scrypto/blob/7cb4af0b35b8462f214e839590234602a11281d0/radix-engine/src/engine/process.rs#L367

    One of way you could work around this is by avoiding the use of the CALL_METHOD_WITH_ALL_RESOURCES before the end of the rtm file and instead replacing the CALL_METHOD_WITH_ALL_RESOURCES in your rtm file with TAKE_ALL_FROM_WORKTOP and regular deposit method calls.

    So as a high level view, what we're trying to do for each of the transfers is: 1- Clone the badge. 2- Withdraw the tokens using cloned badge. 3- Create a bucket out of the withdrawn tokens. 4- Depositing the bucket we just created into the receiver's account.

    I have made the above described modifications to your rtm file:

    CLONE_BUCKET_REF BucketRef(1u32) BucketRef("badge1");
    CALL_METHOD Address("0293c502780e23621475989d707cd8128e4506362e5fed6ac0c00a") "withdraw" Decimal("2000") Address("03bcc1960b6f99bae8614c3bf276ee3217f800f5cc7bdc48db9a5f") BucketRef("badge1");
    TAKE_ALL_FROM_WORKTOP Address("03bcc1960b6f99bae8614c3bf276ee3217f800f5cc7bdc48db9a5f") Bucket("transfer1_bucket");
    CALL_METHOD Address("02a2a79aa613da237bcda37fd79af36e09eadd195976092cb24696") "deposit" Bucket("transfer1_bucket");
    
    CLONE_BUCKET_REF BucketRef(1u32) BucketRef("badge2");
    CALL_METHOD Address("0293c502780e23621475989d707cd8128e4506362e5fed6ac0c00a") "withdraw" Decimal("2000") Address("031773788de8e4d2947d6592605302d4820ad060ceab06eb2d4711") BucketRef("badge2");
    TAKE_ALL_FROM_WORKTOP Address("031773788de8e4d2947d6592605302d4820ad060ceab06eb2d4711") Bucket("transfer2_bucket");
    CALL_METHOD Address("02a2a79aa613da237bcda37fd79af36e09eadd195976092cb24696") "deposit" Bucket("transfer2_bucket");
    
    CLONE_BUCKET_REF BucketRef(1u32) BucketRef("badge3");
    CALL_METHOD Address("0293c502780e23621475989d707cd8128e4506362e5fed6ac0c00a") "withdraw" Decimal("2000") Address("03bcc1960b6f99bae8614c3bf276ee3217f800f5cc7bdc48db9a5f") BucketRef("badge3");
    TAKE_ALL_FROM_WORKTOP Address("03bcc1960b6f99bae8614c3bf276ee3217f800f5cc7bdc48db9a5f") Bucket("transfer3_bucket");
    CALL_METHOD Address("0236ca00316c8eb5ad51b0cb5e3f232cb871803a85ec3847b36bb4") "deposit" Bucket("transfer3_bucket");
    
    CLONE_BUCKET_REF BucketRef(1u32) BucketRef("badge4");
    CALL_METHOD Address("0293c502780e23621475989d707cd8128e4506362e5fed6ac0c00a") "withdraw" Decimal("2000") Address("031773788de8e4d2947d6592605302d4820ad060ceab06eb2d4711") BucketRef("badge4");
    TAKE_ALL_FROM_WORKTOP Address("031773788de8e4d2947d6592605302d4820ad060ceab06eb2d4711") Bucket("transfer4_bucket");
    CALL_METHOD Address("0236ca00316c8eb5ad51b0cb5e3f232cb871803a85ec3847b36bb4") "deposit" Bucket("transfer4_bucket");
    

    Edit: I just want to highlight that this answer is for Scrypto v0.3.0.